problem ze zbudowaniem projektu QT5 i cmake

0

Chcę się nauczyć budować projekt przy pomocy cmake w win 10
W samym środowisku Qt5 projekt buduje się prawidłowo, ale mam problem ze zbudowaniem go przy pomocy cmake.
Poniżej podam ścieżki, jak wyglądają do qt5, cmake 3.28.1 i CodeBlocks 20.03

C:/Qt/Qt5.14.2/5.14.2/mingw73_64/lib/cmake/Qt5
C:/CodeBlocks/MinGW/bin/gcc.exe
C:/CodeBlocks/MinGW/bin/g++.exe
C:\CMake\bin

mój "CMakeLists.txt"

# Ustawienie minimalnej wersji CMake
cmake_minimum_required(VERSION 3.28)

# Ustawienie wersji projektu i nazwy projektu
project(FirstPro VERSION 0.1)

# Ustawienie ścieżki do MinGW
set(CMAKE_C_COMPILER "C:/CodeBlocks/MinGW/bin/gcc.exe")
set(CMAKE_CXX_COMPILER "C:/CodeBlocks/MinGW/bin/g++.exe")

# Ścieżka do Qt
set(Qt5_DIR "C:/Qt/Qt5.14.2/5.14.2/mingw73_64/lib/cmake/Qt5")

# Znalezienie Qt
find_package(Qt5 REQUIRED COMPONENTS Widgets)

# Źródła
set(SOURCES
    main.cpp
    mainwindow.cpp
)

# Nagłówki
set(HEADERS
    mainwindow.h
)

# UI
set(UI_FILES
    mainwindow.ui
)

# Zawijanie plików UI
qt5_wrap_ui(UI_HEADERS ${UI_FILES})

message(STATUS "UI_HEADERS: ${UI_HEADERS}")

# Tworzenie pliku wykonywalnego
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${UI_HEADERS})

# Łączenie z bibliotekami Qt
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)

# Ustawienie standardu C++
set(CMAKE_CXX_STANDARD 17)

uruchamiam cmd, wchodzę do katalogu z projektem, tworzę katalog
mkdir build
cd build
i zaczynam budować

cmake ..

-- Building for: NMake Makefiles
CMake Error at CMakeLists.txt:5 (project):
  Running

   'nmake' '-?'

  failed with:

   no such file or directory


CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
-- Configuring incomplete, errors occurred!

więc wymuszam poleceniem:
cmake .. -G "MinGW Makefiles"
i wydaje się że wszystko o.k, chociaż nie rozumiem tego " - skipped"

-- The C compiler identification is GNU 8.1.0
-- The CXX compiler identification is GNU 8.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/CodeBlocks/MinGW/bin/gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/CodeBlocks/MinGW/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- UI_HEADERS: C:/Users/2025/Desktop/QtStudentAddFile/build/ui_mainwindow.h
-- Configuring done (4.0s)
-- Generating done (0.1s)

chcę teraz zbudować i wydaję polecenie:
cmake --build .

[ 25%] Generating ui_mainwindow.h
[ 50%] Building CXX object CMakeFiles/FirstPro.dir/main.cpp.obj
[ 75%] Building CXX object CMakeFiles/FirstPro.dir/mainwindow.cpp.obj
C:\Users\2025\Desktop\QtStudentAddFile\mainwindow.cpp:2:10: fatal error: ui_mainwindow.h: No such file or directory
 #include "ui_mainwindow.h"
          ^~~~~~~~~~~~~~~~~
compilation terminated.
mingw32-make.exe[2]: *** [CMakeFiles\FirstPro.dir\build.make:95: CMakeFiles/FirstPro.dir/mainwindow.cpp.obj] Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/FirstPro.dir/all] Error 2
mingw32-make.exe: *** [Makefile:90: all] Error 2

W czym popełniam błąd? Co powinienem poprawić? hę?

2

Moim skromnym zdaniem sam sobie wrzucasz kłody pod nogi

Na początku powinieneś używać QtCreator do generowoania projektu cmake
a dopiero jak ogarniesz temat i wiesz CO/GDZIE/JAK to piszesz to z palca

skipped cmake pominelo testy kompilatora , normalnie CMAKE_CXX_COMPILER CMAKE_C_COMPILER podaje sie jako paraemtr cmake , moze jest subtelna różnica jak to jest w kodzie pliku CMakeLists.txt , zobacz w QtCreator zakładkę z komendami cmake

C:\Users\2025\Desktop\QtStudentAddFile\mainwindow.cpp:2:10: fatal error: ui_mainwindow.h: No such file or directory
 #include "ui_mainwindow.h"
          ^~~~~~~~~~~~~~~~~

Brak w cmake

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

Zastanawia mnie tez dlaczego pliki CPP H i UI są rozdzielone na różne zmienne cmake, to strasznie pogarsza czytelność , nie spominajac o utrudnianiu zycia jak trzeba cos zmienic w projekcie

1

chcę się nauczyć cmake to biorę qt? Po co, tam są nawet specyficzne rzeczy odnośnie qml.
porady:

  1. Olej windows szkoda życia, moim zdaniem do nauki lepiej linux bo zwyczajnie łatwiej ściezki ogarniać czy nawet zainstalować.
  2. Także użyj WSL
  3. Weź sobie książkę albo kurs z udemy nawet
  4. sięgnij po źródła jak np. https://github.com/cpp-best-practices/cmake_template
  5. zapoznaj się z cmake-format

qt5? już od dawna powinieneś jechać z qt6.

edit:

# Ustawienie ścieżki do MinGW
set(CMAKE_C_COMPILER "C:/CodeBlocks/MinGW/bin/gcc.exe")
set(CMAKE_CXX_COMPILER "C:/CodeBlocks/MinGW/bin/g++.exe")

# Ścieżka do Qt
set(Qt5_DIR "C:/Qt/Qt5.14.2/5.14.2/mingw73_64/lib/cmake/Qt5")

Zazwyczaj to jest złe podejście(trochę moze zbyt szeroko to ująłem). To powinno być raczej na poziomie systemu operacyjnego ustawione chyba że wiele używasz wielu toolchain lub nawet bym to przeniósł co cmake presets(ale to moze później).

0

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

dodanie tych komend nic nie wnosi, problem jest tutaj:
fatal error: ui_mainwindow.h: No such file or directory
#include "ui_mainwindow.h"

sęk w tym, że plik jest tworzony przy budowaniu

// edit
Zaprojektuję i stworzę projekt od nowa, bez pliku "mainwindow.ui" i dam znać

0

proszę, nie podejmować już dalszych starań w tej sprawie, problem rozwiązałem

zamiast tworzyć projekt w Qt Creatr, który tworzy plik "mainwindow.ui"
napisałem własną klasę class MySolution : public QWidget,
w której tworze layout'y QVBoxLayout czy QHBoxLayout.
Następnie umieszczam na nich QTableWidget, QPlainTextEdit, QPushButton.
Tak stworzony design nie do końca odpowiada moim oczekiwaniom
i wymaga naniesienia dużych poprawek w kwestii estetyki, ale program się buduje / kompiluje.

cmake .. -G "MinGW Makefiles"
-- The C compiler identification is GNU 8.1.0
-- The CXX compiler identification is GNU 8.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/CodeBlocks/MinGW/bin/gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/CodeBlocks/MinGW/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (5.8s)
-- Generating done (0.1s)

\build>cmake --build .
[ 50%] Building CXX object CMakeFiles/QtAppExample.dir/main.cpp.obj
[100%] Linking CXX executable QtAppExample.exe
[100%] Built target QtAppExample

My Idea, My Solution.

0

@R7YM: jeżeli osiągnąłeś swój cel na teraz to OK choc mi to wyglada na spory kompromis skoro sam napisałeś

nie do końca odpowiada moim oczekiwaniom

, jeżeli zamierzasz dalej używać C++ a w raz z nim Qt to powinieneś zrozumieć cmake i starać sie używać standardów obowiązujących w danym momencie.

Uzycie Qt5 dzisiaj jest uzasadnione tylko wtedy gdy masz jakis bardzo stary projekt i go kontynuujesz , nawet chatgpt odpowiada juz w Qt6 😉
W smietniku jakim jest Internet jest masa kiepskich przykladów np. uzycie qt5_wrap_ui wydaje mi sie tutaj nie na miejscu na tym poziomie, lepiej na początek obejrzeć przykłady ktore sa w QtCreator (każdy działa)
Uzywasz kompilatora z CodeBlocks jak Qt instaluje kompilator dedykowany do danej wersji Qt , jeżeli to działa dzisiaj to nie znaczy że będzie zawsze

Generalnie zajmujesz sie rozwiązywaniem nieistniejących* problemów zamiast skupić się na poznawaniu biblioteki

nieistniejących* = sam je stworzyłeś, normalnie one nie istnieją jak używasz QtCreator ;)

2

najlepiej zacznij od przykładu z dokumentacji i na tej podstawie popraw do swojego kodu:
https://doc.qt.io/qt-5/cmake-get-started.html

cmake_minimum_required(VERSION 3.1.0)

project(helloworld VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

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

if(CMAKE_VERSION VERSION_LESS "3.7.0")
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()

find_package(Qt5 COMPONENTS Widgets REQUIRED)

add_executable(helloworld
    mainwindow.ui
    mainwindow.cpp
    main.cpp
    resources.qrc
)

target_link_libraries(helloworld Qt5::Widgets)
0

@MarekR22
I appreciate.
pomimo naniesionych poprawek, dalej jest "fatal error", co jest dziwne, wyjaśnienie zamieszczam trochę niżej odnosząc się do zarzutów wysuniętych przez @Marius.Maximus z którymi się nie do końca zgadzam.

build>cmake --build . --config Release
[ 16%] Automatic MOC and UIC for target FirstPro
[ 16%] Built target FirstPro_autogen
[ 33%] Generating ui_mainwindow.h
[ 50%] Building CXX object CMakeFiles/FirstPro.dir/FirstPro_autogen/mocs_compilation.cpp.obj
[ 66%] Building CXX object CMakeFiles/FirstPro.dir/mainwindow.cpp.obj
C:\Users\2025\Desktop\QtStudentAddFile\mainwindow.cpp:2:10: fatal error: ui_mainwindow.h: No such file or directory
 #include "ui_mainwindow.h"
          ^~~~~~~~~~~~~~~~~
compilation terminated.
mingw32-make.exe[2]: *** [CMakeFiles\FirstPro.dir\build.make:95: CMakeFiles/FirstPro.dir/mainwindow.cpp.obj] Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:83: CMakeFiles/FirstPro.dir/all] Error 2
mingw32-make.exe: *** [Makefile:90: all] Error 2

powinieneś zrozumieć cmake i starać sie używać standardów obowiązujących w danym momencie

Rozumiem, że zrozumienie CMake i przestrzeganie obowiązujących standardów jest ważne, obecnie się nim zajmuję i uczę się na bieżąco.
Postaram się w miarę prosto wyjaśnić twoje nieprawdziwe założenie.
Tworząc najprostszy program w QTCreator. Tworzy on plik nazwijmy go "mainwindow.ui"
jak zajrzysz do niego ujrzysz że jest to xml . Co robi CMake czy qmake ? konwertuje ten plik na "ui_mainwindow.h"
jak zajrzysz do tego pliku ujrzysz, że jest tam klasa generowana automatycznie przez narzędzie uic (Qt User Interface Compiler)
na podstawie pliku *.ui
Plik ten "ui_mainwindow.h" zawiera definicję interfejsu użytkownika w aplikacji Qt.
Na podstawie tej klasy stworzyłem swoją prostszą z deklaracja wskaźników do widżetów co pozwoliło mi na nie używanie pliku "mainwindow.ui"
i zbudowanie programu.

taka ciekawostka, w python'ie z qt6 można zrobić podobnie
dołączy plik uic.loadUi('my_file.ui', self)
lub przekonwertować
pyuic6 -x my_file.ui -o my_file.py

1
 #include "ui_mainwindow.h"

include z "" to odwołujesz się gdzieś w lokalnym katalogu, w cmake jak tworzysz sobie bibliotekę to lokalizacja jest dodawana przez -I w make file w ninja nie wiem jak, i normalnie możesz <ui_mainwindow.h> dać, wtedy się odwoła program nie przez lokalny folder, a przez path dodany przez -I parametr, który cmake zrobi.

Też nie wiem do końca jestem pewny, może to coś jeszcze innego, ale cmake tworzy skrypt, który potem inny silnik typu make, ninja wykorzystuje do budowania aplikacji, jak make znasz to popatrz jaki plik make się wygenerował i jak umiesz dobrze makefile to łatwiej ci będzie problem zdjagnozować ja tak robiłem wiele razy, generowałem z cmake makefile z logami i patrzyłem czy plik jest taki jak bym ten program chciał ręcznie kompilować, bo cmake jest znacznie bardziej generyczny on generuje instrukcje do innych systemów budowania, np. make czy ninja, które potem są czytelne bardzo dobrze dla człowieka i to można analizować i zobaczyć gdzie ten program wyżej popełnił bład.

Ja tak robiłem i to rzeczywiście działa bo na najniższym poziomie to bez problemu idzie ręcznie skompilować jak ręcznie zrobisz, bardzo wysoko poziomowo zrobisz czyli przez jakieś ide co za ciebie zrobi wszystko, wtedy nic nie wiesz jak coś działa, to średnio/nisko poziomowo gdzie jakiś skrypt ci generuje pośredni skrypt to dasz radę wydedukować co jest źle.
Make wykonuje taki kod jakbyś ręcznie w konsoli gcc/g++ wywołał i dalego jest taki prosty makefile.

0

@R7YM: zainstalowałem sobie codeblocks aby zrobić podobne zamieszanie jak na Twoim kompie
uzylem CMakeLists.txt z postu @MarekR22
uzylem cmake z lini poleceń
i u mnie wszystko działa

Musiałbyś zrobić kompletny przykład

blad fatal error: ui_mainwindow.h: No such file or directory u mnie jest zawsze jak zapomnę o tym co podałem w pierwszym poscie

U ciebie widzę

[ 16%] Automatic MOC and UIC for target FirstPro
[ 16%] Built target FirstPro_autogen
[ 33%] Generating ui_mainwindow.h

wiec wiec plik raczej sie generuje tylko cos jest zamotane w innym miejscu

Jak skasuje set(CMAKE_AUTO... ON)

C:\Users\max\Documents\untitled103\build\Desktop>C:\Qt\Tools\CMake_64\bin\cmake.exe --build . --config Release
[ 33%] Building CXX object CMakeFiles/helloworld.dir/mainwindow.cpp.obj
C:\Users\max\Documents\untitled103\mainwindow.cpp:2:10: fatal error: ./ui_mainwindow.h: No such file or directory
 #include "./ui_mainwindow.h"
          ^~~~~~~~~~~~~~~~~~~
compilation terminated.

A nie masz przypadkiem w PATH kilku kompilatorów, Qt albo innych dziwnych narzedzi

Zrób wszystko w BAT gdzie na pcozatku ustawisz
set PATH=C:\CodeBlocks\MinGW\bin

1

już poprawiłem też CMakeLists.txt i teraz już nie muszę ręcznie budować klasy z GUI. Oto poprawiona wersja

# Ustawienie minimalnej wersji CMake
cmake_minimum_required(VERSION 3.28)

# Ustawienie wersji projektu i nazwy projektu
project(Student)

# Ustawienie ścieżki do MinGW
set(CMAKE_C_COMPILER "C:/CodeBlocks/MinGW/bin/gcc.exe")
set(CMAKE_CXX_COMPILER "C:/CodeBlocks/MinGW/bin/g++.exe")

# Ścieżka do Qt
set(Qt5_DIR "C:/Qt/Qt5.14.2/5.14.2/mingw73_64/lib/cmake/Qt5")

# Znalezienie Qt
find_package(Qt5 REQUIRED COMPONENTS Widgets)

# Włącza automatyczne przetwarzanie plików .ui
set(CMAKE_AUTOUIC ON)

# Włącza automatyczne przetwarzanie plików .cpp
set(CMAKE_AUTOMOC ON)

# Włącza automatyczne przetwarzanie plików .qrc
set(CMAKE_AUTORCC ON)

# Źródła
set(SOURCES
    main.cpp
    mainwindow.cpp
)

# Nagłówki
set(HEADERS
    mainwindow.h
)

# UI
set(UI_FILES
    mainwindow.ui
)

# Tworzenie pliku wykonywalnego
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${UI_FILES})

# Łączenie z bibliotekami Qt
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)

# Ustawienie standardu C++
set(CMAKE_CXX_STANDARD 17)

uruchamiam konsole w windows cmd
wchodzę do katalogu / folderu z projektem
tworze w nim nowy folder / katalog:
mkdir build
cd build
i wydaje polecenia

C:\Users\2025\Desktop\QtStudentAddFile\build>cmake .. -G "MinGW Makefiles"
-- The C compiler identification is GNU 8.1.0
-- The CXX compiler identification is GNU 8.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/CodeBlocks/MinGW/bin/gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/CodeBlocks/MinGW/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (4.0s)
-- Generating done (0.2s)
-- Build files have been written to: C:/Users/2025/Desktop/QtStudentAddFile/build

C:\Users\2025\Desktop\QtStudentAddFile\build>cmake --build . --config Release
[ 20%] Automatic MOC and UIC for target Student
[ 20%] Built target Student_autogen
[ 40%] Building CXX object CMakeFiles/Student.dir/Student_autogen/mocs_compilation.cpp.obj
[ 60%] Building CXX object CMakeFiles/Student.dir/main.cpp.obj
[ 80%] Building CXX object CMakeFiles/Student.dir/mainwindow.cpp.obj
[100%] Linking CXX executable Student.exe
[100%] Built target Student

dziękuję wszystkim za zaangażowanie i przyczynienie się swoimi uwagami do mojego małego sukcesu

1

Pamiętaj o zasięgu zmiennych ,
CMAKE_CXX_STANDARD zaczyna działać od miejsca gdzie ja wpisałeś
tam gdzie jest teraz nie ma znaczenia dla projektu

Dlatego sugeruje używanie na początku QtCreatora, opatrzysz się przykłady to intuicyjnie będziesz wybierał poprawne rozwiązania,
trochę jak pamięcią mięśniowa w technicznych sportach "Trening czyni mistrza"

1
R7YM napisał(a):
# Ustawienie ścieżki do MinGW
set(CMAKE_C_COMPILER "C:/CodeBlocks/MinGW/bin/gcc.exe")
set(CMAKE_CXX_COMPILER "C:/CodeBlocks/MinGW/bin/g++.exe")

# Ścieżka do Qt
set(Qt5_DIR "C:/Qt/Qt5.14.2/5.14.2/mingw73_64/lib/cmake/Qt5")

Ta część to bardzo bardzo zła praktyka.
To powoduje, że ten projekt można zbudować tylko na komputerze z identyczna konfigurację jak twoja. Praktycznie tylko na twoim komputerze.
Qt i CMake są wieloplatformowe, ergo powinno tez działać bez problemu na MacOS i Linux.

Wnerwia mnie też target_link_libraries(${PROJECT_NAME}.
To bardzo pogarsza czytelność i łączy ze sobą nazwy w niepotrzebny sposób.

0

Ta część to bardzo bardzo zła praktyka.

# Ustawienie ścieżki do MinGW
set(CMAKE_C_COMPILER "C:/CodeBlocks/MinGW/bin/gcc.exe")
set(CMAKE_CXX_COMPILER "C:/CodeBlocks/MinGW/bin/g++.exe")

# Ścieżka do Qt
set(Qt5_DIR "C:/Qt/Qt5.14.2/5.14.2/mingw73_64/lib/cmake/Qt5")

zamieniłem na

# Dodanie lokalizacji do zmiennej CMAKE_PREFIX_PATH
set(CMAKE_PREFIX_PATH "C:/Qt/Qt5.14.2/5.14.2/mingw73_64")
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets)

aktualnie CMakeLists.txt

# Ustawienie minimalnej wersji CMake
cmake_minimum_required(VERSION 3.28)

# Ustawienie wersji projektu i nazwy projektu
project(Student VERSION 0.1)

# Ustawienie standardu C++
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Dodanie lokalizacji do zmiennej CMAKE_PREFIX_PATH
set(CMAKE_PREFIX_PATH "C:/Qt/Qt5.14.2/5.14.2/mingw73_64")
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets)

# Włącza automatyczne przetwarzanie plików .ui
set(CMAKE_AUTOUIC ON)

# Włącza automatyczne przetwarzanie plików .cpp
set(CMAKE_AUTOMOC ON)

# Włącza automatyczne przetwarzanie plików .qrc
set(CMAKE_AUTORCC ON)

# Źródła
set(SOURCES
    main.cpp
    mainwindow.cpp
)

# Nagłówki
set(HEADERS
    mainwindow.h
)

# UI
set(UI_FILES
    mainwindow.ui
)

# Tworzenie pliku wykonywalnego
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${UI_FILES})

# Łączenie z bibliotekami Qt
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)

Wnerwia mnie też target_link_libraries(${PROJECT_NAME}.

nie wiem czym można by zastąpić

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.