This paper adopts Creative Commons Attribution 4.0 international license agreement For permission, please indicate the original link when reprinting. Please keep all the contents of the picture when using it, which can be scaled appropriately, and attach the article link where the picture is located in the quotation.
- CMake
- Common predefined variables in CMake
- Common grammar
- Basic control grammar
- actual combat
- reference material
CMake
CMakeLists.txt
cmake PATH
ccmake PATH
The difference between ccmake and cmake is that the former provides an interactive interface
PATH is cmakelists Txt directory
Compile using the make command.
Common predefined variables in CMake
Predefined variables for CMake
- PROJECT_SOURCE_DIR: project root directory;
- PROJECT_BINARY_DIR: the directory where the cmake command is run. The author suggests that it be defined as ${PROJECT_SOURCE_DIR}/ build. See the external compilation section below for specific reasons;
- CMAKE_INCLUDE_PATH: environment variable, non cmake variable;
- CMAKE_LIBRARY_PATH: environment variable;
- CMAKE_CURRENT_SOURCE_DIR: currently processed cmakelists Txt file path;
- CMAKE_CURRENT_BINARY_DIR: target compilation directory;
- Use add_ The surdirectory instruction can change the value of the variable;
- The set (executable_output_path < dir >) instruction does not affect this variable, but changes the storage path of the final target file;
- CMAKE_CURRENT_LIST_FILE: output the cmakelists that call this variable Txt;
- CMAKE_CURRENT_LIST_LINE: output the line where the variable is located;
- CMAKE_MODULE_PATH: define the path of your cmake module;
- EXECUTABLE_OUTPUT_PATH: redefine the storage location of the target binary executable file;
- LIBRARY_OUTPUT_PATH: redefine the storage location of the target link library file;
- PROJECT_NAME: returns the project name defined by the project directive;
- CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS: used to control the writing method of IF... ELSE... Statements;
System information predefined variables
- CMAKE_MAJOR_VERSION cmake major version number, such as 2 in 2.8.6
- CMAKE_MINOR_VERSION cmake minor version number, such as 8 in 2.8.6
- CMAKE_PATCH_VERSION cmake patch level, such as 6 in 2.8.6
- CMAKE_SYSTEM system name, for example, Linux-2.6.22
- CMAKE_SYSTEM_NAME does not contain the system name of the version, such as Linux
- CMAKE_SYSTEM_VERSION system version, such as 2.6.22
- CMAKE_SYSTEM_PROCESSOR processor name, such as i686
- UNIX is TRUE on all UNIX like platforms, including OS X and cygwin
- win32 is TRUE on all win32 platforms, including cygwin
Switch options
- BUILD_SHARED_LIBS controls the default library compilation method.
Note: if not set, use ADD_LIBRARY does not specify the library type. By default, the libraries generated by compilation are static libraries. - CMAKE_C_FLAGS setting C compilation options
- CMAKE_CXX_FLAGS setting C + + compilation options
Common grammar
CMakeLists.txt syntax is relatively simple, composed of commands, comments and spaces, where commands are case insensitive. What # follows the symbol is considered a comment. The command consists of the command name, parentheses, and parameters, separated by spaces.
- Under each directory where cmake operation is required, there must be a file cmakelists txt .
- The cmake instruction is not case sensitive.
- The built-in variable cmake is case sensitive.
- The variable is valued in ${} mode, but the variable name is directly used in the IF control statement;
- Instruction (parameter 1, parameter 2...), the parameters are enclosed in parentheses, and the parameters are separated by spaces or semicolons;
CMAKE_MINIMUM_REQUIRED
This statement can generally be placed in cmakelists Txt is used to describe the minimum version requirements of CMake.
This line of command is optional. We can not write this sentence, but in some cases, if cmakelists When some commands unique to the higher version of cmake are used in the txt file, you need to add such a line to remind the user to upgrade to this version before executing cmake.
cmake_minimum_required (VERSION 2.6)
PROJECT
PROJECT(name)
Name: project name
This instruction is generally placed in cmakelists Txt, which defines the name of the project. However, the executable generated by the final compilation of the project is not necessarily the name of the project.
After the instruction is executed, two variables will be automatically created:
< projectname >_BINARY_DIR: Binary file saving path; < projectname >_SOURCE_DIR: Source code path;
project(CRNode)
The last instruction is executed, that is, an item name crnode is defined, and two variables will be generated accordingly: CRNode_BINARY_DIR, CRNode_SOURCE_DIR.
Two variables are predefined in cmake: PROJECT_BINARY_DIR and PROJECT_SOURCE_DIR.
In this example:
PROJECT_BINARY_DIR = CRNode_BINARY_DIR PROJECT_SOURCE_DIR = CRNode_SOURCE_DIR
It is recommended to use project directly_ BINARY_ Dir and PROJECT_SOURCE_DIR, so that if the project name changes, it will not affect cmakelists Txt file.
Whether the above two variables are the same involves whether the compilation method is internal compilation or external compilation. In case of internal compilation, the above two variables are the same; In case of external compilation, the two variables are different.
External construction and internal construction
Suppose you have completed cmakelists Txt, in cmakelists Txt directory, there are two methods to execute cmake:
cmake ./ make
And:
mkdir build cd ./build cmake ../ make
The first method is internal build, and the second method is external build. The biggest difference between the above two methods is that the working paths of cmake and make are different.
In the internal construction method, the intermediate files and executable files generated by cmake will be stored in the project directory; In the external construction method, the intermediate files and executable files are stored in the build directory.
External build methods are recommended. The advantages are obvious: the code directory is kept clean to the greatest extent. The generation, compilation and installation are in other directories different from the project directory. Under the external construction method, PROJECT_SOURCE_DIR points to the same directory as the internal build, cmakelists Txt root directory; And project_ BINARY_ Unlike dir, it points to cmakelists Txt under the root directory.
SET
SET(VAR [VALUE] [CACHE TYPEDOCSTRING [FORCE]])
eg:
SET(CMAKE_INSTALL_PREFIX /usr/local)
We explicitly put cmake_ INSTALL_ The value of prefix is defined as / usr/local, so when you execute the make install command in the case of external build, make will copy the generated executable file to the / usr/local/bin directory.
Of course, the installation path of the executable is CMAKE_INSTALL_PREFIX can also be specified when executing the cmake command. The cmake parameters are as follows:
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
If cmake parameter and cmakelists If the value is not specified in the txt file, the value is the default / usr/local.
ADD_SUBDIRECTORY
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
- source_dir: source file path;
- [binary_dir]: storage path of intermediate binary and target binary;
- [EXECLUDE_FROM_ALL]: exclude this directory from the compilation process;
This instruction is used to add a subdirectory for storing source files to the current project, and specify the storage location of intermediate binary and target binary.
EXCLUDE_ FROM_ The all parameter means to exclude this directory from compilation. For example, sometimes there is an example in a project. After the project is built, you may need to enter the example directory to build it separately.
INCLUDE_DIRECTORIES
INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
- [AFTER|BEFORE]: append flag, which specifies whether to control append or set before;
- [SYSTEM]: (I don't know why)
- dir1,..., dir n: a series of header file search paths added;
Add multiple specific header file search paths to the project, separated by spaces. It is similar to the compilation parameter - l in gcc, which specifies the path for the compiler to search the header file during compilation. When the header file required by the project is not in the system default search path, specify the path.
AFTER/BEFORE parameter, which controls whether to append or set before. By default, the current header file search path is appended.
Note: if the path contains spaces, you can use double quotation marks to enclose it.
eg:
INCLUDE_DIRECTORIES(/usr/include/thrift)
ADD_EXECUTABLE
ADD_EXECUTABLE(exename srcname)
- exename: executable name
- srcname: the source file that generates the executable
This command gives the name of the source file and indicates the name of the executable file to be compiled.
eg:
ADD_EXECUTABLE(hello ${SRC_LIST})
The above routine describes Src_ The source file in the list variable needs to compile an executable file named hello.
eg:
SET(SRC_LIST main.cc rpc/CRNode.cpp rpc/Schd_types.cpp task/TaskExecutor.cpp task/TaskMoniter.cpp util/Const.cpp util/Globals.cc ) ADD_EXECUTABLE(CRNode ${SRC_LIST})
In this routine, it is defined that the project will generate an executable file named CRNode, and the dependent source file is the variable SRC_LIST defines the list of source files.
Note: if the project name defined in the PROJECT() instruction above is also defined as CRNode, there is no problem, and there is no relationship between the two.
ADD_LIBRARY
ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
- libname: library file name;
- [SHARED|STATIC|MODULE]: generate library file type (shared library / static library)
- [EXCLUDE_FROM_ALL]: indicates that the library will not be built by default
- source1,..., sourceN: generate the source file that the library depends on
eg:
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
Variable EXECUTABLE_OUTPUT_PATH, LIBRARY_OUTPUT_PATH
EXECUTABLE_OUTPUT_PATH is the path to generate executable files, LIBRARY_OUTPUT_PATH is the path to the generated library file.
We can SET the location of the final target binary through the SET instruction, that is, the final generated project executable file and the final shared library, without including the intermediate file generated by compilation.
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
Note: instruction add_ EXECUTABLE, ADD_ The location where library appears. If you need to change the target storage path, add the above definition there.
LINK_DIRECTORIES
LINK_DIRECTORIES(directory1 directory2 ...)
This directive is used to add a search path for an external library.
TARGET_LINK_LIBRARIES
TARGET_LINK_LIBRARIES(target library1 <debug | optimized> library2 ..)
- Target: target file;
- library1,..., libraryN: link external library files;
Specify the external library that needs to be linked when linking the target file. The effect is similar to the gcc compilation parameter - L, which solves the problem of external library dependency.
MESSAGE
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)
Output user-defined information or variable values to the terminal
- SEND_ERROR: an error is generated and the generation process is skipped;
- STATUS: output information prefixed with -;
- FATAL_ERROR: immediately terminate all cmake processes;
SET_TARGET_PROPERTIES
SET_TARGET_PROPERTIES(target1 target2 ... PROPERTIES prop1 value1 prop2 value2 ...)
Set some properties of goals and change how they are built.
AUX_SOURCE_DIRECTORY
Basic control grammar
actual combat
Single source file
# CMake minimum version number requirements # cmake_minimum_required: Specifies the minimum version of CMake required to run this profile cmake_minimum_required (VERSION 2.8) # Project information # Project: the parameter value is Demo1. This command indicates that the name of the project is Demo1 project (Demo1) # Specify build target # add_executable: name it main The source file of CC is compiled into an executable file named Demo add_executable(Demo main.cc)
cmake .
Multiple source files
Multiple source files in the same directory
# CMake minimum version number requirements cmake_minimum_required (VERSION 2.8) # Project information project (Demo2) # Specify build target add_executable(Demo main.cc MathFunctions.cc)
aux_source_directory: find all source files in the specified directory, and then save the results into the specified variable name.
aux_source_directory(<dir> <variable>)
# CMake minimum version number requirements cmake_minimum_required (VERSION 2.8) # Project information project (Demo2) # Find all source files in the current directory # And save the name to DIR_SRCS variable aux_source_directory(. DIR_SRCS) # Specify build target add_executable(Demo ${DIR_SRCS})
Multiple directories, multiple source files
add_subdirectory: the project contains a subdirectory math, so that cmakelists in the math directory Txt files and source code will also be processed.
target_link_libraries: indicates that the executable main needs to be connected to a linked library called MathFunctions.
# CMake minimum version number requirements cmake_minimum_required (VERSION 2.8) # Project information project (Demo3) # Find all source files in the current directory # And save the name to DIR_SRCS variable aux_source_directory(. DIR_SRCS) # Add math subdirectory add_subdirectory(math) # Specify build target add_executable(Demo main.cc) # Add link library target_link_libraries(Demo MathFunctions)
Cmakelists. In the subdirectory txt:
# Find all source files in the current directory # And save the name to DIR_LIB_SRCS variable aux_source_directory(. DIR_LIB_SRCS) # Generate link library add_library (MathFunctions ${DIR_LIB_SRCS})
The command add is used in this file_ Compile the library as a statically linked source file in the src Library Directory.
Custom compilation options
CMake allows you to add compilation options to the project, so that you can select the most appropriate compilation scheme according to your environment and needs.
# CMake minimum version number requirements cmake_minimum_required (VERSION 2.8) # Project information project (Demo4) # Add a configuration header file to handle CMake's settings for the source code configure_file ( "${PROJECT_SOURCE_DIR}/config.h.in" "${PROJECT_BINARY_DIR}/config.h" ) # Do you want to use your own MathFunctions library option (USE_MYMATH "Use provided math implementation" ON) # Add MathFunctions library if (USE_MYMATH) include_directories ("${PROJECT_SOURCE_DIR}/math") add_subdirectory (math) set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) endif (USE_MYMATH) # Find all source files in the current directory # And save the name to DIR_SRCS variable aux_source_directory(. DIR_SRCS) # Specify build target add_executable(Demo ${DIR_SRCS}) target_link_libraries (Demo ${EXTRA_LIBS})
Of which:
Configure on line 7_ The file command is used to add a configuration header file config h. This file is created by CMake from config. Exe h. In generation, through such a mechanism, the generation of code can be controlled by predefined parameters and variables.
The option command ON line 13 adds a USE_MYMATH option, and the default value is ON.
Line 17 according to use_ The value of the mymath variable determines whether to use the MathFunctions library written by ourselves.
config.h.in
#cmakedefine USE_MYMATH
CMake will automatically generate config.config according to the settings in the CMakeLists configuration file H file.
You can find the use you just defined_ For the mymath option, press the direction key on the keyboard to jump between different option windows, and press the enter key to modify the option. After modification, you can press option c to complete the configuration, and then press key g to confirm the generation of Makefile. For other operations of ccmake, please refer to the instruction prompt given at the bottom of the window.
Installation and testing
CMake can also specify installation rules and add tests. These two functions can be performed by using make install and make test after generating the makefile. In the previous GNU Makefile, you may need to write two pseudo targets and corresponding rules for install and test, but in CMake, such work also requires only a few simple commands.
Custom installation rules
math/CMakeLists.txt indicates the installation path of the MathFunctions library
# Specify the installation path of the MathFunctions library install (TARGETS MathFunctions DESTINATION bin) install (FILES MathFunctions.h DESTINATION include)
Change the CMakeLists file in the root directory
# Specify the installation path install (TARGETS Demo DESTINATION bin) install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)
Through the above customization, the generated Demo file and MathFunctions library libmathfunctions O files will be copied to / usr/local/bin, and MathFunctions H and generated config The H file is copied to / usr/local/include. (here, / usr/local / is the root directory of the default installation. You can specify which root directory these files should be copied to by modifying the value of the CMAKE_INSTALL_PREFIX variable).
Add tests to the project
Adding tests is also simple. CMake provides a testing tool called CTest. All we have to do is to call a series of add_ in the CMakeLists file of the project root directory. Test command.
# enable test enable_testing() # Test whether the program runs successfully add_test (test_run Demo 5 2) # Test whether the help information can be prompted normally add_test (test_usage Demo) set_tests_properties (test_usage PROPERTIES PASS_REGULAR_EXPRESSION "Usage: .* base exponent") # Square of test 5 add_test (test_5_2 Demo 5 2) set_tests_properties (test_5_2 PROPERTIES PASS_REGULAR_EXPRESSION "is 25") # Test 10 to the 5th power add_test (test_10_5 Demo 10 5) set_tests_properties (test_10_5 PROPERTIES PASS_REGULAR_EXPRESSION "is 100000") # 10 times of test add_test (test_2_10 Demo 2 10) set_tests_properties (test_2_10 PROPERTIES PASS_REGULAR_EXPRESSION "is 1024")
The above code contains four tests. First test_run is used to test whether the program runs successfully and returns a value of 0. The remaining three tests are used to test whether the square of 5, the 5th power of 10 and the 10th power of 2 can get the correct results. Where PASS_REGULAR_EXPRESSION is used to test whether the output contains the following string.
You can do this by writing macros
# Define a macro to simplify testing macro (do_test arg1 arg2 result) add_test (test_${arg1}_${arg2} Demo ${arg1} ${arg2}) set_tests_properties (test_${arg1}_${arg2} PROPERTIES PASS_REGULAR_EXPRESSION ${result}) endmacro (do_test) # Use this macro for a series of data tests do_test (5 2 "is 25") do_test (10 5 "is 100000") do_test (2 10 "is 1024")
reference material
CMake introduction practice
CMake entry actual combat source code
CMake syntax