Macros and Conditionals/fr
│
English (en) │
français (fr) │
русский (ru) │
Généralité
Des macros peuvent être utilisées dans les chemins de recherche et les noms de fichier pour laisser l'EDI les adapter à la plate-forme cible. Les macros de construction sont des macros spécifiques au projet/paquet. Elles ne sont pas passées au compilateur. Un exemple important est la LCLWidgetType, laquelle est définie dans le paquet LCL et permet de choisir le jeu de widgets (carbon, gtk, qt, win32, wince, ...).
Les conditionnelles sont des règles permettant de mettre des macros dépendantes de la palte-forme cible et/ou d'autres macros. Par exemple, vous pouvez les utiliser pour définir des options spéciales de l'éditeur de lien pour Mac OS X. Elle utilisent un langage de script comme Pascal pour définir des règles complexes.
Vous pouvez définir les macros de construction via Project / Project Options / Compiler Options / Additions and Overrides (en)
Vous pouvez faire des conditionnelles via Projet / Options du projet / Options du compilateur / Options personnalisées.
Les macros de construction et les conditionnelles existent depuis Lazarus 0.9.29.
Conditionnelles
Les expressions conditionnelles utilisent un langage de scripting simple.
Changement des options du compilateur avec les expressions conditionnelles
Le script de conditionnelles peut définir certaines variables dont les valeurs sont utilisées par l'EDI pour les options du compilateur :
- UnitPath: ajouté en fin de Autres fichiers sources (-Fu). Les caractères / et \ sont automatiquement convertis vers le séparateur de chemin courant. Après avoir ajouté le(s) chemin(s) de recherche) avec un point-virgule, les macros sont remplacées et les chemins relatifs sont expansés par le chemin d'accès du projet/paquet.
- IncPath: ajouté en fin de Fichiers d'inclusion (-Fi).
- LibraryPath: ajouté en fin de Bibliothèques (-Fl).
- SrcPath: ajouté en fin de Autres sources (non utilisé par le compilateur, uniquement par l'EDI).
- DebugPath: ajouté en fin de Ajout de chemin du débogueur (non utilisé par le compilateur ni par les outils de code, seulement par le débogueur)
- LinkerOptions: ajouté en fin des options de l'éditeur de liens (-k). Les délimiteurs de chemin ne sont pas changés. Les chemins relatifs ne sont pas expansés. Les macros sont remplacées.
- CustomOptions: ajouté en fin des paramètres du compilateur. Les délimiteurs de chemin ne sont pas changés. Les chemins relatifs ne sont pas expansés. Les macros sont remplacées.
- OutputDir: si défini, il remplacera le dossier de sortie courant. Les délimiteurs de chemin sont changés. Les chemins relatifs sont expansés. Les macros sont remplacées.
Pour les paquets, il y a plus de variables pour les options d'usage. Ces chemins sont hérités, cela signifie qu'ils sont ajoutés à tous les paquets/projets utilisant ce paquet, directement ou non :
- UsageUnitPath : ajouté en fin du chemin d'usage Unité (-Fu). Les caractères / et \ sont automatiquement convertis dans le séparateur de chemin actuel. Après avoir ajouté le(s) chemin(s) de recherche) avec un point-virgule, les macros sont remplacées et les chemins relatifs sont expansés par le chemin d'accès du projet/paquet.
- UsageIncPath : ajouté en fin du chemin d'usage Inclusion (-Fi).
- UsageLibraryPath : ajouté en fin du chemin d'usage Bibliothèque (-Fl).
- UsageSrcPath : ajouté en fin du chemin d'usage Source (pas utilisé par le compilateur, seulement l'EDI).
- UsageDebugPath : ajouté en fin du chemin d'usage Débogueur (pas utilisé par le compilateur, ni par les outils de code, utilisé seulement par le débogueur).
- UsageLinkerOptions : ajouté en fin des options de l'éditeur de liens (-k). Les délimiteurs de chemin ne sont pas changés. Les chemins relatifs ne sont pas expansés. Les macros sont remplacées.
- UsageCustomOptions : ajouté en fin des paramètres d'usage du compilateur. Les délimiteurs de chemin ne sont pas changés. Les chemins relatifs ne sont pas expansés.
Syntaxe des expressions conditionnelles
Constructions de syntaxe supportées
- If expression then instruction;
- If expression then instruction else instruction;
- begin instruction; ... instruction; end;
- Variable:=expression;
- Variable+=expression;
- Commentaires //, { }, (* *)
- Espaces, tabulations et saut de ligne sont les mêmes. Comme en Pascal, ils ne sont requis que pour séparer deux identificateurs/mots-clés.
Variables
Les variables sont définies simplement en assignant une valeur. Il y a des variables prédéfinies. Voir ci-dessous pour une liste.
Les variables peuvent être définies ou indéfinies :
if defined(Name) then ...
if undefined(Name) then ...
undefine(Name);
Si une variables est définie, elle peut avoir l'un de ces trois types :
- aucun
- chaîne de caractères
- numérique (int64)
Une variable est false si elle prend la valeur numérique 0 ou chaîne '0'. Sinon, elle vaut true. Cela signifie qu'une variable sans valeur est vraie tout comme une variable indéfinie.
Vous pouvez changer le type d'une variable avec :
a:='1'; // string
a:=integer(a); // convertit vers un nombre en utilisant StrToInt(), en cas d'échec, la variable demeure une chaîne
a:=int64(a); // convertit vers un nombre en utilisant StrToInt64(), en cas d'échec, la variable demeure une chaîne
a:=string(a); // convertit vers une chaîne
Constantes
a:=1234; // decimal
a:=$A1B; // hexadecimal
a:=&127; // octal
a:=%101; // binary
a:='10'; // string
a:=#123; // character
Opérateurs
- + : Deux nombres sont ajoutés, sinon ils sont traités comme une chaîne et concaténés.
- <, >, <=, >=, =, <> : Deux nombres sont comparés mathématiquement, sinon ils sont traités comme des chaînes et comparés lexicographiquement (sensible à la casse).
- not : opérateur booléen unaire.
- and, or, xor : Opérateurs booléens.
- (,) : operations de groupe.
- := : Affectation. Pas permis dans les expressions (désolé, c'est pas du langage C).
- += : Ajout et affectation. Pas permis dans les expressions.
Niveaux de précédence:
- 1 Not et - (moins unaire)
- 1 And
- 2 Or
- 2 XOr
- 2 +
- 4 =
- 4 <>
- 4 <
- 4 <=
- 4 >
- 4 >=
Variables prédéfinies
Avant que le script d'expressions conditionnelles ne soit exécuté, l'EDI initialise quelques variables :
- TargetOS : le système d'exploitation cible comme défini par fpc p.ex. 'linux', 'win32', 'darwin', 'freebsd', 'wince'.
- TargetCPU: le processeur cible du projet comme défini par fpc p.exe. 'i386', 'x86_64', 'arm'.
- SrcOS: la valeur 'win' pour toute plate-forme MS Windows et 'unix' pour toutes les plate-formes unixiennes. La valeur dépend de TargetOS.
- SrcOS2: la valeur 'bsd' pour toutes les plates-formes BSD-iennes. La valeur dépend de TargetOS.
- True : valeur 1
- False : valeur 0
- toutes les macros de construction définies par le projet en cours.
- Toutes les macros de construction définies par les paquets utilisés. Cela signifie que si le projet n'a pas défini une valeur pour une macro du paquet, la valeur de la conditionnelle du paquet utilisé sera utilisée.
Fonction prédéfinies
- Defined(Variable) : retourne 1 (vrai) si la variable est définie et 0 (faux) sinon. Exemple if Defined(Macro1) then ;
- Undefine(Variable) : annule la définition de la variable. Exemple: Undefine(A);
- Int64(expression) : Retourne la valeur Int64 de l'expression. Exemple: i:=int64('3');
- Integer(expression) : Retourne la valeur entière d'une expression. Exemple: i:=integer('3');
- String(expression) : Retourne la valeur chaîne d'une expression. Exemple: s:=string(3);
- GetIDEValue(string) : Voir Macros EDI (en).
- GetIDEValue('OS') : Retourne le système d'exploitation dans lequel l'EDI a été compilé. Depuis la version 1.0.
- GetIDEValue('CPU') : Retourne le processeur avec lequel l'EDI a été compilé. Depuis la version 1.0.
- GetIDEValue('SrcOS') : SrcOS de l'EDI. Depuis la version 1.0.
- GetIDEValue('SrcOS2') : SrcOS2 de l'EDI. Depuis la version 1.0.
- GetIDEValue('LCLWidgeType') : Plate-forme LCL de l'EDI, qui peut être différente du projet. lazbuild retourne win32, carbon ou gtk2 selon son système d'exploitation. Depuis la version 1.0.
- GetEnv(string) : Retourne la valeur de la variable d'environnement. Par exemple, GetEnv('HOME') retourne sous Linux le répertoire d'acceuil de l'utilisateur. Depuis la version 1.0.
- GetProjValue(string) : Retourne une valeur de projet.
- GetProjValue('FPC_FULLVERSION'): Retourne la FPC_FULLVERSION rapportée du compilateur. La version est un entier p.ex. 20701. Depuis la version 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
- SrcOS and SrcOS2 are computed from 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.
- 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.
- 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.
Examples
Adding a compiler flag for target Linux
if TargetOS = 'linux' then
CustomOptions := '-dUseCThreads';
Note:
- TargetOS is a predefined macro by the IDE.
- CustomOptions is a result variable used by the 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.
- The IDE adds the first space automatically when adding the custom options.
- 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
The compiler uses for Mac OS X the value 'darwin' for TargetOS.
if TargetOS = 'darwin' then begin
LinkerOptions += ' -framework Cocoa';
if TargetCPU = 'i386' then
LinkerOptions += ' -framework OpenGL';
end;
Notes:
- TargetOS and TargetCPU are predefined macros by the 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.
- You can nest begin..end just like Pascal.
- If both conditions hold LinkerOptions will contain the value ' -framework Cocoa -framework OpenGL'.
- The IDE automatically prepends the -k option when passing linker options to the compiler.
- The above only works for project's conditionals.
Adding some linker options for Mac OS X for all projects using a package
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:
if TargetOS = 'darwin' then begin
UsageLinkerOptions += ' -framework Cocoa';
if TargetCPU = 'i386' then
UsageLinkerOptions += ' -framework OpenGL';
end;
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:
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'.
Open the package editor of your package 'pkg1', click on compiler options, select the page IDE 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_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'.
Add the following code into the Conditionals (Compiler Options / Other / Conditionals) text box:
if Pkg1_UseOpenGL='True' then
CustomOptions := '-dEnableOpenGL';
Notes:
- The value 'True' is case sensitive. Because the value is usually selected from the combobox, there is no chance of typos.
- If the user has not set any value for the macro, the Variable 'Pkg1_UseOpenGL' is undefined and the expression results to false.
Add a release/debug mode
A release/debug mode for your project and all your packages
Note: This requires Lazarus 0.9.31 or higher.
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.
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 its value to the options. For example "-O3".
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).
A special release/debug mode for one package
Let's say the normal mode is the debug mode and you want another mode for the release.
Open the package editor of your package 'pkg1', click on compiler options, select the page 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'.
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'.
Add the following code into the Conditionals text box:
if Pkg1_Release='True' then
// release mode
CustomOptions := '-O3'
else
// debug mode
CustomOptions := '-Sa Ctroi';
Notes:
- The value 'True' is case sensitive. Because the value is usually selected from the combobox, there is no chance of typos.
- If the user has not set any value for the macro, the Variable 'Pkg1_Release' is undefined and the expression results to 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:
/path/of/your/package/pkg1/ pkg1.lpk pkg1.pas generalunit.pas gdi/ backend.pas x11/ backend.pas
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:
Open the package editor of your package 'pkg1', click on compiler options, select the page 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'.
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'.
Add the following code into the Conditionals text box:
// choose a value for Pkg1_Backend depending on the TargetOS
if undefined(Pkg1_Backend) then begin
if SrcOS='win' then
Pkg1_Backend:='gdi'
else
Pkg1_Backend:='x11';
end;
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).
Notes:
- The user can override the value of Pkg1_Backend. Therefore it is good practice to enclose the setting in if undefined(Pkg1_Backend).
- Instead of the SrcOS macro you could use 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 |