Home > Enterprise >  How to determine current build type of visual studio in CMakeList.txt
How to determine current build type of visual studio in CMakeList.txt

Time:08-24

This is my build command in CMD:

cmake --build . --config Debug

This Debug can sometimes be Release, or sometimes it is the default. And I have a code in my CMakeList.txt:

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    target_link_libraries(${PROJECT_NAME} PRIVATE LLUd wstp64i4)
else()
    target_link_libraries(${PROJECT_NAME} PRIVATE LLU wstp64i4)
endif()

I think its grammar is fine. But it is a great pity that Visual Studio(multi-config generators) does not recognize the CMAKE_BUILD_TYPE variable as the document. How should I change it?


I have found a similar topic here, but it seem don't work for me.

CodePudding user response:

This is all you should need:

find_package(LLU REQUIRED PATH_SUFFIXES LLU)

target_link_libraries(MyTarget PRIVATE LLU::LLU)

If the above isn't working, you should ask about that error, not your attempted workaround.


The code you show is broken on several levels. First, the value of CMAKE_BUILD_TYPE should never be used to check the active build type because it is not set when using a multi-config generator like Visual Studio. Every in-project use of CMAKE_BUILD_TYPE is a code smell. It is meant to be set by the person building your project (maybe you, maybe not) as a cache variable from the outside.

Second, what you are actually trying to do is to pick a different physical (i.e. on disk) library for Debug mode versus Release (and other *Rel*) mode(s). But this is handled by CMake already. You shouldn't have to do what you're attempting.

I'm assuming that LLU is the Wolfram LibraryLink Utilities. If so, you should read the documentation which shows very nearly the same code I gave above. Notice that LLU::LLU is an imported target. Unless Wolfram's LLU package is broken, this will handle per-config library selection automatically. If it is broken, you should complain to the developers, loudly.

The moral of the story is, as always, to link to imported targets. If what you're linking to doesn't have :: in its name, you should be wary.


Here's a little background on why this is the case:

Imported targets that are generated by CMake's package export mechanism have the following properties set on them. These properties control CMake's view of which physical libraries should be used in which build types:

  1. IMPORTED_LOCATION_<CONFIG> - This property names the path to the physical library that is to be used in the given configuration.
  2. IMPORTED_CONFIGURATIONS - This property contains a list of the configurations that have been imported for the given target.
  3. MAP_IMPORTED_CONFIG_<CONFIG> - This is a per-config property that maps <CONFIG>, which should not be present in IMPORTED_CONFIGURATIONS, to a second config that is present in IMPORTED_CONFIGURATIONS. The physical library from the second configuration will be used.

Regarding point (3), some packages forget to map MinSizeRel and RelWithDebInfo to Release. If you are getting an error in these configs (but not in Release) you can add the following code to your project before importing any packages:

set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO Release)
set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL Release)

This happens with LLVM's broken CMake packages. Most of the time, though, you don't have to worry about any of this.

  • Related