[Lazarus] Bug on CodeTools to find unit using in `../path/unit.pas`

Marcos Douglas B. Santos md at delfire.net
Mon Dec 10 01:33:47 CET 2018

On Sun, Dec 9, 2018 at 12:59 PM Juha Manninen via lazarus
<lazarus at lists.lazarus-ide.org> wrote:
> On Sun, Dec 9, 2018 at 2:06 PM Marcos Douglas B. Santos via lazarus
> <lazarus at lists.lazarus-ide.org> wrote:
> > Instead, can I add it on Search Path but using a macro or custom
> > definition, to get the path accordingly to Build Mode choose?
> Why?
> The "Other unit files (-Fu)" setting is part of Build Modes. You can
> set a different path for each Build Mode.

Indeed. I've answered quickly without thinking properly. Sorry.

However, this do not solve "my problem", which is not use Search Paths.
Why? I'll try to explain:
When I realized that I can use paths in uses clauses I thought that I
could use `alias for units`, which is better than "namespaces", IMHO.

So, using my example before, I could do that:
  `MyMsg in 'msg/msg.pas'`;

I just choose a new name for the file `msg.pas`, which is `MyMsg`.
It compiles. I can use it as a prefix, eg., `MyMsg.AFunction()`, and
it is great.
But if you put the `msg` folder in Search Path, the compiler will use
the same file name as the unit, ie, the identifier will be the same:
Then I thought: If I "register" the name what I want for `msg.pas` on
project (lpr), the compiler will use it in all code. However, as I've
explained before, it doesn't work on IDE, having some issues on
Then I thought: I could use the path on each uses clause, no problem.
If I need to change some path, I could just do a replace in all files
- no big deal. But, I discovered that I cannot use different `alias`
pointing to the same file, because there are some issues about classes
and interfaces.
For example:
unit A;
uses msg1 in 'msg/msg.pas'
unit B;
uses msg2 in 'msg/msg.pas'

As I understood, when the compiler knows about `msg.pas`, it will use
the first identifier that appeared, which is `msg1`. And that is a
problem. Why?
Consider that:

unit strings;
  TStr = type string;
unit b;
uses str in 'abc.strings.pas';
  IBar = interface
    procedure Exec(const s: TStr);
unit c;
uses abcstr in 'abc.strings.pas';
  TBar = interface
    procedure Exec(const s: TStr);

So, units B and C uses A, which has a `TStr` type declared.
The problem here is that `IBar` is using `TStr` as `str.TStr`
implicit; on C unit, `TBar` is using `TStr` as `abcstr.TStr`, and I
have a compiler error.
As I understand, the compiler uses units as prefix for types.

Finally, it turn back us for the original issue: if I can "register"
just one `alias` for an unit on the project (lpr), I could use it on
all code of my project, in theory.
And why this is "important"?
If I have an unit like "Some.Long.Name.Unit", I will could use it like:
  foo in 'path/Some.Long.Name.Unit.pas';

And I've discovered another issue on IDE:
If I use like above `foo in 'path/Some.Long.Name.Unit.pas';`, IDE will
save on XML project files the unit as `Some.Long.Name.Unit`, when it
should be `foo` as the name of the unit.

best regards,
Marcos Douglas

More information about the Lazarus mailing list