CMake produces Visual Studio solutions seamlessly. This post will map CMake commands to the Visual Studio IDE with an example which makes learning much easier. It is primarily intended for a C++ developer using Visual Studio. Most references here is based on Visual Studio 2010 but will apply equally well to other versions. Continuing from the preface CMake for Visual Studio Developers.
Introduction
Visual Studio to CMake Mapping
Example
Source Structure
Execute CMake
Visual Studio Solution Explorer View
Build and Run
Test
CMakeLists.txt Details
CMake pre-defined projects
Debug and Release Configurations
Conclusion
Introduction
A short background on the CMake philosophy. Typically source should be considered as any files that are explicitly modified by the developer. Anything that is or can be consistently generated from the source files should be considered as output of the build process. A build will always generate a lot of temporary/intermediate files and to avoid polluting the actual source, it is recommended to have out of source builds.
Other than the typical intermediate files like .obj, Visual Studio produces many more transient files including .sln, .sbr, .suo, .vcxproj.user, .vcxproj.filters. These need not (and should not) be checked into the source repository as sometimes they are large and user specific.
A Visual Studio developer might consider the project file (.vcproj) as a “source” since it involves adding, removing source files and modifying dependencies etc. However, with CMake you can consider this to be an intermediate file too, as CMake will generate it and is recommended for it to be outside the source directory.
In a CMake build system, the build “rules” or “project settings” are defined in text files called CMakeLists.txt .
Visual Studio to CMake Mapping
Some common Visual Studio project operations and settings and its mapping to CMake is listed below as an overview.
Visual Studio |
CMake Command |
Solution file (.sln) |
project |
Project file (.vcproj) |
target name in the command add_executable or add_library |
executable (.exe) |
add_executable |
static library (.lib) |
add_library |
dynamic library (.dll) |
add_library(SHARED) |
Source Folders |
source_group |
Project Folders |
set_property(TARGET <target> PROPERTY FOLDER <name>) |
Properties->C/C++->Preprocessor->Preprocessor Definitions |
add_definitions |
Properties->C/C++->General->Additional Include Directories |
include_directories |
Properties->Linker->General->Additional Library Directories |
link_directories |
Properties->Linker->Input->Additional Dependencies |
target_link_libraries |
Example
The CMake tutorial from http://www./cmake/help/cmake_tutorial.html is a very simple example. Please refer to it if you are not familiar with the basics. Here it has been enhanced to show specific aspects commonly used on Windows.
The example code can be accessed via GitHub at https://github.com/cognitivewaves/CMake-VisualStudio-Example. For those not familiar with GitHub, the same example code is in a 7z file. Right mouse click on tutorial-7z.jpg, Save Link As on to disk, rename it as Tutorial.7z and extract the zip file for the sources.
Source Structure
CMake-VisualStudio-Example
|-- app
| |-- CMakeLists.txt
| |-- main.cxx
|-- math
| |-- advanced
| | |-- AdvancedFunctions.cxx
| | |-- AdvancedFunctions.h
| |-- simple
| | |-- SimpleFunctions.cxx
| | |-- SimpleFunctions.h
| |-- CMakeLists.txt
| |-- MathExports.h
|-- CMakeLists.txt
|-- TutorialConfig.h.in
Execute CMake
As recommended earlier, for an out of source build, create a directory where CMake will produce the required Visual Studio Project files and a lot of CMake specific files.
D:\tmp\CMake-VisualStudio-Example> mkdir _build
Make the build directory the current working directory.
D:\tmp\CMake-VisualStudio-Example> cd _build
Run the CMake command and specify where to find the first(root) CMakeLists.txt . In this case ".." is used to indicate one directory up from the current working directory. The -G option specifies it to generate a Visual Studio 2010 Win64 project files. Note that there are other generators that can be specified.
D:\tmp\CMake-VisualStudio-Example\_build> cmake .. -G "Visual Studio 10 Win64"
The Visual Studio solution file will be created in the _build directory.
Visual Studio Solution Explorer View
Open the solution file in Visual Studio.
Build and Run
Build the solution in Visual Studio. The output binary files (app.exe , math.dll ) from the build are created under their own sub-directories in the _build directory. So you will not be able to run the executable in this state because it will not be able to find math.dll
This is where install comes into play. Build INSTALL.vcproj as it does not get built as part of the solution. This project copies the binaries to _build\bin\ directory.
The executable can now be run in a command window.
D:\tmp\CMake-VisualStudio-Example\_build\bin> app.exe 200
The sum of 200 and 200 is 400
The square root of 200 is 14.1421
Note that project ALL_BUILD is the default “Startup Project”. This is never the case for debugging. So right click on the executable project ( app in this case) and select as “Startup Project”.
To run/debug it from Visual Studio, the properties on the executable project ( app in this case), must be changed.
Set Properties->Debugging->Command to ..\bin\app.exe .
Set Properties->Debugging->Command Arguments to 200
Test
Invoking CTest from the build directory will run the tests. Alternatively, the tests can be run within the Visual Studio environment by right click “Build” on the RUN_TESTS project and the test run report will be displayed in the output window.
D:\tmp\CMake-VisualStudio-Example\_build>ctest
Test project D:/tmp/CMake-VisualStudio-Example/_build
Start 1: AppTest1
1/3 Test #1: AppTest1 ......................... Passed 0.00 sec
Start 2: AppTest2
2/3 Test #2: AppTest2 ......................... Passed 0.00 sec
Start 3: AppTest3
3/3 Test #3: AppTest3 ......................... Passed 0.00 sec
100% tests passed, 0 tests failed out of 3
Total Test time (real) = 0.03 sec
CMakeLists.txt Details
The comments in each line provides more details about each CMake command.
File: CMake-VisualStudio-Example/CMakelist.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | cmake_minimum_required (VERSION 2.6)
# Maps to Visual Studio solution file (Tutorial.sln)
# The solution will have all targets (exe, lib, dll)
# as Visual Studio projects (.vcproj)
project (Tutorial)
# Turn on the ability to create folders to organize projects (.vcproj)
# It creates "CMakePredefinedTargets" folder by default and adds CMake
# defined projects like INSTALL.vcproj and ZERO_CHECK.vcproj
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Set compiler flags and options.
# Here it is setting the Visual Studio warning level to 4
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 ")
# Command to output information to the console
# Useful for displaying errors, warnings, and debugging
message ("cxx Flags: " ${CMAKE_CXX_FLAGS})
# Sub-directories where more CMakeLists.txt exist
add_subdirectory(app)
add_subdirectory (math)
# Turn on CMake testing capabilities
enable_testing()
# Add test cases
add_test(AppTest1 ${PROJECT_BINARY_DIR} /bin/app .exe 100)
add_test(AppTest2 ${PROJECT_BINARY_DIR} /bin/app .exe 200)
add_test(AppTest3 ${PROJECT_BINARY_DIR} /bin/app .exe 300)
|
File: CMake-VisualStudio-Example/math/CMakeLists.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # Collect sources into the variable MATH_SOURCES without
# having to explicitly list each header and source file.
#
# CMake documentation states "We do not recommend using GLOB to collect a
# list of source files from your source tree. If no CMakeLists.txt file
# changes when a source is added or removed then the generated build system
# cannot know when to ask CMake to regenerate".
file (GLOB MATH_SOURCES
"*.h")
# Collect sources into the variable SIMPLE_FUNCTION_SOURCES
file (GLOB SIMPLE_FUNCTION_SOURCES
"simple/*.h",
"simple/*.cxx")
# The recommended way to collect sources in variable
# ADVANCED_FUNCTION_SOURCES by explicitly specifying the source files
set (ADVANCED_FUNCTION_SOURCES
"advanced /AdvancedFunctions .h"
"advanced /AdvancedFunctions .cxx")
# Create named folders for the sources within the .vcproj
# Empty name lists them directly under the .vcproj
source_group("" FILES ${MATH_SOURCES})
source_group("simple" FILES ${SIMPLE_FUNCTION_SOURCES})
source_group("advanced" FILES ${ADVANCED_FUNCTION_SOURCES})
# Properties->C/C++->General->Additional Include Directories
include_directories (.)
# Set Properties->General->Configuration Type to Dynamic Library(.dll)
# Creates math.dll with the listed sources collected in the variables
# Also adds sources to the Solution Explorer
add_library(math SHARED ${MATH_SOURCES}
${SIMPLE_FUNCTION_SOURCES}
${ADVANCED_FUNCTION_SOURCES})
# Creates folder "libraries" and adds target project (math.vcproj)
set_property(TARGET math PROPERTY FOLDER "libraries")
# Adds logic to INSTALL.vcproj to copy math.dll to destination directory
install (TARGETS math
RUNTIME DESTINATION ${PROJECT_BINARY_DIR} /bin )
|
File: CMake-VisualStudio-Example/app/CMakeLists.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # Properties->C/C++->General->Additional Include Directories
include_directories ("${PROJECT_SOURCE_DIR} /Math ")
# Set Properties->General->Configuration Type to Application(.exe)
# Creates app.exe with the listed sources (main.cxx)
# Adds sources to the Solution Explorer
add_executable (app main.cxx)
# Properties->Linker->Input->Additional Dependencies
target_link_libraries (app math)
# Creates a folder "executables" and adds target
# project (app.vcproj) under it
set_property(TARGET app PROPERTY FOLDER "executables")
# Adds logic to INSTALL.vcproj to copy app.exe to destination directory
install (TARGETS app
RUNTIME DESTINATION ${PROJECT_BINARY_DIR} /bin )
|
CMake pre-defined projects
To add some CMake functionality to the Visual Studio environment, it creates a few project files which can be ignored for the most part. In any case, a brief description is given below.
INSTALL |
CMake install specification. It is simulating the Linux make install so it has to be manually built after the full build. |
RUN_TESTS |
CMake test specification. This project will enable running tests in Visual Studio and the test run report will be shown in the output window |
ZERO_CHECK |
Used to make sure that the project files are up-to-date with respect to the CMakeLists.txt files |
ALL_BUILD |
Builds all projects with its dependency order |
Debug and Release Configurations
Visual Studio supports multiple configurations in a single project file and creates a per-configuration directory. CMake generates four configurations by default: Debug, Release, MinSizeRel and RelWithDebInfo .
See the link for changing the default.
CMake Wiki: How can I specify my own configurations (for generators that allow it) ?
Conclusion
CMake is a better build system than Visual Studio projects and solutions. It is compact and much more easier to maintain even for a Windows only projects.
Hope the the document is useful. Feel free to comment if you need any clarifications or further information.
|