How to get CMake to link an executable to an external shared library that is not build within the same CMake project?
Just doing target_link_libraries(GLBall ${CMAKE_BINARY_DIR}/res/mylib.so)
gives the 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 into the binary dir bin/res
.
I tried using find_library(RESULT mylib.so PATHS ${CMAKE_BINARY_DIR}/res)
Which fails with RESULT-NOTFOUND
.
Set libraries search path first:
And then just do
arrowdodger's answer is correct and preferred on many occasions. I would simply like to add an alternative to his answer:
You could add an "imported" library target, instead of a link-directory. Something like:
And then link as if this library was built by your project:
Such an approach would give you a little more flexibility: Take a look at the add_library( ) command and the many target-properties related to imported libraries.
I do not know if this will solve your problem with "updated versions of libs".
I assume you want to link to a library called foo, its filename is usually something link
foo.dll
orlibfoo.so
.1. Find the library
You have to find the library. This is a good idea, even if you know the path to your library. CMake will error out if the library vanished or got a new name. This helps to spot error early and to make it clear to the user (may yourself) what causes a problem.
To find a library foo and store the path in
FOO_LIB
useCMake will figure out itself how the actual file name is. It checks the usual places like
/usr/lib
,/usr/lib64
and the paths inPATH
.You already know the location of your library. Add it to the
CMAKE_PREFIX_PATH
when you call CMake, then CMake will look for your library in the passed paths, too.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 From 1. you have the full library name in
FOO_LIB
. You use this to link the library to your targetmylib
as inYou might want to add
PRIVATE
,PUBLIC
, orINTERFACE
in front of the library, cf. the documentation: https://cmake.org/cmake/help/latest/command/target_link_libraries.html3. Add includes (This step might be not mandatory.)
If you also want to include header files, use
find_path
similar tofind_library
and search for a header file. Then add the include directory withtarget_include_directories
similar totarget_link_libraries
.Documentation: https://cmake.org/cmake/help/latest/command/find_path.html and https://cmake.org/cmake/help/latest/command/target_include_directories.html
If available for the external software, you can replace
find_library
andfind_path
byfind_package
.One more alternative, in the case you are working with the Appstore, need "Entitlements" and as such need to link with an Apple-Framework.
For Entitlements to work (e.g. GameCenter) you need to have a "Link Binary with Libraries"-buildstep and then link with "GameKit.framework". CMake "injects" the libraries on a "low level" into the commandline, hence Xcode doesn't really know about it, and as such you will not get GameKit enabled in the Capabilities screen.
One way to use CMake and have a "Link with Binaries"-buildstep is to generate the xcodeproj with CMake, and then use 'sed' to 'search & replace' and add the GameKit in the way XCode likes it...
The script looks like this (for Xcode 6.3.1).
save this to "gamecenter.sed" and then "apply" it like this ( it changes your xcodeproj! )
You might have to change the script-commands to fit your need.
Warning: it's likely to break with different Xcode-version as the project-format could change, the (hardcoded) unique number might not really by unique - and generally the solutions by other people are better - so unless you need to Support the Appstore + Entitlements (and automated builds), don't do this.
This is a CMake bug, see http://cmake.org/Bug/view.php?id=14185 and http://gitlab.kitware.com/cmake/cmake/issues/14185