I'm building a small program that's using OpenCV 3.1 with CMake 3.5 and Visual Studio 2015 x64.
I link against OpenCV's .lib file, but when I try to run the program I get an error about a missing DLL:
Here's my CMakeLists.txt
:
cmake_minimum_required(VERSION 3.5)
project (MyProj)
set(CMAKE_FIND_LIBRARY_SUFFIXES, ".lib")
#Boost
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost REQUIRED system thread serialization filesystem)
#OpenCV
find_package(OpenCV REQUIRED)
add_executable(
MyApp
main.cpp
)
target_include_directories(MyApp PRIVATE
${OpenCV_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)
target_link_libraries(MyApp
${OpenCV_LIBRARIES}
${Boost_LIBRARIES}
)
OpenCV_DIR
is set to C:\tools\opencv3\build\x64\vc14\lib
which has include/ opencv_world310.lib opencv_world310d.lib OpenCVConfig.cmake OpenCVModules.cmake OpenCVModules-debug.cmake OpenCVModules-release.cmake
and is extracted from official Windows binaries of OpenCV v3.1
Then I generate VS solution with cmake . -G "Visual Studio 14 Win64"
As you can see, OpenCV lib was added to dependencies:
And is used in the linking step:
Link:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\link.exe /ERRORREPORT:QUEUE /OUT:"C:\...\Debug\MyApp.exe" /
INCREMENTAL /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib
advapi32.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib
C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib
C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib
C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib
C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib
C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib
C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib
C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib
C:\tools\opencv3\build\x64\vc14\lib\opencv_world310d.lib "C:\tools\boost_1_61_0\stage\lib\libboost_system-vc140-mt-gd-1_61.lib"
"C:\tools\boost_1_61_0\stage\lib\libboost_thread-vc140-mt-gd-1_61.lib"
"C:\tools\boost_1_61_0\stage\lib\libboost_serialization-vc140-mt-gd-1_61.lib"
"C:\tools\boost_1_61_0\stage\lib\libboost_filesystem-vc140-mt-gd-1_61.lib"
"C:\tools\boost_1_61_0\stage\lib\libboost_chrono-vc140-mt-gd-1_61.lib"
"C:\tools\boost_1_61_0\stage\lib\libboost_date_time-vc140-mt-gd-1_61.lib"
"C:\tools\boost_1_61_0\stage\lib\libboost_atomic-vc140-mt-gd-1_61.lib" /MANIFEST /MANIFESTUAC:"level='asInvoker'
uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:/Users/.../Debug/MyApp.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /
IMPLIB:"C:/Users/.../Debug/MyApp.lib" /MACHINE:X64 /machine:x64 MyApp.dir\Debug\sheepface.obj MyApp.dir\Debug\source.obj
MyApp.vcxproj -> C:\Users\...\Debug\MyApp.exe
MyApp.vcxproj -> C:/Users/.../Debug/MyApp.pdb (Full PDB)
I already tried setting magical variables
set(OpenCV_STATIC ON)
set(BUILD_SHARED_LIBS OFF)
but they made no difference
You have three different alternatives to create and use a library; static, dynamic implicit and dynamic explicit. A library.lib is not necessarily a static library which will contain the compiled code as you expected. It either contains the code or (simply said) contains the name of the required *.dll, which is loaded by the OS, and the entry points to the functions inside this dll. If you don't know what kind of lib the particular library is, you can use
lib /list foo.lib
(see here) to determine the type of the lib. If it is a static lib it will show you some .obj files used while creating the lib. If it is an import lib, it will show you the required .dll you should provide. The dll itself should in one of the search paths. It can become quite complex if you want to use some special path, but the simplest is to put it into the same folder as the executable which is using it or the system folder. Read Dynamic-Link Library Search Order for more detail. Both, the static lib and the implicit dynamic you will need a header file and a .lib file.
The third way (dynamic explicit) you have to use LoadLibrary[AW], GetProcAddress and FreeLibrary. Here you specify the path to the dll and use the dll "directly". You don't have any headers or .lib files but have to know exactly how the functions are named and how they are declared (return and parameter value types) otherwise your program won't work as expected.
You can find more information on dll's on MSDN.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With