来自CMake 3.8的FindBoost.cmake
模块:
foreach(COMPONENT ${Boost_FIND_COMPONENTS})
if(_Boost_IMPORTED_TARGETS AND NOT TARGET Boost::${COMPONENT})
string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
if(Boost_${UPPERCOMPONENT}_FOUND)
if(Boost_USE_STATIC_LIBS)
add_library(Boost::${COMPONENT} STATIC IMPORTED)
else()
# Even if Boost_USE_STATIC_LIBS is OFF, we might have static
# libraries as a result.
add_library(Boost::${COMPONENT} UNKNOWN IMPORTED)
endif()
以及docu of that module的相应评论:
重要的是要注意导入的目标与此模块创建的变量的行为不同:在同一目录中对find_package(Boost)的多次调用或具有不同选项的子目录(例如,静态或共享)不会覆盖这些值第一次调用创建的目标。
我认为目标不是GLOBAL
的理性。
然而,使它们成为全球化的首选方式是什么?
我习惯在包含任何find_package(...)
调用的子目录中定义项目的依赖关系。因此,Boost导入的目标在另一个目录中不可用,例如/tests/CMakeLists.txt
:
<project_root>
/3rdparty
/git-submodule-of-a-small-lib
/CMakeLists.txt
/include
/...
/tests
/CMakeLists.txt
/CMakeLists.txt
答案 0 :(得分:7)
在CMake&gt; = 3.11:
中有一个IMPORTED_GLOBAL
目标属性
set_target_properties(Boost::unit_test_framework PROPERTIES IMPORTED_GLOBAL TRUE)
对于旧版本:find_package()
使用标准add_library()
调用,因此您始终可以更改/扩展其功能,使IMPORTED
目标始终GLOBAL
,例如:
<强>的3rdParty \的CMakeLists.txt 强>
function(add_library)
set(_args ${ARGN})
if ("${_args}" MATCHES ";IMPORTED")
list(APPEND _args GLOBAL)
endif()
_add_library(${_args})
endfunction()
find_package(Boost REQUIRED COMPONENTS unit_test_framework)
<强>声明强>
@CraigScott评论覆盖CMake的内置函数是危险的:
<强>参考强>
答案 1 :(得分:2)
我设法解决了导入的Boost目标在全局项目范围内不可用的问题,方法是3rdparty/CMakeLists.txt
不是add_subdirectory(3rdparty)
而是include(3rdparty/CMakeLists.txt)
,因为这会评估3rdparty/CMakeLists.txt
在调用者的范围内。