Re: [CMake] Include source files on a per-configuration basis

2011-10-21 Thread Michael Hertling
On 10/06/2011 10:29 AM, Michael Wild wrote:
 On 10/06/2011 08:14 AM, Michael Hertling wrote:
 On 10/06/2011 07:04 AM, Michael Wild wrote:
 On Thu 06 Oct 2011 05:17:00 AM CEST, Michael Hertling wrote:
 On 10/05/2011 10:47 PM, Robert Dailey wrote:
 In my particular CMake project, I have three CPP files:

 a.cpp
 b.cpp
 c.cpp

 I want 'a.cpp' to be compiled in all configurations (release  debug).br
 I only want 'b.cpp' to be compiled in DEBUG configuration.br
 I only want 'c.cpp' to be compiled in RELEASE configuration.

 How can I do this? I need something similar to the `debug` and `optimized`
 keywords that are accepted by the `target_link_libraries()` CMake 
 operation.

 If it's okay that b.cpp and c.cpp are compiled in all configurations but
 incorporated in the final binaries only in the DEBUG or in the RELEASE
 configuration, respectively, you might do the following:

 CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
 PROJECT(IMPORTEDEMPTY C)
 SET(CMAKE_VERBOSE_MAKEFILE ON)
 # Add library for DEBUG:
 FILE(WRITE ${CMAKE_BINARY_DIR}/b.c void b(void){}\n)
 ADD_LIBRARY(b STATIC b.c)
 # Add library for RELEASE:
 FILE(WRITE ${CMAKE_BINARY_DIR}/c.c void c(void){}\n)
 ADD_LIBRARY(c STATIC c.c)
 # Add empty static library:
 FILE(WRITE ${CMAKE_BINARY_DIR}/empty.c )
 ADD_LIBRARY(empty STATIC empty.c)
 # Reimport empty static library:
 EXPORT(TARGETS empty NAMESPACE imported FILE importedempty.cmake)
 INCLUDE(${CMAKE_BINARY_DIR}/importedempty.cmake)
 # Impose IMPORTED_LINK_INTERFACE_LIBRARIES_{DEBUG,RELEASE} properties:
 FOREACH(i IN LISTS CMAKE_CONFIGURATION_TYPES ITEMS ${CMAKE_BUILD_TYPE})
 STRING(TOUPPER ${i} i)
 IF(i STREQUAL DEBUG)
 SET_TARGET_PROPERTIES(importedempty PROPERTIES
 IMPORTED_LINK_INTERFACE_LIBRARIES_${i} b)
 ELSEIF(i STREQUAL RELEASE)
 SET_TARGET_PROPERTIES(importedempty PROPERTIES
 IMPORTED_LINK_INTERFACE_LIBRARIES_${i} c)
 ENDIF()
 ENDFOREACH()
 # Specify required dependencies:
 ADD_DEPENDENCIES(importedempty empty b c)
 # Add final binary:
 FILE(WRITE ${CMAKE_BINARY_DIR}/a.c int main(void){return 0;}\n)
 ADD_EXECUTABLE(a a.c)
 TARGET_LINK_LIBRARIES(a importedempty)

 Adventurous, but somewhat clean; see [1] for an explanation, and be
 especially careful with a file named libc.a on *nix systems. ;-)

 If you really need to avoid the compilation of b.cpp or c.cpp in
 certain configurations, you might try the following approach:

 CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
 PROJECT(RECONF C)
 SET(CMAKE_VERBOSE_MAKEFILE ON)
 FILE(WRITE ${CMAKE_BINARY_DIR}/a.c int main(void){return 0;}\n)
 FILE(WRITE ${CMAKE_BINARY_DIR}/b.c void b(void){}\n)
 FILE(WRITE ${CMAKE_BINARY_DIR}/c.c void c(void){}\n)
 STRING(TOUPPER ${CONF} CONF)
 IF(CONF STREQUAL DEBUG)
 ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c b.c)
 ELSEIF(CONF STREQUAL RELEASE)
 ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c c.c)
 ELSE()
 ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c)
 ENDIF()
 ADD_CUSTOM_TARGET(a ALL
 COMMAND ${CMAKE_COMMAND}
 -DCONF=$CONFIGURATION
 ${CMAKE_BINARY_DIR}
 COMMAND ${CMAKE_COMMAND}
 --build ${CMAKE_BINARY_DIR}
 --config $CONFIGURATION
 --target a0)

 Effectively, when target a is built, the project reconfigures itself
 with the current configuration passed in via CONF and with a helper
 target a0 which is made up from the configuration-specific sources;
 finally, this target a0 is built with the current configuration.
 This can be seen working on *nix with Makefiles, but there might
 be issues with other generators and IDEs.

 'hope that helps.

 Regards,

 Michael

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

 I think it would be much easier to have a wrapper file, say b_or_c.cpp
 which #include's b.cpp or c.cpp at compile time depending on the current
 configuration. E.g. like this:

 ///
 #if defined USE_B_CPP
 #  include b.cpp
 #elseif defined USE_C_CPP
 #  include c.cpp
 #else // what should happen otherwise?
 #  error Either USE_B_CPP or USE_C_CPP must be defined!
 #endif
 ///


 And then in your CMakeLists.txt you do:

 ###
 set_source_files_properties(b_or_c.cpp PROPERTIES
   COMPILE_DEFINITIONS_DEBUG USE_B_CPP
   COMPILE_DEFINITIONS_RELEASE USE_C_CPP
   # what should happen in a default build?
   # Or RELWITHDEBINFO and MINSIZEREL?
   )
 ###

 Yes, this would work, too, but if neither b.cpp nor c.cpp should be
 compiled if the current configuration is neither DEBUG nor RELEASE,
 the b_or_c.cpp file would be effectively empty, and adding an object
 file compiled from an empty source file to a binary is not 100 % the
 same as dropping the object file completely - at least with gcc and
 even with -Os. However, it's a quite negligible effect, but linking
 

Re: [CMake] Include source files on a per-configuration basis

2011-10-13 Thread Robert Dailey
In visual studio, there is a way to exclude a source file from the build on
a per-configuration basis (debug vs release). The actual VCPROJ looks like
this when you exclude a CPP file from the build for only DEBUG
configuration:


File
RelativePath=C:\Code\work\rdailey-t510-sandbox\n2\gpr\security\gtisecprovcleartext.cpp
FileConfiguration
Name=Debug|Win32
ExcludedFromBuild=TRUE
Tool
Name=VCCLCompilerTool/
/FileConfiguration
/File


Is there a way in CMake to make it generate this? There has to be some sort
of platform agnostic feature for this, and for other platforms it will
implement it accordingly

-
Robert Dailey


On Wed, Oct 5, 2011 at 3:47 PM, Robert Dailey rcdai...@gmail.com wrote:

 In my particular CMake project, I have three CPP files:

 a.cpp
 b.cpp
 c.cpp

 I want 'a.cpp' to be compiled in all configurations (release  debug).br
 I only want 'b.cpp' to be compiled in DEBUG configuration.br
 I only want 'c.cpp' to be compiled in RELEASE configuration.

 How can I do this? I need something similar to the `debug` and `optimized`
 keywords that are accepted by the `target_link_libraries()` CMake operation.

 -
 Robert Dailey

--

Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake

Re: [CMake] Include source files on a per-configuration basis

2011-10-13 Thread David Cole
On Thu, Oct 13, 2011 at 3:37 PM, Robert Dailey rcdai...@gmail.com wrote:
 In visual studio, there is a way to exclude a source file from the build on
 a per-configuration basis (debug vs release). The actual VCPROJ looks like
 this when you exclude a CPP file from the build for only DEBUG
 configuration:

 File
 RelativePath=C:\Code\work\rdailey-t510-sandbox\n2\gpr\security\gtisecprovcleartext.cpp
 FileConfiguration
 Name=Debug|Win32
 ExcludedFromBuild=TRUE
 Tool
 Name=VCCLCompilerTool/
 /FileConfiguration
 /File

 Is there a way in CMake to make it generate this? There has to be some sort
 of platform agnostic feature for this, and for other platforms it will
 implement it accordingly
 -
 Robert Dailey


 On Wed, Oct 5, 2011 at 3:47 PM, Robert Dailey rcdai...@gmail.com wrote:

 In my particular CMake project, I have three CPP files:
     a.cpp
     b.cpp
     c.cpp
 I want 'a.cpp' to be compiled in all configurations (release  debug).br
 I only want 'b.cpp' to be compiled in DEBUG configuration.br
 I only want 'c.cpp' to be compiled in RELEASE configuration.
 How can I do this? I need something similar to the `debug` and `optimized`
 keywords that are accepted by the `target_link_libraries()` CMake operation.
 -
 Robert Dailey


 --

 Powered by www.kitware.com

 Visit other Kitware open-source projects at
 http://www.kitware.com/opensource/opensource.html

 Please keep messages on-topic and check the CMake FAQ at:
 http://www.cmake.org/Wiki/CMake_FAQ

 Follow this link to subscribe/unsubscribe:
 http://www.cmake.org/mailman/listinfo/cmake


At present, the only time we generate ExcludedFromBuild=true is when
the source file property HEADER_FILE_ONLY is set to a non-false value.
That is on a per-source-file basis, though, not on a per-configuration
basis.

What you want is a new feature request for CMake. It does not exist yet.


HTH,
David
--

Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Include source files on a per-configuration basis

2011-10-13 Thread Robert Dailey
On Thu, Oct 13, 2011 at 3:16 PM, David Cole david.c...@kitware.com wrote:

 On Thu, Oct 13, 2011 at 3:37 PM, Robert Dailey rcdai...@gmail.com wrote:
  In visual studio, there is a way to exclude a source file from the build
 on
  a per-configuration basis (debug vs release). The actual VCPROJ looks
 like
  this when you exclude a CPP file from the build for only DEBUG
  configuration:
 
  File
 
 RelativePath=C:\Code\work\rdailey-t510-sandbox\n2\gpr\security\gtisecprovcleartext.cpp
  FileConfiguration
  Name=Debug|Win32
  ExcludedFromBuild=TRUE
  Tool
  Name=VCCLCompilerTool/
  /FileConfiguration
  /File
 
  Is there a way in CMake to make it generate this? There has to be some
 sort
  of platform agnostic feature for this, and for other platforms it will
  implement it accordingly
  -
  Robert Dailey
 
 
  On Wed, Oct 5, 2011 at 3:47 PM, Robert Dailey rcdai...@gmail.com
 wrote:
 
  In my particular CMake project, I have three CPP files:
  a.cpp
  b.cpp
  c.cpp
  I want 'a.cpp' to be compiled in all configurations (release 
 debug).br
  I only want 'b.cpp' to be compiled in DEBUG configuration.br
  I only want 'c.cpp' to be compiled in RELEASE configuration.
  How can I do this? I need something similar to the `debug` and
 `optimized`
  keywords that are accepted by the `target_link_libraries()` CMake
 operation.
  -
  Robert Dailey
 
 
  --
 
  Powered by www.kitware.com
 
  Visit other Kitware open-source projects at
  http://www.kitware.com/opensource/opensource.html
 
  Please keep messages on-topic and check the CMake FAQ at:
  http://www.cmake.org/Wiki/CMake_FAQ
 
  Follow this link to subscribe/unsubscribe:
  http://www.cmake.org/mailman/listinfo/cmake
 

 At present, the only time we generate ExcludedFromBuild=true is when
 the source file property HEADER_FILE_ONLY is set to a non-false value.
 That is on a per-source-file basis, though, not on a per-configuration
 basis.

 What you want is a new feature request for CMake. It does not exist yet.


I was able to find this existing feature request for what seems to be the
same thing I want:
http://www.itk.org/Bug/view.php?id=11902

I've voiced my vote for it. I hope it will be implemented.
--

Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake

Re: [CMake] Include source files on a per-configuration basis

2011-10-06 Thread Michael Hertling
On 10/06/2011 07:04 AM, Michael Wild wrote:
 On Thu 06 Oct 2011 05:17:00 AM CEST, Michael Hertling wrote:
 On 10/05/2011 10:47 PM, Robert Dailey wrote:
 In my particular CMake project, I have three CPP files:

 a.cpp
 b.cpp
 c.cpp

 I want 'a.cpp' to be compiled in all configurations (release  debug).br
 I only want 'b.cpp' to be compiled in DEBUG configuration.br
 I only want 'c.cpp' to be compiled in RELEASE configuration.

 How can I do this? I need something similar to the `debug` and `optimized`
 keywords that are accepted by the `target_link_libraries()` CMake operation.

 If it's okay that b.cpp and c.cpp are compiled in all configurations but
 incorporated in the final binaries only in the DEBUG or in the RELEASE
 configuration, respectively, you might do the following:

 CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
 PROJECT(IMPORTEDEMPTY C)
 SET(CMAKE_VERBOSE_MAKEFILE ON)
 # Add library for DEBUG:
 FILE(WRITE ${CMAKE_BINARY_DIR}/b.c void b(void){}\n)
 ADD_LIBRARY(b STATIC b.c)
 # Add library for RELEASE:
 FILE(WRITE ${CMAKE_BINARY_DIR}/c.c void c(void){}\n)
 ADD_LIBRARY(c STATIC c.c)
 # Add empty static library:
 FILE(WRITE ${CMAKE_BINARY_DIR}/empty.c )
 ADD_LIBRARY(empty STATIC empty.c)
 # Reimport empty static library:
 EXPORT(TARGETS empty NAMESPACE imported FILE importedempty.cmake)
 INCLUDE(${CMAKE_BINARY_DIR}/importedempty.cmake)
 # Impose IMPORTED_LINK_INTERFACE_LIBRARIES_{DEBUG,RELEASE} properties:
 FOREACH(i IN LISTS CMAKE_CONFIGURATION_TYPES ITEMS ${CMAKE_BUILD_TYPE})
 STRING(TOUPPER ${i} i)
 IF(i STREQUAL DEBUG)
 SET_TARGET_PROPERTIES(importedempty PROPERTIES
 IMPORTED_LINK_INTERFACE_LIBRARIES_${i} b)
 ELSEIF(i STREQUAL RELEASE)
 SET_TARGET_PROPERTIES(importedempty PROPERTIES
 IMPORTED_LINK_INTERFACE_LIBRARIES_${i} c)
 ENDIF()
 ENDFOREACH()
 # Specify required dependencies:
 ADD_DEPENDENCIES(importedempty empty b c)
 # Add final binary:
 FILE(WRITE ${CMAKE_BINARY_DIR}/a.c int main(void){return 0;}\n)
 ADD_EXECUTABLE(a a.c)
 TARGET_LINK_LIBRARIES(a importedempty)

 Adventurous, but somewhat clean; see [1] for an explanation, and be
 especially careful with a file named libc.a on *nix systems. ;-)

 If you really need to avoid the compilation of b.cpp or c.cpp in
 certain configurations, you might try the following approach:

 CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
 PROJECT(RECONF C)
 SET(CMAKE_VERBOSE_MAKEFILE ON)
 FILE(WRITE ${CMAKE_BINARY_DIR}/a.c int main(void){return 0;}\n)
 FILE(WRITE ${CMAKE_BINARY_DIR}/b.c void b(void){}\n)
 FILE(WRITE ${CMAKE_BINARY_DIR}/c.c void c(void){}\n)
 STRING(TOUPPER ${CONF} CONF)
 IF(CONF STREQUAL DEBUG)
 ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c b.c)
 ELSEIF(CONF STREQUAL RELEASE)
 ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c c.c)
 ELSE()
 ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c)
 ENDIF()
 ADD_CUSTOM_TARGET(a ALL
 COMMAND ${CMAKE_COMMAND}
 -DCONF=$CONFIGURATION
 ${CMAKE_BINARY_DIR}
 COMMAND ${CMAKE_COMMAND}
 --build ${CMAKE_BINARY_DIR}
 --config $CONFIGURATION
 --target a0)

 Effectively, when target a is built, the project reconfigures itself
 with the current configuration passed in via CONF and with a helper
 target a0 which is made up from the configuration-specific sources;
 finally, this target a0 is built with the current configuration.
 This can be seen working on *nix with Makefiles, but there might
 be issues with other generators and IDEs.

 'hope that helps.

 Regards,

 Michael

 [1] http://www.mail-archive.com/cmake@cmake.org/msg34680.html
 
 I think it would be much easier to have a wrapper file, say b_or_c.cpp
 which #include's b.cpp or c.cpp at compile time depending on the current
 configuration. E.g. like this:
 
 ///
 #if defined USE_B_CPP
 #  include b.cpp
 #elseif defined USE_C_CPP
 #  include c.cpp
 #else // what should happen otherwise?
 #  error Either USE_B_CPP or USE_C_CPP must be defined!
 #endif
 ///
 
 
 And then in your CMakeLists.txt you do:
 
 ###
 set_source_files_properties(b_or_c.cpp PROPERTIES
   COMPILE_DEFINITIONS_DEBUG USE_B_CPP
   COMPILE_DEFINITIONS_RELEASE USE_C_CPP
   # what should happen in a default build?
   # Or RELWITHDEBINFO and MINSIZEREL?
   )
 ###

Yes, this would work, too, but if neither b.cpp nor c.cpp should be
compiled if the current configuration is neither DEBUG nor RELEASE,
the b_or_c.cpp file would be effectively empty, and adding an object
file compiled from an empty source file to a binary is not 100 % the
same as dropping the object file completely - at least with gcc and
even with -Os. However, it's a quite negligible effect, but linking
against an empty static library or building a reconfigured project
means *exactly* the same as if b.cpp 

[CMake] Include source files on a per-configuration basis

2011-10-05 Thread Robert Dailey
In my particular CMake project, I have three CPP files:

a.cpp
b.cpp
c.cpp

I want 'a.cpp' to be compiled in all configurations (release  debug).br
I only want 'b.cpp' to be compiled in DEBUG configuration.br
I only want 'c.cpp' to be compiled in RELEASE configuration.

How can I do this? I need something similar to the `debug` and `optimized`
keywords that are accepted by the `target_link_libraries()` CMake operation.

-
Robert Dailey
--
Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake

Re: [CMake] Include source files on a per-configuration basis

2011-10-05 Thread Michael Hertling
On 10/05/2011 10:47 PM, Robert Dailey wrote:
 In my particular CMake project, I have three CPP files:
 
 a.cpp
 b.cpp
 c.cpp
 
 I want 'a.cpp' to be compiled in all configurations (release  debug).br
 I only want 'b.cpp' to be compiled in DEBUG configuration.br
 I only want 'c.cpp' to be compiled in RELEASE configuration.
 
 How can I do this? I need something similar to the `debug` and `optimized`
 keywords that are accepted by the `target_link_libraries()` CMake operation.

If it's okay that b.cpp and c.cpp are compiled in all configurations but
incorporated in the final binaries only in the DEBUG or in the RELEASE
configuration, respectively, you might do the following:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(IMPORTEDEMPTY C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
# Add library for DEBUG:
FILE(WRITE ${CMAKE_BINARY_DIR}/b.c void b(void){}\n)
ADD_LIBRARY(b STATIC b.c)
# Add library for RELEASE:
FILE(WRITE ${CMAKE_BINARY_DIR}/c.c void c(void){}\n)
ADD_LIBRARY(c STATIC c.c)
# Add empty static library:
FILE(WRITE ${CMAKE_BINARY_DIR}/empty.c )
ADD_LIBRARY(empty STATIC empty.c)
# Reimport empty static library:
EXPORT(TARGETS empty NAMESPACE imported FILE importedempty.cmake)
INCLUDE(${CMAKE_BINARY_DIR}/importedempty.cmake)
# Impose IMPORTED_LINK_INTERFACE_LIBRARIES_{DEBUG,RELEASE} properties:
FOREACH(i IN LISTS CMAKE_CONFIGURATION_TYPES ITEMS ${CMAKE_BUILD_TYPE})
STRING(TOUPPER ${i} i)
IF(i STREQUAL DEBUG)
SET_TARGET_PROPERTIES(importedempty PROPERTIES
IMPORTED_LINK_INTERFACE_LIBRARIES_${i} b)
ELSEIF(i STREQUAL RELEASE)
SET_TARGET_PROPERTIES(importedempty PROPERTIES
IMPORTED_LINK_INTERFACE_LIBRARIES_${i} c)
ENDIF()
ENDFOREACH()
# Specify required dependencies:
ADD_DEPENDENCIES(importedempty empty b c)
# Add final binary:
FILE(WRITE ${CMAKE_BINARY_DIR}/a.c int main(void){return 0;}\n)
ADD_EXECUTABLE(a a.c)
TARGET_LINK_LIBRARIES(a importedempty)

Adventurous, but somewhat clean; see [1] for an explanation, and be
especially careful with a file named libc.a on *nix systems. ;-)

If you really need to avoid the compilation of b.cpp or c.cpp in
certain configurations, you might try the following approach:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(RECONF C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
FILE(WRITE ${CMAKE_BINARY_DIR}/a.c int main(void){return 0;}\n)
FILE(WRITE ${CMAKE_BINARY_DIR}/b.c void b(void){}\n)
FILE(WRITE ${CMAKE_BINARY_DIR}/c.c void c(void){}\n)
STRING(TOUPPER ${CONF} CONF)
IF(CONF STREQUAL DEBUG)
ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c b.c)
ELSEIF(CONF STREQUAL RELEASE)
ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c c.c)
ELSE()
ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c)
ENDIF()
ADD_CUSTOM_TARGET(a ALL
COMMAND ${CMAKE_COMMAND}
-DCONF=$CONFIGURATION
${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND}
--build ${CMAKE_BINARY_DIR}
--config $CONFIGURATION
--target a0)

Effectively, when target a is built, the project reconfigures itself
with the current configuration passed in via CONF and with a helper
target a0 which is made up from the configuration-specific sources;
finally, this target a0 is built with the current configuration.
This can be seen working on *nix with Makefiles, but there might
be issues with other generators and IDEs.

'hope that helps.

Regards,

Michael

[1] http://www.mail-archive.com/cmake@cmake.org/msg34680.html
--
Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Include source files on a per-configuration basis

2011-10-05 Thread Michael Wild
On Thu 06 Oct 2011 05:17:00 AM CEST, Michael Hertling wrote:
 On 10/05/2011 10:47 PM, Robert Dailey wrote:
 In my particular CMake project, I have three CPP files:

 a.cpp
 b.cpp
 c.cpp

 I want 'a.cpp' to be compiled in all configurations (release  debug).br
 I only want 'b.cpp' to be compiled in DEBUG configuration.br
 I only want 'c.cpp' to be compiled in RELEASE configuration.

 How can I do this? I need something similar to the `debug` and `optimized`
 keywords that are accepted by the `target_link_libraries()` CMake operation.

 If it's okay that b.cpp and c.cpp are compiled in all configurations but
 incorporated in the final binaries only in the DEBUG or in the RELEASE
 configuration, respectively, you might do the following:

 CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
 PROJECT(IMPORTEDEMPTY C)
 SET(CMAKE_VERBOSE_MAKEFILE ON)
 # Add library for DEBUG:
 FILE(WRITE ${CMAKE_BINARY_DIR}/b.c void b(void){}\n)
 ADD_LIBRARY(b STATIC b.c)
 # Add library for RELEASE:
 FILE(WRITE ${CMAKE_BINARY_DIR}/c.c void c(void){}\n)
 ADD_LIBRARY(c STATIC c.c)
 # Add empty static library:
 FILE(WRITE ${CMAKE_BINARY_DIR}/empty.c )
 ADD_LIBRARY(empty STATIC empty.c)
 # Reimport empty static library:
 EXPORT(TARGETS empty NAMESPACE imported FILE importedempty.cmake)
 INCLUDE(${CMAKE_BINARY_DIR}/importedempty.cmake)
 # Impose IMPORTED_LINK_INTERFACE_LIBRARIES_{DEBUG,RELEASE} properties:
 FOREACH(i IN LISTS CMAKE_CONFIGURATION_TYPES ITEMS ${CMAKE_BUILD_TYPE})
 STRING(TOUPPER ${i} i)
 IF(i STREQUAL DEBUG)
 SET_TARGET_PROPERTIES(importedempty PROPERTIES
 IMPORTED_LINK_INTERFACE_LIBRARIES_${i} b)
 ELSEIF(i STREQUAL RELEASE)
 SET_TARGET_PROPERTIES(importedempty PROPERTIES
 IMPORTED_LINK_INTERFACE_LIBRARIES_${i} c)
 ENDIF()
 ENDFOREACH()
 # Specify required dependencies:
 ADD_DEPENDENCIES(importedempty empty b c)
 # Add final binary:
 FILE(WRITE ${CMAKE_BINARY_DIR}/a.c int main(void){return 0;}\n)
 ADD_EXECUTABLE(a a.c)
 TARGET_LINK_LIBRARIES(a importedempty)

 Adventurous, but somewhat clean; see [1] for an explanation, and be
 especially careful with a file named libc.a on *nix systems. ;-)

 If you really need to avoid the compilation of b.cpp or c.cpp in
 certain configurations, you might try the following approach:

 CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
 PROJECT(RECONF C)
 SET(CMAKE_VERBOSE_MAKEFILE ON)
 FILE(WRITE ${CMAKE_BINARY_DIR}/a.c int main(void){return 0;}\n)
 FILE(WRITE ${CMAKE_BINARY_DIR}/b.c void b(void){}\n)
 FILE(WRITE ${CMAKE_BINARY_DIR}/c.c void c(void){}\n)
 STRING(TOUPPER ${CONF} CONF)
 IF(CONF STREQUAL DEBUG)
 ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c b.c)
 ELSEIF(CONF STREQUAL RELEASE)
 ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c c.c)
 ELSE()
 ADD_EXECUTABLE(a0 EXCLUDE_FROM_ALL a.c)
 ENDIF()
 ADD_CUSTOM_TARGET(a ALL
 COMMAND ${CMAKE_COMMAND}
 -DCONF=$CONFIGURATION
 ${CMAKE_BINARY_DIR}
 COMMAND ${CMAKE_COMMAND}
 --build ${CMAKE_BINARY_DIR}
 --config $CONFIGURATION
 --target a0)

 Effectively, when target a is built, the project reconfigures itself
 with the current configuration passed in via CONF and with a helper
 target a0 which is made up from the configuration-specific sources;
 finally, this target a0 is built with the current configuration.
 This can be seen working on *nix with Makefiles, but there might
 be issues with other generators and IDEs.

 'hope that helps.

 Regards,

 Michael

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

I think it would be much easier to have a wrapper file, say b_or_c.cpp
which #include's b.cpp or c.cpp at compile time depending on the current
configuration. E.g. like this:

///
#if defined USE_B_CPP
#  include b.cpp
#elseif defined USE_C_CPP
#  include c.cpp
#else // what should happen otherwise?
#  error Either USE_B_CPP or USE_C_CPP must be defined!
#endif
///


And then in your CMakeLists.txt you do:

###
set_source_files_properties(b_or_c.cpp PROPERTIES
  COMPILE_DEFINITIONS_DEBUG USE_B_CPP
  COMPILE_DEFINITIONS_RELEASE USE_C_CPP
  # what should happen in a default build?
  # Or RELWITHDEBINFO and MINSIZEREL?
  )
###


HTH

Michael W.
--
Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake