CMake

例子:单个文件编译

目录结构

├── CMakeLists.txt

├── Calculator.cpp

├── Calculator.h

├── main.cpp

CMakeLists.txt

cmake_minimum_required(VERSION 3.0) project(BUILD) set(SOURCES test.cpp) add_executable(test1 ${SOURCES})

注:

  1. 需要先声明CMake的最新版本号
  2. 设置项目名称
  3. 设置变量 SOURCES
  4. 把test.cpp 编译成可执行的二进制文件

test1.cpp

#include using namespace std; int main(int argc, char const *argv[]) { cout<<"hello world"<

编译命令

外部编译:

mkdir build cd build cmake . make

注:

  1. 创建build目录
  2. 切换到build目录下
  3. 根据CMakeLists.txt 构建和编译源文件 生成MakeFile 文件, makeFile文件中定义了一系列规则,例如如何编译、链接和打包等
  4. 根据CMakeFile文件生成可执行的二进制文件

执行

./test1

常见命令

cmake_minimum_required

设置 cmake 的最新版本号,每个 CMakeLists.txt 文件首行必须包含

project 设置项目名称

project( [VERSION ] [LANGUAGES ...])

project(projcetName VERSION 1.0)

其中,projectname 是项目的名称,version 是项目的版本号,language 是项目使用的编程语言。

在 CMake 中,project 命令通常是作为 CMakeLists.txt 文件的第一条命令出现,用于定义项目的名称和版本号。该命令会自动创建一些变量,例如 PROJECT_NAME 和 PROJECT_VERSION

add_executable

把一个或多个文件编译成一个可执行的二进制文件

例 1 直接使用文件

add_executable(name1 test.cpp)

执行文件: ./name1

例 2 使用变量

set(SOURCES test1.cpp test2.cpp ....)

add_executable(name1 ${SOURCES})

执行: ./name1

例 3

示例中我们使用 file(GLOB ...) 命令从 src 目录中查找所有扩展名为 .cpp 的文件,并将它们存储在 SOURCES 变量中。然后,我们使用 add_executable 命令创建了一个名为 my_program 的可执行文件,并将 SOURCES 变量作为参数传递给该命令。这样,CMake 将会将这些文件编译成一个可执行文件。

file(GLOB SOURCES src/*.cpp)

add_executable(my_program ${SOURCES})

执行:./my_program

message 打印信息

project(my_project VERSION 1.0)

message("Project name: ${PROJECT_NAME}")

message("Project version: ${PROJECT_VERSION}")

add_subdirectory 添加子目录编译

add_subdirectory(test1)

注:子目录中需要含有 CMakeLists.txt

add_library 编译成库文件

add_library( [STATIC | SHARED | MODULE]

[EXCLUDE_FROM_ALL]

source1 [source2 ...])

add_library(mylib STATIC foo.cpp bar.cpp)

target_sources 确定那些源文件会编译进目标

例1

不使用 target_sources

定义一个名为 my_library 的库 add_library(my_library SHARED foo.cpp bar.cpp )

使用 target_sources

定义一个名为 my_library 的库 add_library(my_library SHARED) 将 foo.cpp 和 bar.cpp 添加到 my_library 中 target_sources(my_library PRIVATE foo.cpp bar.cpp)

例2

不使用 target_sources

定义一个名为 my_executable 的可执行文件 add_executable(my_executable main.cpp)

使用 target_sources

定义一个名为 my_executable 的可执行文件 add_executable(my_executable) 将 main.cpp 添加到 my_executable 中 target_sources(my_executable PRIVATE main.cpp)

target_link_libraries 链接库文件(静态库或动态库)

例子

子目录CMakeListx.txt

cmake_minimum_required(VERSION 3.0) project(VECTOR) #c++标准 set(CMAKE_CXX_STANDARD 11) #set(CMAKE_CXX_STANDARD_REQUIRED ON) 是一个CMake命令,它用于指定编译器是否应该强制使用所需的C++标准。将此命令设置为 #ON 将强制编译器使用所需的C++标准,如果编译器不支持所需的标准,则会引发错误。如果将其设置为 #OFF,则编译器会尝试使用所需的标准,但如果不支持,则会回退到较低的标准。 set(CMAKE_CXX_STANDARD_REQUIRED ON) # 自动找出当前目录下的源文件(不包含子目录),并赋值给SOURCES变量 aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/lib SOURCES) # 生成共享库 add_library(vector_lib SHARED ${SOURCES}) #告知搜索的头文件路径 却是可以开放权限 target_include_directories(vector_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

主目录CMakeLists.txt

cmake_minimum_required(VERSION 3.0) project(MAIN) # 通知子目录Vector的CMakeLists.txt 编译 add_subdirectory(Vector) #生成二级制文件 main 源文件是main.cpp add_executable(main main.cpp) # 链接vector库文件 target_link_libraries(main PRIVATE vector_lib)

main.cpp

#include #include "Vector.h" using namespace std; int main() { Vector v1(1, 2, 3); Vector v2(4, 5, 6); Vector v3 = v1.add(v2); std::cout << "v1: (" << v1.getX() << ", " << v1.getY() << ", " << v1.getZ() << ")" << std::endl; std::cout << "v2: (" << v2.getX() << ", " << v2.getY() << ", " << v2.getZ() << ")" << std::endl; std::cout << "v3 = v1 + v2: (" << v3.getX() << ", " << v3.getY() << ", " << v3.getZ() << ")" << std::endl; return 0; }

set

1. 设置一个字符串变量

set(MY_STRING "Hello, world!")

2. 设置一个字符串列表

set(MY_LIST "foo" "bar" "baz")

3. 设置一个布尔值

set(MY_BOOL TRUE)

读取变量、使用变量

1. 在 CMakeLists.txt 中使用

(其也有作用域和访问权限,只可使用自身变量和自身所包含的子 CMakeLists.txt)

set(MY_STRING "Hello, world!")

message("${MY_STRING}")

2. 在代码中使用

#include int main() { std::cout << "${MY_STRING}" << std::endl; std::cout << "CMAKE_CXX_FLAGS: " << CMAKE_CXX_FLAGS << std::endl; return 0; }

常用常量

  1. VERSTION 版本号
  2. PROJECT_NAME 项目名称
  3. PROJECT_VERSION 项目版本号
  4. CMAKE_SOURCE_DIR:项目的根目录路径。
  5. CMAKE_BINARY_DIR:二进制文件的存放目录路径,通常是在项目根目录下的 build 目录。
  6. CMAKE_CURRENT_SOURCE_DIR:当前正在处理的 CMakeLists.txt 文件所在的目录路径。
  7. CMAKE_CURRENT_BINARY_DIR:当前正在处理的 CMakeLists.txt 文件的输出目录路径。
  8. CMAKE_INSTALL_PREFIX:项目的安装目录路径。
  9. CMAKE_C_COMPILER:C 语言编译器的路径。
  10. CMAKE_CXX_COMPILER:C++ 语言编译器的路径。
  11. CMAKE_C_FLAGS:C 编译器的编译选项。
  12. CMAKE_CXX_FLAGS:C++ 编译器的编译选项。
  13. CMAKE_BUILD_TYPE:构建类型,包括 Debug、Release、MinSizeRel、RelWithDebInfo
  14. CMAKE_MODULE_PATH:指定用于查找 CMake 模块文件的路径,以便在项目中引入自定义模块。
  15. CMAKE_INCLUDE_PATH:指定用于查找头文件的路径,以便在项目中引入第三方头文件。
  16. CMAKE_LIBRARY_PATH:指定用于查找库文件的路径,以便在项目中引入第三方库文件。
  17. CMAKE_PREFIX_PATH:指定用于查找安装的库和头文件的路径。
  18. CMAKE_INSTALL_RPATH:指定二进制文件运行时查找共享库文件的路径。
  19. CMAKE_INSTALL_RPATH_USE_LINK_PATH:在安装二进制文件时,自动将 RPATH 设为使用与二进制文件链接的库的路径。
  20. CMAKE_BUILD_WITH_INSTALL_RPATH:在构建时将 RPATH 设为使用 CMAKE_INSTALL_RPATH 指定的路径。
  21. CMAKE_FIND_LIBRARY_SUFFIXES:指定用于查找库文件的后缀名。
  22. CMAKE_FIND_ROOT_PATH:指定查找库和头文件的根路径。
  23. CMAKE_FIND_ROOT_PATH_MODE_LIBRARY:指定库文件查找方式,包括 NEVER、ONLY、FIRST、LAST、BOTH

注意事项

在 CMakeLists.txt 中共享变量

变量需要设置为缓存才可以跨区域访问

aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SUB_DIR_SRC)

# 把 DIR_SRCS 追加到主目录定义的 ALL_SRCS 中 set(ALL_SRCS ${ALL_SRCS} ${SUB_DIR_SRC} CACHE INTERNAL "")

注:

1,在当前的CMakeLists.txt 目录下,找到所有的源文件(无法找到子目录下的源文件),并给变量SUB_DIR_SRC

2,设置变量 ALL_SRCS 为缓存、访问权限是INTERNAL 、初始值 "" 空字符串。

而后方可在主目录下的CMakeLists.txt 中访问到改变量,其他子目录也可访问到。

大型项目

在编译大型项目时,并不建议使用file命令、aux_source_directory命令。手动导入源文件列表编译效率更高。

官网:

CMake Reference Documentation — CMake 3.26.3 Documentation

你可能感兴趣的:(linux,运维,服务器,c++,c)