qmake je orodje za gradnjo sistema, ki je priloženo Knjižnica Qt ki poenostavlja postopek izdelave na različnih platformah. Za razliko CMake in Qbs , qmake je bil del Qt že od samega začetka in bo veljal za 'domače' orodje. Ni treba posebej poudarjati, da je privzeti IDE Qt - Qt Creator - ima najboljšo podporo za qmake out of the box. Da, tam lahko izberete tudi CMake in Qbs gradbene sisteme za nov projekt, vendar ti niso tako dobro integrirani. Verjetno se bo podpora CMake v programu Qt Creator sčasoma izboljšala, kar bo dober razlog za izdajo druge izdaje tega vodnika, namenjenega posebej CMake. Tudi če ne nameravate uporabljati Qt Creator, boste morda vseeno želeli qmake obravnavati kot drugi sistem gradnje, če gradite javne knjižnice ali vtičnike. Skoraj vse neodvisne knjižnice ali vtičniki, ki temeljijo na Qt, zagotavljajo datoteke qmake, ki se uporabljajo za nemoteno integracijo v projekte, ki temeljijo na qmake. Le nekaj jih ponuja dvojno konfiguracijo, npr. Qmake in CMake. Morda raje uporabite qmake, če za vas velja naslednje:
Ta priročnik opisuje najbolj uporabne funkcije qmake in ponuja resnične primere za vsako od njih. Bralci, ki so novi v Qt, lahko ta priročnik uporabijo kot vadnico Qt-ovega sistema gradnje. Razvijalci Qt lahko to obravnava kot kuharsko knjigo pri zagonu novega projekta ali pa lahko nekatere funkcije selektivno uporabi pri katerem koli od obstoječih projektov z majhnim učinkom.
Specifikacija qmake je zapisana v .pro
(»Projektne«) datoteke. To je primer najpreprostejšega možnega .pro
mapa:
SOURCES = hello.cpp
Privzeto bo to ustvarilo Makefile
ki bi zgradil izvedljivo datoteko iz ene datoteke izvorne kode hello.cpp
.
Če želite zgraditi binarno datoteko (v tem primeru izvedljivo), morate najprej zagnati qmake, da ustvarite datoteko Makefile, nato pa make
(ali nmake
ali mingw32-make
, odvisno od vaše orodne verige) za izdelavo cilja.
Na kratko, specifikacija qmake ni nič drugega kot seznam definicij spremenljivk, pomešanih z neobveznimi stavki krmilnega toka. Vsaka spremenljivka ima na splošno seznam nizov. Stavki nadzornega toka vam omogočajo, da vključite druge specifikacijske datoteke qmake, nadzorujete pogojne odseke in celo klicne funkcije.
Ko se učite obstoječih projektov qmake, boste morda presenečeni, kako se lahko sklicujete na različne spremenljivke: (VAR, ) (VAR) ali $$ (VAR) ...
Med sprejemanjem pravil uporabite to mini varalnico:
VAR = value
Dodelite vrednost VARVAR += value
Dodaj vrednost na seznam VARVAR -= value
Odstranite vrednost s seznama VAR$$VAR
ali $${VAR}
Pridobi vrednost VAR v času, ko se izvaja qmake$(VAR)
Vsebina okolja VAR v času, ko se izvaja datoteka Makefile (ne qmake)$$(VAR)
Vsebina okolja VAR v času, ko se izvaja qmake (ne Makefile)Celoten seznam spremenljivk qmake najdete v specifikaciji: http://doc.qt.io/qt-5/qmake-variable-reference.html
Oglejmo si nekaj pogostih predlog za projekte:
# Windows application TEMPLATE = app CONFIG += windows # Shared library (.so or .dll) TEMPLATE = lib CONFIG += shared # Static library (.a or .lib) TEMPLATE = lib CONFIG += static # Console application TEMPLATE = app CONFIG += console
Samo dodaj VIRI + = ... in GLAVE + =… za seznam vseh datotek z izvorno kodo in ste končali.
Do zdaj smo pregledali zelo osnovne predloge. Bolj zapleteni projekti običajno vključujejo več podprojektov, ki so medsebojno odvisni. Poglejmo, kako to upravljati s pomočjo qmake.
Najpogostejši primer uporabe je aplikacija, ki je priložena eni ali več knjižnicam in testnim projektom. Upoštevajte naslednjo strukturo:
/project ../library ..../include ../library-tests ../application
Očitno si želimo, da bi lahko zgradili vse naenkrat, takole:
cd project qmake && make
Da bi dosegli ta cilj, potrebujemo datoteko projekta qmake pod /project
mapa:
TEMPLATE = subdirs SUBDIRS = library library-tests application library-tests.depends = library application.depends = library
OPOMBA: z uporabo CONFIG += ordered
se šteje za slabo prakso - raje uporabite .depends
namesto tega.
Ta specifikacija naroča qmakeu, da najprej izdela podprojekt knjižnice, ker so od njega odvisni drugi cilji. Potem lahko gradi library-tests
in prijavo v poljubnem vrstnem redu, ker sta ti dve odvisni.
V zgornjem primeru imamo knjižnico, ki jo je treba povezati z aplikacijo. V C / C ++ to pomeni, da moramo konfigurirati še nekaj stvari:
-I
zagotoviti poti iskanja za direktive #include.-L
za zagotavljanje iskalnih poti za povezovalnik.-l
zagotoviti tisto, kar mora knjižnica povezati.Ker želimo, da so vsi podprojekti premični, ne moremo uporabljati absolutnih ali relativnih poti. Na primer, tega ne bomo storili: INCLUDEPATH + = ../library/include in seveda se ne moremo sklicevati na binarno datoteko knjižnice (.a datoteka) iz začasne mape gradnje. Po načelu ločevanja pomislekov lahko hitro ugotovimo, da se datoteka prijavnega projekta povzema iz knjižničnih podrobnosti. Namesto tega je knjižnica odgovorna, da pove, kje najti datoteke glav itd.
Izkoristimo qmake’s include()
direktivo za rešitev tega problema. V projektu knjižnice bomo v novo datoteko s pripono .pri
dodali še eno specifikacijo qmake (razširitev je lahko karkoli, tukaj pa i
pomeni vključiti). Torej, knjižnica bi imela dve specifikaciji: library.pro
in library.pri
. Prvi se uporablja za gradnjo knjižnice, drugi pa za zagotavljanje vseh podrobnosti, ki jih potrebuje zahteven projekt.
Vsebina datoteke library.pri bi bila naslednja:
LIBTARGET = library BASEDIR = $${PWD} INCLUDEPATH *= $${BASEDIR}/include LIBS += -L$${DESTDIR} -llibrary
BASEDIR
določa mapo projekta knjižnice (natančneje, lokacija trenutne specifikacijske datoteke qmake, ki je v našem primeru library.pri
). Kot ugibate, INCLUDEPATH
bo ocenjeno na /project/library/include
. DESTDIR
je imenik, kamor sistem za gradnjo postavlja izhodne artefakte, na primer (.o .a .so .dll ali .exe datoteke). To je običajno konfigurirano v vašem IDE, zato nikoli ne smete postavljati predpostavk, kje so izhodne datoteke.
V application.pro
datoteko samo dodajte include(../library/library.pri)
in končali ste.
Oglejmo si, kako se v tem primeru gradi aplikacijski projekt:
project.pro
je projekt poddirekt. Pove nam, da je najprej treba zgraditi projekt knjižnice. Torej qmake vstopi v mapo knjižnice in jo gradi z uporabo library.pro
. Na tej stopnji je library.a
se izdela in postavi v DESTDIR
mapo.application.pro
mapa. Ugotovi include(../library/library.pri)
direktivo, ki qmakeu nalaga, da jo takoj prebere in razlaga. To doda nove definicije INCLUDEPATH
in LIBS
spremenljivke, tako da zdaj prevajalnik in povezovalnik vesta, kje je treba poiskati vključene datoteke, binarne datoteke knjižnice in katero knjižnico povezati.Izpustili smo gradnjo projekta knjižničnih preizkusov, vendar je enak projektu prijave. Očitno bi moral tudi naš testni projekt povezati knjižnico, ki naj bi jo testiral.
S to nastavitvijo lahko projekt knjižnice enostavno premaknete v drug projekt qmake in ga vključite ter se tako sklicujete na .pri
mapa. Skupnost natančno tako distribuira neodvisne knjižnice.
config.pri
Zapleteni projekt ima zelo pogosto nekaj skupnih konfiguracijskih parametrov, ki jih uporabljajo številni podprojekti. Da se izognete podvajanju, lahko znova uporabite include()
direktivo in ustvari config.pri
v zgornji mapi. Morda imate tudi skupne »pripomočke« qmake, ki jih delite s svojimi podprojekti, podobno kot bomo obravnavali v tem priročniku.
Pogosto imajo projekti nekatere 'druge' datoteke, ki jih je treba distribuirati skupaj s knjižnico ali aplikacijo. Vse take datoteke moramo samo kopirati v DESTDIR
med postopkom gradnje. Upoštevajte naslednji delček:
defineTest(copyToDestDir) { files = $ for(FILE, files) { DDIR = $$DESTDIR FILE = $$absolute_path($$FILE) # Replace slashes in paths with backslashes for Windows win32:FILE ~= s,/,\,g win32:DDIR ~= s,/,\,g QMAKE_POST_LINK += $$QMAKE_COPY $$quote($$FILE) $$quote($$DDIR) $$escape_expand(\n\t) } export(QMAKE_POST_LINK) }
Opomba: S tem vzorcem lahko določite lastne funkcije za večkratno uporabo, ki delujejo na datotekah.
To kodo postavite v /project/copyToDestDir.pri
tako da lahko include()
zahtevne podprojekte, kot sledi:
include(../copyToDestDir.pri) MYFILES += parameters.conf testdata.db ## this is copying all files listed in MYFILES variable copyToDestDir($$MYFILES) ## this is copying a single file, a required DLL in this example copyToDestDir($${3RDPARTY}/openssl/bin/crypto.dll)
Opomba: DISTFILES je bil predstavljen za isti namen, vendar deluje le v Unixu.
Odličen primer ustvarjanja kode kot vnaprej izdelanega koraka je, ko projekt C ++ uporablja Googlov protobuf. Poglejmo, kako si lahko vbrizgamo protoc
izvedbo v gradbeni postopek.
Primerno rešitev lahko preprosto najdete v Googlu, vendar se morate zavedati enega pomembnega primera. Predstavljajte si, da imate dve pogodbi, pri čemer se A sklicuje na B.
A.proto <= B.proto
Če bi ustvarili kodo za A.proto
najprej (da ustvari A.pb.h
in A.pb.cxx
) in ga posreduje prevajalniku, bo le spodletelo, ker je odvisnost B.pb.h
še ne obstaja. Da bi to rešili, moramo pred gradnjo nastale izvorne kode opraviti vse faze generiranja proto kode.
Tu sem našel odličen delček za to nalogo: https://github.com/jmesmon/qmake-protobuf-example/blob/master/protobuf.pri
To je precej velik skript, vendar bi ga že morali vedeti:
PROTOS = A.proto B.proto include(protobuf.pri)
Ko preučujete protobuf.pri
, boste morda opazili splošni vzorec, ki ga je mogoče enostavno uporabiti za katero koli prevajanje po meri ali generiranje kode:
my_custom_compiler.name = my custom compiler name my_custom_compiler.input = input variable (list) my_custom_compiler.output = output file path + pattern my_custom_compiler.commands = custom compilation command my_custom_compiler.variable_out = output variable (list) QMAKE_EXTRA_COMPILERS += my_custom_compiler
Pogosto moramo definirati deklaracije posebej za določeno platformo, na primer Windows ali MacOS. Qmake ponuja tri vnaprej določene kazalnike platforme: win32, macx in unix. Tu je sintaksa:
win32 { # add Windows application icon, not applicable to unix/macx platform RC_ICONS += icon.ico }
Obsegi so lahko ugnezdeni, lahko se uporabljajo operatorji !
, |
in celo nadomestne znake:
macx:debug { # include only on Mac and only for debug build HEADERS += debugging.h } win32|macx { HEADERS += windows_or_macx.h } win32-msvc* win32-mscv.net
Opomba: Unix je definiran v sistemu Mac OS! Če želite preizkusiti sistem Mac OS (ne generični Unix), uporabite unix:!macx
stanje.
V programu Qt Creator so pogoji obsega debug
in release
ne delujejo po pričakovanjih. Če želite pravilno delovati, uporabite naslednji vzorec:
CONFIG(debug, debug|release) { LIBS += ... } CONFIG(release, debug|release) { LIBS += ... }
Qmake ima številne vdelane funkcije, ki dodajajo več avtomatizacije.
Prvi primer je files()
funkcijo. Ob predpostavki, da imate korak generiranja kode, ki ustvari spremenljivo število izvornih datotek. Tukaj je opisano, kako jih lahko vse vključite v SOURCES
SOURCES += $$files(generated/*.c)
Tu bodo našli vse datoteke s pripono .c
v podmapi generated
in jih dodajte v SOURCES
spremenljivka.
Drugi primer je podoben prejšnjemu, zdaj pa je generacija kode ustvarila besedilno datoteko, ki vsebuje imena izhodnih datotek (seznam datotek):
SOURCES += $$cat(generated/filelist, lines)
S tem boste le prebrali vsebino datoteke in vsako vrstico obravnavali kot vnos za SOURCES
.
Opomba: Celoten seznam vdelanih funkcij najdete tukaj: http://doc.qt.io/qt-5/qmake-function-reference.html
Naslednji delček uporablja prej opisano funkcijo pogojnega obsega:
*g++*: QMAKE_CXXFLAGS += -Werror *msvc*: QMAKE_CXXFLAGS += /WX
Razlog za to je, ker ima MSVC drugačno zastavico, ki omogoča to možnost.
Naslednji delček je uporaben, ko morate ustvariti definicijo predprocesorja, ki vsebuje trenutno različico SW, pridobljeno iz Gita:
DEFINES += SW_VERSION=\'$$system(git describe --always --abbrev=0)\'
To deluje na kateri koli platformi, dokler je git
ukaz je na voljo. Če uporabljate oznake Git, bo ta pokukala najnovejšo oznako, čeprav je veja šla naprej. Spremenite git describe
ukaz, da dobite izhod po vaši izbiri.
Qmake je odlično orodje, ki je osredotočeno na gradnjo vaših medplatformnih projektov, ki temeljijo na Qt. V tem priročniku smo pregledali osnovno uporabo orodij in najpogosteje uporabljene vzorce, zaradi katerih bo struktura vašega projekta fleksibilna, specifikacije zgradbe pa bodo enostavne za branje in vzdrževanje.
Se želite naučiti, kako izboljšati svojo aplikacijo Qt? Poskusite: Kako dobiti zaobljene vogalne oblike v jeziku C ++ z uporabo Bezierjevih krivulj in QPainterja: Vodnik po korakih
Qt je okvir za razvoj različnih platform za namizne, vdelane in mobilne naprave. Podprte platforme vključujejo Linux, OS X, Windows, VxWorks, QNX, Android, iOS, BlackBerry, Sailfish OS in druge.
Qt je napisan v jeziku C ++, zato je C ++ najboljši programski jezik, ki mu omogoča, da izkoristi vse prednosti okolja. Vendar obstajajo povezave za druge jezike, kot je Python (https://wiki.python.org/moin/PyQt).
Qt ima bogat licenčni model, ki vključuje Commercial, LGPL3 in GPLv2 (ali odprtokodni).
Aplikacija Qt je programska oprema, zgrajena z ogrodjem Qt.
CMake in Make imata veliko skupnih idej, CMake pa je veliko naprednejše orodje. Toda v bistvu imata ta dva enak namen.
CMake je še eno orodje za gradnjo, ki ga skupnost pogosto uporablja, saj CMake ni prevajalnik.
Qmake ustvari datoteko Make na podlagi informacij v datoteki projekta. Projektne datoteke ustvari razvijalec in so navadno preproste, za bolj zapletene projekte pa je mogoče ustvariti bolj dovršene projektne datoteke.