8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

CMake 链接到外部库

Mando 2月前

127 0

如何让 CMake 将可执行文件链接到不在同一个 CMake 项目内构建的外部共享库?只需执行 target_link_libraries(GLBall ${CMAKE_BINARY_DIR}/res/mylib.so) 即可...

如何让 CMake 将可执行文件链接到不在同一 CMake 项目内构建的外部共享库?

只是这样做 target_link_libraries(GLBall ${CMAKE_BINARY_DIR}/res/mylib.so) 会产生错误

make[2]: *** No rule to make target `res/mylib.so', needed by `GLBall'.  Stop.
make[1]: *** [CMakeFiles/GLBall.dir/all] Error 2
make: *** [all] Error 2
(GLBall is the executable)

将库复制到二进制目录后 bin/res .

我尝试使用 find_library(RESULT mylib.so PATHS ${CMAKE_BINARY_DIR}/res)

失败了 RESULT-NOTFOUND .

帖子版权声明 1、本帖标题:CMake 链接到外部库
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Mando在本站《c》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 首先设置库搜索路径:

    link_directories(${CMAKE_BINARY_DIR}/res)
    

    然后就做

    target_link_libraries(GLBall mylib)
    
  • 不鼓励使用 link_directories,即使在其自己的文档中也是如此。我认为最好在这里解决原始问题中失败的 find_library 调用,或者使用@Andre 的解决方案。

  • 我发现 \'imported\' 库目标更加强大,因为它以特定库的位置为目标,而不是简单地提供全局搜索路径。请参阅 Andre 的回答。

  • 您应该始终使用 find_library 并使用此路径而不是对其进行硬编码,请参阅我的回答。

  • arrowdodger 的答案是正确的,在很多情况下都是首选。我只想为他的答案添加一个替代方案:

    您可以添加 \'imported\' 库目标,而不是链接目录。例如:

    # Your-external "mylib", add GLOBAL if the imported library is located in directories above the current.
    add_library( mylib SHARED IMPORTED )
    # You can define two import-locations: one for debug and one for release.
    set_target_properties( mylib PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/res/mylib.so )
    

    然后进行链接,就好像这个库是由你的项目构建的一样:

    TARGET_LINK_LIBRARIES(GLBall mylib)
    

    这种方法可以给你更多的灵活性:看看 add_library(IMPORTED) 命令和 与导入库相关的许多目标属性 .

    我不知道这是否能解决您的“更新库版本”问题。

  • 这可能是 add_library( mylib SHARED IMPORTED ) 或者你得到一个使用 IMPORTED 参数调用的 add_library 但没有库类型错误

  • @Andre:我认为 IMPORTED_LOCATION 后面的左括号是错误的

  • 如果您想访问当前目录上级目录中的导入库,则需要在 IMPORTED 后添加 GLOBAL:add_library(breakpad STATIC IMPORTED GLOBAL)

  • @SOUser:是的,IMPORTED_LOCATION 应该指向文件,而不是目录。我已经修复了这个问题,我想作者不会抱怨。

  • 我假设你想链接到一个名为 foo ,它的文件名通常是链接 foo.dll libfoo.so .

    1. 找到图书馆
    您必须找到库。这是一个好主意,即使您知道库的路径。如果库消失或改名,CMake 将出错。这有助于尽早发现错误并让用户(您自己)清楚是什么导致了问题。
    查找库 foo 使用的 FOO_LIB 路径

        find_library(FOO_LIB foo)
    

    CMake 会自行确定实际的文件名。它会检查常见位置, /usr/lib , /usr/lib64 例如 PATH .

    您已经知道库的位置。 CMAKE_PREFIX_PATH 在调用 CMake 时将其添加到,然后 CMake 也会在传递的路径中查找库。

    有时需要添加提示或路径后缀,详情查看文档: https://cmake.org/cmake/help/latest/command/find_library.html

    2. 链接库 从 1. 开始,您可以在 中找到完整的库名称 FOO_LIB 。您可以使用它将库链接到目标, GLBall 如下所示

      target_link_libraries(GLBall PRIVATE "${FOO_LIB}")
    

    您应该 PRIVATE , PUBLIC 在目标后 INTERFACE ,或 https://cmake.org/cmake/help/latest/command/target_link_libraries.html

    如果您不添加这些可见性说明符之一,它将表现得像 PRIVATE PUBLIC ,具体取决于 CMake 版本和设置的策略。

    3. 添加包含内容 (此步骤可能不是强制性的。)
    如果您还想包含头文件,请使用 find_path 类似 find_library 并搜索头文件。然后使用 target_include_directories 类似 target_link_libraries .

    文档: https://cmake.org/cmake/help/latest/command/find_path.html and https://cmake.org/cmake/help/latest/command/target_include_directories.html

    如果外部软件可用,您 find_library 可以 find_path find_package .

  • 在我看来这是最好的答案。但是,我遇到了麻烦,因为我没有在“project”之后调用“find_library”,也没有在“add_executable”之后调用“target_link_libraries”。

  • 引用 13

    我想我不明白第 2 步。对于共享库,${FOO_LIB} 将类似于 /full/path/to/libfoo.dylib。这有什么用?target_link_libraries 不会创建 \'-L/full/path/to -lfoo\',因此 find_library 除了验证库是否位于我已经知道的位置外,没有返回任何有用的东西。我遗漏了什么?

  • target_link_libraries(mylib \'${FOO_LIB}\')? 目标是 mylib,而不是他的实际目标 GLBall? 对我来说没有多大意义

  • 假设你有一个如下的可执行文件:

    add_executable(GLBall GLBall.cpp)
    

    如果外部库有标题,请给出其包含文件夹的路径:

    target_include_directories(GLBall PUBLIC "/path/to/include")
    

    添加库目录路径:

    target_link_directories(GLBall PUBLIC "/path/to/lib/directory")
    

    最后链接库名

    target_link_libraries(GLBall mylib)
    

    注意去掉库文件的前缀和扩展名:

    libmylib.a mylib
    mylib.so mylib

  • 引用 16

    你的答案对我有用!这是一个不同的用例,但我真的非常困惑,直到我尝试了你的方法 :)

  • 如果您没有指定--static,@david-c ld 将优先选择mylib.so而不是my lib.a。

  • 另一种选择是,如果您正在使用 Appstore,则需要“Entitlements”,因此需要链接到 Apple-Framework。

    要使权利 (例如 GameCenter) 发挥作用,您 需要 有一个“将二进制文件与库链接”-buildstep,然后链接到“GameKit.framework”。CMake 将“低级”上的库“注入”到命令行中,因此 Xcode 对此并不 了解 ,因此您无法功能屏幕中启用 GameKit。

    使用 CMake 并拥有“链接二进制文件”-buildstep 的一种方法是使用 CMake 生成 xcodeproj,然后使用“sed”进行“搜索和替换”并以 XCode 喜欢的方式添加 GameKit...

    该脚本如下所示(适用于 Xcode 6.3.1)。

    s#\/\* Begin PBXBuildFile section \*\/#\/\* Begin PBXBuildFile section \*\/\
        26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks \*\/ = {isa = PBXBuildFile; fileRef = 26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/; };#g
    
    s#\/\* Begin PBXFileReference section \*\/#\/\* Begin PBXFileReference section \*\/\
        26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System\/Library\/Frameworks\/GameKit.framework; sourceTree = SDKROOT; };#g
    
    s#\/\* End PBXFileReference section \*\/#\/\* End PBXFileReference section \*\/\
    \
    \/\* Begin PBXFrameworksBuildPhase section \*\/\
        26B12A9F1C10543B00A9A2BA \/\* Frameworks \*\/ = {\
            isa = PBXFrameworksBuildPhase;\
            buildActionMask = 2147483647;\
            files = (\
                26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks xxx\*\/,\
            );\
            runOnlyForDeploymentPostprocessing = 0;\
        };\
    \/\* End PBXFrameworksBuildPhase section \*\/\
    #g
    
    s#\/\* CMake PostBuild Rules \*\/,#\/\* CMake PostBuild Rules \*\/,\
                26B12A9F1C10543B00A9A2BA \/\* Frameworks xxx\*\/,#g
    s#\/\* Products \*\/,#\/\* Products \*\/,\
                26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/,#g
    

    将其保存为\'gamecenter.sed\',然后像这样\'apply\'它(它会改变你的xcodeproj!)

    sed -i.pbxprojbak -f gamecenter.sed myproject.xcodeproj/project.pbxproj
    

    您可能需要更改脚本命令以满足您的需要。

    警告:由于项目格式可能会发生变化,因此它可能会因不同的 Xcode 版本而中断,(硬编码的)唯一编号可能并不是真正唯一的 - 并且通常其他人的解决方案更好 - 所以除非您需要支持 Appstore + 权利(和自动构建),否则不要这样做。

    这是一个 CMake 错误,请参阅 http://cmake.org/Bug/view.php?id=14185 http://gitlab.kitware.com/cmake/cmake/issues/14185

  • 具体来说 - 让 cmake 链接外部库不是问题(上面有几种解决方案)。让它以自动化的方式工作,以便与 Apple Appstore 和授权一起工作是一个挑战。在这种特定情况下,上述解决方案不起作用,因为 XCode 不会“看到”以这种方式链接的库,并且授权将不起作用。据我所知,cmake 无法以“与 appstore 兼容的方式”按照 xcode 需要的方式添加库 - 再次,请随时启发我。

  • sliq 2月前 0 只看Ta
    引用 20

    哦,真可悲。为了完整起见,新问题跟踪器的链接目前不包含任何评论:gitlab.kitware.com/cmake/cmake/issues/14185

返回
作者最近主题: