Reputation: 9525
I am building a library from source and an executable that depends on the library. The library depends on a third-party library, libjpeg
, which I would like to handle via static linking. libjpeg
is installed on my system. I can see the .a
file at /usr/lib/x86_64-linux-gnu/libjpeg.a
(I am building on Ubuntu.)
When processing my library's CMakeLists.txt
file, CMake successfully finds libjpeg
but its output announces that is has found the dynamic version of libjpeg i.e. the output from CMake is
-- Found JPEG: /usr/lib/x86_64-linux-gnu/libjpeg.so (found version "80")
then later in the CMakeLists.txt
I link my library to libjpeg
via
target_link_libraries( my_library
PRIVATE JPEG
)
and building is succesful. However when I then link to my_library from my_executable I get the following error:
[100%] Linking CXX executable my_executable /usr/bin/ld: cannot find -lJPEG collect2: error: ld returned 1 exit status
which I take to mean that the problem is that since my_library
is linking to libjpeg
dynamically I would need to target_link_libraries
to libjpeg
from the executable rather than the library. In any case what I want to do is completely hide my_library
's dependency on libjpeg
.
Is there some way to tell find_package
to prefer static libraries?
Upvotes: 0
Views: 2994
Reputation: 97805
You can indicate the name:
find_library(JPEGLIB REQUIRED NAMES libjpeg.a)
add_executable(myapp myapp.c)
target_link_libraries(myapp PRIVATE ${JPEGLIB})
Each library name given to the NAMES option is first considered as a library file name and then considered with platform-specific prefixes (e.g. lib) and suffixes (e.g. .so). Therefore one may specify library file names such as libfoo.a directly. This can be used to locate static libraries on UNIX-like systems.
Upvotes: 0
Reputation: 13542
Before anything, you should fix your script:
target_link_libraries(my_library PRIVATE JPEG::JPEG)
You have to give the imported target name to target_link_libraries
.
That being said, no, not directly. find_package
itself does nothing of the sort, it simply looks for the correct script and calls it. Thus the actual behavior is library-specific. For libjpeg, probably it finds a copy of this script and runs it.
For libjpeg in particular, FindJPEG.cmake
provides no way to tell it to prefer static or dynamic version.
However, you can define JPEG_LIBRARY_RELEASE before calling find_package, to force it to find a specific version. For instance, if you do:
cmake -DJPEG_LIBRARY_RELEASE=/usr/lib/x86_64-linux-gnu/libjpeg.a .....
Then you should get a static build (replace with JPEG_LIBRARY_DEBUG
to define the debug version). You can do the same with pretty much any detected thing where you want to force the detection of something else, as most script will not overwrite values defined on the command line.
If that suits your workflow, perfect. Otherwise, you won't have a clean solution with CMake alone, and you should add a dependency manager on top of that (vcpkg, conan.io).
Upvotes: 2