所有子项目都依赖于A,而A的变化相当频繁.
另外,可能还有一些依赖项:
在这个例子中,D取决于B.
现在:很多人正在研究这些项目.主CMakeLists.txt文件应包含所有目录,以便构建all构建所有目录.但人们也希望能够只在其中一个项目上工作,而不必每次都构建/安装所有项目.
如果我正在研究D,我可以通过调用轻松构建“仅”D
cmake --build . --target D -- -j7
要么
ninja -j7 D
如果他们的某些东西发生了变化,这也将构建A和B.完善.
但是如何在不触发构建全部的情况下仅为D调用安装?
如果我打电话,我想这样:
ninja -j7 D install
它只构建D(和依赖项),然后只安装D及其依赖项(A和B).
相反,它构建目标all并安装所有.
我想保持目标都在继续建立一切.所以EXCLUDE_FROM_ALL不是一个选项.但是朝着那个方向走,我找不到任何解决方案.
所以我在考虑以下策略:
>除子项目A外,所有其他目标都设置为EXCLUDE_FROM_ALL,安装时可选.
>我添加了一个额外的子项目,它只依赖于所有其他子项目(也许我通过使用PARENT_SCOPE中设置的一些变量使每个目标发布其名称),人们将不得不在他们想要构建和安装所有内容时调用它.
它会起作用吗?有没有更好的解决方案?
我们希望避免每个人都必须编辑主CMakeLists.txt文件以排除他不感兴趣的项目.解决方案应该可以移植到不同的操作系统.
编辑:
我尝试了我提出的策略,但它没有用:在我的情况下,为目标设置一个install语句(即使指定为OPTIONAL)也会使EXCLUDE_FROM_ALL无效.在documentation中读得更好我发现:
Installing a target with EXCLUDE_FROM_ALL set to true has undefined behavior.
我也收到这个警告:
Target <targetname> has EXCLUDE_FROM_ALL set and will not be built by default but an install rule has been provided for it. CMake does not define behavior for this case.
编辑2:
我尝试将EXCLUDE_FROM_ALL作为add_subdirectory的选项(而不是add_library / add_executable),但是那些子目录中的所有安装语句似乎都被忽略:只安装非排除所有子目录中的安装语句.
编辑3:
即使我激活CMAKE_SKIP_INSTALL_ALL_DEPENDENCY:
set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY true)
在主CMakeLists.txt文件中,我省略了所有EXCLUDE_FROM_ALL,安装了我想要的多个目标可选(在我的情况下,除了A之外),如果在安装之前构建特定目标,那么命令:
ninja -j7 D && ninja install
由于某种原因会失败,说明C(其安装设置为OPTIONAL)不存在(它没有创建,因为D仅依赖于A和B)…
file INSTALL cannot find "<name of dll file for C>"
编辑4:
它看起来像是一个cmake bug. (我在Windows下使用2.8.11,也测试了2.8.10)
这个INSTALL命令
install(TARGETS ${targetname} RUNTIME DESTINATION . LIBRARY DESTINATION . OPTIONAL)
在cmake_install.cmake中转换为:
06009
FILE(INSTALL DESTINATION “${CMAKE_INSTALL_PREFIX}/.” TYPE SHARED_LIBRARY FILES *path_to_dll*)
IF(EXISTS “$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/./” AND NOT IS_SYMLINK “$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/./*dll_name*”)
060010
命令FILE缺少OPTIONAL!如果我手动添加OPTIONAL,它可以工作!
(注意:我在这里编辑了* dll_name *和* path_to_dll *占位符)
编辑5:
我确认这是cmake的错误,或者至少是错误的文档.我会报告这个.
这种情况解决了要么更简单
install(TARGETS ${targetname} DESTINATION . OPTIONAL)
(但在我的情况下,这也将安装我不想要的.lib.a文件)
或者在可选标志前面移动:
install(TARGETS ${targetname} OPTIONAL RUNTIME DESTINATION . LIBRARY DESTINATION .)
从cmake documentation可以理解的是,OPTIONAL应该作为最后的选择.
> Remove dependency of “install” target to “all” target(一次,在主CMakeLists.txt中):
设置(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY为true)
>设置为您不希望始终构建的所有目标的可选安装:
安装(TARGETS<< targetname>> DESTINATION.可选)
>构建要安装的目标
ninja -j7<<目标列表>>,或更一般地说:
<< your builder>> <<您的选项>> <<目标列表>>
这将构建列出的所有目标及其依赖项
>致电安装人员
忍者安装.这将安装您构建的所有库,您明确提到的库以及它们所依赖的库.这解决了安装特定目标及其依赖项的问题!
>要在Unix和Windows上连接命令,您可以使用
ninja -j7<<目标列表>> &安培;&安培;忍者安装
>请注意,至少对于忍者来说,你不能简单地将“安装”添加到目标列表中,因为目标“安装”不再依赖于任何目标,并且在你正在构建你的工作时,并行化工作的忍者会运行安装目标.替换旧的忍者-j7安装是
忍者-j7&&忍者安装.
目标“all”仍然可用(它仍然是默认目标).
>如果需要创建要一起构建的目标列表,可以定义custom target:
add_custom_target(<<< collective target name>> DEPENDS<<目标列表>>)
这不会包含在目标中.添加一个COMMAND还允许为我们想要的目标创建一个安装目标,例如ninja -j7 install_D,但我认为现在我们超出了这个问题的范围.
进一步考虑:
>(注意,2018年7月:这可能已经过时)如果您使用RUNTIME DESTINATION,LIBRARY DESTINATION等,很可能是因为CMake错误,OPTIONAL关键字应该准确放在下面指出的位置:
安装(TARGETS<< targetname>> OPTIONAL RUNTIME DESTINATION<< some dir>> LIBRARY DESTINATION<< some(other)dir>>)
这与documentation中的内容相矛盾,我将继续将其作为一个错误报告给CMake开发人员.
>将EXCLUDE_FROM_ALL与INSTALL OPTIONAL结合使用是a bad idea
Installing a target with EXCLUDE_FROM_ALL set to true has undefined behavior.
(并且cmake会在解析代码时尝试警告你)