链接到外部库

如何让 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也失败了。

352631 次浏览

首先设置库搜索路径:

link_directories(${CMAKE_BINARY_DIR}/res)

然后就去做

target_link_libraries(GLBall mylib)

阿罗道奇的回答是正确的,在许多情况下,他更受欢迎。我只想在他的回答之外添加一个备选答案:

您可以添加一个“导入的”库目标,而不是链接目录:

# 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)命令和 许多与导入库相关的目标属性

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

另一个选择是,如果您正在使用 Appstore,则需要“ Entitments”,因此需要与 Apple-Framework 链接。

为了让权限工作(例如 GameCenter) ,你需要 需要有一个“链接二进制与库”-构建步骤,然后链接到“ GameKit.Framework”。CMake 在命令行中“低级”地“注入”库,因此 Xcode 不会让 真的知道它,因此您将在 Capability 屏幕中启用 没有 GameKit。

一种使用 CMake 并有一个“ Link with Binaries”-buildstep 的方法是使用 CMake 生成 xcodeproj,然后使用“ sed”来“ search & place”,并按照 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”,然后像这样“ application”它(它会更改 xcodeproj!)

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

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

警告: 随着项目格式的改变,它很可能与不同的 Xcode 版本决裂,(硬编码的)唯一数字可能不是真正的唯一,通常其他人的解决方案更好,所以除非你需要支持 Appstore + Entitments (和自动构建) ,不要这样做。

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

我假设你想链接到一个叫做 的库,它的文件名通常是链接 foo.dll或者 libfoo.so

1. 找到图书馆
你得找到图书馆。这是个好主意,即使你知道去图书馆的路。如果库消失或获得新名称,CMake 将出错。这有助于及早发现错误,并使用户(可能是您自己)清楚地了解问题的原因。
若要查找库 并将路径存储在 FOO_LIB中,请使用

    find_library(FOO_LIB foo)

CMake 会自己弄清楚实际的文件名是什么样的。它检查通常的位置,如 /usr/lib/usr/lib64PATH中的路径。

你已经知道图书馆的位置了。当您调用 CMake 时将它添加到 CMAKE_PREFIX_PATH,那么 CMake 也将在传递的路径中查找您的库。

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

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

  target_link_libraries(GLBall PRIVATE "${FOO_LIB}")

应该在目标后面添加 PRIVATEPUBLICINTERFACE,参考文档: Https://cmake.org/cmake/help/latest/command/target_link_libraries.html

如果不添加这些可见性说明符之一,它的行为将与 PRIVATEPUBLIC类似,具体取决于 CMake 版本和策略集。

3. Add include < em > (此步骤可能不是强制性的)
如果还希望包含头文件,请使用类似于 find_libraryfind_path并搜索头文件。然后用类似于 target_link_librariestarget_include_directories添加 include 目录。

文件: Https://cmake.org/cmake/help/latest/command/find_path.html 还有 Https://cmake.org/cmake/help/latest/command/target_include_directories.html

如果可用于外部软件,可以用 find_package代替 find_libraryfind_path

假设您有一个可执行文件,比如:

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)

注意,库文件的前缀和扩展名已被删除:

∮我的自由∮
∮我的自由∮

这个问题已经发布很长时间了,但是我留下这个问题只是为了参考。 我有一篇博客文章,描述了一步一步几乎你(或任何其他人)正在尝试做的事情。 请点击这里: http://michae9.wordpress.com/2022/09/01/share-lib-to-be-used-by-client-program-with-cmake/”rel = “ nofollow norefrer”> https://michae9.wordpress.com/2022/09/01/shared-lib-to-be-used-by-client-programs-with-cmake/