如何在公共根目录下顺利添加各种 3rd 方库的包含目录?
how to smoothly add include directories for various 3rd party libraries under common root?
我正在尝试学习 cmake,但找不到解决常见问题的聪明方法。
我想使用几个第 3 方库。假设我将它们都放在同一个根目录下(更高级的情况:有几个这样的根目录)。假设它们的结构如下:
root
--Lib1 // headers here
--Lib2
--include // headers here
--Lib3 // headers here
--private_headers // ...and here (non public)
我想实现一个目标,我可以在 cmakelists.txt 中指定我想使用哪些库,但是:
没有指定根目录在哪里——它必须独立于我的 libs 目录结构(可能它应该来自一些标准的 cmake env 变量,但似乎 none CMAKE_xxx_PATH套装)
无需担心 Lib3 中的私有 header 依赖项和子文件夹(我只想包括顶级 header(s) 和所有较低级别的 headers必须找到它们的相对路径)
如何实现这些目标?
我不确定这是否是您要找的。
在此解决方案中,您有一个指向根目录的环境变量 LIB_ROOT_DIR。然后 include_directories
和 link_directories
用于将目录添加到您的项目中。
include_directories(
${LIB_ROOT_DIR}/Lib1
${LIB_ROOT_DIR}/Lib2/include
${LIB_ROOT_DIR}/Lib3
)
link_directories(${LIB_ROOT_DIR}/Lib1 ${LIB_ROOT_DIR}/Lib2 ${LIB_ROOT_DIR}/Lib3)
use by anyone with any libs directory structure
那行不通 out-of-the-box。最后,您需要所有第 3 方库的路径,无论它们位于公共根目录还是单独目录中。在任何情况下,至少需要 XX_INCLUDE_PATH
和 XX_LIBRARIES
来指向每个包各自的位置。
您的问题的答案是为每个库使用 FindXXX.cmake 模块。
它们旨在包含为任何第 3 方包查找 libraries/include 目录的逻辑。 cmake 来了 with a pile of them, and there are more written every day. they all use "default" logic and paths and will need aid if the packages requested reside at a nonstandard location; see the CMAKE_PREFIX_PATH
variable。
如果您找不到适用于您的第 3 方库的库,请编写您自己的库:find_package interface guidelines for MODULE mode。确保您正确设置 CMAKE_MODULE_PATH
以在 "overwriting" 现有 FindLIBX.cmake 时首先包含您的文件夹以根据您的需要定制它。
最终,如果您的 CMAKE_MODULE_PATH
上有一个 FindLIBX.cmake
:
,那么您将在主 CMakeLists.txt
中调用类似的东西
SET(USE_LIBX TRUE)
if(USE_LIBX)
find_package(LIBX QUIET)
endif()
...
add_library(my_main_lib ${sources})
...
if(LIBX_FOUND)
target_link_libraries(my_main_lib PUBLIC ${LIBX_LIBRARIES})
target_include_directories(my_main_lib PUBLIC ${LIBX_INCLUDE_PATH})
endif()
这里的标志 "USE_LIBX" 使您可以轻松切换组件 on/off 的使用。
您也可以使用上面描述的命令 uncletall,但是,target_
命令更具体并且不会将库添加到所有项目目标;取决于项目的复杂程度。
并且:"public" headers 将自动正确包含 "private" headers 的事实将取决于您的第 3 方库的编写情况。然而,private headers 永远不需要针对您的第 3 方库进行构建,这就是为什么它们是私有的。 "dependent" headers 将包含在您的 "public" headers 中。然后这些也必然是 "public",因为它们需要移动(正确地相对)到您的 "public" headers 所在的任何地方以包含在内。
我正在尝试学习 cmake,但找不到解决常见问题的聪明方法。
我想使用几个第 3 方库。假设我将它们都放在同一个根目录下(更高级的情况:有几个这样的根目录)。假设它们的结构如下:
root
--Lib1 // headers here
--Lib2
--include // headers here
--Lib3 // headers here
--private_headers // ...and here (non public)
我想实现一个目标,我可以在 cmakelists.txt 中指定我想使用哪些库,但是:
没有指定根目录在哪里——它必须独立于我的 libs 目录结构(可能它应该来自一些标准的 cmake env 变量,但似乎 none CMAKE_xxx_PATH套装)
无需担心 Lib3 中的私有 header 依赖项和子文件夹(我只想包括顶级 header(s) 和所有较低级别的 headers必须找到它们的相对路径)
如何实现这些目标?
我不确定这是否是您要找的。
在此解决方案中,您有一个指向根目录的环境变量 LIB_ROOT_DIR。然后 include_directories
和 link_directories
用于将目录添加到您的项目中。
include_directories(
${LIB_ROOT_DIR}/Lib1
${LIB_ROOT_DIR}/Lib2/include
${LIB_ROOT_DIR}/Lib3
)
link_directories(${LIB_ROOT_DIR}/Lib1 ${LIB_ROOT_DIR}/Lib2 ${LIB_ROOT_DIR}/Lib3)
use by anyone with any libs directory structure
那行不通 out-of-the-box。最后,您需要所有第 3 方库的路径,无论它们位于公共根目录还是单独目录中。在任何情况下,至少需要 XX_INCLUDE_PATH
和 XX_LIBRARIES
来指向每个包各自的位置。
您的问题的答案是为每个库使用 FindXXX.cmake 模块。
它们旨在包含为任何第 3 方包查找 libraries/include 目录的逻辑。 cmake 来了 with a pile of them, and there are more written every day. they all use "default" logic and paths and will need aid if the packages requested reside at a nonstandard location; see the CMAKE_PREFIX_PATH
variable。
如果您找不到适用于您的第 3 方库的库,请编写您自己的库:find_package interface guidelines for MODULE mode。确保您正确设置 CMAKE_MODULE_PATH
以在 "overwriting" 现有 FindLIBX.cmake 时首先包含您的文件夹以根据您的需要定制它。
最终,如果您的 CMAKE_MODULE_PATH
上有一个 FindLIBX.cmake
:
CMakeLists.txt
中调用类似的东西
SET(USE_LIBX TRUE)
if(USE_LIBX)
find_package(LIBX QUIET)
endif()
...
add_library(my_main_lib ${sources})
...
if(LIBX_FOUND)
target_link_libraries(my_main_lib PUBLIC ${LIBX_LIBRARIES})
target_include_directories(my_main_lib PUBLIC ${LIBX_INCLUDE_PATH})
endif()
这里的标志 "USE_LIBX" 使您可以轻松切换组件 on/off 的使用。
您也可以使用上面描述的命令 uncletall,但是,target_
命令更具体并且不会将库添加到所有项目目标;取决于项目的复杂程度。
并且:"public" headers 将自动正确包含 "private" headers 的事实将取决于您的第 3 方库的编写情况。然而,private headers 永远不需要针对您的第 3 方库进行构建,这就是为什么它们是私有的。 "dependent" headers 将包含在您的 "public" headers 中。然后这些也必然是 "public",因为它们需要移动(正确地相对)到您的 "public" headers 所在的任何地方以包含在内。