Cmake commands do not distinguish between write down and write down, such as message, set and other commands; However, cmake variables are case sensitive.
For a unified style, all Cmake commands this time are in lowercase, and all variables are in uppercase and underlined combination.
Cmake variable
The Cmake variable can be assigned with the keyword set. The variable can be assigned in the form of switch, number, string and list, which will be used many times in Cmake later.
Option is a switch option, which is usually used as a compilation switch.
Sample code
option(OPEN_TEST "open test" ON) set(FALSE_TEST FALSE) set(NUMBER_TEST 3.14) set(STRING_TEST "Cmake Test") set(SOURCE_LIST_TEST main.cpp module1.cpp module2.cpp) if (OPEN_TEST) message(STATUS "open test: ${OPEN_TEST}") endif() if (NOT FALSE_TEST) message(STATUS "false test: ${FALSE_TEST}") endif() message(STATUS "number test: ${NUMBER_TEST}") message(STATUS "string test: ${STRING_TEST}") message(STATUS "code list test: ${SOURCE_LIST_TEST}")
results of enforcement
-- open test: ON -- false test: FALSE -- number test: 3.14 -- string test: Cmake Test -- code list test: main.cpp;module1.cpp;module2.cpp
The collection of variables will be marked with ';' separate
Cmake pass parameter
When executing the cmake command, cmake can pass parameters to variables, for example:
- For variable CMAKE_TOOLCHAIN_FILE parameters:
-DCMAKE_TOOLCHAIN_FILE=.../config.cmake - For variable CMAKE_BUILD_TYPE parameters:
-DCMAKE_BUILD_TYPE="Debug"
Read the configuration file cmake
Some common cmake configurations do not need to be configured again in cmake projects. They can be imported through different cmake projects. The suffix of this file is Cmake, the read configuration file can be imported by passing parameters or loaded by CmakeLists keyword
Import by passing parameters through cmake command
cmake -G "$CMAKE_TYPE" ../ -DCMAKE_TOOLCHAIN_FILE=../config.cmake
Import by keyword
include(${PROJECT_SOURCE_DIR}/common_config.cmake)
Setup project: Project
The parameter set for project in the description of the current version is
project(<PROJECT-NAME> [<language-name>...]) project(<PROJECT-NAME> [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]] [DESCRIPTION <project-description-string>] [HOMEPAGE_URL <url-string>] [LANGUAGES <language-name>...])
LANGUAGES is the specified language. If the project has a mixture of multiple LANGUAGES, this value can not be set
The simple version directly sets a project name
set(MAIN_NAME CmakeTest) project(${MAIN_NAME})
The corresponding description can be added in the detailed version
set(MAIN_NAME CmakeTest) project(${MAIN_NAME} VERSION 1.2.3.4 DESCRIPTION "CmekTest" HOMEPAGE_URL "https://cmake.org/cmake/help/v3.15/command/project.html")
Print engineering variables
message("PROJECT_NAME ${PROJECT_NAME}") message("PROJECT_VERSION ${PROJECT_VERSION}") message("PROJECT_DESCRIPTION ${PROJECT_DESCRIPTION}") message("PROJECT_HOMEPAGE_URL ${PROJECT_HOMEPAGE_URL}") # If there are multiple projects in the project, the corresponding project name can be used message("MAIN_NAME ${MAIN_NAME}") message("${MAIN_NAME}_VERSION ${${MAIN_NAME}_VERSION}") message("${MAIN_NAME}_DESCRIPTION ${${MAIN_NAME}_DESCRIPTION}") message("${MAIN_NAME}_HOMEPAGE_URL ${${MAIN_NAME}_HOMEPAGE_URL}")
Print results
PROJECT_NAME CmakeTest PROJECT_VERSION 1.2.3.4 PROJECT_DESCRIPTION CmekTest PROJECT_HOMEPAGE_URL https://cmake.org/cmake/help/v3.15/command/project.html MAIN_NAME CmakeTest CmakeTest_VERSION 1.2.3.4 CmakeTest_DESCRIPTION CmekTest CmakeTest_HOMEPAGE_URL https://cmake.org/cmake/help/v3.15/command/project.html
notes
Cmake annotates with "#"
Condition judgment: if
Like C/C + +, conditional judgment is carried out through if, else if and endif keywords.
if(<condition>) <commands> elseif(<condition>) # optional block, can be repeated <commands> else() # optional block <commands> endif()
Official description:
https://cmake.org/cmake/help/v3.15/command/if.html?highlight=#command:if
if(NOT <condition>) Conditional non if(<cond1> AND <cond2>) Conditions and if(<cond1> OR <cond2>) Condition or if(<variable|string> LESS <variable|string>) If the value of the given string or variable is a valid value and is less than the value on the right; otherwise True. if(<variable|string> GREATER <variable|string>) If the value of the given string or variable is a valid value and greater than the value on the right; otherwise True. if(<variable|string> EQUAL <variable|string>) If the value of a given string or variable is a valid value and is equal to the value on the right; otherwise True. if(<variable|string> LESS_EQUAL <variable|string>) If the value of the given string or variable is a valid value and is less than or equal to the value on the right; otherwise True. if(<variable|string> GREATER_EQUAL <variable|string>) If the value of the given string or variable is a valid value and is greater than or equal to the value on the right; otherwise True.
Loop: foreach, while
foreach
foreach(<loop_var> <items>) <commands> endforeach()
foreach can extend the following forms
foreach(<loop_var> RANGE <stop>) Starting from 0, stop Fill in non negative integers with numbers 0, 1, 2 foreach(<loop_var> RANGE <start> <stop> [<step>]) start stop step Fill in non negative integers with numbers of 0, 1, 2,..., if step Unspecified, default step size is 1, stop Not less than start foreach(loop_var IN [LISTS [<lists>]] [ITEMS [<items>]]) Incoming list or item
Official details:
https://cmake.org/cmake/help/v3.15/command/foreach.html?highlight=foreach
The keyword continue is the same as the break logic
Examples
message(STATUS "foreach(getValue 2 3 5 7 11 13 17 19)") foreach(getValue 2 3 5 7 11 13 17 19) if(getValue LESS 5) continue() endif() message(STATUS "foreach1 getValue: ${getValue}") endforeach() message(STATUS "getValue RANGE 5") foreach(getValue RANGE 5) if(getValue GREATER 3) break() endif() message(STATUS "foreach2 getValue: ${getValue}") endforeach() message(STATUS "foreach(getValue RANGE 2 20 4)") foreach(getValue RANGE 2 20 4) message(STATUS "foreach3 getValue: ${getValue}") endforeach() # Use official examples set(A 0;1) set(B 2 3) set(C "4 5") set(D 6;7 8) set(E "") message(STATUS "foreach(X IN LISTS A B C D E)") foreach(X IN LISTS A B C D E) message(STATUS "X=${X}") endforeach()
results of enforcement
-- foreach(getValue 2 3 5 7 11 13 17 19) -- foreach1 getValue: 5 -- foreach1 getValue: 7 -- foreach1 getValue: 11 -- foreach1 getValue: 13 -- foreach1 getValue: 17 -- foreach1 getValue: 19 -- getValue RANGE 5 -- foreach2 getValue: 0 -- foreach2 getValue: 1 -- foreach2 getValue: 2 -- foreach2 getValue: 3 -- foreach(getValue RANGE 2 20 4) -- foreach3 getValue: 2 -- foreach3 getValue: 6 -- foreach3 getValue: 10 -- foreach3 getValue: 14 -- foreach3 getValue: 18 -- foreach(X IN LISTS A B C D E) -- X=0 -- X=1 -- X=2 -- X=3 -- X=4 5 -- X=6 -- X=7 -- X=8
while
while(<condition>) <commands> endwhile()
The condition variable needs to be self increasing or self decreasing
Examples
set(getValue 2) while(getValue LESS 6) message(STATUS "while getValue : ${getValue}") math(EXPR getValue "${getValue} + 1") endwhile()
results of enforcement
-- while getValue : 2 -- while getValue : 3 -- while getValue : 4 -- while getValue : 5
Judge the current system name
It can be judged through the system macro
if(WIN32) message("PC Windows ${CMAKE_BUILD_TYPE}") elseif(UNIX) message("PC UNIX ${CMAKE_BUILD_TYPE}") add_definitions(-D USE_LINUX) endif(WIN32) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") message ("PC Linux") elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") message ("PC Windows") else () message ("other system: ${CMAKE_SYSTEM_NAME}") endif ()
You can also use the default variable cmake directly_ SYSTEM_ Name to judge
Windows effects
PC Windows Debug PC Windows
Linux effect
PC UNIX Debug PC Linux
Display compilation information
After Cmake builds the project, compiling with make will display the compilation progress of Cmake by default, but the complete compilation information is not displayed
[ 3%] Building C object src/lib/TestLib/CMakeFiles/test_lib.dir/src/open_module1.c.o [ 7%] Building CXX object src/app/AlgorithmTest/CMakeFiles/algorithmTest.dir/src/BinaryTree.cpp.o [ 10%] Building C object src/lib/TestLib/CMakeFiles/test_lib.dir/src/open_module2.c.o
There are three ways to display complete compilation information
1,CmakeLists.txt setting variables
set(CMAKE_VERBOSE_MAKEFILE ON)
2. When cmake is executed, variables are passed in through cmake parameters
-DCMAKE_VERBOSE_MAKEFILE=ON
3. Add parameters when making
make VERBOSE=1
Execution effect
[3%] Building C object src/lib/TestLib/CMakeFiles/test_lib.dir/src/open_module1.c.o cd /home/ghost/test_Makefile/project_cache/src/lib/TestLib && /usr/bin/gcc -Dtest_lib_EXPORTS -I/home/ghost/test_Makefile/src/include -I/home/ghost/test_Makefile/src/lib/TestLib/inc -O3 -DNDEBUG -fPIC -D USE_LINUX -o CMakeFiles/test_lib.dir/src/open_module1.c.o -c /home/ghost/test_Makefile/src/lib/TestLib/src/open_module1.c [7%] Building CXX object src/app/AlgorithmTest/CMakeFiles/algorithmTest.dir/src/BinaryTree.cpp.o [10%] Building CXX object src/app/AlgorithmTest/CMakeFiles/algorithmTest.dir/src/ClassicalAlgorithm.cpp.o cd /home/ghost/test_Makefile/project_cache/src/app/AlgorithmTest && /usr/bin/g++ -I/home/ghost/test_Makefile/src/include -I/home/ghost/test_Makefile/src/app/AlgorithmTest/inc -std=c++11 -std=c++11 -O3 -DNDEBUG -D USE_LINUX -o CMakeFiles/algorithmTest.dir/src/BinaryTree.cpp.o -c /home/ghost/test_Makefile/src/app/AlgorithmTest/src/BinaryTree.cpp cd /home/ghost/test_Makefile/project_cache/src/app/AlgorithmTest && /usr/bin/g++ -I/home/ghost/test_Makefile/src/include -I/home/ghost/test_Makefile/src/app/AlgorithmTest/inc -std=c++11 -std=c++11 -O3 -DNDEBUG -D USE_LINUX -o CMakeFiles/algorithmTest.dir/src/ClassicalAlgorithm.cpp.o -c /home/ghost/test_Makefile/src/app/AlgorithmTest/src/ClassicalAlgorithm.cpp
Predefined macros: add_definitions
Encountered in macro definition, for example
#ifdef USE_LINUX std::cout << "use linux" << std::endl; #endif
This definition can be passed in Cmake
if(WIN32) message("PC Windows ${CMAKE_BUILD_TYPE}") elseif(UNIX) message("PC UNIX ${CMAKE_BUILD_TYPE}") add_definitions(-D USE_LINUX) endif(WIN32)
The macros defined here are public macros. If you need to specify the macro of the target, you need to use the target constraint
target_compile_definitions(${PROJECT_APP} PRIVATE -D DEFINE_TEST)
Functions: function
function(<name> [<arg1> ...]) <commands> endfunction()
The functions defined in the parent directory can be called by the child directory, and the functions can be placed in the parent directory cmake configuration file
Examples
function (PrintPCName arg1 arg2 arg3) message(STATUS "function ARGC: ${ARGC}") message(STATUS "function ARGV: ${ARGV}") message(STATUS "function ARGV0: ${ARGV0}") message(STATUS "function ARGV1: ${ARGV1}") message(STATUS "function ARGV2: ${ARGV2}") message(STATUS "function ARGN: ${ARGN}") message(STATUS "System Name : ${CMAKE_SYSTEM_NAME}") endfunction() PrintPCName(1 ${PROJECT_APP} 2 3 4)
results of enforcement
-- function ARGC: 5 -- function ARGV: 1;project_app;2;3;4 -- function ARGV0: 1 -- function ARGV1: project_app -- function ARGV2: 2 -- function ARGN: 3;4 -- System Name : Linux
Function parameter description
Variable name | explain |
---|---|
ARGC | Number of parameters |
ARGV | parameter list |
ARGV0 | Parameter 0 |
ARGV1 | Parameter 1 |
ARGV2 | Parameter 2 |
... | ... |
ARGN | Parameter list exceeding the number of parameters passed |
Loop get variable
Examples
function (PrintPCName arg1 arg2 arg3) message(STATUS "ARGC : ${ARGC}") foreach(getValue ${ARGV}) message(STATUS "argv: ${getValue}") endforeach() message(STATUS "System Name : ${CMAKE_SYSTEM_NAME}") endfunction() PrintPCName(1 ${PROJECT_APP} 2 3 4)
results of enforcement
-- ARGC : 5 -- argv: 1 -- argv: project_app -- argv: 2 -- argv: 3 -- argv: 4 -- System Name : Linux