Редактирование: Undocumented qmake

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 2: Строка 2:
qmake очень мощная "meta-make" система, которая может быть использована для создания makefile для различных компиляторов и платформ из одного и того же файла проекта qmake (.pro). Но в документации по qmake отсутствует много информации - есть много, очень много вариантов, которые просто не описаны в Trolltech документации. Эта страница призвана помочь с этими примерами. (Заметим, что эта информация относится к Qt4; возможно будет работать в Qt3, но не факт.)
qmake очень мощная "meta-make" система, которая может быть использована для создания makefile для различных компиляторов и платформ из одного и того же файла проекта qmake (.pro). Но в документации по qmake отсутствует много информации - есть много, очень много вариантов, которые просто не описаны в Trolltech документации. Эта страница призвана помочь с этими примерами. (Заметим, что эта информация относится к Qt4; возможно будет работать в Qt3, но не факт.)
-
== Недокументированные переменные ==
+
== Undocumented variables ==
The simplest sort of control that you can get over your generated makefile is by using the built-in variables that qmake provides. Of course, the challenge is that many of those variables are not listed in the documentation for qmake. But... you have a handy list of them all right there (along with a rich source of tricks and hacks written by the Trolls - I have mined it extensively for this page). In your qmake installation directory is a subdirectory called "mkspecs". This contains the definitions for all the platform/compiler combinations that qmake supports (note that not all of them are "formally" supported!) There are directories named "features" at various points within this tree; in there you will find qmake code for many of the things you can enable via the CONFIG variable.
The simplest sort of control that you can get over your generated makefile is by using the built-in variables that qmake provides. Of course, the challenge is that many of those variables are not listed in the documentation for qmake. But... you have a handy list of them all right there (along with a rich source of tricks and hacks written by the Trolls - I have mined it extensively for this page). In your qmake installation directory is a subdirectory called "mkspecs". This contains the definitions for all the platform/compiler combinations that qmake supports (note that not all of them are "formally" supported!) There are directories named "features" at various points within this tree; in there you will find qmake code for many of the things you can enable via the CONFIG variable.
Строка 8: Строка 8:
Here are a few particularly useful ones I have come across only by digging through the qmake source (and the first version they are confirmed to exist in):  
Here are a few particularly useful ones I have come across only by digging through the qmake source (and the first version they are confirmed to exist in):  
-
*  _DATE_ — текущая дата и время. (v4.3.4)
+
*  _DATE_ — the current date and time. (v4.3.4)
-
* _FILE_ — имя файла в данный момент обрабатываемого [[Qt:Документация 4.3.2/qmake-manual|qmake]]. (v4.3.4)
+
* _FILE_ — the current file name being parsed by qmake. (v4.3.4)
-
* _LINE_ — the current line number being parsed by [[Qt:Документация 4.3.2/qmake-manual|qmake]]. (v4.3.4)
+
* _LINE_ — the current line number being parsed by qmake. (v4.3.4)
* _QMAKE_CACHE_ — the path to any .qmake.cache file in use. (v4.3.4)
* _QMAKE_CACHE_ — the path to any .qmake.cache file in use. (v4.3.4)
* IN_PWD — the base directory of the source tree. (v4.3.4)
* IN_PWD — the base directory of the source tree. (v4.3.4)
-
* PWD — Текущий рабочий каталог. Be aware that this is not necessarily either the location of the .pro file, or the current qmake (.pri?) file - it's the directory the user was in when they invoked qmake. (v4.3.4)
+
* PWD — the current working directory. Be aware that this is not necessarily either the location of the .pro file, or the current qmake (.pri?) file - it's the directory the user was in when they invoked qmake. (v4.3.4)
* OUT_PWD — indicates the output directory that the current target will be written to. In normal usage, OUT_PWD will be the same as IN_PWD, unless you are attempting an out-of-source build - in which case it will indicate the base directory of the build tree. Not to be confused with DESTDIR, which indicates the directory relative to OUT_PWD in which to place the build target. (v4.3.4)
* OUT_PWD — indicates the output directory that the current target will be written to. In normal usage, OUT_PWD will be the same as IN_PWD, unless you are attempting an out-of-source build - in which case it will indicate the base directory of the build tree. Not to be confused with DESTDIR, which indicates the directory relative to OUT_PWD in which to place the build target. (v4.3.4)
* QMAKE_HOST — a compound variable containing details about the OS in use: (v4.3.4)
* QMAKE_HOST — a compound variable containing details about the OS in use: (v4.3.4)
Строка 27: Строка 27:
*** Win2003 (maybe??)
*** Win2003 (maybe??)
*** WinXP
*** WinXP
-
*** WinVista
+
*** WinVista  
-
== Пользовательские функции ==
+
== Custom functions ==
qmake distinguishes two types of function :
qmake distinguishes two types of function :
* conditional functions that may take parameters and return true or false. They can be used much like scopes to customize your projects depending to some configuration features, file availability...
* conditional functions that may take parameters and return true or false. They can be used much like scopes to customize your projects depending to some configuration features, file availability...
Строка 37: Строка 37:
* defineTest(nameOfTestFunction),
* defineTest(nameOfTestFunction),
* defineReplace(nameOfDataProcessingFunction).  
* defineReplace(nameOfDataProcessingFunction).  
-
Whatever the type of function you define, the above strings have to be followed by a '{' on the same line as the defineX statement. It indeed appears that, as with scopes and conditionnals, qmake gets mad when the bracket isn't on the same line... To return from the function, the return(value) function is used, and, of course, the function definition ends with a '}'.
+
Whatever the type of function you define, the above strings have to be followed by a '{' on the same line as the defineX statement. It indeed appears that, as with scopes and conditionnals, qmake gets mad when the bracket isn't on the same line... To return from the function, the return(value) function is used, and, of course, the function definition ends with a '}'.  
-
== Пользовательские инструменты ==
+
== Custom tools ==
The documentation for qmake in Qt4 briefly mentions the possibility of custom "compilers", but not much information is given to describe this.
The documentation for qmake in Qt4 briefly mentions the possibility of custom "compilers", but not much information is given to describe this.
Строка 110: Строка 110:
</source>
</source>
-
This tool simply outputs the contents of the CXXFLAGS variable to a file called "compile.inp". Since this tool is meant to generate a file of a fixed name, the variable passed into .input contains only "." (current directory) which will always exist (but is not used anywhere in the rule). The construct \$(foo) is used in this rule. This construct outputs a GNU Make or NMAKE format variable expansion, basically delaying the expansion of the variable until make or NMAKE is called on the generated makefile.
+
This tool simply outputs the contents of the CXXFLAGS variable to a file called "compile.inp". Since this tool is meant to generate a file of a fixed name, the variable passed into .input contains only "." (current directory) which will always exist (but is not used anywhere in the rule). The construct \$(foo) is used in this rule. This construct outputs a GNU Make or NMAKE format variable expansion, basically delaying the expansion of the variable until make or NMAKE is called on the generated makefile.  
-
== Особенности конфигурации ==
+
== Config features ==
There are also several "switches" which can be added to the CONFIG variable which affect various behaviours of qmake. The ones that I have uncovered are as follows (note that this doesn't include CONFIG features specific to custom tools or installers):
There are also several "switches" which can be added to the CONFIG variable which affect various behaviours of qmake. The ones that I have uncovered are as follows (note that this doesn't include CONFIG features specific to custom tools or installers):
* app_bundle — makes the target into a bundle, instead of a standalone executable (Mac only),
* app_bundle — makes the target into a bundle, instead of a standalone executable (Mac only),
Строка 144: Строка 144:
Another interesting functionality of qmake, at least since Qt4, is that it features an (undocumented) "config" switch that modify the value of the CONFIG variable on run-time without changing the content of the processed file. This is especially useful to replace build targets. Indeed qmake is unable to generate other build targets than the classic "release", "debug", "clean" and "install". As the CONFIG variable is checked when resolving scopes it allows to create complex project structure based on targets which remains human-readable...  
Another interesting functionality of qmake, at least since Qt4, is that it features an (undocumented) "config" switch that modify the value of the CONFIG variable on run-time without changing the content of the processed file. This is especially useful to replace build targets. Indeed qmake is unable to generate other build targets than the classic "release", "debug", "clean" and "install". As the CONFIG variable is checked when resolving scopes it allows to create complex project structure based on targets which remains human-readable...  
-
<source lang="xorg_conf">
+
<source lang="bash">
#sample project
#sample project
Строка 185: Строка 185:
This trick will used by Edyuk so as to allow the *.pro format ot become as powerful as well-known standards such as *.cbp, used by Code::Blocks, and *.vcproj, used by MSVC.  
This trick will used by Edyuk so as to allow the *.pro format ot become as powerful as well-known standards such as *.cbp, used by Code::Blocks, and *.vcproj, used by MSVC.  
-
== Проекты типа ''SUBDIRS'' ==
+
== SUBDIRS projects ==
SUBDIRS is a powerful method for breaking projects into smaller chunks. It's actually much more powerful than is indicated in the documentation, though.
SUBDIRS is a powerful method for breaking projects into smaller chunks. It's actually much more powerful than is indicated in the documentation, though.
Строка 196: Строка 196:
For example:
For example:
-
<source lang="xorg_conf">
+
<source lang="bash">
TEMPLATE = subdirs
TEMPLATE = subdirs
SUBDIRS = sub_lib sub_tests sub_app
SUBDIRS = sub_lib sub_tests sub_app
Строка 208: Строка 208:
This makes it possible to use make -j 4 on your fancy quad-core system with a project that consists of several components that depend on each other. To simplify the process a bit, the following test function can be defined:
This makes it possible to use make -j 4 on your fancy quad-core system with a project that consists of several components that depend on each other. To simplify the process a bit, the following test function can be defined:
-
<source lang="xorg_conf">
+
<source lang="bash">
# addSubdirs(subdirs,deps): Adds directories to the project that depend on
# addSubdirs(subdirs,deps): Adds directories to the project that depend on
# other directories
# other directories
Строка 227: Строка 227:
</source>
</source>
You can then use it like
You can then use it like
-
<source lang="xorg_conf">
+
<source lang="bash">
addSubdirs (contrib/*)
addSubdirs (contrib/*)
Строка 247: Строка 247:
* a main program that uses the gui and kernel libs
* a main program that uses the gui and kernel libs
* several modules that only depend on the kernel lib  
* several modules that only depend on the kernel lib  
-
and that compiles in parallel where possible.
+
and that compiles in parallel where possible.  
-
== Недокументированные режимы ==
+
== Undocumented modes ==
Apart from the well known "-project" and "-makefile" modes, qmake support a few other switches that can put it in different modes.
Apart from the well known "-project" and "-makefile" modes, qmake support a few other switches that can put it in different modes.
* -prl turn it into "prl generation mode". Quite honestly I don't know what that means. This is certainly related to the .prl files that are present in the $QTDIR/libs directory...
* -prl turn it into "prl generation mode". Quite honestly I don't know what that means. This is certainly related to the .prl files that are present in the $QTDIR/libs directory...
Строка 280: Строка 280:
User-defined properties are global to the system - they are not per-project. Under Win32, they are stored in the Registry at HKEY_CURRENT_USER\Software\Trolltech\QMake\2.00a.
User-defined properties are global to the system - they are not per-project. Under Win32, they are stored in the Registry at HKEY_CURRENT_USER\Software\Trolltech\QMake\2.00a.
-
You can also get the values of these variables by using $$[varname] (note the use of the square brackets).
+
You can also get the values of these variables by using $$[varname] (note the use of the square brackets).  
-
''Курсивное начертание''
+
-
== Недокументированные функции ==
+
== Undocumented functions ==
There are some very handy functions that do not appear in the Qt4 documentation. Some of these were not added until Qt 4.2, so beware...  
There are some very handy functions that do not appear in the Qt4 documentation. Some of these were not added until Qt 4.2, so beware...  
-
=== Тест-функции ===
+
== Test functions ==
These functions return true or false:
These functions return true or false:
* defined(func, type) — Returns true if func is defined; type must be either "test" or "replace", to match "defineTest" or "defineReplace".
* defined(func, type) — Returns true if func is defined; type must be either "test" or "replace", to match "defineTest" or "defineReplace".
Строка 295: Строка 294:
* lessThan(var1, var2) — Returns true if var1 is less than var2 (as an integer).  
* lessThan(var1, var2) — Returns true if var1 is less than var2 (as an integer).  
-
=== Program flow functions ===
+
== Program flow functions ==
These are test functions as far as qmake is concerned, but I felt they really belong in their own section:
These are test functions as far as qmake is concerned, but I felt they really belong in their own section:
* break() — Acts like a C break statement.
* break() — Acts like a C break statement.
Строка 304: Строка 303:
* unset(var) — Deletes the variable entirely (it will act as if it had never been set).  
* unset(var) — Deletes the variable entirely (it will act as if it had never been set).  
-
=== Replace functions ===
+
== Replace functions ==
These functions return a value:
These functions return a value:
* cat(file) — Returns the contents of the specified file.
* cat(file) — Returns the contents of the specified file.
Строка 325: Строка 324:
MIDPARMS will now contain "bar/dead".  
MIDPARMS will now contain "bar/dead".  
* split(var, sep) — This splits the specified variable at each occurrence of "sep", and returns the result.
* split(var, sep) — This splits the specified variable at each occurrence of "sep", and returns the result.
-
* upper(string) — Converts the string to upper case.
+
* upper(string) — Converts the string to upper case.  
-
== Недокументированные тонкости ==
+
== Undocumented niceties ==
qmake is a really powerful tool, if you were still a bit unsure of that, have a look :
qmake is a really powerful tool, if you were still a bit unsure of that, have a look :
* scopes can be nested but also combined using logical operators. The following lines are equivalent :  
* scopes can be nested but also combined using logical operators. The following lines are equivalent :  

Пожалуйста, обратите внимание, что все ваши добавления могут быть отредактированы или удалены другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см. Wiki.crossplatform.ru:Авторское право). НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!