CMake quick start

Posted by lpxxfaintxx on Fri, 11 Feb 2022 04:31:59 +0100

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

CMake official documents

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 )

Topics: C++ OpenCV Visual Studio