void.pointer
void.pointer

Reputation: 26415

Include source files on a per-configuration basis in CMake

In my particular CMake project, I have three C++ files:

a.cpp
b.cpp
c.cpp

I want 'a.cpp' to be compiled in all configurations (release & debug).
I only want 'b.cpp' to be compiled in DEBUG configuration.
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.

Upvotes: 1

Views: 963

Answers (3)

starball
starball

Reputation: 52470

Use the $<CONFIG:cfgs> generator expression in your call to add_library, add_executable, or target_sources. Ex.

add_executable(my_target
  a.cpp
  $<$<CONFIG:Debug>:b.cpp>
  $<$<CONFIG:Release>:c.cpp>
)

Upvotes: 2

user14903939
user14903939

Reputation:

This this issue has been fixed as of 3.17: https://cmake.org/cmake/help/latest/release/3.17.html#generators

"Visual Studio Generators learned to support per-config sources. Previously only Command-Line Build Tool Generators supported them."

Upvotes: 0

Andrey Kamaev
Andrey Kamaev

Reputation: 30152

As far as I know cmake does not provide a way to exclude some files based on configuration. So you need a workaround to achieve this behavior.

For example, you can wrap the whole content of b.cpp and c.cpp with some guard macro:

#ifdef BUILD_ME
//original content of your file
#endif

and next set configuration-specific compiler definitions in cmake:

if (${CMAKE_GENERATOR} MATCHES "Make" AND "${CMAKE_BUILD_TYPE}" STREQUAL "")
    # This block might be needed because CMAKE_BUILD_TYPE is usually
    # undefined for makefiles.
    # And COMPILE_DEFINITIONS_RELEASE are not chosen by default.
    set(CMAKE_BUILD_TYPE RELEASE)
endif()

set_source_files_properties(b.cpp PROPERTIES COMPILE_DEFINITIONS_DEBUG BUILD_ME )
set_source_files_properties(c.cpp PROPERTIES COMPILE_DEFINITIONS_RELEASE BUILD_ME )
add_executable(target_name a.cpp b.cpp c.cpp)

Upvotes: 0

Related Questions