Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何指导cmake/automoc查找外部标头 我有一个Qt小部件C++类,它加载了Qt创建者创建的UI文件。类的头文件和源文件位于两个单独的目录中。我无法指示cmake/automoc查找类的标题。CGuess认识到它需要对C++文件进行建模,但不能找到类似的标头。_Qt_Cmake_Qt5_Moc - Fatal编程技术网

如何指导cmake/automoc查找外部标头 我有一个Qt小部件C++类,它加载了Qt创建者创建的UI文件。类的头文件和源文件位于两个单独的目录中。我无法指示cmake/automoc查找类的标题。CGuess认识到它需要对C++文件进行建模,但不能找到类似的标头。

如何指导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

我能帮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/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)