Is it possible, in the same CMakeLists.txt, to set

2019-07-04 11:32发布

问题:

I have a project for which I create a static and a dynamic version of the libraries. The tools are linked against the static version so no special DLLs are required to run them on the final system.

I can setup the entire everything to compile with /MD or /MT (and corresponding debug) with a simple set in the root CMakeLists.txt.

For example, to force /MT I can use the following:

set ( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT" )
set ( CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT" )
set ( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_RELEASE} /MTd" )
set ( CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_RELEASE} /MTd" )

However, that means the dynamic libraries get compiled with /MT which is wrong. Is it possible to do the same thing on a per project basis? After all, once the solution is created, I can edit each project and fix the /MD and /MT objects to what I need. Can cmake do that? It would be handy.

I looked at the set_target_properties() but that does not seem to take the CMAKE_C_FLAGS_<type> variables and if I just set a standard set of flags it won't be specific to Debug or Release.

The following does set the property, but I don't seem to have a choice for debug and release options.

set_target_properties( ${PROJECT_NAME} PROPERTIES
    COMPILE_FLAGS "/MT"
)

Any solution?

回答1:

Well! I got it working!

I found this question which has a terrible solution, splitting the library in two directories and have the set() in each directory. That would work, but it would be quite a bit of work.

How can I set specific compiler flags for a specific target in a specific build configuration using CMake?

That solution had a comment with a link to this issue:

http://public.kitware.com/Bug/view.php?id=6493

which actually was just marked as fixed on 2013-06-03 12:52! This means the solution is NOT available in the latest stable version of cmake yet. However, what Brad King and Stepen Kelly worked on is definitively working well. It can be downloaded from the daily builds found here:

http://www.cmake.org/files/dev/?C=M;O=D

The way to use the new command is a bit tricky, there is what I wrote:

function(StaticCompile)
    target_compile_options( ${PROJECT_NAME}
        PUBLIC "/MT$<$<STREQUAL:$<CONFIGURATION>,Debug>:d>"
    )
endfunction()

which in English means: if the string "$<CONFIGURATION>" is equal to "Debug" then output "d" after the "/MT", otherwise output nothing.

Then, anywhere I have a target that needs to be compiled with /MT or /MTd I use the command as in:

project(wpkg)

add_executable( ${PROJECT_NAME}
    wpkg.cpp
    license.cpp
)

StaticCompile()

The result is exactly as expected without any directory or other tricks!

It worked for me with version cmake-2.8.11.20130803-gd5dc2-win32-x86.exe which is the one available today. Really cool! 8-)