Quick Start with CMake Compilation Tool

1. Introduction to CMake

CMake manages a program project. In fact, it creates a CMakeLists.txt file in the root directory of the source code as the root node, and then includes its lower-level source code subdirectory through add_subdirectory(subdir), and the CMakeLists.txt in the lower-level source code directory is further passed through add_subdirectory( subdir) contains its lower-level source code directory, and finally all the source codes are concatenated together, and all CMakeLists.txt files are also concatenated together.

In addition, each CMakeLists.txt requires include_directories to set the header file search path for the source code in the current folder. For projects with multiple source code subdirectories (multiple CMakeLists.txt), arbitrarily specify one of the source code directories to be compiled into executable files, and other source code directories to be compiled into static libs, and in any CMakeLists.txt, pass target_link_libraries links the executable with all libraries, static or dynamic.

CMake vs Autotools:

First of all, it doesn't make much sense to compare them. They are all project compilation management tools that generate makefiles. CMake was generated late and solved many problems with autotools tools.

autotools is a tool set with great flexibility, but because of too many steps and cumbersome configuration, there are many alternatives, and cmake is one of the best.

In the early days, there were not so many options, and a large number of open source projects used autotools to manage projects.

2、CMakeLists.txt

A CMakeLists.txt file must be configured in each source code directory of the project, and it is not required in the header file directory.

If there is no source code in the project root directory, but there are multiple source code subdirectories, then a CMakeLists.txt also needs to be configured in the project root directory to connect all source code subdirectories together.

CMakeLists.txt common instructions and variables:

  • Command project(project_name)

Set the project name. This instruction must be placed in the top-level CMakeLists.txt. Do not use the project instruction again in the lower-level CMakeLists.txt, otherwise it will cause the PROJECT_SOURCE_DIR variable to be confused.

  • Variable PROJECT_SOURCE_DIR

Point to the directory where the topmost CMakeLists.txt is located.

  • directive cmake_minimum_required

The minimum version of cmake is required. If you do not add this line, you will receive a warning message.

Just set it in the root node CMakeLists.txt.

  • 指令 include_directories (include_path)

Set the search path for the header file when compiling the source code in the current directory, and separate multiple paths with spaces.

Each CMakeLists.txt needs to set the search path for source code header files in the current directory.

  • Directive link_directories (lib_path)          

Set the search path for library files when compiling the source code in the current directory, and separate multiple paths with spaces.

This instruction is not officially recommended, and the alternative is find_library.

For example:

find_library(libpath_jsoncpp  libjsoncpp.so  ${PROJECT_SOURCE_DIR}/lib)

First search libjsoncpp.so from the system library path, and then search from the custom specified path. Once the match is successful, the path will be returned to the variable libpath_jsoncpp.

  • Command set(des src)

Variable copy, if the target variable does not exist, it will be created automatically.

For example:

set(lib_path "hello")  //赋值变量lib_path为字符串"hello"
message("lib_path=${lib_path}") 输出变量内容

3. Example 1

flat project, all source codes are in the same folder.

Under the demo folder, there are three files, main.c, test.c, test.h:

demo/
   |– main.c
   |– test.c
   |– test.h

Create a CMakeLists.txt file under the demo folder, edit the content as follows:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ cmake_minimum_required (VERSION 2.6)          #cmake最低版本需求,不加入此行会受到警告信息
┃ project(hello)                                #设置项目名(不是指最终编译出的可执行文件名)
┃ aux_source_directory( .  src_list)            #把当前目录(.)下所有源代码文件和头文件路径赋值给变量src_list;
┃ set (EXECUTABLE_OUTPUT_PATH   ${PROJECT_SOURCE_DIR}/bin ) #设置应用程序输出路径
┃ add_executable(demo ${src_list})                          #将目标源码编译成可执行文件demo
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Execute cmake <root node CMakeLists.txt path> in the demo directory, and the Makefile and other related configuration files will be generated in the current directory, and then the Makefile can be called to compile after executing the make command.

In order to avoid generating a lot of target files in the code directory, you can create a subdirectory under the project root directory, such as build, then enter the subdirectory, and run the cmake .. command, the philosophical .. represents the root node CMakeLists.txt path in the parent directory.

After executing cmake .., all configuration information files including Makefile will be generated in the current directory (build), and then the make command will be executed to generate the target file in the build directory. To clean up the target files, just delete the build folder directly.

Note:

  1. EXECUTABLE_OUTPUT_PATH is a system variable of CMake, which is used to set the data path of the application;
  2. PROJECT_SOURCE_DIR is the folder where the last CMakeLists.txt file containing project (project name) is located. Usually project(...) only needs to be defined once in the root CMakeLists.txt file, so PROJECT_SOURCE_DIR usually points to the project root directory.

4. Example 2

Hierarchical structure:

demo/
  ┣main.c
  ┣include/
      ┣test1.h
      ┣test2.h
  ┣src/
     ┣test1.c
     ┣test2.c

Create a CMakeLists.txt file under the demo folder, edit the content as follows:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ cmake_minimum_required (VERSION 2.6)          #cmake最低版本需求,不加入此行会受到警告信息
┃ project(hello)                                #设置项目名(不是指最终编译出的可执行文件名)
┃ aux_source_directory( .  src_list)            #把当前目录(.)下所有源代码文件和头文件路径赋值给变量src_list;
┃ include_directories (include /usr/include)    #设置头文件搜索路径,多个路径用空格隔开,
┃                                               #若有相对路径则是基于当前CMakeLists.txt所在目录;
┃ add_subdirectory(src)                         #添加其他源码子目录
┃ set (EXECUTABLE_OUTPUT_PATH   ${PROJECT_SOURCE_DIR}/bin ) #设置应用程序输出路径
┃ add_executable(demo ${src_list})                          #将目标源码编译成可执行文件demo
┃ link_directories (${PROJECT_SOURCE_DIR}/lib)              #设置库文件搜索路径  
┃ target_link_libraries (demo libpthread.so libsqlite3.so libcurl.so libjsoncpp.so) #设置添加到目标程序中去的库(静态或动态)    
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Create a CMakeLists.txt file under the src folder, edit the content as follows:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃aux_source_directory(. dir_sub_src)   #把当前目录(.)下所有源代码文件和头文件加入变量dir_sub_src
┃include_directories (../include)      #为当前目录下的源码文件设置头文件搜索路径,相对路径基于当前CMakeLists.txt所在目录。
┃add_library (testlib ${dir_sub_src})  #把当前目录源码编译成静态库testlib
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

5. Example 3

Hierarchical structure (multiple source code subdirectories, but no source code files in the project root directory):

 demo/
  ┣include/
      ┣test1.h
      ┣test2.h
  ┣app/
      ┣main.c
  ┣src/
      ┣test1.c
      ┣test2.c

Create a CMakeLists.txt root node file under the demo folder, edit the content as follows:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ cmake_minimum_required (VERSION 2.6)          #cmake最低版本需求,不加入此行会受到警告信息
┃ project(hello)                                #设置项目名(不是指最终编译出的可执行文件名)
┃ add_subdirectory(app)                         #添加源码子目录app(只允许添加子目录,而且一次只能添加一个子目录)
┃ add_subdirectory(src)                         #添加源码子目录src(只允许添加子目录,而且一次只能添加一个子目录)
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Create a CMakeLists.txt root node file under the demo/app folder, edit the content as follows:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ aux_source_directory(.  src_list)             #把当前目录(.)下所有源代码文件和头文件路径赋值给变量src_list;
┃ include_directories (../include)              #设置头文件搜索路径,多个路径用空格隔开
┃ set (EXECUTABLE_OUTPUT_PATH   ${PROJECT_SOURCE_DIR}/bin ) #设置应用程序输出路径
┃ add_executable(demo ${src_list})                    #将目标源码编译成可执行文件demo
┃ link_directories (${PROJECT_SOURCE_DIR}/lib)        #设置库文件搜索路径  
┃ target_link_libraries (demo testlib libpthread.so)  #设置添加到目标程序中去的库(静态或动态)  
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Note:

When calling add_executable to specify the output executable file, set the application output path through set (EXECUTABLE_OUTPUT_PATH) in the same CMakeLists.txt file. When calling target_link_libraries to connect library files, set the library file search path through link_directoriesadd in the same CMakeLists.txt file.

Create a CMakeLists.txt file under the demo/src folder, edit the content as follows:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃aux_source_directory(. dir_sub_src)   #把当前目录(.)下所有源代码文件和头文件路径赋值给变量dir_sub_src
┃include_directories (../include)      #为当前目录下的源码文件设置头文件搜索路径,相对路径基于当前CMakeLists.txt所在目录。
┃add_library (testlib ${dir_sub_src})  #把当前目录源码编译成静态库testlib
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

For some global public configurations, you only need to configure them in the root node CMakeLists.txt, such as the following public configurations:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ cmake_minimum_required (VERSION 2.6)          #cmake最低版本需求,不加入此行会受到警告信息
┃ project(hello)                                #设置项目名(不是指最终编译出的可执行文件名)
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Guess you like

Origin blog.csdn.net/qq_35029061/article/details/131010820