如何在编译时全局获取CMake的目标/库名称
CMake全局自动添加PROJECT_NAME编译宏的实现方案
我们可以通过两种简洁的方式实现全局自动为每个目标添加PROJECT_NAME编译宏,避免在每个CMakeLists.txt中重复编写代码:
方案1:封装自定义构建函数(兼容旧版CMake)
在根目录的CMakeLists.txt中定义封装函数,替代原生的add_executable和add_library,在函数内部自动注入编译宏:
# 封装自定义可执行目标创建函数 function(my_add_executable target) add_executable(${target} ${ARGN}) # 自动添加PROJECT_NAME宏,值为当前目标名称 target_compile_definitions(${target} PRIVATE PROJECT_NAME="${target}") endfunction() # 封装自定义库目标创建函数 function(my_add_library target) add_library(${target} ${ARGN}) target_compile_definitions(${target} PRIVATE PROJECT_NAME="${target}") endfunction()
之后所有子模块的CMakeLists.txt中,用my_add_executable替代add_executable,my_add_library替代add_library即可。这种方式兼容性强,支持所有CMake版本,还可以灵活扩展其他公共编译配置。
方案2:全局编译定义+生成表达式(无需修改子模块)
如果使用CMake 3.12及以上版本,可以直接在根CMakeLists.txt中设置全局编译定义,利用生成表达式自动获取当前目标名称:
# 为C++目标全局添加PROJECT_NAME宏 set(CMAKE_CXX_COMPILE_DEFINITIONS "${CMAKE_CXX_COMPILE_DEFINITIONS};PROJECT_NAME=\"$<TARGET_NAME:$<TARGET_PROPERTY:NAME>>\"") # 如果涉及C语言项目,添加对应的全局定义 # set(CMAKE_C_COMPILE_DEFINITIONS # "${CMAKE_C_COMPILE_DEFINITIONS};PROJECT_NAME=\"$<TARGET_NAME:$<TARGET_PROPERTY:NAME>>\"")
这种方式不需要修改任何子模块的构建代码,全局自动生效。编译时每个目标会自动将PROJECT_NAME替换为自身的目标名称,和原MSVC原生构建中$(ProjectName)的效果完全一致。
验证效果
无论使用哪种方案,当你创建名为DemoApp的目标时,MSVC编译阶段会自动添加参数:
/DPROJECT_NAME="DemoApp"
和原全局.props文件中定义的宏效果完全匹配。
内容的提问来源于stack exchange,提问作者pepece
相关产品推荐
相关产品推荐

