之后如何制作进口目标GLOBAL?

Tor*_*örn 6 cmake dependency-management

FindBoost.cmakeCMake 3.8 的模块:

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()
Run Code Online (Sandbox Code Playgroud)

以及该模块文件中的相应评论:

重要的是要注意导入的目标与此模块创建的变量的行为不同:在同一目录中多次调用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
Run Code Online (Sandbox Code Playgroud)

Flo*_*ian 7

IMPORTED_GLOBAL在CMake> = 3.11中有一个目标属性:

set_target_properties(Boost::unit_test_framework PROPERTIES IMPORTED_GLOBAL TRUE)
Run Code Online (Sandbox Code Playgroud)

对于旧版本: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)
Run Code Online (Sandbox Code Playgroud)

放弃

正如@CraigScott评论覆盖CMake的内置函数是危险的:

参考


Tor*_*örn 1

我设法解决了导入的 Boost 目标在全局项目范围中不可用的问题,方法是包含3rdparty/CMakeLists.txtnot byadd_subdirectory(3rdparty)而是 via include(3rdparty/CMakeLists.txt),因为这3rdparty/CMakeLists.txt在调用者的范围中进行评估。

  • 我知道这可以解决您的问题,这是一个很好的答案,但考虑到弗洛里安的完美分析,这应该是公认的答案。 (3认同)