如何指导cmake/automoc查找外部标头 我有一个Qt小部件C++类,它加载了Qt创建者创建的UI文件。类的头文件和源文件位于两个单独的目录中。我无法指示cmake/automoc查找类的标题。CGuess认识到它需要对C++文件进行建模,但不能找到类似的标头。
我能帮cmake找到这些文件吗 如果cpp和头文件都在同一个目录中,则一切正常。只有当标题位于其他位置时,才会出现此选项 我的目录结构是如何指导cmake/automoc查找外部标头 我有一个Qt小部件C++类,它加载了Qt创建者创建的UI文件。类的头文件和源文件位于两个单独的目录中。我无法指示cmake/automoc查找类的标题。CGuess认识到它需要对C++文件进行建模,但不能找到类似的标头。,qt,cmake,qt5,moc,Qt,Cmake,Qt5,Moc,我能帮cmake找到这些文件吗 如果cpp和头文件都在同一个目录中,则一切正常。只有当标题位于其他位置时,才会出现此选项 我的目录结构是 project src include Foo Bar.h lib Foo Bar.cpp forms Bar.ui 在src/include/Foo/B
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/lib/Foo中的My 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:error:/automoc/src/lib/Foo/Bar.cpp该文件包含moc文件“moc_Bar.cpp”,但在/automoc/src/lib/Foo/中找不到标题“Bar{.h、.hh、.h++、.hm、.hpp、.hxx、.in、.tx}”,您必须手动包装标题文件。 将其放入您的CMakeLists.txt:
file(GLOB HEADERS_TO_MOC src/include/Foo/ *.h)
qt5_wrap_cpp(PROCESSED_MOCS
${HEADERS_TO_MOC}
TARGET Foo
OPTIONS --no-notes) # Don't display a note for the headers which don't produce a moc_*.cpp
target_sources(Foo PRIVATE ${PROCESSED_MOCS}) # This adds generated moc cpps to target
这种方法的真实例子
我发现将
AUTOMOC
留给自己的设备就可以简化解决方法。以下是我所做的(适用于我们所有受支持的CMake版本,目前为3.2…3.17
):
Bar.cpp
PRIVATE
源:AUTOMOC
将在moc相关文件时创建一个Foo_autogen
输出目录moc_Bar.cpp
和moc_Baz.cpp
将在随机命名的ABDEADBEEF
子目录中创建,并且将创建一个mocs_编译.cpp
文件,其内容如下:
//此文件是自动生成的。更改将被覆盖。
#包括“ABDEADBEEF/moc_Bar.cpp”
#包括“ABDEADBEEF/moc_Baz.cpp”
该文件将被编译并链接到目标的最终输出中
当CMAKE_AUTOMOC
全局设置为True
时,每个目标也将接收其自己的target_autogen
目录,尽管在没有任何MOC类的目标中不会生成任何内容。不过,最好只在需要的目标上设置AUTOMOC
target属性:
set_property(TARGET Foo PROPERTY AUTOMOC ON)
代码中有很多东西是不需要的(例如,如果您已经在使用
find_包(Qt5Core)
,那么find_包(Qt5Widget)
)。但我认为错误在于您需要包含ui\u Bar.h
,而不是*.cpp
文件。请看,这只是一个错误,当我从我为重现问题而构建的实际测试用例中重新键入代码时。真正的代码包括头,而不是cpp。谢谢你赶上它;我纠正了这个问题。顺便说一句,我尝试过使用其他一些自动功能(我不知道),比如autouic by do set(CMAKE_autouic ON),但也失败了,因为它只在Bar.cpp所在的同一目录中查找ui文件;它无法判断它是否在一个单独的目录(forms)中。是的,我试图将表单移动到其他目录,但编译失败。看起来它的设计使所有文件都必须在同一目录中。似乎这是当前CMake automoc代码中的一个限制,作为一种解决方法,您可以添加一个自定义目标来调用moc src/include/Foo-o src/lib/moc\u Foo.cpp
。似乎没有任何选项可以传递给主运行中心,也不起作用。看起来唯一的解决方案是提交一个CMake bugreport。也许这会在另一个方向上起作用,但是如果(如您所说)src/include
是公共include目录,那么可能就是安装头的地方。安装一个只包含另一个(未安装)头的相对include的头将创建一个非常坏的安装。
set(CMAKE_AUTOMOC True)
target_sources(Foo PRIVATE
${CMAKE_SOURCE_DIR}/src/include/Foo/Bar.h
${CMAKE_SOURCE_DIR}/src/include/Foo/Baz.h)
set_property(TARGET Foo PROPERTY AUTOMOC ON)