CMake链接到外部库

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

只是做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失败。

首先设置库searchpath:

 LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/res) 

然后就这样做

 TARGET_LINK_LIBRARIES(GLBall mylib) 

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/ ) 

然后链接,如果这个库是由您的项目build立的:

 TARGET_LINK_LIBRARIES(GLBall mylib) 

这样的方法会给你更多的灵活性:查看add_library()命令以及与导入的库相关的许多目标属性 。

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

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

1.find图书馆
你必须find图书馆。 这是一个好主意,即使你知道你的图书馆的path。 如果图书馆消失或得到一个新的名字,CMake会报错。 这有助于及早发现错误,并向用户(可能自己)明确是什么原因造成问题。
查找foo库并将path存储在FOO_LIB

  find_library(FOO_LIB foo) 

CMake会自己弄清楚实际的文件名是如何的。 它检查通常的位置,例如/usr/lib/usr/lib64PATH中的PATH

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

有时您需要添加提示或path后缀,请参阅文档以获取详细信息: https : //cmake.org/cmake/help/latest/command/find_library.html

2.链接库从1.你有完整的库名在FOO_LIB 。 你可以使用这个将库链接到你的目标mylib

  target_link_libraries(mylib "${FOO_LIB}") 

你可能想要在图书馆前加上PRIVATEPUBLICINTERFACE ,参见 文档: https : //cmake.org/cmake/help/latest/command/target_link_libraries.html

3.添加包含 (这一步可能不是强制性的)。
如果您还想包含头文件,请使用类似于find_library并search头文件。 然后添加包含与target_include_directories相似的target_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_packagereplacefind_libraryfind_package

如果你正在使用Appstore,还需要另外一个select,它需要“权利”,因此需要链接到Apple-Framework。

对于权利的工作(如GameCenter),你需要有一个“链接二进制文件库”–buildstep,然后链接到“GameKit.framework”。 CMake将“低级”的库注入命令行,因此Xcode并不真正了解它,因此在Capabilities屏幕中将不会启用GameKit。

一种使用CMake的方法,有一个“与二进制链接”-buildstep是用CMake生成xcodeproj,然后用'sed'来search和replace,并以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版本,(硬编码)唯一编号可能并不是唯一的,而且其他人的解决scheme通常更好 – 所以除非您需要支持Appstore +权利(和自动构build),不要这样做。

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