开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 10 天,点击查看活动详情
file命令在Windows上的目录问题
file(GLOB ffmpeg_shared_libries ${FFMPEG_DEV_ROOT}/bin/*dll)
file(COPY ${ffmpeg_shared_libries} DESTINATION ${EXECUTABLE_OUTPUT_PATH})
以上的逻辑,在mac上,的确会将dll复制到对应的目录,但是在Windows上目录结构会变成这样:
- EXECUTABLE_OUTPUT_PATH
- Debug
- Release
- *.dll
在Windows上编译工程时,EXECUTABLE_OUTPUT_PATH
等目录会自动在后边追加Debug
/Release
,当我们要copy文件时,因为这一层目录的原因,就会非常麻烦,因为cmake中是无法感知到这个目录的。
当然也可以把DESTINATION
写死也能解决问题,但是file命令,无法区分debug、release,必须通过build_type设置,没办法将debug/release关联起来。
解决办法
在Windows上,通过add_custom_command和vs的宏变量
巧妙解决,算是取巧:
add_custom_command(TARGET ${APP_NAME} PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory ${COCOS2DX_ROOT_PATH}/xxx $(outdir)
就是这个$(outdir)
(有可能是其他,需要自己查找下合适的环境变量),注意是()
,这个目录在vs中是一个宏变量,是指向exe的生成目录的。
再通过COMMADN copy、COMMAND copy-directory,就解决文件copy的问题。
示例:将dll复制到构建目录
file(GLOB lua51dll ${LUAJIT_DIR}/src/*.dll)
add_custom_command(TARGET luajit PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${lua51dll} $(OutDir))
区分debug、release
有时候我们还希望针对不同的编译模式,COMMAND也不同,最常见的场景就是debug、release。
之前我尝试在CMAKE中使用CMAKE_BUILD_TYPE
,其实是没有任何效果的,因为这个cmake生成的vs工程中其实已经自带了debug、release模式,至于CMAKE_BUILD_TYPE
和vs编译模式之间的关系,具体我也没搞明白。
这里就要借助CMAKE的生成器表达式,直接看CMAKE代码:
COMMAND "$<$<CONFIG:Release>:${CMAKE_COMMAND}>" "$<$<CONFIG:Release>:-E>" "$<$<CONFIG:Release>:copy_directory>"
"$<$<CONFIG:Release>:${CMAKE_CURRENT_LIST_DIR}/static/dll>" $(outdir)
大概的用法就是$<条件:值>
,如果条件成立,那么就采用这个值,如果条件不成立,那么值就会被忽略,会被空字符串代替。生成器表达式也支持嵌套。
举例:
生成器表达式 | 值 |
---|---|
$<1:foo> | foo |
$<0:foo> |
而上边的CMAKE代码中,$<CONFIG:arg>
是用来测试构建类型,如果arg对应的构建类型正在构建,那么它的的值就为TRUE
。