CMakeLists用法总结

分一下几个方面来描述:
1. 每一个LIB要编译成静态库或动态库如何描述,每一个TOOL要编译成可执行文件如何描述?
2. LIB和TOOL可能会依赖于其他LIB,该如何描述?
3. 每个LIB和TOOL都会include很多头文件,相同的头文件如何处理,私有的头文件如何处理?
4. CMake中的一些用法
5. LLVM中用到的技巧

先举一个简单的例子:
//
└─tutorial.c
└─TutorialConfig.h.in
└─CMakeLists.txt
└─include
 └─mysqrt.h
└─lib
└─CMakeLists.txt
 └─MakeTable.c
 └─mysqrt.c

在这个例子中,Top level和lib中会分别定义一个CMakeLists.txt用来指定编译规则。这个例子主要做了以下几件事:
1)用宏USE_MYMATH来控制是否使用自己定义的sqrt()
2) 定义了一个MakeTable.c文件生成sqrt()的一个结果表,在自己定义的sqrt()函数中查表得出简单的结果。

3)或者通过exp和log来计算sqrt的值,但前提是当前库支持exp和log,这些都通过check_function_exists检查是否支持,如果支持相应的宏就会打开。

4)通过CTest,定义相应的测试用例,检查执行结果是否正确。

Top Level中的
Tutorial.c:

// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
#include "mysqrt.h"
#endif

int main (int argc, char *argv[])
{
  if (argc < 2)
    {
    fprintf(stdout,"%s Version %d.%d\n", argv[0],
            Tutorial_VERSION_MAJOR,
            Tutorial_VERSION_MINOR);
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
    }

  double inputValue = atof(argv[1]);

#ifdef USE_MYMATH
  double outputValue = mysqrt(inputValue);
  printf ("call local sqrt\n");
#else
  double outputValue = sqrt(inputValue);
#endif

  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);
  return 0;
}

当cmake为头文件配置”@Tutorial_VERSION_MAJOR@”和
“@Tutorial_VERSION_MINOR@”两个值时,会从CMakeLists.txt中找到相应的值来替换配置文件中对应行。

TutorialConfig.h.in

// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

#cmakedefine USE_MYMATH

#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

CMakeList.txt定义如下:

cmake_minimum_required (VERSION 2.6)
project (Tutorial)

# The version number.
//"set"用来给对应的变量赋值
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
set(include_dir ${CMAKE_CURRENT_SOURCE_DIR}/include)

//"MESSAGE"用来打印信息,包括变量的值
MESSAGE(STATUS "include folder: " ${include_dir})

//"option"用来定义宏,"ON"表示打开,"OFF"表示关闭
option (USE_MYMATH "Use tutorial provided math implementation" ON)

//configure_file: 将一份文件拷贝到另一个位置并修改它的内容。
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )

# add the binary tree to the search path for in
### CMakeLists.txt 中常见函数的用法 #### 1. `project` 函数 用于定义项目的名称以及支持的语言。此函数通常位于 CMakeLists.txt 文件的第一行。 ```cmake project(MyProjectName LANGUAGES CXX) ``` 上述代码片段表示创建名为 MyProjectName 的项目,并指定使用的编程语言为 C++[^2]。 --- #### 2. `add_executable` 和 `add_library` 这两个函数分别用于声明可执行文件和库文件。 - **`add_executable`**: 创建一个可执行目标。 ```cmake add_executable(myExecutable main.cpp utils.cpp) ``` 这会将 main.cpp 和 utils.cpp 编译成一个名为 myExecutable 的可执行程序。 - **`add_library`**: 定义静态或共享库。 ```cmake add_library(myLibrary STATIC librarySource.cpp) ``` 这里通过 static 参数指定了生成的是静态库,如果改为 SHARED,则会生成动态库[^3]。 --- #### 3. `set` 函数 用于设置变量值,在后续脚本中可以调用这些变量。 ```cmake set(CMAKE_CXX_STANDARD 17) ``` 这段代码设置了 C++ 标准版本为 C++17[^1]。 --- #### 4. `find_package` 函数 用于查找外部依赖包并加载其配置模块。 ```cmake find_package(Boost REQUIRED COMPONENTS filesystem system) if (Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) endif() ``` 上面的例子展示了如何检测 Boost 库是否存在,并将其头文件路径加入到编译选项中[^4]。 --- #### 5. `target_include_directories`, `target_link_libraries`, 和 `target_compile_options` 这三个函数针对特定的目标提供更细粒度的操作: - **`target_include_directories`**: 设置目标所需的额外包含路径。 ```cmake target_include_directories(myExecutable PRIVATE ${PROJECT_SOURCE_DIR}/include) ``` 这里的 PRIVATE 表明只影响当前目标;PUBLIC 或 INTERFACE 可以让其他目标也继承这一属性。 - **`target_link_libraries`**: 配置链接器行为,告诉它哪些库应该被连接至某个目标上。 ```cmake target_link_libraries(myExecutable PRIVATE pthread dl) ``` 同样地,PRIVATE/INTERFACE/PUBLIC 控制作用范围。 - **`target_compile_options`**: 自定义编译参数给定目标。 ```cmake target_compile_options(myExecutable PRIVATE -Wall -Wextra) ``` 添加警告标志 `-Wall` 和 `-Wextra` 来增强编译期间错误提示能力。 --- #### 6. `install` 命令 负责安装构建产物到适当位置。 ```cmake install(TARGETS myExecutable DESTINATION bin) install(DIRECTORY include/ DESTINATION include) ``` 第一条语句把最终生成的应用放置于系统的二进制目录下(通常是 `/usr/local/bin`),第二条则复制整个 include 子树到全局头文件夹里。 --- #### 7. `add_subdirectory` 引入子级源码区域及其对应的 CMake 脚本继续处理。 ```cmake add_subdirectory(src) ``` 假设 src 是另一个含有独立 CMakeLists.txt 的子目录,那么这条指令会让 cmake 进入其中解析相关内容。 --- #### 总结 以上列举了一些常用的 cmake 函数功能介绍及简单实例演示。实际开发过程中可能还会遇到更多复杂场景下的应用需求,比如条件判断、循环迭代等高级特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值