問題描述和解決辦法
整個項目包括: 庫、測試程序,都是基於源碼生成;測試程序肯定是executable類型了,而如果生成的庫是SHARED類型,在windows下就是.dll(以及對應的.lib)文件。
執行測試程序時,出現"xxx.dll"找不到,其中"xxx.dll"是整個解決方案產生的那個共享庫。
雖然可以手動復制xxx.dll到yyy.exe的目錄,但是每次手動復制很低效。
方法1:設定LIBRARY_OUTPUT_PATH和EXECUTABLE_OUTPUT_PATH
需要在add_subdirectory()前設定,例如:
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
就能夠分別在CMAKE_BINARY_DIR/Debug或CMAKE_BINARY_DIR/Release下得到xxx.lib和yyy.exe在一塊兒了。這兩個變量是全局級別的(具體到某個target,可能不起作用,見方法2)
例子1:給opencv1.0.0添加cmake支持
根目錄的CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.13)
project(opencv_100)
add_definitions(
-DCVAPI_EXPORTS
-DHAVE_JPEG
-DHAVE_PNG
-DHAVE_TIFF
-DHAVE_JASPER
)
include_directories(
"cv/include"
"cv/src"
"cxcore/Include"
"cvaux/include"
"otherlibs/highgui"
"otherlibs/_graphics/include"
)
link_directories("otherlibs/_graphics/lib")
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
#message("inside windows")
# add SAFESEH to Visual Studio. copied from http://www.reactos.org/pipermail/ros-diffs/2010-November/039192.html
#if(${_MACHINE_ARCH_FLAG} MATCHES X86) # fails
#message("inside that branch")
# in VS2013, there is: fatal error LNK1104: cannot open file "LIBC.lib"
# so, we have to add /NODEFAULTLIB:LIBC.LIB
# reference: https://stackoverflow.com/questions/6016649/cannot-open-file-libc-lib
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO /NODEFAULTLIB:LIBC.LIB")
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO /NODEFAULTLIB:LIBC.LIB")
set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO /NODEFAULTLIB:LIBC.LIB")
#endif()
endif (CMAKE_SYSTEM_NAME MATCHES "Windows")
add_subdirectory("cxcore")
add_subdirectory("cv")
add_subdirectory("cvaux")
add_subdirectory("otherlibs/highgui")
add_subdirectory("samples")
# add_subdirectory("ml")
# add_subdirectory("otherlibs/cvcam")
方法2:設定target的ARCHIVE_OUTPUT_DIRECTORY和RUNTIME_OUTPUT_DIRECTORY屬性
這種方法是針對特定的target來設定的。是在opencv_220/OpenCVModule.cmake
中看來的。這個版本的opencv官方配備了cmake,絕大多數模塊使用define_opencv_module
宏來簡化target的構建規則的編寫,其定義中關於輸出的庫路徑和可執行文件路徑的設定,修改后如下(我都改成${CMAKE_BINARY_DIR}了,這樣使得在VS中可以直接運行樣例工程,而不至於說xxx.dll找不到):
# Additional target properties
set_target_properties(${the_target} PROPERTIES
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
#ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/"
#RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/"
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
)