CMake编译COM服务器修改idl后tlb资源未自动更新如何解决
问题原因
当前配置缺失两个关键依赖关系,导致资源编译步骤无法感知TLB文件更新:
- MIDL自定义命令未将生成的
.tlb文件声明为输出产物,CMake不知道midl执行会更新该文件 - 资源文件
myLib.rc的编译规则未关联.tlb依赖,TLB更新后不会触发资源重编译
修复方案
按以下步骤修改CMake配置即可:
- 第一步:将TLB文件加入
add_custom_command的OUTPUT列表,让CMake识别这是MIDL的生成产物 - 第二步:通过
set_source_files_properties给myLib.rc设置编译依赖,明确告知资源编译依赖最新的TLB文件
修改后的完整CMake配置如下:
set(SOURCES ... myLib.idl myLib.rc) add_executable(myLib.exe WIN32 ${SOURCES}) set(MIDL_OUTPUT ${CMAKE_CURRENT_LIST_DIR}/myLib_i.h ${CMAKE_CURRENT_LIST_DIR}/myLib_i.c # 新增:将tlb加入MIDL输出产物列表 ${CMAKE_CURRENT_LIST_DIR}/myLib.tlb ) set(MIDL_FILE ${CMAKE_CURRENT_LIST_DIR}/myLib.idl) set(TLB_NAME "${CMAKE_CURRENT_LIST_DIR}/myLib.tlb") add_custom_command( OUTPUT ${MIDL_OUTPUT} COMMENT "midl /h myLib_i.h /iid myLib_i.c /tlb ${TLB_NAME} /proxy myLib_p.c ${MIDL_FILE} /env x64 /W1 /char signed /robust /nologo /Oicf /target NT60" COMMAND midl /h myLib_i.h /iid myLib_i.c /tlb ${TLB_NAME} /proxy myLib_p.c ${MIDL_FILE} /env x64 /W1 /char signed /robust /nologo /Oicf /target "NT60" WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} DEPENDS ${MIDL_FILE} MAIN_DEPENDENCY ${MIDL_FILE} VERBATIM ) target_sources(myLib.exe PRIVATE ${MIDL_FILE} ${MIDL_OUTPUT}) # 新增:设置rc资源文件依赖TLB,TLB更新后自动重编译资源 set_source_files_properties(myLib.rc PROPERTIES OBJECT_DEPENDS ${TLB_NAME} )
可选最佳实践
建议将所有MIDL生成产物(头文件、C文件、TLB)放到构建二进制目录而非源码目录,避免污染源码仓库,只需要将上述路径里的CMAKE_CURRENT_LIST_DIR替换为CMAKE_CURRENT_BINARY_DIR,同时给RC文件设置包含目录让rc.exe能找到生成的TLB:
# 给资源编译器添加二进制目录的查找路径 target_include_directories(myLib.exe PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
内容的提问来源于stack exchange,提问作者Anton Shchyrov
相关产品推荐
相关产品推荐

