导入库的 INTERFACE_LINK_LIBRARIES 是否正确?

问题描述 投票:0回答:1

我正在尝试编写一个 FindFoo.cmake 脚本来定位一个名为 libfoo.so 的外部库,我想使用它,但问题是 libfoo.so 还链接了 2 个外部库(我们称它们为 libbar.so 和 libbaz.so )所以当我尝试链接时我总是有未定义的引用。

这是我尝试过的:

查找Foo.cmake

find_path(Foo_INCLUDE_DIR NAMES foo.h)
mark_as_advanced(Foo_INCLUDE_DIR)

find_library(Foo_LIBRARY NAMES foo)
mark_as_advanced(Foo_LIBRARY)

if(Foo_INCLUDE_DIR AND Foo_LIBRARY)
  set(Foo_FOUND TRUE)

if(Foo_FOUND)
  add_library(Foo UNKNOWN IMPORTED)
  set_target_properties(Foo PROPERTIES
    IMPORTED_LOCATION                   "${Foo_LIBRARIES}"
    INTERFACE_INCLUDE_DIRECTORIES       "${Foo_INCLUDE_DIR}"
    INTERFACE_LINK_LIBRARIES            "${Foo_LIBRARIES};bar;baz"
  )
endif()

然后我链接到:

CMakeLists.txt

find_package(Foo REQUIRED)
add_executable(Test test.cxx)
target_link_libraries(Test PUBLIC Foo)

问题是它链接到Foo,还链接到bar和baz(尽管有

INTERFACE_LINK_LIBRARIES
属性),因此生成了很多未定义的引用。

这是唯一的问题,因为手动更改链接到以下内容可以使可执行文件正确链接:

target_link_libraries(Test
  PUBLIC Foo
  PUBLIC bar
  PUBLIC baz
)

但是既然我不应该手动执行此操作,我做错了什么?

编辑:根据评论中的建议,我也尝试过

target_link_libraries(Foo INTERFACE bar baz)

但是问题仍然存在,当任何链接到 Foo 时,它都会忽略 foo 的链接依赖关系。

也许 Foo 定义是错误的,所以 cmake 忽略了它的属性?或者我应该将 bar 和 baz 声明为外部,以便 cmake 也考虑它们?

还尝试将外部库设置为:

add_library(Foo SHARED IMPORTED)

CMake版本:3.30.5

cmake
1个回答
0
投票

感谢@Tsyvarev 的评论,我发现了问题并得到了我在这里分享的解决方案,以防有人发现类似的错误:

问题:

  1. Foo_LIBRARY
    var 为空,因此目标库未正确创建
  2. 导入的目标不是
    GLOBAL
    所以目标库的范围只是当前文件

最后,导入库并设置其依赖项的解决方案是:

查找Foo.cmake

# Look for the necessary header
find_path(Foo_INCLUDE_DIR NAMES foo.h)
mark_as_advanced(Foo_INCLUDE_DIR)

# Look for the necessary library
find_library(Foo_LIBRARY NAMES foo)
mark_as_advanced(Foo_LIBRARY)

# Extract version information from the header file
if(Foo_INCLUDE_DIR AND Foo_LIBRARY)
    set(Foo_FOUND TRUE)
    set(Foo_LIBRARIES bar baz)
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Foo
    REQUIRED_VARS Foo_INCLUDE_DIR Foo_LIBRARY Foo_LIBRARIES
)

# Create the imported target
if(Foo_FOUND)
    set(Foo_INCLUDE_DIRS ${StormByte_INCLUDE_DIR})
    if(NOT TARGET Foo)
        add_library(Foo UNKNOWN IMPORTED GLOBAL)
        set_target_properties(Foo PROPERTIES
            IMPORTED_LOCATION                   "${Foo_LIBRARY}"
            INTERFACE_INCLUDE_DIRECTORIES       "${Foo_INCLUDE_DIRS}"
            INTERFACE_LINK_LIBRARIES            "${Foo_LIBRARIES}"
        )
    endif()
endif()

因此,从现在开始,使用此配置,目标是

GLOBAL
每个 other
CMakeFiles.txt
都可以通过以下方式将 Foo 库及其依赖项定位为:
target_link_libraries(TARGET Foo)
如果
find_package(Foo)
已在某处执行。

注意:无需在最终目标之前或之后执行

find_package(Foo)
,无论如何它都会起作用。

© www.soinside.com 2019 - 2024. All rights reserved.