How do I tell cmake I want my project to link libraries statically?
Asked Answered
F

7

27

I'm trying to build an OpenCV-based project using CMake, running on Linux. So far my CMakeLists.txt files looks something like

FIND_PACKAGE (OpenCV REQUIRED)
...
TARGET_LINK_LIBRARIES (my-executable ${OpenCV_LIBS})

but this results in dynamically linked libraries. How do I link with static libraries?

Farewell answered 20/9, 2010 at 21:2 Comment(2)
How do you point "CMake at a static OpenCV build"? My build has both static and shared libs.Murraymurre
see answer below: https://mcmap.net/q/519137/-how-do-i-tell-cmake-i-want-my-project-to-link-libraries-staticallyFarewell
F
13

You build static OpenCV libraries by just setting the BUILD_SHARED_LIBS flag to false in CMake. Then all you need to do to build your own application with those static libraries is to add a dependency on OpenCV in your CMakeLists.txt:

FIND_PACKAGE (OpenCV REQUIRED)
...
TARGET_LINK_LIBRARIES (your-application ${OpenCV_LIBS})

and CMake will take care of everything.

Farewell answered 22/5, 2012 at 20:10 Comment(4)
It's BUILD_SHARED_LIBS, not _LIBRARIES. :-)Cyrus
I corrected BUILD_SHARED_LIBRARIES to BUILD_SHARED_LIBS.Bigod
At least with CLion under Windows (CLion 2016.3 EAP) which comes bundled with CMake 3.6.1, when building OpenCV 3.1.0, this was the only way of those listed here which caused CMake to build OpenCV as static rather than shared libraries. Note that attempts to enable this option by editing CMakeLists.txt failed; only by editing the CMake cache via CLion's Cache window and clicking the Apply Changes and Reload Project icon was I able to get my CLion/CMake combination to accept BUILD_SHARED_LIBS. Not sure if this is a problem with CLion that should be documented.Bigod
This only works if you're building opencv as well. Not in the case where you're using preinstalled opencv libraries.Boschbok
C
13

Actually this issue seems to have already been fixed in the OpenCVConfig.cmake that comes with OpenCV. All you have to do is define OpenCV_STATIC in your CMakeLists.txt. I.e.

set(OpenCV_STATIC ON)
find_package(OpenCV REQUIRED)
Cryptozoite answered 13/11, 2014 at 23:40 Comment(2)
What does 'find_package(OpenCV REQUIRED)' do?Anyaanyah
This doesn't work for me on Ubuntu 18.04. In which version was this fixed?Metaphase
K
6

To link everything statically, I believe you're looking for CMAKE_EXE_LINKER_FLAGS (add -static).

Are you using the 'simple method' of OpenCVConfig.cmake? or the older FindOpenCV.cmake?

Khanate answered 20/9, 2010 at 21:37 Comment(0)
L
5

AFAIK that's a bit tricky, because CMake, more precisely the find_library command, prefers shared libs and finds those if both shared and static are available.

I'm still looking for a good solution myself to be able to compile binaries "as static as possible", but I've found no elegant solution yet. The only way it would surely work is to implement everything through custom FindXXXX modules.

Langobard answered 21/9, 2010 at 13:34 Comment(1)
The only way I now is to change searched library suffixes: set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) before find_library(). FindBoost and has special option to force the use of static libraries (Boost_USE_STATIC_LIBS), but it also works internally by changing CMAKE_FIND_LIBRARY_SUFFIXES.Ironbark
I
3

on the add_library line specify static. See https://cmake.org/cmake/help/latest/command/add_library.html

Correction since you are looking to link against a static library I would look into the CMAKE_FIND_LIBRARY_SUFFIXES property

Intensify answered 20/9, 2010 at 21:52 Comment(4)
I think the add_library command is to generate an output binary. In this case, specifying STATIC causes it to generate .a.Khanate
The static keyword for add_library specifies what type of library it generates, it is not for when generating the binary.Intensify
Perhaps I misunderstood, but I thought the OP was trying to link with a static library, not generate one.Khanate
yep, I'm not creating a library, I want to link (statically) to the OpenCV libraries.Farewell
L
1

Note that gcc refuses to link if you pass the -static option, but you have dynamic libs in the link arguments - which you will if you just simply use FindOpenCV.cmake and this picks up the dynamic libs (I don't know how OpenCVConfig.cmake behaves though)...

Langobard answered 21/9, 2010 at 14:35 Comment(0)
S
-1
SET (CMAKE_EXE_LINKER_FLAGS "-static")
Sepulture answered 6/3, 2019 at 7:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.