Recent

Author Topic: [SOLVED] How to compile conditional for FPC 3.0.4 and all later?  (Read 1089 times)

PascalDragon

  • Hero Member
  • *****
  • Posts: 951
  • Compiler Developer
Re: [REOPENED] How to compile conditional for FPC 3.0.4 and all later?
« Reply #15 on: January 09, 2020, 09:41:16 am »
Remember the {$IF} family (all of them) are unit local, so every other unit would need the same {$IF/$IFDEF}. Maybe that is the case.
I never encountered your issue, probably because I handle them correct by nature. (Which also means I can not explain it without full code)
Are you saying that using {$IF ...} inside a uses clause is "incorrect by nature"?
To my mind the incorrectness is in the compiler stumbling over this, hence my suggestion that this is a bug.
However, I am not really sure because I avoid explicit conditional compilation if possible (it makes source code very much harder to read - and in some cases almost impenetrable), so I am not skilled in all the nuances of FPC's extensive conditional dialect. Nevertheless I recognise that for a cross-platform environment conditional compilation is a necessary evil. The FCL/LCL hides it from most of us by clever use of .inc files, but the gory details are still there, of course, if you delve into the sources.

This is a known problem and an incompatibility with Delphi (I think it was a bit premature by Jonas to close that bug report). The thing is that FPC parses the whole uses-clause and only then loads the unit while Delphi loads a used unit immediately.

It hardly makes code simpler in this case, but FPC does have a simple macro facility (not enabled by default) which lets you write this sort of code following, which if you have many instances where a variable definition/implementation of spinedit is needed might be worth the extra typing:
Code: Pascal  [Select]
  1. unit mainConditional;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. {$Macro on}
  6.  
  7. {$Define DeclareAppropriateSpinEdit1 := {$IF LCL_FullVersion >= 1080000}
  8.     SpinEdit1: TSpinEditEx
  9.   {$ELSE}
  10.     SpinEdit1: TSpinEdit
  11.   {$IFEND} }
  12.  
  13. {$Define CreateAppropriateSpinEdit1 :=  {$IF LCL_FullVersion >= 1080000}
  14.     SpinEdit1 := TSpinEditEx.Create(Self)
  15.   {$ELSE}
  16.     SpinEdit1 := TSpinEdit.Create(Self)
  17.   {$IFEND} }
  18.  
  19. interface
  20. // snip
  21.  

I'd write it like this as it allows for multiple spin edits to be used:

Code: Pascal  [Select]
  1. {$macro on}
  2.  
  3. {$if LCL_FullVersion >= 1080000}
  4. {$define TMySpinEdit := TSpinEditEx}
  5. {$else}
  6. {$define TMySpinEdit := TSpinEdit}
  7. {$endif}
  8.  
  9. // in form class:
  10.   SpinEdit1: TMySpinEdit;
  11.  
  12. // in constructor:
  13.   SpinEdit1 := TMySpinEdit.Create(Self);
  14.  

Control "TSpinEditEx" was introduced in Lazarus 1.8.0 which came out with FPC 3.0.4. I used it frequently, but wanted my sources to be backwards-compatible, so I created a lot of constructs like this:

Lazarus 1.8.0 also supports FPC 3.0.2 and maybe also 3.0.0, so checking for the compiler version is the wrong approach (and you've already learned about LCL_FullVersion now). However should you ever need to check for FPC's version, you can use FPC_FULLVERSION (for 3.0.4 it has the value 30400) and that one can be used also in a uses clause, because that is a define provided by the compiler. ;) (see also here)

Hartmut

  • Sr. Member
  • ****
  • Posts: 357
Re: [SOLVED] How to compile conditional for FPC 3.0.4 and all later?
« Reply #16 on: January 09, 2020, 10:07:34 am »
Thank you PascalDragon for your reply. Your suggestion how to use macros makes things even easier and clearer. And you are right that the LCL version should be checked for TSpinEditEx and not the FPC version.

As you noted, my bug report was closed to "won't fix" with the note from Jonas Maebe "Units are only loaded once the entire uses clause is parsed. What you want to do requires the use of an include file".

Should I reopen it with your hint, that this behavior is not Delphi compatible?

PascalDragon

  • Hero Member
  • *****
  • Posts: 951
  • Compiler Developer
Re: [SOLVED] How to compile conditional for FPC 3.0.4 and all later?
« Reply #17 on: January 09, 2020, 10:27:45 am »
Should I reopen it with your hint, that this behavior is not Delphi compatible?

Leave it for now. I'll raise the point on the core mailing list.

Hartmut

  • Sr. Member
  • ****
  • Posts: 357
Re: [SOLVED] How to compile conditional for FPC 3.0.4 and all later?
« Reply #18 on: January 09, 2020, 11:15:00 am »
Leave it for now. I'll raise the point on the core mailing list.
Thanks a lot.

Ondrej Pokorny

  • Full Member
  • ***
  • Posts: 216
Re: [SOLVED] How to compile conditional for FPC 3.0.4 and all later?
« Reply #19 on: January 09, 2020, 02:35:03 pm »
It could be solved within Lazarus/LCL if the LCL_FULLVERSION was defined in the LCLBase package like the LCL and LCL$(LCLWidgetType) (e.g. LCLWin32) are defined in the LCL package.

A definition for -dLCL_FULLVERSION:=203000 had to be added. (And had to be updated automatically somehow.)

Hartmut

  • Sr. Member
  • ****
  • Posts: 357
Re: [SOLVED] How to compile conditional for FPC 3.0.4 and all later?
« Reply #20 on: January 09, 2020, 06:35:03 pm »
Thank you Ondrej for your suggestion. But sorry, I understood something like nothing. On one hand my English is not the very best and on the other hand my knowledge about packages is as much as zero. I searched a while in Lazarus to "find" your screenshot: in Menu Package / Open Loaded Package / select "LCL" / Open / Icon "Options" I found it. But what shall I do there?

Quote
It could be solved within Lazarus/LCL if the LCL_FULLVERSION was defined in the LCLBase package like the LCL and LCL$(LCLWidgetType) (e.g. LCLWin32) are defined in the LCL package.
Where do I have something to define? In the options of LCLBase or in the options of LCL?

Quote
A definition for -dLCL_FULLVERSION:=203000 had to be added.
Should I add "-dLCL_FULLVERSION:=203000" in the "Custom" field of the "LCLBase" options?
Why do you use "203000"? Should this represent ver 2.3.0.0? Must this not be "2030000" (one zero more)? And why do you use here ver 2.3 and the title of your screenshot shows "LCL 2.1"? Is it correct, that this number always must represent the current version number of Lazarus. e.g. "1080400" for ver 1.8.4.0?

Quote
(And had to be updated automatically somehow.)
Must I update this (when?) or is this done completely automatically?

Thanks a lot for your patience and your help.

Ondrej Pokorny

  • Full Member
  • ***
  • Posts: 216
Re: [SOLVED] How to compile conditional for FPC 3.0.4 and all later?
« Reply #21 on: January 10, 2020, 09:07:52 am »
It's more or less work for the Lazarus team - it would make sense to define the constants in the LCL/LCLBase package.

Hartmut

  • Sr. Member
  • ****
  • Posts: 357
Re: [SOLVED] How to compile conditional for FPC 3.0.4 and all later?
« Reply #22 on: January 10, 2020, 09:27:30 am »
Hello Ondrej, your writings are like an oracle to me.

It's more or less work for the Lazarus team
What is more or less work for the Lazarus team?

Quote
it would make sense to define the constants in the LCL/LCLBase package
"constants"? More than one? Until now you only told me to add LCL_FULLVERSION.
"in the LCL/LCLBase package"? In LCL or LCLBase or both? 

Did you see my questions in reply #20?

Please be a bit more detailed. Many thanks for helping a beginner to all that stuff.

howardpc

  • Hero Member
  • *****
  • Posts: 3296
Re: [SOLVED] How to compile conditional for FPC 3.0.4 and all later?
« Reply #23 on: January 10, 2020, 02:20:51 pm »
I think Ondrej was responding specifically to the question of specifying alternative uses clauses depending on Lazarus version.
He was not suggesting you do anything, but that the Lazarus team might consider refactoring the LCLBase/LCL packages and add constants that avoided the need for explicit inclusion of LCLVersion as a unit in this sort of situation.
Currently one needs to include conditional directives (whether in a uses clause or elsewhere). Ondrej's proposal is a possibility for the future.

Hartmut

  • Sr. Member
  • ****
  • Posts: 357
Re: [SOLVED] How to compile conditional for FPC 3.0.4 and all later?
« Reply #24 on: January 10, 2020, 02:52:02 pm »
Ok, now I understand. Thanks for that clarification, howardpc. I will stay with my solution which I described in reply #12.