CMake link to an external library

How do I get CMake to link an executable file to an external shared library that is not built in one CMake project?

Just executing target_link_libraries(GLBall ${CMAKE_BINARY_DIR}/res/mylib.so) gives an error

 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) 

after I copied the library to the bin/res binary directory.

I tried using find_library(RESULT mylib.so PATHS ${CMAKE_BINARY_DIR}/res)

What fails with RESULT-NOTFOUND .

+75
external cmake
Jan 08 '12 at 1:16
source share
4 answers

First find the library search path:

 LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/res) 

And then just

 TARGET_LINK_LIBRARIES(GLBall mylib) 
+64
Jan 08 2018-12-12T00:
source share

arrowdodger's answer is correct and preferred in many cases. I just wanted to add an alternative to his answer:

You can add the "imported" library target, rather than a catalog link. Something like:

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

And then combine, as if this library was built by your project:

 TARGET_LINK_LIBRARIES(GLBall mylib) 

This approach will give you a little more flexibility. Take a look at the add_library () command and the many target properties associated with imported libraries .

I do not know if this will solve your problem with "updated versions of libs".

+76
May 11 '12 at 11:19
source share

I assume that you want to associate a library with the name foo, its file name usually has a link foo.dll or libfoo.so .

1. Find a library
You must find the library. This is a good idea, even if you know the path to your library. CMake crashes if the library disappears or gets a new name. This helps to identify errors at an early stage and make it clear to the user (maybe himself) what causes the problem.
To find the library foo and save the path in FOO_LIB , use

  find_library(FOO_LIB foo) 

CMake will figure out how this file name is. It checks for common places like /usr/lib , /usr/lib64 and paths in PATH .

You already know the location of your library. Add it to CMAKE_PREFIX_PATH when you call CMake, then CMake will also look for your library in the paths it has traveled.

Sometimes you need to add hints or path suffixes, see the documentation for details: https://cmake.org/cmake/help/latest/command/find_library.html

2. Link the library to 1. You have the full name of the library in FOO_LIB . You use this to link the library to your mylib target, as in

  target_link_libraries(mylib "${FOO_LIB}") 

You might want to add PRIVATE , PUBLIC or INTERFACE in front of the library, cf. documentation: https://cmake.org/cmake/help/latest/command/target_link_libraries.html

3. Add includes (this step may be optional.)
If you also want to include header files, use find_path , similar to find_library , and find the header file. Then add the include directory with target_include_directories similar to target_link_libraries .

Documentation: https://cmake.org/cmake/help/latest/command/find_path.html as well as https://cmake.org/cmake/help/latest/command/target_include_directories.html

If available to external software, you can replace find_library and find_path with find_package .

+18
Jan 28 '17 at 12:08 on
source share

Another alternative, if you are working with the Appstore, needs "rights" and, as such, should be associated with the Apple-Framework.

In the "Access rights to work" section (for example, GameCenter), you must have "Link Binary with Libraries" -buildstep, and then a link to "GameKit.framework". CMake "embeds" libraries "at a low level" in the command line, so Xcode really does not know about it, and therefore you cannot enable GameKit on the Capabilities screen.

One way to use CMake and "Link with Binaries" -buildstep is to generate xcodeproj using CMake, then use "sed" to "find and replace" and add GameKit the way Xcode likes it ..

The script looks like this (for 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 

save this in "gamecenter.sed" and then apply it like this (it will change your xcodeproj!)

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

You may need to modify the script commands to suit your needs.

Warning: it may break with another version of Xcode, because the project format may change, the unique number (hardcoded) may not be unique - and, as a rule, other people's decisions are better - so if you don’t need support for Appstore + Ent Rightsments (and automatic assemblies), do not do this.

This is a CMake error, see http://cmake.org/Bug/view.php?id=14185 and http://gitlab.kitware.com/cmake/cmake/issues/14185

+3
Dec 04 '15 at 16:41
source share



All Articles