解决办法
在启用 CMAKE_AUTOUIC 的同时,将使用了#include "ui_<base_ui>.h"
的头文件加入到add_executable
的 SOURCE 中即可。
参考 CMake 文档:CMake Doc | AUTOUIC¶
猜测原因
如果未将包含了#include "ui_<base_ui>.h"
的头文件加入到add_executable
的 SOURCE 中,那么执行编译时会抛出找不到 “ui_<base_ui>.h” 头文件的错误,从输出中可以发现,其实 UIC 的编译任务在这之前已经完成了,说明 CMake 并没有发现需要编译的 .ui 文件。
CMake 文档如此描述,构建时 CMake 会扫描源文件,若发现有头文件或源文件包含了 "ui_<base_ui>.h"
形式的头文件,则会搜索工程中 "<base_ui>.ui"
并调用 QT 提供的 uic 工具,将其编译为对应的头文件。
% cmake --build ./build
[ 20%] Automatic MOC and UIC for target test_autouic
[ 20%] Built target test_autouic_autogen
[ 40%] Building CXX object CMakeFiles/test_autouic.dir/test_autouic_autogen/mocs_compilation.cpp.o
[ 60%] Building CXX object CMakeFiles/test_autouic.dir/src/main.cpp.o
In file included from /home/yu/codefield/window/src/main.cpp:1:
/home/yu/codefield/window/include/test.h:2:10: fatal error: ui_test.h: No such file or directory
2 | #include "ui_test.h"
| ^~~~~~~~~~~
compilation terminated.
结合上面的报错可以发现,CMake 可能只会扫描add_executable
的 SOURCE 中的头文件和源文件,若发现有文件包含了"ui_<base_ui>.h"
,则会在 target test_autouic 的构建流程中调用 uic 生成头文件。
test_autouic 无法发现需要编译的 .ui 文件,报错处已经是 g++ 编译器展开头文件的流程,自然无法调用 uic 生成所需的头文件了。
拓展实践 🍎:将 .ui 与 .cpp / .h 分离
如果想实现如下的工程结构,还需要配置 CMAKE_AUTOUIC_SEARCH_PATHS
变量,该变量用于配置 CMake 从哪些目录中搜索需要被编译的 .ui 文件。
.
├── CMakeLists.txt
├── include
│ └── test.h
├── src
│ ├── main.cpp
│ └── test.cpp
└── ui
└── test.ui
需要在 CMakeLists.txt 中写:
set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_SOURCE_DIR}/ui)
否则 uic 会报错:
[ 20%] Automatic MOC and UIC for target test_autouic
AutoUic error
-------------
"SRC:/include/test.h"
includes the uic file "ui_test.h",
but the user interface file "test.ui"
could not be found in the following directories
"SRC:/include"