Where

When

September 2017
M T W T F S S
« Jun    
 123
45678910
11121314151617
18192021222324
252627282930  

jb_logo_6_small

logo
  • Blog
  • CMake
  • Installing multiple build types In CMake generated Visual Studio projects

Installing multiple build types In CMake generated Visual Studio projects

One of the issues a build manager faces is the differing behavior of makefile and solution based build systems; particularly when it comes to installation procedure. What we’re talking about specifically is the behavior of gmake on Linux versus Visual Studio on Windows.

The CMake build type is set at configure time on Linux, but at build time on Windows. One of the issues that arises from this dichotomous mechanism is how “install” targets are handled for multiple build types. Install locations are fairly straight forward on Linux. When one is releasing multiple configurations, then the compilation products simply go some place like:

${CMAKE_INSTALL_PREFIX}/${CMAKE_BUILD_TYPE}/install_dir

The issue with cmake generated Visual Studio solutions is that CMAKE_BUILD_TYPE is undefined for solution based systems. The build type is a compile-time choice  in Visual Studio, and unknown when the solution file is generated.

So why is this an issue? Consider that you are making a release of your software, and you have two (user defined) configurations to include in the release — Debug-assert, and Debug-no-assert. In Linux, the build type is set at configure time, so we have no problem. You will configure before each build and tell cmake the build type. Now installation is a one liner that never varies, like so:

install(TARGETS ${MY_SHARED_LIB} EXPORT ${MY_SHARED_LIB} LIBRARY DESTINATION ${CMAKE_BUILD_TYPE}/lib)
That same code won’t work in Visual Studio however. In Visual Studio , you set the build type at compile time (through the GUI), and so there is no way for the build system to know the configuration type — right? Not so fast! Cmake generates the Visual Studio project, then the generated project invokes Cmake,  handing it $(OutDir). Cmake then sets the variable BUILD_TYPE equal to $(OutDir) and uses it throughout the course of the install procedure. In the generated INSTALL.vcproj file, you’ll see a line similar to the following in the section for each configuration type:
CommandLine="C:\Program Files (x86)\CMake 2.8\bin\cmake.exe; -DBUILD_TYPE=$(OutDir) -P cmake_install.cmake"
Well Cmake is happy now, but what about you?  How in the hell do you refer to a Visual Studio configuration type that doesn’t exist until compile time? That answer is of course undocumented, but fairly simple. What you want to do is hand the install command the literal string “${BUILD_TYPE}”.
install(TARGETS ${MY_IMPORT_LIB} EXPORT ${MY_IMPORT_LIB} ARCHIVE DESTINATION ${BUILD_TYPE}/lib)
In Cmake, the backslash is analogous to := in gmake — that is — it defers expansion of the variable it precedes. cmake_install.cmake is then passed  the literal string ${BUILD_TYPE}. You have what you want. Cmake has what it wants. At least in theory, everyone is happy.

Print Friendly, PDF & Email

Tags: , ,