[CMake entry and advanced (3)] CMakeLists.txt grammar rule basis and some common instructions (with code)

        In the last two articles, the author demonstrated how to use cmake through a few simple examples. From this we can see that the use of cmake is actually very simple. The focus is on writing CMakeLists.txt, and the grammar rules of CMakeLists.txt are also Simple, not as complicated and difficult to understand as the grammar rules of Makefile! In this article, we will learn the grammar rules of CMakeLists.txt.

Introduction to Simple Grammar

  • note

        In the CMakeLists.txt file, use the "#" sign for single-line comments, for example:

#
# 这是注释信息
#
cmake_minimum_required(VERSION 3.5)
project(HELLO)

        Most scripting languages ​​use the "#" sign for comments.

  • command

        Usually in the CMakeLists.txt file, commands are used the most. For example, the cmake_minimum_required project in the above example is a command; the use of commands is somewhat similar to functions in C language, because a pair of parentheses need to be provided after the command, and usually need We provide parameters, and multiple parameters are separated by spaces instead of commas "," which is different from functions. The syntax format of the command is as follows:

command(参数 1 参数 2 参数 3 ...)

        Different commands require different parameters. It should be noted that parameters can be divided into required parameters and optional parameters (usually called options). Many commands provide these two types of parameters. Required parameters are represented by Use [parameter] to express, such as the set command:

set(<variable> <value>... [PARENT_SCOPE])

        The set command is used to set variables. The first parameter and the second parameter are required parameters. An optional parameter PARENT_SCOPE (PARENT_SCOPE option) can be added at the end of the parameter list (… means there is no limit to the number of parameters). Since it is optional Yes, it is not necessary, and it is determined whether it needs to be added according to the actual usage.

        In CMakeLists.txt, the command name is not case-sensitive, you can use uppercase and lowercase letters to write the command name, for example:

project(HELLO) #小写
PROJECT(HELLO) #大写

        The effect of the two is the same, the same command is specified, there is no difference; this mainly depends on personal preference, the author uses lowercase letters, mainly to distinguish them from variables, because the names of cmake's built-in variables are all capitalized made up of letters.

  • variable

        Variables can be used in the CMakeLists.txt file, and variables can be set using the set command, for example:

# 设置变量 MY_VAL
set(MY_VAL "Hello World!")

        In the above example, the variable MY_VAL is set through the set command, and its content is set to "Hello World!"; then how to reference this variable? This is the same as Makefile, refer to variables by ${MY_VAL}, as follows:

#设置变量 MY_VAL
set(MY_VAL "Hello World!")

#引用变量 MY_VAL
message(${MY_VAL})

        Variables can be divided into cmake built-in variables and custom variables. For example, MY_VAL defined in the above example is a custom variable ; Library file (with code)_GPIOB_PIN7's blog-CSDN blog The LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH variables used by cmake are built-in variables of cmake. Each built-in variable has its own meaning. There are many built-in variables like this, and I will introduce them to you later .

Some common commands

         cmake provides many commands, and each command has its own function and function. Through this link address cmake-commands(7) — CMake 3.5.2 Documentation, you can query all commands and their corresponding introductions, usage methods, etc. ,As follows:

         You can save this link address, and use it as a dictionary to query when necessary. Since there are so many commands, it is impossible for the author to introduce all the commands to you. Here are some basic commands for you. As shown in the table below:

command illustrate
add_executable executable program target
add_library library file target
add_subdirectory Go to the specified directory to find the new CMakeLists.txt file
aux_source_directory Collect the file names in the directory and assign them to variables
cmake_minimum_required Set the minimum version number requirement of cmake
get_target_property Get the properties of the target
include_directories Set the search path for all target header files, equivalent to the -L option of gcc
link_directories Set the search path for all target library files, equivalent to the -L option of gcc
link_libraries Set the libraries that all targets need to link with
list List related operations
message For printing, outputting information
project Set project name
set set variable
set_target_properties Set target properties
target_include_directories Sets the search path for the specified target header files
target_link_libraries Set the search path for the specified target library file
target_sources Sets the source files required for the specified target

        Next, I will introduce each command in detail.

  • add_executable

        The add_executable command is used to add an executable program target and set the source files required by the target. The command definition is as follows:

add_executable(<name> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 [source2 ...])

        This command provides some optional parameters. I won’t say much about the meaning of these optional parameters. Usually, you don’t need to add them. For the specific meaning, you can check the official cmake documentation ( add_executable — CMake 3.5.2 Documentation ); just pass Just enter the target name and the corresponding source file, for example:

#生成可执行文件 hello
add_executable(hello 1.c 2.c 3.c)

        An executable program target hello is defined, and the source files required to generate the target file are 1.c, 2.c and 3.c. It should be noted that the source file path can use either a relative path or an absolute path, and the relative path is interpreted as relative to the current source code path (note that the source code here refers to the CMakeLists.txt file, because CMakeLists.txt is called The source code of cmake, unless otherwise specified, this concept will be used in the future!).

  • add_library

        The add_library command adds a library file target and sets the source files required by the target. The command definition is as follows:

add_library(<name> [STATIC | SHARED | MODULE]
 [EXCLUDE_FROM_ALL]
 source1 [source2 ...])

        The first parameter name specifies the name of the target, and the parameters source1...source2 correspond to the list of source files; the default library file generated by the add_library command is a static library file, and the SHARED option can be used to generate a dynamic library file. The specific usage is as follows:

#生成静态库文件 libmylib.a
add_library(mylib STATIC 1.c 2.c 3.c)

#生成动态库文件 libmylib.so
add_library(mylib SHARED 1.c 2.c 3.c)

        Same as the add_executable command, the source file in the add_library command can be specified using either a relative path or an absolute path, and the relative path is interpreted as relative to the current source code path.

        Regardless of add_executable or add_library, the target names defined by them must be unique in the entire project, and two targets with the same target name cannot appear.

  • add_subdirectory

        The add_subdirectory command tells cmake to find the source code in the specified directory and execute it, a bit like the include of Makefile, and its definition is as follows:

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

        The parameter source_dir specifies a directory, and tells cmake to find the CMakeLists.txt file in the directory and execute it; the parameter binary_dir specifies a path, which is used as a sub-source code (the source code that calls the add_subdirectory command is called the current source code or the parent source code, and the executed The source code is called the sub-source code) output file (intermediate file generated by the cmake command) directory, the binary_dir parameter is an optional parameter, if not specified explicitly, a default output file directory will be used; for the convenience of subsequent expression, we Call the output file directory BINARY_DIR.

        For example, the project directory structure is as follows:

├── build
├── CMakeLists.txt
└── src
  ├── CMakeLists.txt
  └── main.c

        The content of the top-level CMakeLists.txt file is as follows:

# 顶层 CMakeLists.txt
cmake_minimum_required("VERSION" "3.5")
project("HELLO")

# 告诉 cmake 去 src 目录下寻找 CMakeLists.txt
add_subdirectory(src)

        CMakeLists.txt file in the src directory:

# src 下的 CMakeLists.txt
add_executable(hello main.c)

        Enter the build directory, execute cmake and make to build and compile; the output files corresponding to the top-level source code will be stored in the build directory, which is the directory where the cmake command is executed; the output files corresponding to the sub-source code (CMakeLists.txt in the src directory) will be Stored in the build/src directory, including the generated executable files will be placed in the same directory as these intermediate files by default, as follows:

├── build
│  ├── CMakeCache.txt
│  ├── CMakeFiles
│  ├── cmake_install.cmake
│  ├── Makefile
│  └── src
│    ├── CMakeFiles
│    ├── cmake_install.cmake
│    ├── hello
│    └── Makefile
├── CMakeLists.txt
└── src
  ├── CMakeLists.txt
  └── main.c

        Therefore, it can be seen that when the current source code calls the add_subdirectory command to execute the sub-source code, if BINARY_DIR is not specified for the sub-source code, by default, a folder with the same name as the subdirectory (the directory where the sub-source code is located) will be created in the BINARY_DIR of the current source code. It serves as the subsource's BINARY_DIR. Next we modify the top-level CMakeCache.txt file:

# 顶层 CMakeLists.txt
cmake_minimum_required("VERSION" "3.5")
project("HELLO")

# 告诉 cmake 去 src 目录下寻找 CMakeLists.txt
add_subdirectory(src output)

        Specify the BINARY_DIR of the sub-source code as output, and the relative path method is used here. The interpretation of the add_subdirectory command for the relative path is: relative to the BINARY_DIR of the current source code; after the modification is completed, enter the build directory again and execute the cmake and make commands to build, Compile, and an output directory will be generated under the build directory at this time, which is the BINARY_DIR of the sub-source code.

        You can use a relative path or an absolute path to set BINARY_DIR. The relative path is relative to the BINARY_DIR of the current source code, not the current source code path. This should be understood.

        Load and execute the source code in an external folder through the add_subdirectory command, which can be a subdirectory of the current source code path, a directory at the same level as the current source code path, or a superior directory of the current source code path, etc.; for the current source code path The subdirectory of the subdirectory does not force the caller to explicitly specify the BINARY_DIR of the subsource code; if it is not a subdirectory of the current source code path, the caller needs to explicitly specify BINARY_DIR, otherwise an error will be reported when the source code is executed. Next, test. For example, the project directory structure is as follows:

├── build
├── CMakeLists.txt
├── lib
│  └── CMakeLists.txt
└── src
  ├── CMakeLists.txt
  └── main.c

        There are a total of 3 CMakeLists.txt files here. The lib directory and the src directory are in a horizontal relationship. The content of the top-level CMakeLists.txt is as follows:

# 顶层 CMakeLists.txt
cmake_minimum_required("VERSION" "3.5")
project("HELLO")

# 加载 src 目录下的源码
add_subdirectory(src)

        CMakeLists.txt in the src directory:

# src 目录 CMakeLists.txt
add_executable(hello main.c)

# 加载平级目录 lib 中的源码
add_subdirectory(../lib)

        At this time, when calling add_subdirectory to load the source code of the lib directory and explicitly specify BINARY_DIR, enter the build directory, execute the cmake command, an error occurs, and it prompts us that the add_subdirectory command must specify BINARY_DIR, then we will CMakeLists in the src directory. txt to explicitly specify BINARY_DIR as follows:

# src 目录 CMakeLists.txt
add_executable(hello main.c)

# 加载平级目录 lib 中的源码
add_subdirectory(../lib output)

        Then execute cmake again (clean up before each execution of cmake, and delete all files generated in the build directory).


To be continued...

Guess you like

Origin blog.csdn.net/cj_lsk/article/details/131042474