【问题标题】:Can't include ui-file from linked library using CMake's autouic无法使用 CMake 的 autouic 包含来自链接库的 ui 文件
【发布时间】:2020-03-29 20:43:20
【问题描述】:

我有一个 CMake 项目,我对其进行了简化以找到错误的根源。 该项目有一个 CMakeLists.txt 文件,该文件添加了一个库和一个链接到该库的可执行文件。 库和可执行文件都包含 ui 文件。为了生成 ui 文件的头文件,使用了变量 CMAKE_AUTOUIC。 库和可执行文件都可以包含它们的自己的 ui 文件:它们位于我的构建目录的子目录[projectname]_autogen\include_Debug 中。 但是,我的可执行文件中的另一个文件包含库中的一个文件,该文件又包含一个 ui 文件。在这里我得到了错误:

Error   C1083   Cannot open include file: 'ui_MainWidget.h': No such file or directory  QtGUI
\QtGUI\src\QtWidgets\include\MainWidget.h   5

我的项目如下所示:

cmake_minimum_required (VERSION 3.14 FATAL_ERROR)

project(QtGUI)

find_package(Qt5 COMPONENTS Widgets Core Gui REQUIRED)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

add_library(QtWidgets
    QtWidgets/source/MainWidget.cpp
    QtWidgets/include/MainWidget.h
    QtWidgets/include/MainWidget.ui
)
target_link_libraries(QtWidgets
    PUBLIC
        Qt5::Widgets
        Qt5::Core
        Qt5::Gui
)
target_include_directories(QtWidgets
    PUBLIC
        QtWidgets/include
)

add_executable(${PROJECT_NAME}
    Main/include/MainWindow.h
    Main/include/MainWindow.ui
    Main/source/MainWindow.cpp
    Main/source/Main.cpp
)
target_link_libraries(${PROJECT_NAME}
    PUBLIC
        QtWidgets
)
target_include_directories(${PROJECT_NAME}
    PUBLIC
        Main/include
)

还有来自项目QtGUIMainWindow.cpp文件,发生错误的地方:

#include "MainWindow.h" // inside this project
#include "MainWidget.h" // inside the linked library 'QtWidgets'

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{ 
...

MainWidget.h 看起来像这样

// Qt Includes
#include <ui_MainWidget.h> // inside this project
#include <QWidget>

namespace Ui
{
    class MainWidget;
}

class MainWidget : public QWidget
{
    Q_OBJECT

public:
...

我在这里缺少什么? 我知道拆分 CMakeLists.txt 并在链接库中有一个自己的 CMakeLists.txt 并将add_library 的东西移到那里会更干净(并对可执行文件做同样的事情,例如application-目录)但是我认为这个例子更容易理解结构。

编辑/添加

我回到这个(不幸的是没有回答)问题并发现了这一点:查看我的 QtGUI-Project(可执行文件)的“配置属性 -> C/C++ -> 附加包含目录”,我看到以下内容:

  • QtGUI\build\QtGUI_autogen\include_Debug
  • QtGUI\src\Main\include
  • QtGUI\src\QtWidgets\include

还有更多。

但所需的ui_MainWidget.h 位于QtGUI\build\QtWidgets_autogen\include_Debug 内部,未设置为附加包含目录。 我手动添加了它,一切正常。

我需要如何修改我的 CMakeLists.txt 文件,以便为我的其他包含目录自动设置此目录?

PS:我也检查了Implementing Qt project through CMake,但在配置中找不到任何相关差异。

【问题讨论】:

    标签: visual-studio qt cmake


    【解决方案1】:

    经过一番挖掘,我意识到 AUTOUIC 目标属性的设计方式,CMake 是在特定目录中查找生成的 UI 头文件。这些目录会自动添加到目标的 INCLUDE_DIRECTORIES,即上面提到的 [projectname]_autogen\include_Debug。 这仅针对每个目标执行,而不是跨目标执行。

    一种选择是将目标属性AUTOGEN_BUILD_DIR 设置为无需任何特殊字符串即可轻松包含的目录:

    set_target_properties(QtWidgets
                          PROPERTIES AUTOGEN_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
    

    但是,这种方法的问题是我有两个目标,因此mocs_compilation.cpp 将被放在同一个目录中,因此一个会被覆盖。最后我不得不做类似的事情

    set_target_properties(${PROJECT_NAME}
                          PROPERTIES AUTOGEN_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/QtWidgets")
    

    这让整个事情变得多余。

    回答我最新编辑的问题,关于如何包含其他目标 autogen-include 目录: $&lt;$&lt;CONFIG:DEBUG&gt;:${CMAKE_CURRENT_BINARY_DIR}/QtWidgets_autogen/include_Debug&gt; 可以在target_include_directories 中使用QtGUI-target,结果是

    target_include_directories(${PROJECT_NAME}
        PUBLIC
            Main/include
        $<$<CONFIG:DEBUG>:${CMAKE_CURRENT_BINARY_DIR}/QtWidgets_autogen/include_Debug>
        $<$<CONFIG:RELEASE>:${CMAKE_CURRENT_BINARY_DIR}/QtWidgets_autogen/include_Release>
    )
    

    此外,可以将代码更改为使用经典的qt5_wrap_uiqt5_wrap_cpp 方法,这会将生成的UI 头文件放入我的QtGUI\build 目录中。

    编辑/添加

    查看我的 QtGUI-Project(可执行文件)的“配置属性 -> C/C++ -> 附加包含目录”,我现在可以看到以下内容:

    • QtGUI\build\QtGUI_autogen\include_Debug
    • QtGUI\src\Main\include
    • QtGUI\build\QtWidgets_autogen\include_Debug
    • QtGUI\src\QtWidgets\include

    还有更多。

    【讨论】:

      猜你喜欢
      • 2017-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 2021-03-04
      • 2021-10-29
      • 1970-01-01
      • 2020-06-22
      相关资源
      最近更新 更多