Difference between revisions of "Macros and Conditionals/ru"

From Lazarus wiki
Jump to navigationJump to search
 
(15 intermediate revisions by the same user not shown)
Line 86: Line 86:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===Constants===
+
===Константы===
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
a := 1234; // decimal
+
a := 1234; // десятичная
a := $A1B; // hexadecimal
+
a := $A1B; // шестнадцатеричная
a := &127; // octal
+
a := &127; // восьмеричная
a := %101; // binary
+
a := %101; // двоичная
a := '10'; // string
+
a := '10'; // строковая
a := #123; // character
+
a := #123; // символьная
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===Operators===
+
===Операторы===
  
*'''+''': Two numbers are added, otherwise they are treated as strings and concatenated.
+
*'''+''': Два числа складываются, иначе они рассматриваются как строки и объединяются.
*'''<''', '''>''', '''<=''', '''>=''', '''=''', '''<>''': Two numbers are compared mathematically, otherwise they are treated as strings and compared lexicographically (case sensitive).
+
*'''<''', '''>''', '''<=''', '''>=''', '''=''', '''<>''': Два числа сравниваются математически, в противном случае они рассматриваются как строки и сравниваются лексикографически (с учетом регистра).
*'''not''': Unary boolean operator
+
*'''not''': Унарный (с изменением знака) логический оператор
*'''and''', '''or''', '''xor''': Boolean operators
+
*'''and''', '''or''', '''xor''': Логические операторы
*'''(''',''')''': Group operations
+
*'''(''',''')''': Групповые операторы
*''':=''': Assignment. Not allowed in expressions.
+
*''':=''': Присвоение. Не допускается в выражениях.
*'''+=''': Add and assign. Not allowed in expressions.
+
*'''+=''': Добавление и назначение. Не допускается в выражениях.
  
Precedence levels:
+
Уровни приоритета:
*1 Not and unary minus
+
*1 Not и унарный минус
 
*1 And
 
*1 And
 
*2 Or
 
*2 Or
Line 120: Line 120:
 
*4 >=
 
*4 >=
  
==Predefined Variables==
+
==Предопределенные переменные==
  
Before the conditionals script is run the IDE initializes a few variables:
+
Перед запуском условного сценария среда IDE инициализирует несколько переменных:
  
*'''TargetOS''': the project's target operating system as defined by fpc. e.g. 'linux', 'win32', 'darwin', 'freebsd', 'wince'.
+
*'''TargetOS''': целевая операционная система проекта, определенная fpc. например 'linux', 'win32', 'darwin', 'freebsd', 'wince'.
*'''TargetCPU''': the project's target processor as defined by fpc. e.g. 'i386', 'x86_64', 'arm'
+
*'''TargetCPU''': целевой процессор проекта, определенный fpc. например 'i386', 'x86_64', 'arm'
*'''SrcOS''': the value 'win' for all MS Windows platforms and 'unix' for all unix like platforms. The value depends on the TargetOS.
+
*'''SrcOS''': значение 'win' для всех платформ MS Windows и 'unix' для всех unix-подобных платформ. Значение зависит от TargetOS.
*'''SrcOS2''': the value 'bsd' for all BSD like platforms. The value depends on the TargetOS.
+
*'''SrcOS2''': значение 'bsd' для всех платформ, подобных BSD. Значение зависит от TargetOS.
*'''True''': value 1
+
*'''True''': значение 1
*'''False''': value 0
+
*'''False''': значение 0
*all build macros defined by the current project.
+
*все макросы сборки, определенные в текущем проекте.
*all build macros defined by used packages. That means if the project has not defined a value for a package macro the value of the conditionals of the used package will be used.
+
*все макросы сборки, определенные используемыми пакетами. Это означает, что если в проекте не определено значение для макроса пакета, будет использоваться значение условных операторов используемого пакета.
  
==Predefined Functions==
+
==Предопределенные функции==
  
*'''Defined(Variable)''': returns 1 (true) if the variable is defined otherwise 0 (false). Example if Defined(Macro1) then ;
+
*'''Defined(Variable)''': возвращает 1 (истина), если переменная определена, иначе 0 (ложь). Пример, <code>if Defined(Macro1) then ;</code>
*'''Undefine(Variable)''': undefine the variable. Example: Undefine(A);
+
*'''Undefine(Variable)''': отменяет определение переменной. Пример: <code>Undefine(A);</code>
*'''Int64(expression)''': Returns the int64 value of expression. Example: i:=int64('3');
+
*'''Int64(expression)''': возвращает значение выражения int64. Пример: <code>i:=int64('3');</code>
*'''Integer(expression)''': Returns the integer value of expression. Example: i:=integer('3');
+
*'''Integer(expression)''': возвращает целочисленное значение выражения. Пример: <code>i:=integer('3');</code>
*'''String(expression)''': Returns the string value of expression. Example: s:=string(3);
+
*'''String(expression)''': возвращает строковое значение выражения. Пример: <code>s:=string(3);</code>
*'''GetIDEValue(string)''': See [[IDE_Macros_in_paths_and_filenames|IDE macros]]
+
*'''GetIDEValue(string)''': См. [[IDE_Macros_in_paths_and_filenames/ru|IDE macros]]
**GetIDEValue('OS'): Returns the OS with which the IDE was compiled. since 1.0.
+
**GetIDEValue('OS'): возвращает ОС, с которой была скомпилирована IDE (начиная с 1.0).
**GetIDEValue('CPU'): Returns the CPU with which the IDE was compiled. since 1.0.
+
**GetIDEValue('CPU'): возвращает процессор, с которым была скомпилирована IDE (начиная с 1.0).
**GetIDEValue('SrcOS'): SrcOS of IDE. since 1.0.
+
**GetIDEValue('SrcOS'): SrcOS IDE (начиная с 1.0).
**GetIDEValue('SrcOS2'): SrcOS2 of IDE. since 1.0.
+
**GetIDEValue('SrcOS2'): SrcOS2 IDE (начиная с 1.0).
**GetIDEValue('LCLWidgeType'): LCL platform of the IDE, which might be different than project. lazbuild returns win32, carbon or gtk2 depending on its OS. since 1.0.
+
**GetIDEValue('LCLWidgeType'): платформа LCL среды IDE, которая может отличаться от проекта. lazbuild возвращает win32, carbon или gtk2 в зависимости от ОС (начиная с 1.0).
*'''GetEnv(string)''': Returns the environment variable. For example GetEnv('HOME') returns under Linux the user's home directory. since 1.0.
+
*'''GetEnv(string)''': возвращает переменную среды. Например, GetEnv('HOME') возвращает в Linux домашний каталог пользователя (начиная с 1.0).
*'''GetProjValue(string)''': Returns a project value.
+
*'''GetProjValue(string)''': возвращает значение проекта.
**GetProjValue('FPC_FULLVERSION'): Returns the FPC_FULLVERSION fetched from the project compiler. The version is an integer e.g. 20701. since 1.3.
+
**GetProjValue('FPC_FULLVERSION'): возвращает FPC_FULLVERSION, полученный из компилятора проекта. Версия является целым числом, например 20701 (начиная с 1.3).
  
=Order of macro computation=
+
=Порядок вычисления макроса=
  
#the values of the current project are taken
+
#берутся значения текущего проекта
#if the project does not define values for TargetOS, TargetCPU the IDE sets defaults
+
#если в проекте не определены значения для TargetOS, TargetCPU, IDE устанавливает значения по умолчанию
#SrcOS and SrcOS2 are computed from TargetOS
+
#SrcOS и SrcOS2 вычисляются из TargetOS
#the conditionals of used packages are computed. If package A uses package B, then the conditionals of B are computed before the conditionals of A.
+
#вычисляются условные выражения используемых пакетов. Если пакет A использует пакет B, то условные выражения B вычисляются перед условными операторами A.
#Every conditional script starts with the values of the project.  
+
#Каждый условный сценарий начинается со значений проекта.
#*If the project does not define a value for a package macro, the result of the used package is used.
+
#*Если проект не определяет значение для макроса пакета, используется результат используемого пакета.
#*A script can alter any macro while it runs, but only the build macros and the built-in macros are used. For example you can set TargetOS to another value, but this has no effect on any other script, nor on any search path using $(TargetOS), not even the search path of the package itself.
+
#*Сценарий может изменять любой макрос во время выполнения, но используются только макросы сборки и встроенные макросы. Например, вы можете установить для TargetOS другое значение, но это не повлияет ни на какой другой сценарий, ни на какой путь поиска с использованием $(TargetOS), даже на путь поиска самого пакета.
#*If two packages define the same build macro, then both can alter the value (unless the project sets a value). The exact effect depends on the dependency order.
+
#*Если два пакета определяют один и тот же макрос сборки, то оба могут изменять значение (если только проект не устанавливает значение). Точный эффект зависит от порядка зависимости.
#the default IDE macros are used last.
+
#Макросы IDE по умолчанию используются последними.
  
=Examples=
+
=Примеры=
  
==Adding a compiler flag for target Linux==
+
==Добавление флага компилятора для цели Linux==
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 171: Line 171:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Note:  
+
Примечание:
*TargetOS is a predefined macro by the IDE.
+
*TargetOS - это предопределенный макрос IDE.
*CustomOptions is a result variable used by the IDE.
+
*CustomOptions - это результирующая переменная, используемая IDE.
*The identifiers are case insensitive, but '''=''' (equal) operator is not. The TargetOS macro uses the same case as the compiler does, which is currently all lowercase.
+
*Идентификаторы нечувствительны к регистру, а оператор '''='''(равно) - нет. Макрос TargetOS использует тот же регистр, что и компилятор, но в настоящее время все в нижнем регистре.
*The IDE adds the first space automatically when adding the custom options.
+
*IDE автоматически добавляет первое пространство при добавлении пользовательских параметров.
*When used in a package the above only will be applied to the options used for compiling the package, not to the project using the package.
+
*При использовании в пакете вышеуказанное будет применяться только к параметрам, используемым для компиляции пакета, но не к проекту, использующему пакет.
  
==Adding some linker options for target Mac OS X==
+
==Добавление некоторых параметров компоновщика для цели Mac OS X==
  
The compiler uses for ''Mac OS X'' the value 'darwin' for ''TargetOS''.
+
Компилятор использует для ''Mac OS X'' значение 'darwin' для ''TargetOS''.
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 190: Line 190:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Notes:
+
Примечание:
*TargetOS and TargetCPU are predefined macros by the IDE.
+
*TargetOS и TargetCPU - это предопределенные в среде IDE макросы.
*The '''+=''' operator appends a string or adds a number.
+
*Оператор '''+=''' добавляет строку или число.
*When adding several options you have to add a space between options.
+
*При добавлении нескольких опций вы должны добавить пробел между опциями.
*The IDE adds the first space automatically when adding the linker options.
+
*IDE автоматически добавляет первое пространство при добавлении параметров компоновщика.
*You can nest '''begin'''..'''end''' just like Pascal.
+
*Вы можете вложить '''begin'''..'''end''' точно так же, как в Паскаль.
*If both conditions hold '''LinkerOptions''' will contain the value ' -framework Cocoa -framework OpenGL'.
+
*Если выполняются оба условия, '''LinkerOptions''' будет содержать значение ' -framework Cocoa -framework OpenGL'.
*The IDE automatically prepends the -k option when passing linker options to the compiler.
+
*Среда IDE автоматически добавляет параметр -k при передаче параметров компоновщика компилятору.
*The above only works for project's conditionals.
+
*Вышеуказанное работает только для условных выражений проекта.
  
==Adding some linker options for Mac OS X for all projects using a package==
+
==Добавление некоторых параметров компоновщика для Mac OS X для всех проектов с использованием пакета==
  
Packages have two different sets of options. The set used for compiling the package itself and the options added to all projects/packages using the package. You have to change the '''usage''' options of the package:
+
Пакеты имеют два разных набора опций. Набор, используемый для компиляции самого пакета, и параметры, добавленные ко всем проектам/пакетам, использующим пакет. Вам необходимо изменить параметр '''usage''' пакета:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 212: Line 212:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==Adding an option to a package==
+
==Добавление опции в пакет==
  
If your package provides some optional parts, for example the ability to use opengl you can define a build macro. The following explains how to set this up step by step:
+
Если ваш пакет предоставляет некоторые дополнительные части, например возможность использовать opengl, вы можете определить макрос сборки. Далее объясняется, как это настроить шаг за шагом:
  
Let's say your package is called ''Pkg1'' and allows to switch on opengl support by compiling it with the flag '''-dEnableOpenGL'''. The package should provide a boolean option '''Pkg1_UseOpenGL''' with the values 'True' and 'False'.
+
Допустим, ваш пакет называется ''Pkg1'' и позволяет включить поддержку opengl, скомпилировав его с флагом '''-dEnableOpenGL'''. В пакете должен быть логический параметр '''Pkg1_UseOpenGL''' со значениями 'True' и 'False'.
  
Open the package editor of your package 'pkg1', click on ''compiler options'', select the page ''IDE Macros''.
+
Откройте редактор пакетов 'pkg1', нажмите ''compiler options'' (Параметры компилятора), выберите страницу ''IDE Macros'' (Макросы IDE).
  
Click on the left '''+''' button to add a new macro. It will be called 'Pkg1_Macro1'. Click on the tree node to rename it to 'Pkg1_UseOpenGL'.
+
Нажмите кнопку слева '''+''', чтобы добавить новый макрос. Он будет называться 'Pkg1_Macro1'. Щелкните узел дерева, чтобы переименовать его в 'Pkg1_UseOpenGL'.
  
Click on the middle '''+''' button to add a new macro value. It will be called 'Value1'. Click on the tree node to rename it to 'True'. Repeat this for the value 'False'.
+
Нажмите среднюю кнопку '''+''', чтобы добавить новое значение макроса. Он будет называться 'Value1'. Щелкните узел дерева, чтобы переименовать его в 'True'. Повторите это для значения 'False'.
  
Add the following code into the Conditionals (Compiler Options / Other / Conditionals) text box:
+
Добавьте следующий код в текстовое поле Conditionals (Compiler Options / Other / Conditionals):
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
Line 233: Line 233:
 
[[Image:Compileroptions buildmacro example1.png]]
 
[[Image:Compileroptions buildmacro example1.png]]
  
Notes:
+
Примечание:
*The value 'True' is case sensitive. Because the value is usually selected from the combobox, there is no chance of typos.
+
*Значение 'True' чувствительно к регистру. Поскольку значение обычно выбирается из поля со списком, вероятность опечаток отсутствует.
*If the user has not set any value for the macro, the Variable 'Pkg1_UseOpenGL' is undefined and the expression results to false.
+
*Если пользователь не установил никакого значения для макроса, переменная 'Pkg1_UseOpenGL' не определена, а результат выражения - 'false'.
  
==Add a release/debug mode==
+
==Добавление режима release/debug==
  
===A release/debug mode for your project and all your packages===
+
===Режим release/debug для вашего проекта и всех ваших пакетов===
  
Note: This requires Lazarus 0.9.31 or higher.
+
Примечание: для этого требуется Lazarus 0.9.31 или выше.
  
In the project's compiler options (Project / Project Options / Compiler Options / Build modes) add a build mode ''Release''. Adding this build mode will automatically activate it, so all changes to the compiler options are now only done in this build mode.
+
В параметрах компилятора проекта (Project / Project Options / Compiler Options / Build modes) добавьте режим сборки ''Release''. Добавление этого режима сборки автоматически активирует его, поэтому все изменения параметров компилятора теперь выполняются только в этом режиме сборки.
  
In "Set Macro Values" click on the left column on the last row "(none)". Set it to "MyPackageOptions". Note: It is not listed in the combo box.  
+
В "Set Macro Values" (Установить значения макроса) щелкните левый столбец в последней строке "(none)". Установите его в "MyPackageOptions". Примечание: его нет в поле со списком.
  
Set its value to the options. For example "-O3".
+
Установите его значение в опции. Например, "-O3".
  
 
[[Image:Build mode release macro1.png]]
 
[[Image:Build mode release macro1.png]]
  
This macro is usable in the project compiler options and all packages.
+
Этот макрос можно использовать в параметрах компилятора проекта и во всех пакетах.
  
For each package do: Open the compiler options of the package, go to the page ''Other''. Add to ''Custom options'' the text $(MyPackageOptions).
+
Для каждого пакета выполните: Откройте параметры компилятора пакета, перейдите на страницу ''Other''. Добавьте в ''Custom options'' текст $(MyPackageOptions).
  
===A special release/debug mode for one package===
+
===Специальный режим release/debug для одного пакета===
  
Let's say the normal mode is the debug mode and you want another mode for the release.
+
Допустим, нормальный режим - это режим debug, и вам нужен другой режим для release.
  
Open the package editor of your package 'pkg1', click on ''compiler options'', select the page ''Build Macros''.
+
Откройте редактор пакетов 'pkg1', нажмите ''compiler options'', выберите страницу ''Build Macros''.
  
Under ''Build macros'' click on the left '''+''' button to add a new macro. It will be called 'Pkg1_Macro1'. Click on the tree node to rename it to 'Pkg1_Release'.
+
В разделе ''Build macros'' нажмите кнопку слева '''+''', чтобы добавить новый макрос. Он будет называться 'Pkg1_Macro1'. Щелкните узел дерева, чтобы переименовать его в 'Pkg1_Release'.
  
Click on the middle '''+''' button to add a new macro ''value''. It will be called 'Value1'. Click on the tree node to rename it to 'True'. Repeat this for the value 'False'.
+
Нажмите среднюю кнопку '''+''', чтобы добавить новое ''значение'' макроса. Он будет называться 'Value1'. Щелкните узел дерева, чтобы переименовать его в 'True'. Повторите это для значения 'False'.
  
Add the following code into the Conditionals text box:
+
Добавьте следующий код в текстовое поле Conditionals:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
 
if Pkg1_Release = 'True' then  
 
if Pkg1_Release = 'True' then  
   // release mode
+
   // режим release
 
   CustomOptions := '-O3'
 
   CustomOptions := '-O3'
 
else
 
else
   // debug mode
+
   // режим debug
 
   CustomOptions := '-Sa Ctroi';
 
   CustomOptions := '-Sa Ctroi';
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Notes:
+
Примечание:
*The value 'True' is case sensitive. Because the value is usually selected from the combobox, there is no chance of typos.
+
*Значение 'True' чувствительно к регистру. Поскольку значение обычно выбирается из поля со списком, вероятность опечаток отсутствует.
*If the user has not set any value for the macro, the Variable 'Pkg1_Release' is undefined and the expression results to false.
+
*Если пользователь не установил никакого значения для макроса, переменная 'Pkg1_Release' не определена, а результат выражения - false.
  
==Adding a macro for search paths to handle different platforms==
+
==Добавление макроса для путей поиска для работы с разными платформами==
  
Let's say your package is called ''Pkg1'' and uses the windows GDI on MS Windows and X11 on Linux and BSD. The platform independent units are in the package main directory and you have created two sub directories 'gdi' and 'x11' containing the platform dependent units:
+
Допустим, ваш пакет называется ''Pkg1'' и использует Windows GDI в MS Windows и X11 в Linux и BSD. Независимые от платформы модули находятся в основном каталоге пакета, и вы создали два подкаталога 'gdi' и 'x11', содержащие зависящие от платформы модули:
  
<pre>
+
<syntaxhighlight lang=bash>
 
/path/of/your/package/pkg1/
 
/path/of/your/package/pkg1/
 
   pkg1.lpk
 
   pkg1.lpk
Line 293: Line 293:
 
   x11/
 
   x11/
 
     backend.pas
 
     backend.pas
</pre>
+
</syntaxhighlight>
  
The unit ''backend'' in ''gdi'' should be used on Win32, Win64 and WinCE, while under Linux and FreeBSD the ''backend'' unit in the ''x11'' should be used. This means the ''Other unit files (-Fu)'' search path must be adapted depending on the target OS. The following describes how to set this up step by step:
+
Модуль ''backend'' в ''gdi'' следует использовать в Win32, Win64 и WinCE, а в Linux и FreeBSD следует использовать модуль ''backend'' в ''x11''. Это означает, что путь поиска ''Other unit files (-Fu)'' (Другие файлы модулей (-Fu)) должен быть адаптирован в зависимости от целевой ОС. Ниже описывается, как настроить это шаг за шагом:
  
Open the package editor of your package 'pkg1', click on compiler options, select the page ''Build Macros''.
+
Откройте редактор пакетов 'pkg1', щелкните параметры компилятора, выберите страницу ''Build Macros'' (Сборка макросов).
  
Click on the left '''+''' button to add a new macro. It will be called 'Pkg1_Macro1'. Click on the tree node to rename it to 'Pkg1_Backend'.
+
Нажмите кнопку слева '''+''', чтобы добавить новый макрос. Он будет называться 'Pkg1_Macro1'. Щелкните узел дерева, чтобы переименовать его в 'Pkg1_Backend'.
  
Click on the middle '''+''' button to add a new macro value. It will be called 'Value1'. Click on the tree node to rename it to 'gdi'. Repeat this for the value 'x11'.
+
Нажмите среднюю кнопку '''+''', чтобы добавить новое значение макроса. Он будет называться 'Value1'. Щелкните узел дерева, чтобы переименовать его в 'gdi'. Повторите это для значения 'x11'.
  
Add the following code into the Conditionals text box:
+
Добавьте следующий код в текстовое поле Conditionals:
  
 
<syntaxhighlight lang=pascal>
 
<syntaxhighlight lang=pascal>
// choose a value for Pkg1_Backend depending on the TargetOS
+
// выбираем значение для Pkg1_Backend в зависимости от TargetOS
 
if undefined(Pkg1_Backend) then begin
 
if undefined(Pkg1_Backend) then begin
 
   if SrcOS='win' then
 
   if SrcOS='win' then
Line 315: Line 315:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
The macro '''$(Pkg1_Backend)''' will become usable once you click Ok. So, click 'Ok' to close the compiler options and open it again to use it in the search path ''Other unit files (-Fu)''.
+
Макрос '''$(Pkg1_Backend)''' станет доступным после нажатия кнопки ОК. Итак, нажмите 'Ok', чтобы закрыть параметры компилятора, и откройте его снова, чтобы использовать его в пути поиска ''Other unit files (-Fu)'' (Другие файлы модулей (-Fu)).
  
 
[[Image:Compileroptions buildmacro example2.png]]
 
[[Image:Compileroptions buildmacro example2.png]]
  
Notes:
+
Примечание:
*The user can override the value of Pkg1_Backend. Therefore it is good practice to enclose the setting in ''if undefined(Pkg1_Backend)''.
+
*Пользователь может изменить значение Pkg1_Backend. Поэтому рекомендуется заключить настройку в ''if undefined(Pkg1_Backend)''.
*Instead of the SrcOS macro you could use if (TargetOS='win32') or (TargetOS='win64') or (TargetOS='wince') then
+
*Вместо макроса SrcOS вы можете использовать <code>if (TargetOS='win32') or (TargetOS='win64') or (TargetOS='wince') then ... </code>
  
 
{{Template:Directives, Defines and Conditionals}}
 
{{Template:Directives, Defines and Conditionals}}

Latest revision as of 22:17, 24 January 2021

English (en) français (fr) русский (ru)

Обзор

Макросы можно использовать в путях поиска и именах файлов, чтобы IDE автоматически адаптировала их к целевой платформе.

Build macros (Макросы сборки) - это макросы, специфичные для проекта/пакета. Они не передаются компилятору. Ярким примером является LCLWidgetType, который определяется пакетом LCL и позволяет выбирать набор виджетов (carbon, gtk, qt, win32, wince, ...).


Conditionals (Условные определения) - это правила, позволяющие задавать макросы в зависимости от целевой платформы и/или других макросов. Например, вы можете использовать их для определения специальных параметров компоновщика при компиляции для Mac OS X. Они используют язык сценариев типа паскаль, позволяющий определять даже сложные правила.

Вы можете задать макросы сборки через Project / Project Options / Compiler Options / Additions and Overrides.

Вы можете задать условные определения через Project / Project Options / Compiler Options / Other / Conditionals (прим.перев.: в версиях Лазаруса 2.0.х и выше опция находится здесь Project / Project Options / Compiler Options / Custom Options).

conditional.png

Макросы сборки и условные определения существуют с Lazarus 0.9.29.

CompilerAdditionsAndOverrides1.png

Условные определения

В условных определениях используется простой язык сценариев.

Изменение параметров компилятора с помощью условных определений

Сценарий условных определений может задавать некоторые переменные, значения которых используются IDE для параметров компилятора:

  • UnitPath: добавляется к Other Source Files (-Fu). Символы / и \ автоматически преобразуются в разделитель текущего пути. После добавления пути поиска с точкой с запятой макросы заменяются, а относительные пути расширяются каталогом пакета/проекта.
  • IncPath: добавляется к Include Files (-Fi).
  • LibraryPath: добавляется к Libraries (-Fl).
  • SrcPath: добавляется к Other sources (не используются компилятором, только IDE).
  • DebugPath: добавляется к Debugger path addition (не используется ни компилятором, ни инструментами кода, используется только отладчиком).
  • LinkerOptions: добавляется к параметрам компоновщика (-k). Разделители путей не меняются. Относительные пути не расширяются. Макросы заменяются.
  • CustomOptions: добавляется к параметрам компилятора. Разделители путей не меняются. Относительные пути не расширяются. Макросы заменяются.
  • OutputDir: если задано, он заменит текущий каталог вывода. Разделители путей не меняются. Относительные пути не расширяются. Макросы заменяются.

Для пакетов существует больше переменных для параметров использования. Эти пути наследуются, то есть добавляются ко всем пакетам/проектам, использующим этот пакет, прямо или косвенно:

  • UsageUnitPath: добавляется к используемым путям Unit (-Fu). Символы / и \ автоматически конвертиуются в текущий разделитель путей. После добавления пути поиска с точкой с запятой макросы заменяются, а относительные пути расширяются каталогом пакета/проекта.
  • UsageIncPath: добавляется к используемым путям Include (-Fi).
  • UsageLibraryPath: добавляется к используемым путям Library (-Fl).
  • UsageSrcPath: добавляется к используемым путям Source (не используются компилятором, только IDE).
  • UsageDebugPath: добавляется к используемым путям Debugger (не используется ни компилятором, ни инструментами кода, используется только отладчиком).
  • UsageLinkerOptions: добавляется к используемым параметрам компоновщика (-k). Разделители путей не меняются. Относительные пути не расширяются. Макросы заменяются.
  • UsageCustomOptions: добавляется к используемым параметрам компилятора. Разделители путей не меняются. Относительные пути не расширяются.

Синтаксис условных определений

Поддерживаемые синтактические конструкции

  • If <условие> then <выражение>;
  • If <условие> then <выражение> else <выражение>;
  • begin <выражение>; ... <выражение>; end;
  • <Переменная>:=<условие>;
  • <Переменная>+=<условие>;
  • <Комментарий> //, { }, (* *)
  • Пробелы, табуляции и переводы строк то же самое. Как и в Паскале, они нужны только для разделения двух идентификаторов/ключевых слов.

Переменные

Переменные задаются просто путем присвоения значения. Есть несколько предопределенных переменных. См. список ниже.

Переменные могут быть определены или не определены:

if defined(Name) then ...
if undefined(Name) then ...
undefine(Name);

Если переменная задана, она имеет один из трех типов:

  • none
  • string
  • number (int64)

Переменная является false, если она имеет номер 0 или строку '0'. В противном случае это true. Это означает, что переменная без значения истинна и неопределенная переменная также истинна.

Вы можете изменить тип переменной с помощью:

a := '1';        // строка
a := integer(a); // преобразование в число с помощью StrToInt(), в случае неудачи 'a' остается строкой
a := int64(a);   // преобразование в число с помощью StrToInt6(), в случае неудачи 'a' остается строкой
a := string(a);  // преобразование в строку

Константы

a := 1234; // десятичная
a := $A1B; // шестнадцатеричная
a := &127; // восьмеричная
a := %101; // двоичная
a := '10'; // строковая
a := #123; // символьная

Операторы

  • +: Два числа складываются, иначе они рассматриваются как строки и объединяются.
  • <, >, <=, >=, =, <>: Два числа сравниваются математически, в противном случае они рассматриваются как строки и сравниваются лексикографически (с учетом регистра).
  • not: Унарный (с изменением знака) логический оператор
  • and, or, xor: Логические операторы
  • (,): Групповые операторы
  • :=: Присвоение. Не допускается в выражениях.
  • +=: Добавление и назначение. Не допускается в выражениях.

Уровни приоритета:

  • 1 Not и унарный минус
  • 1 And
  • 2 Or
  • 2 XOr
  • 2 +
  • 4 =
  • 4 <>
  • 4 <
  • 4 <=
  • 4 >
  • 4 >=

Предопределенные переменные

Перед запуском условного сценария среда IDE инициализирует несколько переменных:

  • TargetOS: целевая операционная система проекта, определенная fpc. например 'linux', 'win32', 'darwin', 'freebsd', 'wince'.
  • TargetCPU: целевой процессор проекта, определенный fpc. например 'i386', 'x86_64', 'arm'
  • SrcOS: значение 'win' для всех платформ MS Windows и 'unix' для всех unix-подобных платформ. Значение зависит от TargetOS.
  • SrcOS2: значение 'bsd' для всех платформ, подобных BSD. Значение зависит от TargetOS.
  • True: значение 1
  • False: значение 0
  • все макросы сборки, определенные в текущем проекте.
  • все макросы сборки, определенные используемыми пакетами. Это означает, что если в проекте не определено значение для макроса пакета, будет использоваться значение условных операторов используемого пакета.

Предопределенные функции

  • Defined(Variable): возвращает 1 (истина), если переменная определена, иначе 0 (ложь). Пример, if Defined(Macro1) then ;
  • Undefine(Variable): отменяет определение переменной. Пример: Undefine(A);
  • Int64(expression): возвращает значение выражения int64. Пример: i:=int64('3');
  • Integer(expression): возвращает целочисленное значение выражения. Пример: i:=integer('3');
  • String(expression): возвращает строковое значение выражения. Пример: s:=string(3);
  • GetIDEValue(string): См. IDE macros
    • GetIDEValue('OS'): возвращает ОС, с которой была скомпилирована IDE (начиная с 1.0).
    • GetIDEValue('CPU'): возвращает процессор, с которым была скомпилирована IDE (начиная с 1.0).
    • GetIDEValue('SrcOS'): SrcOS IDE (начиная с 1.0).
    • GetIDEValue('SrcOS2'): SrcOS2 IDE (начиная с 1.0).
    • GetIDEValue('LCLWidgeType'): платформа LCL среды IDE, которая может отличаться от проекта. lazbuild возвращает win32, carbon или gtk2 в зависимости от ОС (начиная с 1.0).
  • GetEnv(string): возвращает переменную среды. Например, GetEnv('HOME') возвращает в Linux домашний каталог пользователя (начиная с 1.0).
  • GetProjValue(string): возвращает значение проекта.
    • GetProjValue('FPC_FULLVERSION'): возвращает FPC_FULLVERSION, полученный из компилятора проекта. Версия является целым числом, например 20701 (начиная с 1.3).

Порядок вычисления макроса

  1. берутся значения текущего проекта
  2. если в проекте не определены значения для TargetOS, TargetCPU, IDE устанавливает значения по умолчанию
  3. SrcOS и SrcOS2 вычисляются из TargetOS
  4. вычисляются условные выражения используемых пакетов. Если пакет A использует пакет B, то условные выражения B вычисляются перед условными операторами A.
  5. Каждый условный сценарий начинается со значений проекта.
    • Если проект не определяет значение для макроса пакета, используется результат используемого пакета.
    • Сценарий может изменять любой макрос во время выполнения, но используются только макросы сборки и встроенные макросы. Например, вы можете установить для TargetOS другое значение, но это не повлияет ни на какой другой сценарий, ни на какой путь поиска с использованием $(TargetOS), даже на путь поиска самого пакета.
    • Если два пакета определяют один и тот же макрос сборки, то оба могут изменять значение (если только проект не устанавливает значение). Точный эффект зависит от порядка зависимости.
  6. Макросы IDE по умолчанию используются последними.

Примеры

Добавление флага компилятора для цели Linux

if TargetOS = 'linux' then 
  CustomOptions := '-dUseCThreads';

Примечание:

  • TargetOS - это предопределенный макрос IDE.
  • CustomOptions - это результирующая переменная, используемая IDE.
  • Идентификаторы нечувствительны к регистру, а оператор =(равно) - нет. Макрос TargetOS использует тот же регистр, что и компилятор, но в настоящее время все в нижнем регистре.
  • IDE автоматически добавляет первое пространство при добавлении пользовательских параметров.
  • При использовании в пакете вышеуказанное будет применяться только к параметрам, используемым для компиляции пакета, но не к проекту, использующему пакет.

Добавление некоторых параметров компоновщика для цели Mac OS X

Компилятор использует для Mac OS X значение 'darwin' для TargetOS.

if TargetOS = 'darwin' then begin
  LinkerOptions += ' -framework Cocoa';
  if TargetCPU = 'i386' then 
    LinkerOptions += ' -framework OpenGL';
end;

Примечание:

  • TargetOS и TargetCPU - это предопределенные в среде IDE макросы.
  • Оператор += добавляет строку или число.
  • При добавлении нескольких опций вы должны добавить пробел между опциями.
  • IDE автоматически добавляет первое пространство при добавлении параметров компоновщика.
  • Вы можете вложить begin..end точно так же, как в Паскаль.
  • Если выполняются оба условия, LinkerOptions будет содержать значение ' -framework Cocoa -framework OpenGL'.
  • Среда IDE автоматически добавляет параметр -k при передаче параметров компоновщика компилятору.
  • Вышеуказанное работает только для условных выражений проекта.

Добавление некоторых параметров компоновщика для Mac OS X для всех проектов с использованием пакета

Пакеты имеют два разных набора опций. Набор, используемый для компиляции самого пакета, и параметры, добавленные ко всем проектам/пакетам, использующим пакет. Вам необходимо изменить параметр usage пакета:

if TargetOS = 'darwin' then begin
  UsageLinkerOptions += ' -framework Cocoa';
  if TargetCPU = 'i386' then 
    UsageLinkerOptions += ' -framework OpenGL';
end;

Добавление опции в пакет

Если ваш пакет предоставляет некоторые дополнительные части, например возможность использовать opengl, вы можете определить макрос сборки. Далее объясняется, как это настроить шаг за шагом:

Допустим, ваш пакет называется Pkg1 и позволяет включить поддержку opengl, скомпилировав его с флагом -dEnableOpenGL. В пакете должен быть логический параметр Pkg1_UseOpenGL со значениями 'True' и 'False'.

Откройте редактор пакетов 'pkg1', нажмите compiler options (Параметры компилятора), выберите страницу IDE Macros (Макросы IDE).

Нажмите кнопку слева +, чтобы добавить новый макрос. Он будет называться 'Pkg1_Macro1'. Щелкните узел дерева, чтобы переименовать его в 'Pkg1_UseOpenGL'.

Нажмите среднюю кнопку +, чтобы добавить новое значение макроса. Он будет называться 'Value1'. Щелкните узел дерева, чтобы переименовать его в 'True'. Повторите это для значения 'False'.

Добавьте следующий код в текстовое поле Conditionals (Compiler Options / Other / Conditionals):

if Pkg1_UseOpenGL = 'True' then 
  CustomOptions := '-dEnableOpenGL';

Compileroptions buildmacro example1.png

Примечание:

  • Значение 'True' чувствительно к регистру. Поскольку значение обычно выбирается из поля со списком, вероятность опечаток отсутствует.
  • Если пользователь не установил никакого значения для макроса, переменная 'Pkg1_UseOpenGL' не определена, а результат выражения - 'false'.

Добавление режима release/debug

Режим release/debug для вашего проекта и всех ваших пакетов

Примечание: для этого требуется Lazarus 0.9.31 или выше.

В параметрах компилятора проекта (Project / Project Options / Compiler Options / Build modes) добавьте режим сборки Release. Добавление этого режима сборки автоматически активирует его, поэтому все изменения параметров компилятора теперь выполняются только в этом режиме сборки.

В "Set Macro Values" (Установить значения макроса) щелкните левый столбец в последней строке "(none)". Установите его в "MyPackageOptions". Примечание: его нет в поле со списком.

Установите его значение в опции. Например, "-O3".

Build mode release macro1.png

Этот макрос можно использовать в параметрах компилятора проекта и во всех пакетах.

Для каждого пакета выполните: Откройте параметры компилятора пакета, перейдите на страницу Other. Добавьте в Custom options текст $(MyPackageOptions).

Специальный режим release/debug для одного пакета

Допустим, нормальный режим - это режим debug, и вам нужен другой режим для release.

Откройте редактор пакетов 'pkg1', нажмите compiler options, выберите страницу Build Macros.

В разделе Build macros нажмите кнопку слева +, чтобы добавить новый макрос. Он будет называться 'Pkg1_Macro1'. Щелкните узел дерева, чтобы переименовать его в 'Pkg1_Release'.

Нажмите среднюю кнопку +, чтобы добавить новое значение макроса. Он будет называться 'Value1'. Щелкните узел дерева, чтобы переименовать его в 'True'. Повторите это для значения 'False'.

Добавьте следующий код в текстовое поле Conditionals:

if Pkg1_Release = 'True' then 
  // режим release
  CustomOptions := '-O3'
else
  // режим debug
  CustomOptions := '-Sa Ctroi';

Примечание:

  • Значение 'True' чувствительно к регистру. Поскольку значение обычно выбирается из поля со списком, вероятность опечаток отсутствует.
  • Если пользователь не установил никакого значения для макроса, переменная 'Pkg1_Release' не определена, а результат выражения - false.

Добавление макроса для путей поиска для работы с разными платформами

Допустим, ваш пакет называется Pkg1 и использует Windows GDI в MS Windows и X11 в Linux и BSD. Независимые от платформы модули находятся в основном каталоге пакета, и вы создали два подкаталога 'gdi' и 'x11', содержащие зависящие от платформы модули:

/path/of/your/package/pkg1/
  pkg1.lpk
  pkg1.pas
  generalunit.pas
  gdi/
    backend.pas
  x11/
    backend.pas

Модуль backend в gdi следует использовать в Win32, Win64 и WinCE, а в Linux и FreeBSD следует использовать модуль backend в x11. Это означает, что путь поиска Other unit files (-Fu) (Другие файлы модулей (-Fu)) должен быть адаптирован в зависимости от целевой ОС. Ниже описывается, как настроить это шаг за шагом:

Откройте редактор пакетов 'pkg1', щелкните параметры компилятора, выберите страницу Build Macros (Сборка макросов).

Нажмите кнопку слева +, чтобы добавить новый макрос. Он будет называться 'Pkg1_Macro1'. Щелкните узел дерева, чтобы переименовать его в 'Pkg1_Backend'.

Нажмите среднюю кнопку +, чтобы добавить новое значение макроса. Он будет называться 'Value1'. Щелкните узел дерева, чтобы переименовать его в 'gdi'. Повторите это для значения 'x11'.

Добавьте следующий код в текстовое поле Conditionals:

// выбираем значение для Pkg1_Backend в зависимости от TargetOS
if undefined(Pkg1_Backend) then begin
  if SrcOS='win' then
    Pkg1_Backend:='gdi'
  else
    Pkg1_Backend:='x11';
end;

Макрос $(Pkg1_Backend) станет доступным после нажатия кнопки ОК. Итак, нажмите 'Ok', чтобы закрыть параметры компилятора, и откройте его снова, чтобы использовать его в пути поиска Other unit files (-Fu) (Другие файлы модулей (-Fu)).

Compileroptions buildmacro example2.png

Примечание:

  • Пользователь может изменить значение Pkg1_Backend. Поэтому рекомендуется заключить настройку в if undefined(Pkg1_Backend).
  • Вместо макроса SrcOS вы можете использовать if (TargetOS='win32') or (TargetOS='win64') or (TargetOS='wince') then ...
Directives, definitions and conditionals definitions
global compiler directives • local compiler directives

Conditional Compiler Options • Conditional compilation • Macros and Conditionals • Platform defines
$IF