cmake项目相关的变量

cmake项目相关的变量

在cmake项目中,通常需要对路径进行操作,比如我们需要知道源码的顶级目录,源码的构建目录和某个project名字相关的一些目录等。

CMAKE_SOURCE_DIR,这个变量的值代表的是源码的顶级目录。但是这个变量的值可能会发生变化。

比如我们现在有个项目B,他的顶级目录是/root/workspace/code/b。这时候我们在项目B中使用CMAKE_SOURCE_DIR变量的值,毫无疑问,它的值是:/root/workspace/code/b

现在我们又有一个项目A,它的顶级目录是/root/workspace/code/a,同时我们的项目A依赖项目B,所以我们通过某种方式将项目B作为项目A的依赖。假设这个时候项目A依赖的项目B的源码在/root/workspace/code/b/3rd/b目录中。那这个时候我们在项目B中获取到的CMAKE_SOURCE_DIR的值就不是我们期望的/root/workspace/code/a/3rd/b,而变成了/root/workspace/code/a。所以我们的项目如果可能被作为第三方项目使用,那CMAKE_SOURCE_DIR的值可能是不可靠的。

同样CMAKE_BINARY_DIR变量同样有这样的问题。

那cmake是怎么解决这些问题的了?当我们调用project()命令的时候cmake会同时设置一些和project相关的变量的值。

  • PROJECT_SOURCE_DIR
    • 该变量的值是在当前作用域或者父作用域中最近的一处调用project()命令的那个CMakeLists.txt所在的目录。
  • PROJECT_BINARY_DIR
    • PROJECT_SOURCE_DIR 目录对应的构建目录。
  • projectName_SOURCE_DIR
    • 前面的projectName是在调用project()命令时传入的名字,加上——SOURCE_DIR后缀可以特指某个项目的CMakeLists.txt所在的目录。
  • projectName_BINARY_DIR
    • projectName_SOURCE_DIR 目录对应的构建目录

demo

目录结构:

顶层目录下,有一个child文件夹,child文件夹有个grandchild文件夹

top cmake文件:

cmake_minimum_required(VERSION 3.26 FATAL_ERROR)

project(topLevel)

message("Top level : \n")
message("  PROJECT_SOURCE_DIR  = ${PROJECT_SOURCE_DIR}")
message("  topLevel_SOURCE_DIR = ${topLevel_SOURCE_DIR}")

add_subdirectory(child)

 child cmake文件

cmake_minimum_required(VERSION 3.26 FATAL_ERROR)

message("Child \n")
message("  PROJECT_SOURCE_DIR (before)  = ${PROJECT_SOURCE_DIR}")
project(child)
message("  PROJECT_SOURCE_DIR (after)  = ${PROJECT_SOURCE_DIR}")
message("  child_SOURCE_DIR = ${child_SOURCE_DIR}")

add_subdirectory(grandchild)

grandchild cmake文件

cmake_minimum_required(VERSION 3.26 FATAL_ERROR)

message("GrandChild \n")
message("  PROJECT_SOURCE_DIR = ${PROJECT_SOURCE_DIR}")
message("  child_SOURCE_DIR  = ${child_SOURCE_DIR}")
message("  topLevel_SOURCE_DIR = ${topLevel_SOURCE_DIR}")

结果:

  总结:

通过上面的例子,我们可以看到,使用project()命令相关的变量去获取相关的路径是非常可靠的,我们的项目中也建议使用这种方式.

举个例子,我们再使用${CMAKE_SOURCE_DIR}/someFile的时候最好使用${PROJECT_SOURCE_DIR}/someFile 或者${projctName_SOURCE_DIR}/someFile代替.这样无论我们的项目是单独构建的还是作为一个子项目构建都能保证我们期望的目录是对的.我们经常看到一些开源项目的顶级目录的CMakeLists.txt中有类似下面的代码:

if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
    # do something
endif()

这里通过比较CMAKE_CURRENT_SOURCE和CMAKE_SOURCE_DIR两个变量的值来判断当前项目是否单独构建.如果相等,表明这个项目是单独构建的,没有作为任何其他项目的子模块.

上面这种方式还需要我们自己判断,cmake3.21版本开始,cmake提供了一个变量:PROJECT_IS_TOP_LEVEL,如果这个变量为真,就代表当前项目是单独构建的,或者是项目中顶级project.

同理,也有proName_IS_TOP_LEVEL变量.每当我们调用project()命令的时候,就会创建对应的proName_IS_TOP_LEVEL缓存变量.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

波雅_汉库克

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值