'cmake: statically link against opencv libs

On Ubuntu 20.04:

sudo apt install libopencv-dev

Result:

kwu@Dev-KWu:/usr$ find . -name "*opencv_imgproc*" -o -name "*opencv_core*"
./lib/x86_64-linux-gnu/libopencv_core.so
./lib/x86_64-linux-gnu/libopencv_core.so.4.2
./lib/x86_64-linux-gnu/libopencv_imgproc.so.4.2.0
./lib/x86_64-linux-gnu/libopencv_imgproc.a
./lib/x86_64-linux-gnu/libopencv_core.a
./lib/x86_64-linux-gnu/libopencv_imgproc.so.4.2
./lib/x86_64-linux-gnu/libopencv_imgproc.so
./lib/x86_64-linux-gnu/libopencv_core.so.4.2.0

CMakeLists.txt:

...
set(OpenCV_SHARED OFF) # found on internet, makes no difference to resulting ninja.build
set(OpenCV_STATIC ON) # found on internet, makes no difference to resulting ninja.build
find_package(OpenCV REQUIRED COMPONENTS imgproc core)
...
target_link_libraries(foo PRIVATE ${OpenCV_LIBS})

Result in ninja.build:

LINK_LIBRARIES = ... /usr/lib/x86_64-linux-gnu/libopencv_imgproc.so.4.2.0 /usr/lib/x86_64-linux-gnu/libopencv_core.so.4.2.0 ...

What's the magic sauce to link against OpenCV statically?



Solution 1:[1]

After examining OpenCVConfig.cmake, typically, I expected to set(OpenCV_SHARED OFF) before find_package(OpenCV...) to do the job. However, I needed to do it manually. If your cmake supports list(TRANSFORM), which I guess it does, do the following:

...
# replace .so files with .a files for static linking.
list(TRANSFORM ${OpenCV_LIBS} REPLACE "(^[A-Za-z0-9/\\_-]+)(\.so)" "\\1.a" OpenCV_LIBS)
# you can output the result to ensure it is right
message(STATUS ${OpenCV_LIBS})
...
target_link_libraries(foo PRIVATE ${OpenCV_LIBS})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 sa-mustafa