CMake链接到外部库

bvjveswy  于 2022-11-11  发布在  其他
关注(0)|答案(6)|浏览(185)

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

wmvff8tz

wmvff8tz1#

arrowdodger的回答是正确的,在许多情况下都是首选的。我只想在他的回答上加上一个替代方案:
您可以添加一个“导入的”库目标,而不是一个链接目录。


# 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”问题。

shstlldc

shstlldc2#

先设定资源库搜寻路径:

link_directories(${CMAKE_BINARY_DIR}/res)

然后就做

target_link_libraries(GLBall mylib)
eulz3vhy

eulz3vhy3#

我假设你要链接到一个名为 foo 的库,它的文件名通常是foo.dlllibfoo.so

1.寻找媒介柜

你必须找到这个库。这是一个好主意,即使你知道你的库的路径。如果库消失了或者有了一个新的名字,CMake会出错。这有助于及早发现错误,并让用户(可能是你自己)清楚是什么导致了问题。
要查找库 foo 并将路径存储在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}")

您应该在target后面添加PRIVATEPUBLICINTERFACE,请参阅以下文档:https://cmake.org/cmake/help/latest/command/target_link_libraries.html
如果您不添加这些可见性说明符中的任何一个,它的行为将类似于PRIVATEPUBLIC,这取决于CMake版本和策略集。

3.添加包含*(此步骤可能不是必需的。)*

如果您还想包含头文件,请使用类似于find_libraryfind_path并搜索一个头文件。然后添加包含类似于target_link_librariestarget_include_directories的include目录。
文件:https://cmake.org/cmake/help/latest/command/find_path.htmlhttps://cmake.org/cmake/help/latest/command/target_include_directories.html的函数
如果外部软件可用,则可以将find_libraryfind_path替换为find_package

slmsl1lt

slmsl1lt4#

假设您有一个可执行文件,如下所示:

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 库

fxnxkyjh

fxnxkyjh5#

还有一个替代方案,如果您正在使用Appstore,则需要“授权”,因此需要与Apple框架链接。
要使授权正常工作(例如GameCenter),您 * 需要 * 有一个“Link Binary with Libraries”-buildstep,然后链接到“GameKit.framework”。CMake将“低级别”的库“注入”到命令行中,因此Xcode并不 * 真正 * 知道它,因此您 * 不会 * 在“Capabilities”屏幕中启用GameKit。
一种使用CMake并有一个“与二进制文件链接”的方法--构建步骤是用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”,然后像这样“应用”它(它会更改您的xcodeproj!)

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

您可能需要更改脚本命令以满足您的需要。
警告:由于项目格式可能会改变,因此可能会与不同的Xcode版本断开,(硬编码的)唯一编号可能并不真正唯一-通常其他人的解决方案更好-因此,除非您需要支持Appstore +授权(和自动构建),否则不要这样做。
这是CMake错误,请参阅http://cmake.org/Bug/view.php?id=14185http://gitlab.kitware.com/cmake/cmake/issues/14185

wyyhbhjk

wyyhbhjk6#

这个问题已经发布很久了,但我留下这个问题只是为了参考。我有一篇博客文章描述了你(或其他人)试图做的事情。请查看这里:https://michae9.wordpress.com/2022/09/01/shared-lib-to-be-used-by-client-programs-with-cmake/

相关问题