【发布时间】:2016-07-10 17:31:13
【问题描述】:
我正在尝试将一个由 cmake 管理的大型项目拆分为一组较小的项目。我无法让 cmake 接受包含目录的传播。我目前正在使用 ubuntu 14.04 (2.8) 附带的 cmake 版本。如果确实有必要,我可以切换到 3.x,但如果我能提供帮助,我宁愿不要。
考虑一个示例,其中我的源代码树的某个目录由一个可分离的、可隔离的库组成。它在我的源代码树中没有其他依赖项,并且到目前为止由
ADD_SUBDIRECTORY(smdir)
在 smdir 内:
ADD_LIBRARY(something STATIC something.c something.h)
在 something 用作依赖项的其他领域,以下工作完美:
ADD_LIBRARY(something_else STATIC ...)
TARGET_LINK_LIBRARIES(something_else something)
所有这些都发生在 cmake 宏/函数中,这些宏/函数会进行一些其他名称修改,所以如果此处列出的精确代码略有不正确,请原谅我。
我现在要做的是将something 完全从我的源代码树中拉出。我应该注意,这些是用于裸机微控制器的嵌入式库,而不是我在构建机器上安装的东西。
something 的基本编译脚本几乎可以按预期工作,只需进行少量更改。我将这个(现在是外部编译和管理的)库与代码库的其余部分集成的方法是从构建树中导出已编译的库,并将其导入到我的其他项目中。这种方法主要基于https://cmake.org/Wiki/CMake/Tutorials/Exporting_and_Importing_Targets 的Exporting from a Build Tree 部分。我尝试通过以下方式做到这一点:
TARGET_INCLUDE_DIRECTORIES(something PUBLIC /path/to/smdir/src)
EXPORT(TARGETS something FILE something-config.cmake)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/something-config.cmake
DESTINATION ${PLATFORM_PACKAGES_PATH})
其中 ${PLATFORM_PACKAGES_PATH} 是某个系统文件夹,我打算在其中收集所有这些配置文件。生成的配置文件看起来很合理,并且安装到正确的位置就好了,并且有以下几行(以及许多其他行):
add_library(something STATIC IMPORTED)
set_target_properties(something PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "/path/to/smdir/src"
)
set_property(TARGET something APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO)
set_target_properties(something PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELWITHDEBINFO "C" IMPORTED_LOCATION_RELWITHDEBINFO "/correct/path/to/something.a")
导入这个库时出现问题,我使用的是:
ADD_LIBRARY(something STATIC IMPORTED)
SET_PROPERTY(TARGET something PROPERTY IMPORTED_LOCATION "${PLATFORM_PACKAGES_PATH}")
GET_PROPERTY(public_include_dirs TARGET something PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
任何将某些内容列为依赖项的库的构建都不包括 gcc 命令中某些内容的 INCLUDE_FOLDERS。我尝试在此处使用 GET_PROPERTY 读取的 public_include_dirs 变量为空白。
我们将不胜感激任何帮助或见解,包括有关“更清洁”或更好方法的建议。
【问题讨论】:
-
您错误地解释了参考教程的
Exporting from a Build Tree部分:add_library(IMPORTED)和SET_PROPERTY(TARGET .. IMPORTED_LOCATION)行包含在您之前导出的.cmake文件中。您需要包含此文件才能生效:include("${PLATFORM_PACKAGES_PATH}/something-config.cmake")。另请注意,导出的构建树通常是 not installed:The file created by this command is specific to the build tree and should never be installed. -
@Tsyvarev 啊。这让事情变得更有意义了,尽管有以下两个警告: (a) 鉴于 *config.cmake 中的路径是硬编码和绝对的,在构建树之外安装它会有什么问题? (b) 如果不导入文件并按照问题中列出的方式使用它,如果实际上找不到 *config.cmake,cmake 仍然会死掉。我认为这意味着 cmake 在某些时候实际上正在使用该文件。
-
what would be the problem in installing it outside the build tree?- 导出会丢失原始构建树的许多属性。这就是为什么导出的树不适合安装的原因。I took this to mean that cmake is actually using the file at some point.-include()点 CMake 只解释包含文件中的所有命令。