CMAKE use notes

Posted by Helios on Wed, 22 Sep 2021 16:43:36 +0200

thank

First of all, I would like to thank the netizen named "Ren Qilin" for sorting out the PDF. I have a heart.
I forgot where to download it, but it's really complete.

But I also have a heart. After all, the PDF is old and long, and my secondary development is also hard.

Separation of compilation and source code

The intermediate process files generated by compilation are all placed under the build directory, including the files generated by make.

CMakeLists.txt automatically inherits the parent directory

CMakeLists.txt in the subdirectory automatically inherits all macros and variables defined by CMakeLists.txt in the parent directory. This greatly reduces duplicate code.

CMake script basic syntax

notes

# This is a comment

instructions

CMake script consists of a series of commands, each of which can have zero or more parameters. Use the syntax of the instruction to add parentheses to the instruction name. There can be zero or several parameters in the parentheses. The instructions are executed in the order that they appear in CMakeLists.

The parameters of an instruction are usually separated by spaces, tab s, or line breaks.

variable

When writing CMakeLists, you can use variables to store data and as parameters of instructions.

Variables in CMake have the following characteristics:

1,Variables are strictly case sensitive!
2,CMake There are only two types of variables in: string, and string array.
3,Variables can be assigned or used without declaration. An unassigned variable defaults to an empty string.
4,Unlike other programming languages, CMake There is no assignment operation in the syntax of the script. Whether assignment, comparison or judgment operations are completed through built-in instructions. 
5,Variables can be considered global. Even variables defined in a macro can be accessed outside the macro.

If the string does not contain spaces, you can use it without quotation marks.

In CMake, we can use the set() instruction to set the value of a variable. When extracting the value of a variable, you usually have to add the ${} symbol outside, but there are a few exceptions.

Example:

set(var hello)
message(${var})

Will output
hello

Separating strings with spaces or semicolons represents an array of strings.

set(foo this is a list)

Specify the variable foo value as a string array containing four strings: this, is, a and list.

What happens if a variable containing an array of strings is used as an argument in the command? For example, the following variables:

set(foo a b c)

Pass it as a parameter to an instruction:

command(${foo})

This is equivalent to:

command(a b c)

Expand variable in string

If you wrap a variable name in a string with ${}, the variable will also be replaced.
For example, if we execute the following instructions:

set(foo a b c d)
command("${foo}")

It is equivalent to that we execute the command("a b c d").

It's hard to guess. I don't like to talk more nonsense now. I try to be concise and comprehensive.

escape sequence

If you want to represent special characters in CMake, you can also use the \ mark.

set(bar "alpha beta gamma")
message("\${bar}: ${bar}")

Code output above

${bar}: alpha beta gamma

Script flow control

Although I don't know what use this is, I'm not sure when it will be used. It's not difficult anyway. Just remember.

Conditional statement

The conditional statements of CMake are if, else if, else and endif.

# When the expr value is one of the following, execute command1:
# ON, 1, YES, TRUE, Y
# When the expr value is one of the following, execute command2:
# OFF, 0, NO, FALSE, N, NOTFOUND, *-NOTFOUND, IGNORE 
if(expr)
 command1(arg)
else(expr)
 command2(arg)
endif(expr)
if((expr) AND (expr OR (expr)))

If will try to interpret as a variable even if ${} is not added to the conditional expression.

Circular statement

CMake has two loops:

foreach ... endforeach
while ... endwhile
set(V alpha beta gamma)
message(${V})
foreach(i ${V})
   message(${i})
endforeach()
foreach(loop_var RANGE start stop [step])
endforeach(loop_var)
from start Start to stop End with step Step by step

Common commands

Specifies the name of the project

Command syntax: Project (< ProjectName > [languagename1 languagename2...])
Usage example: project(Main)

Specify the minimum required version of CMake

Command syntax: cmake_minimum_required(VERSION major[.minor[.patch[.tweak]]] [FATAL_ERROR])
Usage example: cmake_minimum_required(VERSION 2.8)

Save the names of all source files in dir directory in variables

Command syntax: aux_ source_ directory(<dir> <variable>)
Usage example: aux_source_directory(. DIR_SRCS)

Specifies that an executable file is compiled from a set of source files and named

Command syntax: add_ executable(<name> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL]
source1 source2 ... sourceN)
Usage example: add_executable(Main ${DIR_SRCS})

Specifies that a library file is compiled from a set of source files source1, Source2... sourceN and named

Command syntax: add_library([STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 source2... sourceN)
Usage example: add_library(Lib ${DIR_SRCS})

Specify that a target (executable or library file) depends on other targets

Command syntax: add_dependencies (target name, dependent-target1, dependent-target2...)
The target here must be created by the add_executable, add_library and add_custom_target commands

Add a subdirectory that needs to be built

Command syntax: add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
Usage example: add_subdirectory(Lib)

The specified target requires a link

Command syntax: target_link_libraries (< target > [Item1 [Item2 [...]] [[debug|optimized|general]]...)
Here, the target must have been created, and the linked item can be an existing target (dependencies will be added automatically)
Usage example: target_link_libraries(Main Lib)

Set the value of the variable to

Command syntax: set (< variable > < value > [[cache < type > < docstring > [force]] | parent_scope])
If Cache variable is specified, it will be put into Cache.
Usage example: set(ProjectName Main)

Remove Variable

Command syntax: unset (< variable > [cache])
Command description: used for variable. If cache is specified, the variable will be removed from the cache.
Usage example: unset(VAR CACHE)

Output information

Command syntax: message ([status|warning|author_warning|fat_error|send_error] "message to display"...)
The compilation information of this output will be output by default.
Usage example: message("Hello World")

Set directory

Command syntax: include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2...)
These directories will be used by the compiler to find the include file
Usage example: include_directories(${PROJECT_SOURCE_DIR}/lib)

CMakeLists.txt example

cmake_minimum_required(VERSION 3.0) # Minimum version
project(main)   # Give this project a name. This is not the name of the executable file, but the name of the project

# Set compilation options. I don't know if I can pass in the end
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)

# Set the last output directory of the executable
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

# Search path for configuration header file
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/include/server)
include_directories(${PROJECT_SOURCE_DIR}/include/server/model)
include_directories(${PROJECT_SOURCE_DIR}/include/server/db)
include_directories(${PROJECT_SOURCE_DIR}/thirdparty)

# load subdirectory
add_subdirectory(src)
# Define an SRC_LIST variable to store all source files in this directory
aux_source_directory(. SRC_LIST)
aux_source_directory(./db SRC_LIST)
aux_source_directory(./model SRC_LIST)

# Specifies that the executable is generated
add_executable(ChatServer ${SRC_LIST})

# Specify the external libraries that need to be linked when the executable is generated
target_link_libraries(ChatServer muduo_net muduo_base pthread mysqlclient hiredis)

# Specify the location of executable files
#set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}../bin)

CMake common variables

CMAKE_SOURCE_DIR
 The content is source tree The full path of the root directory, that is CMake The entry point to start the build process.

CMAKE_BINARY_DIR
 The content is binary tree The full path of the root directory, in in-source build Time value and CMAKE_SOURCE_DIR Same.

PROJECT_SOURCE_DIR
 The top-level directory of the project currently in process, which contains project() Directive CMakeLists Folder.

PROJECT_BINARY_DIR
 The build root directory of the current project. stay in-source build Shi He PROJECT_SOURCE_DIR Same.

CMAKE_CURRENT_SOURCE_DIR
 Currently being processed CMakeLists.txt Location.

CMAKE_CURRENT_BINARY_DIR
 Currently being processed CMakeLists.txt The corresponding build folder location. stay in-source build Shi He CMAKE_CURRENT_SOURCE_DIR Same.

CMAKE_CURRENT_LIST_DIR
 Indicates that the is being processed CMakeLists.txt Absolute path of the directory where the file is located (2).8.3 And later versions)

CMAKE_LIBRARY_OUTPUT_DIRECTORY
 For setting LIBRARY Output path of the target

Limitations of CMAKE

CMake does not comply with GNU rules. This makes CMake's support for some open source software insufficient.

Topics: cmake