Lazarus

Using the Lazarus IDE => General => Topic started by: bpranoto on August 31, 2019, 07:19:25 am

Title: Lazarus wrongly pick up unit file
Post by: bpranoto on August 31, 2019, 07:19:25 am
Lazarus v2.0.2 and FPC version 3.0.4

I have units base_modul.pas and the_modul.pas, the_modul pas contains a class inherited from the base class in base_modul.pas

Later on, for another project I need a customized modul from the base class, so I write a new the_modul.pas in a sub directory, the name of the sub directory is "custom".

The .lpi file correctly stores the customized modul as below:

Code: XML  [Select]
  1.       <Unit2>
  2.         <Filename Value="base_modul.pas"/>
  3.         <IsPartOfProject Value="True"/>
  4.         <ComponentName Value="FormBaseModul"/>
  5.         <HasResources Value="True"/>
  6.         <ResourceBaseClass Value="Form"/>
  7.       </Unit2>
  8.       <Unit3>
  9.         <Filename Value="custom/the_modul.pas"/>
  10.         <IsPartOfProject Value="True"/>
  11.         <ComponentName Value="FormModul"/>
  12.         <HasResources Value="True"/>
  13.         <ResourceBaseClass Value="Form"/>
  14.       </Unit3>
  15.  

However, on compiling the IDE still picks up  the standard the_modul.pas which resides in the app directory.

Attached is the demo project.

Do I meet a bug or do I miss something?

Title: Re: Lazarus wrongly pick up unit file
Post by: PascalDragon on August 31, 2019, 11:16:30 am
Your problem is probably the order of the search paths. FPC first searches in the specified output directory, then the directory of the compiled source file (in your case the *.lpr file) and only then the other supplied directories. So you need to restructure your source code better.
Title: Re: Lazarus wrongly pick up unit file
Post by: bpranoto on August 31, 2019, 12:28:34 pm
Your problem is probably the order of the search paths. FPC first searches in the specified output directory, then the directory of the compiled source file (in your case the *.lpr file) and only then the other supplied directories.


I thought as the directory is explicitly specified in the .lpi file it should not search on search paths. It looks a bug to me, isn't it?

So you need to restructure your source code better.

Yes thank you.  As a workaround I renamed the customized unit name.

However, maintaining several project will be easier if the ide doesn't search the paths if the unit directory specified explicitly.
Title: Re: Lazarus wrongly pick up unit file
Post by: Martin_fr on August 31, 2019, 12:36:24 pm
Lazarus stores what you edit.

However compilation is not done per file. Compilation is done per directory.
If you have one file, in one directory, then all other files in that dir will be included.


You can either:

Have several projects (and a project group), each in its own directory. (And do not touch any path settings)
Move common files into a package. That is highly recommended.
That may be awkward if your main form is common....


Move all "the_modules" into diff subdirs, and then you can use only one.
You still do not need to play with path settings)
Or use {$IFDEF} and "uses the_module in dir/file"
Title: Re: Lazarus wrongly pick up unit file
Post by: bpranoto on August 31, 2019, 01:01:29 pm

... "uses the_module in dir/file"

Did you mean something like below? I tried but it fails to compile...

Code: Pascal  [Select]
  1. implementation
  2.  
  3. uses custom/the_modul;
  4.  
  5. {$R *.lfm}
  6.  
  7. { TForm1 }
  8.  
  9. procedure TForm1.Button1Click(Sender: TObject);
  10. var
  11.   F : TFormModul;
  12. begin
  13. ...            
  14.  
Title: Re: Lazarus wrongly pick up unit file
Post by: Martin_fr on August 31, 2019, 01:09:06 pm
https://stackoverflow.com/questions/1990202/uses-with-unit-file-path-in-unit-file
Title: Re: Lazarus wrongly pick up unit file
Post by: bpranoto on August 31, 2019, 01:38:40 pm
https://stackoverflow.com/questions/1990202/uses-with-unit-file-path-in-unit-file

The link above refers to a delphi feature unit aliasing. Is this feature available in fpc/lazarus?

Title: Re: Lazarus wrongly pick up unit file
Post by: Thaddy on August 31, 2019, 03:14:01 pm
yes, the feature is available in full in FPC 3.2.0 but not in 3.0.,4 See https://wiki.freepascal.org/FPC_New_Features_3.2#Default_unit_scopes

Note that FPC 3.0X DOES support explicit unit scoping, as in referencing an implementation from a certain unit that has a duplicate elsewhere.
Title: Re: Lazarus wrongly pick up unit file
Post by: Martin_fr on August 31, 2019, 04:13:15 pm
"uses ... in 'path/unitname.pp'"

Did the "in" only come with scoped unit names?

I know scoped unit names are new, but while I never use it myself, I would have thought "in" to be older.


Well if not, consider using include files.

My advice: stay away from changing any path, in the "project options > path" settings.  A lot of people who tried that, ended up with more problems than they had before.
That said, they are a valid option, and if you do it right they will work.
Title: Re: Lazarus wrongly pick up unit file
Post by: Thaddy on August 31, 2019, 04:26:02 pm
scoped unit names are new in so far as they are resolved from the uses clause.
Referencing unit members has been possible since a very, very long time.
E.g. graphics.Tpoint vs Windows.TPoint and the likes.
The in is since 2.6 or something, probably older and goes only for the program part.

I am a bit bemused you did not know that being you, or did you mean something else...
Title: Re: Lazarus wrongly pick up unit file
Post by: Martin_fr on August 31, 2019, 04:33:24 pm
I am not talking about referencing ....

I just tested 3.0.4 has "in"

Code: Pascal  [Select]
  1. uses a in '/foo/a.pp';

However this is not a scoped unit. So there still is only one unit "a" in all paths of the entire project allowed.
Title: Re: Lazarus wrongly pick up unit file
Post by: Thaddy on August 31, 2019, 04:38:15 pm
Yes,? that always worked... Still not clear what you mean. to me..
There is a distinct difference with the new unit scoping, which is more like Java and has precedence, if that helps.
Lazarus does not support it, but FPC 3.2. does. -FN<> option
Title: Re: Lazarus wrongly pick up unit file
Post by: Martin_fr on August 31, 2019, 04:59:19 pm
If he wants to go the path of:
- having ONE "the_modul" per setup (be that project, sub-project?, build, ...),
- but have a different "the_modul" per setup
- and wants to archive it by putting all his "the_modul" into sub-directories (that means NONE is in path by default)

Then he can use "uses .. in..".

That would allow him to stay clear of changing any fpc path options. => Yes, it is possible to use them. But plenty of people who have done so, have only dug the hole - that they were in - even deeper. (And yes there are people who succeeded using path. And I make no statement about numbers in each group.)
Title: Re: Lazarus wrongly pick up unit file
Post by: Thaddy on August 31, 2019, 05:23:32 pm
Yes, but... Lazarus does not support it... FPC does.... That's what you get when you take a short-cut and want to use over-complicated configuration files ON-TOP-OFF a perfectly parseable program structure. < >:D as you could expect. Bad design is bad design even if the details show up years later).
Title: Re: Lazarus wrongly pick up unit file
Post by: Thaddy on August 31, 2019, 05:30:00 pm
You can not use the in on a unit level. anyway I have a more serious look later, should be possible. (even by deleting the *.lpi and let it regenerate by opening the *.lpr, note I and R: I means shit a not fully architected meta-information storage, whereas (lp) R is a program.)
Title: Re: Lazarus wrongly pick up unit file
Post by: bpranoto on August 31, 2019, 05:31:38 pm
... anyway I have a more serious look later, should be possible.

Thank you very much Thaddy..
Title: Re: Lazarus wrongly pick up unit file
Post by: Martin_fr on August 31, 2019, 05:39:17 pm
Code: [Select]
[quote ]
However, it still compiles the wrong unit file in the app directory
- and wants to archive it by putting all his "the_modul" into sub-directories (that means NONE is in path by default)

Again, no matter what you do: Within the collection of all and any path that you compile any unit from => Each unit can only exists once.

So the other "the_modul" must be in a sub directory too. And at any time, only one of the 2 subdirectories is allowed to be included.


As Thaddy says, using directories that way, to cope with alternate units of the same name: Always a problem.

All my approach attempts to do, is to keep the problem as small as possible.


What you really have is 2 projects. (in one projectgroup)
The shared code should be in a package.
But that is a lot more work to set up.

Or if the_modul is code only (and no lfm). Or differs in code only... Then you only need one file (and only one project, and no package). And a big IFDEF inside it.
Title: Re: Lazarus wrongly pick up unit file
Post by: Thaddy on August 31, 2019, 05:39:56 pm
in the simplest case, which almost always work,
Open up the lpR file and then specify the unit in the uses clause with in.

So: e.g:
Code: Pascal  [Select]
  1. program useless;
  2.   uses my_special in './extra/special.pas',
  3.   sysutils, classes, lclintf, whatever;
  4.  
Here's the whatever unit...., it is free...
Code: Pascal  [Select]
  1. unit whatever;
  2. interface
  3. implementation
  4. end.
That's being sarcastic on purpose, with good intention. (take it with a light heart and attack on content)
Title: Re: Lazarus wrongly pick up unit file
Post by: PascalDragon on September 01, 2019, 11:47:32 am
However, maintaining several project will be easier if the ide doesn't search the paths if the unit directory specified explicitly.
The IDE has nothing to do with it. It's the compiler and it is by design: you only provide directories to the compiler, not filenames. The compiler itself searches the files and there the rule is first come first serve (and the unit output directory as well as the directroy of the main program file are always first).

You can not use the in on a unit level. anyway I have a more serious look later, should be possible. (even by deleting the *.lpi and let it regenerate by opening the *.lpr, note I and R: I means shit a not fully architected meta-information storage, whereas (lp) R is a program.)
Contrary to your believe in can indeed be used on the unit level as well. However if relative paths are used the compiler currently uses its current working directory to resolve these. I'll have to check whether this is by intention, cause for units it would definitely be better if the directory of the currently compiled unit is used as basepath...
Title: Re: Lazarus wrongly pick up unit file
Post by: bpranoto on September 01, 2019, 11:59:41 am
The IDE has nothing to do with it. It's the compiler and it is by design: you only provide directories to the compiler, not filenames. The compiler itself searches the files and there the rule is first come first serve (and the unit output directory as well as the directroy of the main program file are always first).

Thank you for the explanation.

On the positive side it forces us to give good and clear unit file names which will eliminate ambiguities.