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 to use cmake `FILE_SET` option with Qt
Forum Updated to NodeBB v4.3 + New Features

How to use cmake `FILE_SET` option with Qt

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 3 Posters 578 Views 1 Watching
  • 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.
  • DolfostD Offline
    DolfostD Offline
    Dolfost
    wrote on last edited by
    #1

    I have next project:

    .
    ├── CMakeLists.txt
    ├── gui
    │   ├── CMakeLists.txt
    │   ├── gui.cpp
    │   └── include
    │       └── gui.hpp
    └── main.cpp
    

    Here is the file contents:

    # CMakeLists.txt
    cmake_minimum_required(VERSION 3.25)
    
    project(fileSetProj VERSION 1.0.0 LANGUAGES CXX)
    
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    set(CMAKE_CXX_EXTENSIONS OFF)
    
    
    find_package(Qt6 REQUIRED COMPONENTS 
    	Core Widgets Gui
    )
    
    qt_standard_project_setup()
    
    add_subdirectory(gui)
    
    qt_add_executable(program
    	main.cpp
    )
    
    target_link_libraries(program PRIVATE
    	Qt6::Core Qt6::Widgets Qt6::Gui
    	gui
    )
    
    // main.cpp
    #include<gui.hpp>
    
    #include <QApplication>
    #include <QDebug>
    
    int main(int argc, char *argv[]) {
    	QApplication app(argc, argv);
    
    	MainWindow mainWindow = MainWindow();
    	mainWindow.show();
    
    	return app.exec();
    }
    
    # gui/CMakeLists.txt
    find_package(Qt6 REQUIRED COMPONENTS 
    	Core Widgets
    )
    
    qt_add_library(gui)
    target_sources(gui 
    	PRIVATE
    		gui.cpp 
    	PUBLIC FILE_SET gui_headers 
     	TYPE HEADERS
    		BASE_DIRS
    	 		include/
    )
    
    target_link_libraries(gui 
    	Qt6::Widgets
    )
    
    // gui/gui.cpp
    #include <gui.hpp>
    
    // gui/include/gui.hpp
    #ifndef _MAIN_WINDOW_HPP_
    #define _MAIN_WINDOW_HPP_
    
    #include <QMainWindow>
    
    class MainWindow : public QMainWindow {
    	Q_OBJECT
    };
    
    #endif // !_MAIN_WINDOW_HPP_
    

    I build this project with next commnads:

    cmake -B . -S .. -DCMAKE_PREFIX_PATH="~/Qt/6.7.1/macos" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
    cmake --build . 
    

    And i get

    λ › cmake -B . -S .. -DCMAKE_PREFIX_PATH="~/Qt/6.7.1/macos" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
    -- The CXX compiler identification is AppleClang 15.0.0.15000309
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
    -- Detecting CXX compile features
    -- Detecting CXX compile features - done
    -- Performing Test CMAKE_HAVE_LIBC_PTHREAD
    -- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
    -- Found Threads: TRUE
    -- Performing Test HAVE_STDATOMIC
    -- Performing Test HAVE_STDATOMIC - Success
    -- Found WrapAtomic: TRUE
    -- Found OpenGL: /Library/Developer/CommandLineTools/SDKs/MacOSX14.4.sdk/System/Library/Frameworks/OpenGL.framework
    -- Found WrapOpenGL: TRUE
    -- Configuring done (0.5s)
    -- Generating done (0.0s)
    -- Build files have been written to: /Users/vladyslav/Lib/NAU/Mathematical_statistics/Labs/Lab/tmp/build
    λ › cmake --build .
    [  0%] Built target gui_autogen_timestamp_deps
    [ 12%] Automatic MOC and UIC for target gui
    [ 12%] Built target gui_autogen
    [ 25%] Building CXX object gui/CMakeFiles/gui.dir/gui_autogen/mocs_compilation.cpp.o
    [ 37%] Building CXX object gui/CMakeFiles/gui.dir/gui.cpp.o
    [ 50%] Linking CXX shared library libgui.dylib
    [ 50%] Built target gui
    [ 50%] Built target program_autogen_timestamp_deps
    [ 62%] Automatic MOC and UIC for target program
    [ 62%] Built target program_autogen
    [ 75%] Building CXX object CMakeFiles/program.dir/program_autogen/mocs_compilation.cpp.o
    [ 87%] Building CXX object CMakeFiles/program.dir/main.cpp.o
    [100%] Linking CXX executable program
    Undefined symbols for architecture arm64:
      "vtable for MainWindow", referenced from:
          MainWindow::MainWindow() in main.cpp.o
       NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
    ld: symbol(s) not found for architecture arm64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    gmake[2]: *** [CMakeFiles/program.dir/build.make:117: program] Error 1
    gmake[1]: *** [CMakeFiles/Makefile2:106: CMakeFiles/program.dir/all] Error 2
    gmake: *** [Makefile:91: all] Error 2
    λ ›
    

    And if I change the gui/CMakeLists.txt to:

    # gui/CMakeLists.txt
    find_package(Qt6 REQUIRED COMPONENTS 
    	Core Widgets
    )
    
    qt_add_library(gui)
    target_sources(gui 
    	PRIVATE
    		gui.cpp 
    		include/gui.hpp
    )
    
    target_include_directories(gui PUBLIC include)
    
    target_link_libraries(gui 
    	Qt6::Widgets
    )
    

    After this the executable is built successfully.

    How to use FILE_SET with cmake in qt?

    C 1 Reply Last reply
    0
    • DolfostD Dolfost

      I have next project:

      .
      ├── CMakeLists.txt
      ├── gui
      │   ├── CMakeLists.txt
      │   ├── gui.cpp
      │   └── include
      │       └── gui.hpp
      └── main.cpp
      

      Here is the file contents:

      # CMakeLists.txt
      cmake_minimum_required(VERSION 3.25)
      
      project(fileSetProj VERSION 1.0.0 LANGUAGES CXX)
      
      set(CMAKE_CXX_STANDARD 17)
      set(CMAKE_CXX_STANDARD_REQUIRED ON)
      set(CMAKE_CXX_EXTENSIONS OFF)
      
      
      find_package(Qt6 REQUIRED COMPONENTS 
      	Core Widgets Gui
      )
      
      qt_standard_project_setup()
      
      add_subdirectory(gui)
      
      qt_add_executable(program
      	main.cpp
      )
      
      target_link_libraries(program PRIVATE
      	Qt6::Core Qt6::Widgets Qt6::Gui
      	gui
      )
      
      // main.cpp
      #include<gui.hpp>
      
      #include <QApplication>
      #include <QDebug>
      
      int main(int argc, char *argv[]) {
      	QApplication app(argc, argv);
      
      	MainWindow mainWindow = MainWindow();
      	mainWindow.show();
      
      	return app.exec();
      }
      
      # gui/CMakeLists.txt
      find_package(Qt6 REQUIRED COMPONENTS 
      	Core Widgets
      )
      
      qt_add_library(gui)
      target_sources(gui 
      	PRIVATE
      		gui.cpp 
      	PUBLIC FILE_SET gui_headers 
       	TYPE HEADERS
      		BASE_DIRS
      	 		include/
      )
      
      target_link_libraries(gui 
      	Qt6::Widgets
      )
      
      // gui/gui.cpp
      #include <gui.hpp>
      
      // gui/include/gui.hpp
      #ifndef _MAIN_WINDOW_HPP_
      #define _MAIN_WINDOW_HPP_
      
      #include <QMainWindow>
      
      class MainWindow : public QMainWindow {
      	Q_OBJECT
      };
      
      #endif // !_MAIN_WINDOW_HPP_
      

      I build this project with next commnads:

      cmake -B . -S .. -DCMAKE_PREFIX_PATH="~/Qt/6.7.1/macos" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
      cmake --build . 
      

      And i get

      λ › cmake -B . -S .. -DCMAKE_PREFIX_PATH="~/Qt/6.7.1/macos" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
      -- The CXX compiler identification is AppleClang 15.0.0.15000309
      -- Detecting CXX compiler ABI info
      -- Detecting CXX compiler ABI info - done
      -- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
      -- Detecting CXX compile features
      -- Detecting CXX compile features - done
      -- Performing Test CMAKE_HAVE_LIBC_PTHREAD
      -- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
      -- Found Threads: TRUE
      -- Performing Test HAVE_STDATOMIC
      -- Performing Test HAVE_STDATOMIC - Success
      -- Found WrapAtomic: TRUE
      -- Found OpenGL: /Library/Developer/CommandLineTools/SDKs/MacOSX14.4.sdk/System/Library/Frameworks/OpenGL.framework
      -- Found WrapOpenGL: TRUE
      -- Configuring done (0.5s)
      -- Generating done (0.0s)
      -- Build files have been written to: /Users/vladyslav/Lib/NAU/Mathematical_statistics/Labs/Lab/tmp/build
      λ › cmake --build .
      [  0%] Built target gui_autogen_timestamp_deps
      [ 12%] Automatic MOC and UIC for target gui
      [ 12%] Built target gui_autogen
      [ 25%] Building CXX object gui/CMakeFiles/gui.dir/gui_autogen/mocs_compilation.cpp.o
      [ 37%] Building CXX object gui/CMakeFiles/gui.dir/gui.cpp.o
      [ 50%] Linking CXX shared library libgui.dylib
      [ 50%] Built target gui
      [ 50%] Built target program_autogen_timestamp_deps
      [ 62%] Automatic MOC and UIC for target program
      [ 62%] Built target program_autogen
      [ 75%] Building CXX object CMakeFiles/program.dir/program_autogen/mocs_compilation.cpp.o
      [ 87%] Building CXX object CMakeFiles/program.dir/main.cpp.o
      [100%] Linking CXX executable program
      Undefined symbols for architecture arm64:
        "vtable for MainWindow", referenced from:
            MainWindow::MainWindow() in main.cpp.o
         NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
      ld: symbol(s) not found for architecture arm64
      clang: error: linker command failed with exit code 1 (use -v to see invocation)
      gmake[2]: *** [CMakeFiles/program.dir/build.make:117: program] Error 1
      gmake[1]: *** [CMakeFiles/Makefile2:106: CMakeFiles/program.dir/all] Error 2
      gmake: *** [Makefile:91: all] Error 2
      λ ›
      

      And if I change the gui/CMakeLists.txt to:

      # gui/CMakeLists.txt
      find_package(Qt6 REQUIRED COMPONENTS 
      	Core Widgets
      )
      
      qt_add_library(gui)
      target_sources(gui 
      	PRIVATE
      		gui.cpp 
      		include/gui.hpp
      )
      
      target_include_directories(gui PUBLIC include)
      
      target_link_libraries(gui 
      	Qt6::Widgets
      )
      

      After this the executable is built successfully.

      How to use FILE_SET with cmake in qt?

      C Offline
      C Offline
      ChrisW67
      wrote on last edited by
      #2

      I assume that gui.hpp contains the declaration of MainWindow including its Q_OBJECT macro.

      I guess hiding that file in a file set means that the CMAKE_AUTO_MOC and other logic is not seeing it to process and you do not get relevant structures created and included in your application link (i.e. the thing that is failing).

      FILE_SET is a relatively new feature in CMake 3.23+ and not present in required CMake versions for Qt 6 (3.16 and 3.21).

      DolfostD 1 Reply Last reply
      1
      • C ChrisW67

        I assume that gui.hpp contains the declaration of MainWindow including its Q_OBJECT macro.

        I guess hiding that file in a file set means that the CMAKE_AUTO_MOC and other logic is not seeing it to process and you do not get relevant structures created and included in your application link (i.e. the thing that is failing).

        FILE_SET is a relatively new feature in CMake 3.23+ and not present in required CMake versions for Qt 6 (3.16 and 3.21).

        DolfostD Offline
        DolfostD Offline
        Dolfost
        wrote on last edited by
        #3

        @ChrisW67 I also came to this assumption. But like now the Qt team may see this post and update things, isn't she?

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

          modules are not yet supported so I don't see what you want with FILE_SET. And I don't see why you think you can omit gui.hpp when using FILE_SET tbh.
          What you are looking for is maybe something like AUTOUIC_SEARCH_PATHS

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

          DolfostD 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            modules are not yet supported so I don't see what you want with FILE_SET. And I don't see why you think you can omit gui.hpp when using FILE_SET tbh.
            What you are looking for is maybe something like AUTOUIC_SEARCH_PATHS

            DolfostD Offline
            DolfostD Offline
            Dolfost
            wrote on last edited by
            #5

            @Christian-Ehrlicher CMake In regular c++ program FILE_SET simplifies writting cmake code because i can just specify the base directory of include directory with BASE_DIRS and TYPE HEADERS instead of caring about structure of include directory . I think that if I omit the gui.hpp when using FILE_SET, cmake will find the gui.hpp in BASE_DIRS automatically. To be fair, if I add gui.hpp with

            	PUBLIC FILE_SET gui_headers 
            		TYPE HEADERS
            		BASE_DIRS
            			include/
            		FILES include/gui.hpp
            

            then the program compiles. But this kinda drifts away of FILE_SET automatic nature.

            The CMAKE_AUTOUIC_SEARCH_PATHS is for .ui files, isnt it? I could not find corresponding variable for AUTOMOC.

            Christian EhrlicherC 1 Reply Last reply
            0
            • DolfostD Dolfost

              @Christian-Ehrlicher CMake In regular c++ program FILE_SET simplifies writting cmake code because i can just specify the base directory of include directory with BASE_DIRS and TYPE HEADERS instead of caring about structure of include directory . I think that if I omit the gui.hpp when using FILE_SET, cmake will find the gui.hpp in BASE_DIRS automatically. To be fair, if I add gui.hpp with

              	PUBLIC FILE_SET gui_headers 
              		TYPE HEADERS
              		BASE_DIRS
              			include/
              		FILES include/gui.hpp
              

              then the program compiles. But this kinda drifts away of FILE_SET automatic nature.

              The CMAKE_AUTOUIC_SEARCH_PATHS is for .ui files, isnt it? I could not find corresponding variable for AUTOMOC.

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

              @Dolfost said in How to use cmake &#x60;FILE_SET&#x60; option with Qt:

              if I omit the gui.hpp when using FILE_SET, cmake will find the gui.hpp in BASE_DIRS automatically.

              I don't see why it should as it looks only like another way for INCLUDE_DIRECTORIES for me but you might file a bug report.

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

              DolfostD 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                @Dolfost said in How to use cmake &#x60;FILE_SET&#x60; option with Qt:

                if I omit the gui.hpp when using FILE_SET, cmake will find the gui.hpp in BASE_DIRS automatically.

                I don't see why it should as it looks only like another way for INCLUDE_DIRECTORIES for me but you might file a bug report.

                DolfostD Offline
                DolfostD Offline
                Dolfost
                wrote on last edited by Dolfost
                #7

                @Christian-Ehrlicher I did here. Hope I constructed it in such a way that developers could understand.

                1 Reply Last reply
                0

                • Login

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