How to use cmake `FILE_SET` option with Qt
-
wrote on 1 Sept 2024, 00:26 last edited by
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? -
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?wrote on 1 Sept 2024, 03:14 last edited byI 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).
-
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).
-
Lifetime Qt Championwrote on 1 Sept 2024, 08:04 last edited by Christian Ehrlicher 9 Jan 2024, 08:08
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 -
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_PATHSwrote on 1 Sept 2024, 08:35 last edited by@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-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.
@Dolfost said in How to use cmake `FILE_SET` 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.
-
@Dolfost said in How to use cmake `FILE_SET` 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.
wrote on 1 Sept 2024, 09:02 last edited by Dolfost 9 Jan 2024, 09:03@Christian-Ehrlicher I did here. Hope I constructed it in such a way that developers could understand.
1/7