我正在尝试编写一个CMakeLists.txt
作为构建后事件的副本,需要dlls
从外部库到构建后可执行文件所在的文件夹。我正在研究的操作系统是Win7和VS2010。
有很多外部库,所以我不想在CMakeLists.txt
中单独列出它们。我目前的解决方案是使用文件通配并为每个库创建一个后期构建事件:
FILE(GLOB files "${LIBRARY_DIR}/lib/$(ConfigurationName)/*dll")
MESSAGE("FILE LIST IS: ${files}")
FOREACH(file ${files})
ADD_CUSTOM_COMMAND(
TARGET mylib
POST_BUILD
COMMENT "Copying dll ${file}..."
COMMAND ${CMAKE_COMMAND} -E copy ${file} "${CMAKE_BINARY_DIR}/$(ConfigurationName)/"
)
ENDFOREACH()
基本上,如果我将$(ConfigurationName)
替换为Release
或Debug
,则上面的代码会在工作文件中剪切。但是,我想从相应的目录中取出依赖于Release或Debug构建模式的库。在上面剪切的代码中,$(ConfigurationName)
不会被visual studio构建模式取代。我想这是因为这是一个VS2010变量,在cmake生成时间是不知道的。)
有人知道如何解决这个问题吗?
答案 0 :(得分:1)
ADD_CUSTOM_COMMAND
了解生成器表达式,因此您可以使用$<CONFIG>
而不是$(Configuration)
或$(ConfigurationName)
。但是,对于FILE
命令,这将不起作用。更重要的是,如果这些DLL是作为同一项目的一部分构建的,那么第一次构建项目时文件globbing方法将无法工作,因为当你第一次运行CMake时,没有任何DLL会存在布置。
您可能希望将BundleUtilities视为解决问题的更有效方法。尽管它的名字,它支持所有平台,而不仅仅是Mac。您需要调用fixup_bundle
命令作为构建后或安装步骤以实现您描述的内容。已经在线描述了这种方法的一些变体(例如here和here)。
您还可以查看DeployQt4.cmake
文件的来源,该文件应包含在CMake安装的Modules
子目录中以供创意使用。
答案 1 :(得分:0)
假设您的项目名称已填充_TARGET_NAME
,而ADDITIONAL_DLL_PATH
包含包含外部dll的文件夹列表,则以下代码将复制使用dumpbin
找到的所有外部依赖项在窗户上。
foreach(CONF_TYPE ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${CONF_TYPE} CONF_TYPE_U)
get_property(TARGET_LOCATION_${CONF_TYPE_U} TARGET ${_TARGET_NAME} PROPERTY LOCATION_${CONF_TYPE_U})
get_filename_component(TARGE_DIR ${TARGET_LOCATION_${CONF_TYPE_U}} PATH)
install(CODE "
if (\"\${BUILD_TYPE}\" STREQUAL \"${CONF_TYPE}\")
include(BundleUtilities)
fixup_bundle(\"${TARGET_LOCATION_${CONF_TYPE_U}}\" \"\" \"${ADDITIONAL_DLL_PATH}\")
endif()"
COMPONENT Runtime)
endforeach()
这个解决方案有一些缺点,比如需要在需要复制这些文件(可能不会多次)时构建INSTALL
目标,而不是检测延迟加载的dll。