如何让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)
Run Code Online (Sandbox Code Playgroud)
在我将库复制到二进制目录后bin/res.
我试过用 find_library(RESULT mylib.so PATHS ${CMAKE_BINARY_DIR}/res)
哪个失败了RESULT-NOTFOUND.
And*_*dré 111
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 )
Run Code Online (Sandbox Code Playgroud)
然后链接,好像这个库是由您的项目构建的:
TARGET_LINK_LIBRARIES(GLBall mylib)
Run Code Online (Sandbox Code Playgroud)
这种方法可以为您提供更多灵活性:查看add_library()命令以及与导入库相关的许多目标属性.
我不知道这是否可以解决"更新版本的库"的问题.
arr*_*owd 95
首先设置库搜索路径:
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/res)
Run Code Online (Sandbox Code Playgroud)
然后就做
TARGET_LINK_LIBRARIES(GLBall mylib)
Run Code Online (Sandbox Code Playgroud)
usr*_*567 49
我假设你想链接到一个名为foo的库,它的文件名通常是链接foo.dll或libfoo.so.
1.找到图书馆
你必须找到图书馆.即使您知道图书馆的路径,这也是一个好主意.如果库消失或获得新名称,CMake将会出错.这有助于及早发现错误并使用户(可能是您自己)明白导致问题的原因.
要查找库foo并存储正在FOO_LIB使用的路径
find_library(FOO_LIB foo)
Run Code Online (Sandbox Code Playgroud)
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.您可以使用它将库链接到目标,mylib如下所示
target_link_libraries(mylib "${FOO_LIB}")
Run Code Online (Sandbox Code Playgroud)
您可能想要添加PRIVATE,PUBLIC或INTERFACE在库前面,参见 文档:https:
//cmake.org/cmake/help/latest/command/target_link_libraries.html
3.添加包含 (此步骤可能不是必需的.)
如果您还想包含头文件,请使用find_path类似于find_library和搜索头文件.然后添加target_include_directories类似的include目录target_link_libraries.
文档:https: //cmake.org/cmake/help/latest/command/find_path.html 和 https://cmake.org/cmake/help/latest/command/target_include_directories.html
如果可用于外部软件,则可以替换find_library并find_path通过find_package.
Sor*_*ush 16
假设您有一个可执行文件,例如:
\nadd_executable(GLBall GLBall.cpp)\nRun Code Online (Sandbox Code Playgroud)\n如果外部库有标头,请给出其包含文件夹的路径:
\ntarget_include_directories(GLBall PUBLIC "/path/to/include")\nRun Code Online (Sandbox Code Playgroud)\n添加库目录路径:
\ntarget_link_directories(GLBall PUBLIC "/path/to/lib/directory")\nRun Code Online (Sandbox Code Playgroud)\n最后链接库名
\ntarget_link_libraries(GLBall mylib)\nRun Code Online (Sandbox Code Playgroud)\n注意,库文件的前缀和扩展名被删除:
\nlibmylib.a \xe2\x9e\x9c mylib
\nmylib.so \xe2\x9e\x9c mylib
如果您使用 Appstore,另一种选择需要“权利”,因此需要与 Apple 框架链接。
为了使权利生效(例如 GameCenter),您需要有一个“Link Binary with Libraries”-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
Run Code Online (Sandbox Code Playgroud)
将其保存到“gamecenter.sed”,然后像这样“应用”它(它会改变你的 xcodeproj!)
sed -i.pbxprojbak -f gamecenter.sed myproject.xcodeproj/project.pbxproj
Run Code Online (Sandbox Code Playgroud)
您可能需要更改脚本命令以满足您的需要。
警告:由于项目格式可能会发生变化,因此可能会因不同的 Xcode 版本而中断,(硬编码的)唯一编号可能不是唯一的 - 通常其他人的解决方案更好 - 所以除非您需要支持 Appstore +权利(和自动构建),不要这样做。
这是一个 CMake 错误,请参阅http://cmake.org/Bug/view.php?id=14185和http://gitlab.kitware.com/cmake/cmake/issues/14185
| 归档时间: |
|
| 查看次数: |
222367 次 |
| 最近记录: |