preface:
- CMake is a cross platform installation and compilation tool, which can describe the installation (compilation process) of all platforms with simple statements.
- CMake has become the standard configuration of most C + + open source projects
Cross-platform development
What you will do if you want to add new bar.cpp source file? You have to add it to every tool you use:
To keep the environment consistent you have to do the similar update several times. And the most important thing is that you have to do it manually (arrow marked with a red color on the diagram in this case). Of course such approach is error prone and not flexible.
CMake solve this design flaw by adding extra step to development process. You can describe your project in CMakeLists.txt file and use CMake to generate tools you currently interested in using cross-platform CMake code:
Same action - adding new bar.cpp file, will be done in one step now:
Note that the bottom part of the diagram was not changed. I.e. you still can keep using your favorite tools like Visual Studio/msbuild, Xcode/xcodebuild and Makefile/make!
Introduction to grammatical features
Basic syntax format: instruction (parameter 1, parameter 2...)
- Parameters are enclosed in parentheses
- Parameters are separated by spaces or semicolons
Instructions are case independent, and parameters and variables are case dependent
set(HELLO hello.cpp) add_executable(hello main.cpp hello.cpp) ADD_EXECUTABLE(hello main.cpp ${HELLO})
The variable is valued in ${} mode, but the variable name is directly used in the IF control statement
Important instructions and CMake common variables
Important instructions
cmake_minimum_required - specifies the minimum version requirement for CMake
# The minimum version of CMake is required to be 2.8.3 cmake_minimum_required(VERSION 2.8.3)
Syntax: cmake_minimum_required(VERSION versionNumber [FATAL_ERROR])
Project - defines the project name and specifies the language supported by the project
# Specify the project name as HELLOWORLD project(HELLOWORLD)
Syntax: project(projectname [CXX] [C] [Java])
set - explicitly defined variable
# Define SRC variable with value of main cpp hello. cpp set(SRC sayhello.cpp hello.cpp)
Syntax: set(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
include_directories - add multiple specific header file search paths to the project - > equivalent to specifying the - I parameter of the g + + compiler
# Add / usr/include/myincludefolder and/ Include add to header file search path include_directories(/usr/include/myincludefolder ./include)
Syntax: include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 …)
link_directories - add multiple specific library file search paths to the project - > equivalent to specifying the - L parameter of the g + + compiler
# Add / usr/lib/mylibfolder and/ Lib add to library file search path link_directories(/usr/lib/mylibfolder ./lib)
Syntax: link_directories(dir1 dir2 …)
add_library - generate library files
# Generate libhello. Through variable SRC So shared library add_library(hello SHARED ${SRC})
Syntax: add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN)
add_compile_options - add compilation parameters
# Add compilation parameter - Wall -std=c++11 add_compile_options(-Wall -std=c++11 -O2)
Syntax: add_compile_options(
add_executable - generate executable
# Compile main CPP generate executable file main add_executable(main main.cpp)
Syntax: add_library(exename source1 source2 … sourceN)
target_link_libraries - add a shared library to target that needs to be linked - > the same as specifying the g + + compiler - l parameter
# Link the hello dynamic library file to the executable file main target_link_libraries(main hello)
Syntax: target_link_libraries(target library1library2…)
add_subdirectory - add a subdirectory for storing source files to the current project, and specify the storage location of intermediate binary and target binary
# Add the src subdirectory. There should be a cmakelists in src txt add_subdirectory(src)
Syntax: add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
aux_source_directory - find all source code files in a directory and store the list in a variable. This instruction is temporarily used to automatically build the source file list
# Defines the SRC variable whose value is all source code files in the current directory aux_source_directory(. SRC) # Compile the source code file represented by the SRC variable to generate the main executable file add_executable(main ${SRC})
Syntax: aux_source_directory(dir VARIABLE)
6.3.2 CMake common variables
- CMAKE_C_FLAGS gcc compilation options
- CMAKE_CXX_FLAGS g + + compilation options
# At cmake_ CXX_ Add - std=c++11 after flags compilation option set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
- CMAKE_BUILD_TYPE compile type (Debug, Release)
# Set the compilation type to debug, and you need to select debug during debugging set(CMAKE_BUILD_TYPE Debug) # Set the compilation type to release, and select release when publishing set(CMAKE_BUILD_TYPE Release)
-
CMAKE_BINARY_DIR
-
PROJECT_BINARY_DIR
-
__BINARY_DIR
- The three variables refer to the same content.
- If it is in source build, it refers to the top-level directory of the project.
- If it is an out of source compilation, it refers to the directory where the project compilation takes place.
-
PROJECT_BINARY_DIR is slightly different from other instructions, but now, you can understand that they are consistent.
-
CMAKE_SOURCE_DIR
-
PROJECT_SOURCE_DIR
-
__SOURCE_DIR
- The contents referred to by these three variables are consistent. No matter what compilation method is adopted, they are the top-level directory of the project.
- That is, when in source build, he and CMAKE_BINARY_DIR and other variables are consistent.
- PROJECT_SOURCE_DIR is slightly different from other instructions. Now, you can understand that they are consistent.
-
CMAKE_C_COMPILER: Specifies the C compiler
-
CMAKE_CXX_COMPILER: Specifies the C + + compiler
-
EXECUTABLE_OUTPUT_PATH: the storage path of the executable output
-
LIBRARY_OUTPUT_PATH: storage path of library file output
6.4 CMake compilation project
CMake directory structure: there is a cmakelists in the project main directory Txt file
There are two ways to set Compilation Rules:
The subfolder containing the source file contains cmakelists Txt file, cmakelists in the home directory Txt via add_ Add subdirectory to subdirectory;
The subfolder containing the source file does not contain cmakelists Txt file, and the Compilation Rules of subdirectories are reflected in CMakeLists.txt of the main directory Txt;
6.4.1 compilation process
The process of using CMake to build C/C + + project on linux platform is as follows:
Manually write cmakelists txt.
Execute the command cmake PATH to generate a makefile (path is the directory where the top-level CMakeLists.txt is located).
Execute the command make to compile.
# important tips . # Indicates the current directory ./ # Indicates the current directory .. # Indicates the parent directory ../ # Indicates the parent directory
6.4.2 two construction methods
In source build: not recommended
Internal construction will produce a lot of intermediate files in the same level directory. These intermediate files are not what we need in the end. They will appear disorderly together with the project source files.
## Internal construction # In the current directory, compile the cmakelists Txt to generate Makefile and other files cmake . # Execute the make command to generate the target make
Out of source build: recommended
Put the compiled file in a different directory than the source file
## External construction # 1. Under the current directory, create the build folder mkdir build # 2. Enter the build folder cd build # 3. Compile cmakelists of the parent directory Txt to generate Makefile and other files cmake .. # 4. Execute the make command to generate the target make
6.5 [actual combat] CMake code practice
6.5.1 minimum CMake works
# Set the minimum version of CMake that can be used cmake_minimum_required(VERSION 3.0) # Set the project name project (HELLO) # Add an executable add_executable(hello_cmake main.cpp)
6.5.2 multi Directory Project - direct compilation
# Set the minimum version of CMake that can be used cmake_minimum_required(VERSION 3.0) #project name project(SWAP) #head file pat include_directories( include ) #source directory files to var add_subdirectory( src DIR_SRCS ) #add executable file add_executable(swap_02 ${TEST_MATH}) #add link library target_link_libraries(${FS_BUILD_BINARY_PREFIX}sqrt ${LIBRARIES})
6.5.3 multi Directory Project - build library compilation
# Set the minimum version of CMake that can be used cmake_minimum_required(VERSION 3.0) #project name project(SWAP_LIBRARY) #add compile options add_compile_options("-Wall -std=c++11") #set CMAKE_BUILD_TYPE set( CMAKE_BUILD_TYPE Debug ) # set output binary path set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) ############################################################ # Create a library ############################################################ #Generate the static library from the library sources add_library( swap_library STATIC src/Swap.cpp ) target_include_directories( swap_lib PUBLIC ${PROJECT_SOURCE_DIR}/include ) ############################################################ # Create an executable ############################################################ # Add an executable with the above sources add_executable( swap_01 main.cpp ) # link the new swap_01 target with the swap_lib target target_link_libraries( swap_01 swap_liby )