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