#[[ 文件名: WindowsInstall.cmake windows下安装程序 因为windows需要复制动态库到指定位置, 因此需要特殊的安装程序 ]] # 找到导入库的.dll和.lib并添加install function(_wi_install_import_inline target run lib) if(WIN32 OR CYGWIN) # 只有windows需要执行该操作 (包括cygwin也需要处理.dll依赖的问题) if (CMAKE_BUILD_TYPE) string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type) else() set(_build_type DEBUG) endif() get_target_property(imp ${target} IMPORTED_IMPLIB) get_target_property(imp_t ${target} IMPORTED_IMPLIB_${_build_type}) get_target_property(loc ${target} IMPORTED_LOCATION) get_target_property(loc_t ${target} IMPORTED_LOCATION_${_build_type}) if(lib) if (imp) install(FILES ${imp} DESTINATION ${lib}) endif() if (imp_t) install(FILES ${imp_t} DESTINATION ${lib}) endif() endif() if(run) if (loc) install(FILES ${loc} DESTINATION ${run}) endif() if (loc_t) install(FILES ${loc_t} DESTINATION ${run}) endif() endif() endif() endfunction() function(wi_install_import) cmake_parse_arguments(ii "" "RUNTIME;LIBRARY" "TARGETS" ${ARGN}) if (NOT ii_RUNTIME) if (INSTALL_BINDIR) set(runtime ${INSTALL_BINDIR}) else() set(runtime ${CMAKE_INSTALL_BINDIR}) endif() else() set(runtime ${ii_RUNTIME}) endif() if (NOT ii_LIBRARY) if (INSTALL_LIBRARY) set(library ${INSTALL_LIBRARY}) else() set(library ${CMAKE_INSTALL_LIBDIR}) endif() else() set(library ${ii_LIBRARY}) endif() set(targets ${ii_TARGETS}) foreach(tgt IN LISTS targets) # 不需要 ${} _wi_install_import_inline(${tgt} ${runtime} ${library}) endforeach() endfunction() # 找到导入库的.dll和.lib并复制到指定的目录 function(_wi_copy_import_inline target run lib) if(WIN32 OR CYGWIN) if (CMAKE_BUILD_TYPE) string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type) else() set(_build_type DEBUG) endif() get_target_property(imp ${target} IMPORTED_IMPLIB) get_target_property(imp_t ${target} IMPORTED_IMPLIB_${_build_type}) get_target_property(loc ${target} IMPORTED_LOCATION) get_target_property(loc_t ${target} IMPORTED_LOCATION_${_build_type}) if(lib) if (imp) file(COPY ${imp} DESTINATION ${lib} USE_SOURCE_PERMISSIONS) endif() if (imp_t) file(COPY ${imp_t} DESTINATION ${lib} USE_SOURCE_PERMISSIONS) endif() endif() if(run) if (loc) file(COPY ${loc} DESTINATION ${run} USE_SOURCE_PERMISSIONS) endif() if (loc_t) file(COPY ${loc_t} DESTINATION ${run} USE_SOURCE_PERMISSIONS) endif() endif() endif() endfunction() # 添加 target if (NOT TARGET import_build) add_custom_target(import_build ALL COMMENT "Copy import target.") endif() macro(set_copy_command target a b) add_custom_command(TARGET ${target} POST_BUILD COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${a}" "${b}" COMMENT "Copy ${a}.") endmacro() function(_wi_build_import_inline target run lib) if(WIN32 OR CYGWIN) if (CMAKE_BUILD_TYPE) string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type) else() set(_build_type DEBUG) endif() get_target_property(imp ${target} IMPORTED_IMPLIB) get_target_property(imp_t ${target} IMPORTED_IMPLIB_${_build_type}) get_target_property(loc ${target} IMPORTED_LOCATION) get_target_property(loc_t ${target} IMPORTED_LOCATION_${_build_type}) if(lib) if (imp) set_copy_command(import_build ${imp} ${lib}) endif() if (imp_t) set_copy_command(import_build ${imp_t} ${lib}) endif() endif() if(run) if (loc) set_copy_command(import_build ${loc} ${run}) endif() if (loc_t) set_copy_command(import_build ${loc_t} ${run}) endif() endif() endif() endfunction() function(wi_copy_import) cmake_parse_arguments(ii "" "RUNTIME;LIBRARY" "TARGETS" ${ARGN}) if (NOT ii_RUNTIME) if (INSTALL_BINDIR) set(runtime ${INSTALL_BINDIR}) else() set(runtime ${CMAKE_INSTALL_BINDIR}) endif() else() set(runtime ${ii_RUNTIME}) endif() if (NOT ii_LIBRARY) if (INSTALL_LIBRARY) set(library ${INSTALL_LIBRARY}) else() set(library ${CMAKE_INSTALL_LIBDIR}) endif() else() set(library ${ii_LIBRARY}) endif() set(targets ${ii_TARGETS}) foreach(tgt IN LISTS targets) # 不需要${} _wi_copy_import_inline(${tgt} ${runtime} ${library}) endforeach() endfunction() function(wi_build_import) cmake_parse_arguments(ii "" "RUNTIME;LIBRARY" "TARGETS" ${ARGN}) if (NOT ii_RUNTIME) if (INSTALL_BINDIR) set(runtime ${INSTALL_BINDIR}) else() set(runtime ${CMAKE_INSTALL_BINDIR}) endif() else() set(runtime ${ii_RUNTIME}) endif() if (NOT ii_LIBRARY) if (INSTALL_LIBRARY) set(library ${INSTALL_LIBRARY}) else() set(library ${CMAKE_INSTALL_LIBDIR}) endif() else() set(library ${ii_LIBRARY}) endif() set(targets ${ii_TARGETS}) foreach(tgt IN LISTS targets) # 不需要${} _wi_build_import_inline(${tgt} ${runtime} ${library}) endforeach() endfunction() # 安装install的bin目录(检查.dll并安装到指定位置) function(wi_install_dll_bin) if(WIN32 OR CYGWIN) cmake_parse_arguments(ii "" "RUNTIME" "DIRS" ${ARGN}) if (NOT ii_RUNTIME) if (INSTALL_BINDIR) set(runtime ${INSTALL_BINDIR}) else() set(runtime ${CMAKE_INSTALL_BINDIR}) endif() else() set(runtime ${ii_RUNTIME}) endif() set(dirs ${ii_DIRS}) foreach(dir IN LISTS dirs) file(GLOB _dll # 遍历所有的.dll FOLLOW_SYMLINKS # 遍历link LIST_DIRECTORIES FALSE # 不记录列表 CONFIGURE_DEPENDS "${dirs}/*.dll") if (_dll) install(FILES ${_dll} DESTINATION ${runtime}) endif() endforeach() endif() endfunction() # 复制bin目录(检查.dll并复制到指定位置) function(wi_copy_dll_bin) if(WIN32 OR CYGWIN) cmake_parse_arguments(ii "" "RUNTIME" "DIRS" ${ARGN}) if (NOT ii_RUNTIME) if (INSTALL_BINDIR) set(runtime ${INSTALL_BINDIR}) else() set(runtime ${CMAKE_INSTALL_BINDIR}) endif() else() set(runtime ${ii_RUNTIME}) endif() set(dirs ${ii_DIRS}) foreach(dir IN LISTS dirs) file(GLOB _dll # 遍历所有的.dll FOLLOW_SYMLINKS # 遍历link LIST_DIRECTORIES FALSE # 不记录列表 CONFIGURE_DEPENDS "${dirs}/*.dll") if (_dll) file(COPY ${_dll} DESTINATION ${runtime} USE_SOURCE_PERMISSIONS) endif() endforeach() endif() endfunction() # 检查文件夹是否有exe, 若有则将其当作bin目录处理 function(wi_install_dll_dir) if(WIN32 OR CYGWIN) cmake_parse_arguments(ii "" "RUNTIME" "DIRS" ${ARGN}) if (NOT ii_RUNTIME) if (INSTALL_BINDIR) set(runtime ${INSTALL_BINDIR}) else() set(runtime ${CMAKE_INSTALL_BINDIR}) endif() else() set(runtime ${ii_RUNTIME}) endif() set(dirs ${ii_DIRS}) foreach(dir IN LISTS dirs) file(GLOB _exe LIST_DIRECTORIES FALSE # 不记录列表 CONFIGURE_DEPENDS "${dir}/*.exe") if (_exe) wi_install_dll_bin(RUNTIME ${runtime} DIRS ${dir}) endif() endforeach() endif() endfunction() # 检查文件夹是否有exe, 若有则将其当作bin目录处理 function(wi_copy_dll_dir) if(WIN32 OR CYGWIN) cmake_parse_arguments(ii "" "RUNTIME" "DIRS" ${ARGN}) if (NOT ii_RUNTIME) if (INSTALL_BINDIR) set(runtime ${INSTALL_BINDIR}) else() set(runtime ${CMAKE_INSTALL_BINDIR}) endif() else() set(runtime ${ii_RUNTIME}) endif() set(dirs ${ii_DIRS}) foreach(dir IN LISTS dirs) file(GLOB _exe LIST_DIRECTORIES FALSE # 不记录列表 CONFIGURE_DEPENDS "${dir}/*.exe") if (_exe) wi_copy_dll_bin(RUNTIME ${runtime} DIRS ${dir}) endif() endforeach() endif() endfunction() function(wi_find_cygwin1) if(CYGWIN) find_file(cygwin1_dll "cygwin1.dll" DOC "Find cygwin1.dll on windows.") if (NOT cygwin1_dll) message(FATAL_ERROR "The cygwin1.dll not found.") endif() add_library(CYGWIN::cygwin1 SHARED IMPORTED) set_target_properties(CYGWIN::cygwin1 PROPERTIES IMPORTED_LOCATION "${cygwin1_dll}") endif() endfunction()