Conditional compilation/fr

From Free Pascal wiki
Jump to: navigation, search

Deutsch (de) English (en) français (fr)

Directive à la compilation $DEFINE et $IFDEF

Pourquoi ?

Si vous avez une application qui demande plusieurs variantes, disons pour deux clients ou pour deux systèmes d'exploitation alors les directives de compilation sont faites pour vous. Un exemple pratique est quand vous codez pour plusieurs plates-formes. Les applications 32 bit permettent des fichiers de 4 Go parce c'est la taille maximale d'un Integer mais d'autres systèmes d'exploitation n'ont pas cette limitation. Ainsi une définition de FileSize peut être la suivante :

var
  MyFilesize:
  {$ifdef Win32} 
    Cardinal 
  {$else}
    int64
  {$endif}

Rien de ceci n'est sensible à la casse. {$ifdef}, {$else}, etc sont appelés symboles. Quand ils sont assemblés pour réaliser une logique, le code résultant est appelé une macro. Pour d'autres exemples pratiques, voir : Code_Conversion_Guide/fr#Les_variables_utiles_pour_le_compilateur.

Une autre façon de faire la même chose est d'utiliser les macros de l'IDE IDE_Macros_in_paths_and_filenames/fr.

Il ne reste plus qu'à savoir où est placé {$DEFINE WIN32}, dans le code ou l'IDE.

Il y a trois façons de faire cela.

Unité basée sur les instructions {$DEFINE} et {$IFDEF}

  //Insérez le symbole $DEFINE à un point antérieur du code de l'unité
  {$DEFINE Win32}
  var
  MyFilesize:
  {$ifdef Win32} 
    Cardinal 
  {$else}
    int64
  {$endif} 
  //Insert $UNDEF symbol
  {UNDEF $Win32}

Utiliser l'EDI

Dans l'EDI, aller dans la page Projet | Options du projet | Options du compilateur | Options personnalisées et entrez -dWin32 ou Win32, selon la version. Dans Lazarus 1.2.4, le -d est entré automatiquement.

Dans les options personnalisées

-d est identique à #DEFINE
-u est identique à #UNDEF

Ces entrées s'appliquent à la totalité du projet.

Utilisez un fichier d'inclusion

Voir l'exemple plus détaillé plus bas.

Symboles

Les $IFNDEF, $IFDEF, $ENDIF, $ELSE, $DEFINE, $UNDEF imbriqués sont permis. Voir Conditonnelle de compilation pour une liste complète.

Exemples complexes

Les defines et les fichiers d'inclusion (.inc) basés unité doivent ajoutés dans chaque unité concernée. Alors qu'une option personnalisée s'applique à toutes les unités du projet.

Instructions {$DEFINE} et {$IFDEF} basés unité

Créez un projet avec une simple fiche comme ci-dessous. Commentez et décommentez les deux instructions {$DEFINE} tour à tour et regardez ce qui se passe. Si vous ajoutez une seconde fiche (Form2) qui s'ouvre quand la première (Form1) est cliquée, des instructions similaires fonctionneront indépendamment des instructions {$DEFINE} de Form1.

var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
{$DEFINE RED}
//{$DEFINE BLUE}
{ TForm1 }
 
procedure TForm1.FormClick(Sender: TObject);
begin
  {$IFDEF RED} Form1.Color := clRed; {$ENDIF}
  {$IFDEF BLUE} Form1.Color := clBlue; {$ENDIF}
  {$IFDEF BLUE AND $IFDEF RED} Form1.Color := clYellow; {$ENDIF}
  {$IFNDEF RED AND $IFNDEF BLUE} Form1.Color := clAqua; {$ENDIF}
end;

Fichiers d'inclusion

Les fichiers d'inclusion ajoute du code dans toute unité .pas.

Créez un fichier appelé unit1.inc (il pourrait s'appeler n_importe_quoi.pas) qui contient :

{$DEFINE RED}
//{$DEFINE BLUE}

Créeez une autre appelée unit1a.inc qui contient :

  {$IFDEF RED} Form1.Color := clRed; {$ENDIF}
  {$IFDEF BLUE} Form1.Color := clBlue; {$ENDIF}
  {$IFDEF BLUE AND $IFDEF RED} Form1.Color := clYellow; {$ENDIF}
  {$IFNDEF RED AND $IFNDEF BLUE} Form1.Color := clAqua; {$ENDIF}

Ajoutez-les dans le dossier du projet. Une fois compilées, ces lignes remplaceront les instructions $INCLUDE ci-dessous. Les deux méthodes présentent le même code au compilateur. Néanmoins, employer des fichiers d'inclusion permet de répondre à des exigences plus complexes.

var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
  {$INCLUDE unit1.inc}
{ TForm1 }
 
procedure TForm1.FormClick(Sender: TObject);
begin
  {$INCLUDE unit1a.inc}
end;

Maintenant, nous pouvons l'étendre à ceci :

var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
{$IFDEF ABC}  
  {$INCLUDE abc.inc}
{$ELSE}
  {$INCLUDE xyz.inc}
{$ENDIF}
 
{ TForm1 }
 
procedure TForm1.FormClick(Sender: TObject);
begin
 ... some code ...
{$IFDEF ABC}  
  {$INCLUDE abcCode.inc}
{$ELSE}
  {$INCLUDE xyzCode.inc}
{$ENDIF} 
... some more code ... 
end;

Projet | Options du projet | Options du compilateur | Options personnalisées

Mettre en commentaire ou effacer les symboles {$DEFINE} dans votre code et ajouter les directives comme ci-dessous. Dans ce cas, les directives s'appliqueront à toutes les unités.

Ceci définit les symboles FPC. Par exemple, -dDEBUG -dVerbose définiront les symboles FPC DEBUG et Verbose, ainsi vous pouvez utiliser {$IFDEF Debug}. Voir IDE_Macros_in_paths_and_filenames.

Remarquez le préfixe -d.

-dRED
-dBLUE

Une approche similaire peut être utilisée en compilant avec FPC au lieu de Lazarus : spécifiez l'argument -d... dans la ligne de commande en appelant FPC (p.ex. dans un fichier de commandes).

Depuis Lazarus 1.2, la nouvelle IHM des options offre un choix : soit entrer la directive avec -d comme précédemment, soit utiliser l'interface graphique. L'interface graphique stocke toutes les directives entrées et active celles que vous avez sélectionnées. Celles-ci sont alors affichées comme dans la pré version 1.2 avec le préfixe -d.

Directives, Définitions et conditionnelles:
Conditionnelle de compilation | Options conditionnelles du compilateur | Directives globales du compilateur | Directives locales du compilateur | $IF | Macros et conditionnelles | Définitions pour les plateformes