Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How do I use Qt headers in a CMake sub-project?
QtWS25 Last Chance

How do I use Qt headers in a CMake sub-project?

Scheduled Pinned Locked Moved Solved General and Desktop
cmakewindowsmsvc2017msvcvisual studio
6 Posts 3 Posters 3.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    tuzepoito
    wrote on last edited by
    #1

    I'm using Windows. I have a CMake project that uses Qt and I wish to divide it into subprojects for clarity.

    However, if I compile a class outside of the root folder, I get an error that CMake cannot find the Qt headers.

    For example, let's say I have the following project tree :

    root/
    -->gui/
       -->CMakeLists.txt
       -->mainwindow.cpp
       -->mainwindow.h
    -->CMakeLists.txt
    -->main.cpp
    

    CMakeLists.txt:

    cmake_minimum_required(VERSION 3.5)
    
    project(testcmake VERSION 0.1 LANGUAGES CXX)
    
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED)
    find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED)
    
    add_subdirectory(gui)
    
    set(PROJECT_SOURCES main.cpp)
    
    add_executable(testcmake ${PROJECT_SOURCES})
    
    target_link_libraries(testcmake PRIVATE gui Qt${QT_VERSION_MAJOR}::Widgets)
    

    main.cpp:

    #include "gui/mainwindow.h"
    
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
      QApplication a(argc, argv);
      MainWindow w;
      w.show();
      return a.exec();
    }
    

    gui/CMakeLists.txt:

    set(GUI_SRC mainwindow.cpp mainwindow.h)
    add_library(gui ${GUI_SRC})
    

    gui/mainwindow.h:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    class QPushButton;
    
    class MainWindow : public QMainWindow
    {
      Q_OBJECT
    
    public:
      MainWindow(QWidget *parent = nullptr);
      ~MainWindow();
    
    private:
      QPushButton *m_button;
    };
    #endif // MAINWINDOW_H
    

    gui/mainwindow.cpp:

    #include "mainwindow.h"
    
    #include <QPushButton>
    
    MainWindow::MainWindow(QWidget *parent)
      : QMainWindow(parent)
    {
      m_button = new QPushButton("Hello CMake!", this);
      m_button->resize(150, 50);
    }
    
    MainWindow::~MainWindow()
    {
    }
    

    In this example, if I put class MainWindow in the root folder, the project compiles. But MainWindow class is in a subfolder, I get this error:

    [build] ...\build\gui\gui_autogen\include_debug\ewiega46ww\../../../../../gui/mainwindow.h(4): fatal error C1083: Impossible d'ouvrir le fichier include : 'QMainWindow' : No such file or directory [...\build\gui\gui.vcxproj]
    [build]   mainwindow.cpp
    [build] ...\gui\mainwindow.h(4): fatal error C1083: Impossible d'ouvrir le fichier include : 'QMainWindow' : No such file or directory [...\build\gui\gui.vcxproj]
    

    Which means, at the preprocessing step, the compiler cannot find any Qt header file, because the source file is in a sub-folder.
    How do I let CMake use the Qt headers, which are retrieved from the find_package command in the root folder?

    1 Reply Last reply
    0
    • Christian EhrlicherC Christian Ehrlicher

      If you want to use a library you have to link against this library with target_link_libraries()

      M Offline
      M Offline
      mchinand
      wrote on last edited by
      #3

      I've been bitten by this before; forgetting to add a library to a target_link_libraries() statement and getting 'include' errors during compilation. Then, not checking the target_link_libraries() statements; wrongly think they would only come into play during linking.

      1 Reply Last reply
      0
      • Christian EhrlicherC Online
        Christian EhrlicherC Online
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        If you want to use a library you have to link against this library with target_link_libraries()

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        M 1 Reply Last reply
        1
        • Christian EhrlicherC Christian Ehrlicher

          If you want to use a library you have to link against this library with target_link_libraries()

          M Offline
          M Offline
          mchinand
          wrote on last edited by
          #3

          I've been bitten by this before; forgetting to add a library to a target_link_libraries() statement and getting 'include' errors during compilation. Then, not checking the target_link_libraries() statements; wrongly think they would only come into play during linking.

          1 Reply Last reply
          0
          • T Offline
            T Offline
            tuzepoito
            wrote on last edited by
            #4

            OK, I think I have a solution, or maybe a workaround. I added linking to the Qt libraries at the end of gui/CMakeLists.txt:

            set(GUI_SRC mainwindow.cpp mainwindow.h)
            add_library(gui ${GUI_SRC})
            target_link_libraries(gui PUBLIC Qt${QT_VERSION_MAJOR}::Widgets)
            

            and then it compiles.
            Even though it's just a library, I guess I still need to link the Qt libraries so my code can use the header files.

            Christian EhrlicherC 1 Reply Last reply
            0
            • M Offline
              M Offline
              mchinand
              wrote on last edited by
              #5

              Your gui sub-project still needs to link to the libraries, it's not just so it can find the header files. In the compile/build output you should see a link step.

              1 Reply Last reply
              0
              • T tuzepoito

                OK, I think I have a solution, or maybe a workaround. I added linking to the Qt libraries at the end of gui/CMakeLists.txt:

                set(GUI_SRC mainwindow.cpp mainwindow.h)
                add_library(gui ${GUI_SRC})
                target_link_libraries(gui PUBLIC Qt${QT_VERSION_MAJOR}::Widgets)
                

                and then it compiles.
                Even though it's just a library, I guess I still need to link the Qt libraries so my code can use the header files.

                Christian EhrlicherC Online
                Christian EhrlicherC Online
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #6

                @tuzepoito said in How do I use Qt headers in a CMake sub-project?:

                I think I have a solution, or maybe a workaround.

                Why workaround? If you want to use a library, you have to link against it what you're doing now - how should this be a workaround?

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                1

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved