[CMake] How too set properties on all executables

Michael Hertling mhertling at online.de
Fri Feb 25 00:14:43 EST 2011


On 02/24/2011 09:34 PM, Hanna Symanska wrote:
> Hey,
> I have a fairly large project with multiple executables, about 90 to
> be exact and I would like to set the subsystem based on the
> LINK_FLAGS_* property.
> Is there a way for me to globally set this up in a top level
> CMakeLists.txt file so that i do not have to place the below code in
> every single project.
> add_executable(project_n ....)
> IF (WIN32)
>   SET_TARGET_PROPERTIES(project_n PROPERTIES LINK_FLAGS_RELEASE
> "/INCREMENTAL:NO /NODEFAULTLIB:LIBCMT.lib /SUBSYSTEM:WINDOWS" )
>   SET_TARGET_PROPERTIES(project_n PROPERTIES LINK_FLAGS_RELWITHDEBINFO
> "/NODEFAULTLIB:LIBCMT.lib /SUBSYSTEM:WINDOWS" )
>   SET_TARGET_PROPERTIES(project_n PROPERTIES LINK_FLAGS_DEBUG
> "/NODEFAULTLIB:LIBCMTD.lib /SUBSYSTEM:CONSOLE" )
> ENDIF (WIN32)
> 
> As it stands right now I have a top level CMakeLists.txt file with
> several other CMakeLists.txt files in subsequent directories.
> I have 1 CMakeLists.txt per project executable. I am trying to avoid
> putting the above code in EVERY CMakeLists.txt file, when the only
> thing I am changing is the target to reflect the the project that I am
> setting the properties on.
> I am using CMake 2.8.4 to generate visual studio 2008 project files to
> be compiled 64-bit.
> I do not want to use set_executable(project_n WIN32...) because I want
> the subsystem to be console for projects that are being compiled as
> debug.
> - Hanna

AFAIK, you can't set the LINK_FLAGS properties in a global manner as
you do above for a single target. However, possible alternatives are:

1) In the top-level CMakeLists.txt, write a function SET_EXECUTABLE()
   or the like which contains the IF/ENDIF block and apply it in each
   subordinated CMakeLists.txt.

2) Similarly, write a function MY_ADD_EXECUTABLE() or the like which
   encompasses the actual ADD_EXECUTABLE() and the IF/ENDIF block.

3) Rewrite ADD_EXECUTABLE() like:

   FUNCTION(ADD_EXECUTABLE TARGET)
       _ADD_EXECUTABLE(${TARGET} ${ARGN})
       IF (WIN32)
           ....
       ENDIF (WIN32)
   ENDFUNCTION()

   Note that the original function is still available, cf. [1].

4) Collect the concerned executable targets in a variable or,
   preferably, in a global property - perhaps by use of special or
   customized functions similar to the ones above - and impose the
   LINK_FLAGS properties in one go in the top-level CMakeLists.txt.

5) If the CMakeLists.txt files for your numerous executable targets
   differ in a few places only, e.g. the target name and one source
   file, you might set up a suitably parameterised template, say
   CMakeLists.txt.in, and copy it by use of CONFIGURE_FILE() at
   configuration time before jumping into the directories via
   ADD_SUBDIRECTORY(). With this appoach and a strict preference
   for out-of-source builds, the executable targets' CMakeLists.txt
   files will reside in the binary directory, so you'll need to use
   full paths for the ADD_SUBDIRECTORY() command and possibly within
   the CMakeLists.txt files, too.

'hope that helps.

Regards,

Michael

[1] http://www.mail-archive.com/cmake@cmake.org/msg31299.html


More information about the CMake mailing list