【发布时间】:2015-04-14 01:42:45
【问题描述】:
我有一个 Qt 小部件 C++ 类,它加载在 Qt Creator 中创建的 ui 文件。类的头文件和源文件位于两个单独的目录中。我无法指示 cmake/automoc 找到该类的标题。 cmake 认识到它需要 moc C++ 文件,但找不到类似的头文件。
我可以做些什么来帮助 cmake 找到文件吗?
如果 cpp 和头文件都在同一个目录中,则一切正常。仅当标题位于其他位置时才会出现这种情况。
我的目录结构是
project
src
include
Foo
Bar.h
lib
Foo
Bar.cpp
forms
Bar.ui
在 src/include/Foo/Bar.h 我有:
// Bar.h
#include <QtWidgets/QWidget>
namespace Ui { class Bar; }
class Bar : public QWidget {
Q_OBJECT
...
}
在 src/Foo/Bar.cpp 文件中:
#include "Foo/Bar.h"
#include "moc_Bar.cpp"
#include "ui_Bar.h"
我在 src/lib/Foo 中的 CMakeLists.txt 设置如下:
# there is a project() call at the root that defines PROJECT_SOURCE_DIR
set(PUBLIC_HEADERS_DIR ${PROJECT_SOURCE_DIR}/src/include)
# Pick up public library headers
include_directories(${PUBLIC_HEADERS_DIR})
# Pick up private headers in library dir
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
# Set up Qt
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Widgets REQUIRED)
include_directories(${Qt5Core_INCLUDE_DIRS})
include_directories(${Qt5Gui_INCLUDE_DIRS})
include_directories(${Qt5Widgets_INCLUDE_DIRS})
add_definitions(${Qt5Widgets_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
# Set up Qt forms/resources
qt5_wrap_ui(UI_OUT_FILES forms/Bar.ui)
qt5_add_resources(RESOURCE_FILE resources.qrc)
# Library cpp and header files
set(CORE_CPP_FILES Bar.cpp)
set(LIB_CPP_FILES ${LIB_CPP_FILES} ${CORE_CPP_FILES} ${UI_OUT_FILES} ${RESOURCE_FILE})
set(LIB_HEADER_FILES ${PUBLIC_HEADERS_DIR}/Foo/Bar.h)
# Build library
add_library(Foo SHARED ${LIB_CPP_FILES} ${LIB_HEADER_FILES})
target_link_libraries(Foo ${Qt5Widgets_LIBRARIES})
当我运行 cmake 时,我收到以下错误:
AUTOGEN:错误:/automoc/src/lib/Foo/Bar.cpp 该文件包含 moc 文件“moc_Bar.cpp”,但找不到标题“Bar{.h,.hh,.h++,.hm ,.hpp,.hxx,.in,.txx}" 在 /automoc/src/lib/Foo/
【问题讨论】:
-
您的代码中不需要很多东西(例如,如果您已经在使用
find_package(Qt5Widget),则在find_package(Qt5Core)中不需要)。但我认为错误在于您需要包含ui_Bar.h而不是*.cpp文件。见example -
当我从我为重现问题而构建的实际测试用例中重新键入代码时,这只是一个错误。真正的代码包括头文件,而不是 cpp。谢谢你抓住它;我更正了这个问题。
-
顺便说一句,我尝试通过 set(CMAKE_AUTOUIC ON) 使用其他一些自动功能(我不知道),例如 autouic,但这也失败了,因为它只寻找Bar.cpp 所在目录中的 ui 文件;它无法确定它位于单独的目录(表单)中。
-
是的,我尝试将表单移动到其他目录,但编译失败。看起来它的设计使所有文件都必须在同一个目录中。
-
似乎这是当前 CMake automoc 代码中的一个限制,作为一种解决方法,您可以添加一个自定义目标来调用
moc src/include/Foo -o src/lib/moc_Foo.cpp。似乎没有任何选项可以通过AUTOMOC_MOC_OPTIONS 传递给 moc,CMAKE_AUTOMOC_RELAXED_MODE 也不起作用。看起来唯一的解决方案是提交 CMake 错误报告。