如何在 CMake 中对目标依赖项进行分组?

  • 本文关键字:依赖 目标 CMake c++ cmake
  • 更新时间 :
  • 英文 :


我有一个非常复杂的基于make的项目,我正在尝试将其迁移到现代CMake用法。在Makefile中,我有几个类似的共享库目标,它们共享几乎相同的编译标志。所以,它看起来像这样:

add_library(lib1 SHARED src1.cpp src2.cpp)
target_compile_options(lib1 PUBLIC -public-flag1 -public-flag2 -unique-flag3 PRIVATE -private-flag)
add_library(lib2 SHARED src3.cpp src4.cpp) 
target_compile_options(lib2 PUBLIC -public-flag -public-flag2 PRIVATE -private-flag)

有没有办法可以抽象出常见的依赖项,这样我就不必在每个目标下重复它们?似乎接口库是执行此操作的方法,如下所示:

add_library(common_options INTERFACE)
target_compile_options(common_options 
PUBLIC -public-flag1 -public-flag2
PRIVATE -private-flag
)
add_library(lib1 SHARED src1.cpp src2.cpp)
target_compile_options(lib1 PUBLIC -unique-flag3)
target_link_libraries(lib1 common_options)
add_library(lib2 SHARED src3.cpp src4.cpp) 
target_link_libraries(lib1 common_options)

在我看来,这将是可维护性的净胜利。但是,CMake 对此抛出了一个错误,抱怨接口目标只能携带INTERFACE选项(我无法向其添加PRIVATE选项(。有没有其他方法可以让我封装目标之间共享的PUBLICPRIVATE标志?

你走在正确的轨道上。考虑一下:

add_library(public  INTERFACE)
add_library(private INTERFACE)
target_compile_options(public  INTERFACE -Werror)
target_compile_options(private INTERFACE -Wall)
target_link_libraries(lib1
PUBLIC  # <-- public's flags will be applied to lib1 and any targets linking to lib1
public
PRIVATE # <-- private's flags will only be applied to lib1
private
)

简而言之,您忘记在对target_link_libraries的调用中添加范围。

更新

所以我认为对我问题的直接回答是我不能完全做我想做的事,即将私有和公共编译选项依赖项都包含在单个实体中。相反,我只需要做一个公共的和一个私人的。没有我希望的那么干净,但可以管理。

不是真的,您将始终必须指定PUBLICPRIVATE范围,但是如果您愿意使用target_compile_options而不是接口库来实现这一点,那么这也将起作用:

set(COMMON_FLAGS
PUBLIC
-Werror
-ffast-math
PRIVATE
-Wall
)
target_compile_options(lib1 ${COMMON_FLAGS})
target_compile_options(lib2
${COMMON_FLAGS}
PUBLIC # <-- you can still set scoped flags
-fno-fast-math
)

然而,在我看来,使用接口库并只处理你必须使用PUBLIC的事实,从长远来看,PRIVATE既干净又更易于维护。

顺便说一句,如果您想将COMMON_FLAGS压缩到一行:set(COMMON_FLAGS "PUBLIC;-Werror;-ffast-math;PRIVATE;-Wall")

最新更新