CMake与AUTOGEN在特定项目结构下的重复生成问题
QT CMake AUTOGEN重复生成moc/ui文件问题解决
问题场景
在使用QT的AUTOMOC、AUTOUIC特性的CMake项目中,LibB依赖LibA,所有文件均需AUTOGEN处理。为简化LibA的顶层CMakeLists.txt(避免罗列几十个子目录的文件),给LibA的每个子目录都添加了单独的CMakeLists.txt,通过add_subdirectory递归引入,并用target_sources给LibA添加源文件和头文件。
项目结构(修改后)
MinimalCMakeProject/ ├── CMakeLists.txt ├── src/ │ ├── CMakeLists.txt │ ├── libA/ │ │ ├── CMakeLists.txt │ │ ├── include/ │ │ │ └── libA/ │ │ │ ├── CMakeLists.txt │ │ │ ├── bla/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── file1.h │ │ │ └── blubb/ │ │ │ ├── CMakeLists.txt │ │ │ └── file2.h │ │ └── src/ │ │ ├── CMakeLists.txt │ │ ├── bla/ │ │ │ ├── CMakeLists.txt │ │ │ └── file1.cpp │ │ └── blubb/ │ │ ├── CMakeLists.txt │ │ └── file2.cpp │ └── libB/ │ ├── CMakeLists.txt │ ├── include/ │ │ └── libB/ │ │ └── file3.h │ └── src/ │ └── file3.cpp
问题现象
项目可正常编译,但构建目录中出现重复生成的moc/ui文件:
src/libA/libA_autogen/mocs_compilation.cpp包含LibA所有moc文件src/libB/libB_autogen/mocs_compilation.cpp同时包含LibA和LibB的moc文件- UI文件存在同样的重复生成情况
问题原因
当LibA通过target_sources(libA PUBLIC ...)将带Q_OBJECT等需要moc的头文件设为PUBLIC时,这些头文件会被加入LibA的INTERFACE_SOURCES。LibB链接LibA时,CMake默认会让LibB的AUTOMOC扫描这些INTERFACE头文件,导致重复处理生成moc/ui。
解决方案
核心修复
在LibB的CMakeLists.txt中添加以下配置,让LibB的AUTOGEN跳过处理来自依赖库的INTERFACE头文件:
# 让LibB的AUTOMOC跳过依赖库的INTERFACE头文件 set_target_properties(libB PROPERTIES AUTOMOC_SKIP_INTERFACE_HEADERS ON) # 让LibB的AUTOUIC跳过依赖库的INTERFACE头文件 set_target_properties(libB PROPERTIES AUTOUIC_SKIP_INTERFACE_HEADERS ON)
辅助配置(确保LibA正确处理AUTOGEN)
在LibA的顶层CMakeLists.txt中,确保启用AUTOMOC和AUTOUIC:
add_library(libA) # 启用AUTOMOC和AUTOUIC set_target_properties(libA PROPERTIES AUTOMOC ON) set_target_properties(libA PROPERTIES AUTOUIC ON) # 设置头文件包含目录,让LibB能找到LibA的头文件 target_include_directories(libA PUBLIC include ) # 递归引入子目录添加源文件 add_subdirectory(include/libA) add_subdirectory(src)
额外优化(可选)
如果不想维护大量子目录CMakeLists.txt,可以在LibA顶层用file(GLOB_RECURSE)批量添加文件(适合文件结构稳定的项目):
file(GLOB_RECURSE LIB_A_SRC src/**/*.cpp) file(GLOB_RECURSE LIB_A_PUB_HEADERS include/libA/**/*.h) target_sources(libA PRIVATE ${LIB_A_SRC} PUBLIC ${LIB_A_PUB_HEADERS} )
内容的提问来源于stack exchange,提问作者gk017
相关产品推荐
相关产品推荐

