Recent

Author Topic: [SOLVED] Lazarus recompiles some of it's component-units although he should not  (Read 1599 times)

Hartmut

  • Hero Member
  • *****
  • Posts: 1103
That's very interesting. I "knew" that compiling is a complicated and complex thing, but now I know, it's yet much more complicated and complex ;-)

valdir.marcos

  • Hero Member
  • *****
  • Posts: 1186
Summary:
If I understand all this correctly, then there is a need, that packages DateTimeCtrls and SynEdit need to be (always) recompiled, if their compiled Units are older than those from packages LCLBase respective LCL.
Yes, I think is correct. Though that is not the compiler, but the IDE that decides that.

To the IDE, if a unit in DateTimeCtrls was build before the LCLBase was last build, then that DateTimeCtrls  uses an outdate version of LCLBase.

And well, yes and no: The IDE could check if the required ppu checksums are still ok. But afaik it does not.

So, if you would recompile LclBase, just to change the debug info included, which should give you all the same checksums => then technically that should not require a rebuild of DateTimeCtrls (because no code changed, in the used units). But the IDE will want to rebuild it anyway.


To add a bit on top of the explanation (for other also)

The IDE breaks compilation into packages.

The IDE decides if a package needs to be compiled at all or not. If there is a need it calls the compiler.
- For that it creates the "package main file" that just has a big "uses" clause with all the other units (if "Uses unit is checked for the units in the "package window").
- The compiler is called with this file. From there its up to the compiler what to compile
- However, at that point the compiler can only decide for units in that package, because
  => The IDE calls the compiler with
  - the "package main file
  - the path to any unit/include in that package (as configured in the "paths" section of the package option)
  - the PPU files of any required package.
  - but NOT any pas file of any required package
  => so the compiler at this time can not recompile any of those required packages. If those required package had needed recompilation, the IDE would have had to have called the compiler for them before.

That process happens for each package, the IDE decides for each package.




And the above explains the sometimes curious error "unitxyz.pas not found", even if that file clearly exists.

Due to a bug in the compiler, sometimes when a package is written, one of the PPU files gets the wrong checksum. Or actually get a wrong "I require Foo with checksum 123".

I don't know the details on the compiler issue, but you end up with
e.g. LazUtils/LazClasses having checksum 123
LazUtils/Foo saying: I was build with LazUtils/LazClasses that has a checksum 456

So Foo is wrong. The compiler build all those units in a single go, but it wrote Foo too early, when the checksum was not yet complete. So that got wrong.

Now you build SynEdit. Remember the compiler can see only the PPU of LazUtils. It does not see the pas files.
And now the compiler
- loads Foo.pp
- checks if all uses are ok
=> load LazClasses.ppu => ups different checksum
- Compiler goes Foo must be recompiled
- Compiler can not find Foo.pas

And there comes the error it can't find the pas file.


Do not try to fix that by adding the folder to the "paths" config.

Yes, then the compiler can see the pas file => but it will create a new 2nd ppu in the current package, and it will not replace/update the original ppu.
Then there are 2 ppu for the same package. And if further down the project wants that unit, the compiler has to chose between 2 ppu.
And you will all kind of other issues ....

Do not play with the "paths" settings, unless you really know what the IDE and the compiler do with that info.
;D  %)  :'(

creaothceann

  • Sr. Member
  • ****
  • Posts: 279
Summary:
If I understand all this correctly, then there is a need, that packages DateTimeCtrls and SynEdit need to be (always) recompiled, if their compiled Units are older than those from packages LCLBase respective LCL.
Yes, I think is correct. Though that is not the compiler, but the IDE that decides that.

To the IDE, if a unit in DateTimeCtrls was build before the LCLBase was last build, then that DateTimeCtrls  uses an outdate version of LCLBase.

And well, yes and no: The IDE could check if the required ppu checksums are still ok. But afaik it does not.

So, if you would recompile LclBase, just to change the debug info included, which should give you all the same checksums => then technically that should not require a rebuild of DateTimeCtrls (because no code changed, in the used units). But the IDE will want to rebuild it anyway.


To add a bit on top of the explanation (for other also)

The IDE breaks compilation into packages.

The IDE decides if a package needs to be compiled at all or not. If there is a need it calls the compiler.
- For that it creates the "package main file" that just has a big "uses" clause with all the other units (if "Uses unit is checked for the units in the "package window").
- The compiler is called with this file. From there its up to the compiler what to compile
- However, at that point the compiler can only decide for units in that package, because
  => The IDE calls the compiler with
  - the "package main file
  - the path to any unit/include in that package (as configured in the "paths" section of the package option)
  - the PPU files of any required package.
  - but NOT any pas file of any required package
  => so the compiler at this time can not recompile any of those required packages. If those required package had needed recompilation, the IDE would have had to have called the compiler for them before.

That process happens for each package, the IDE decides for each package.




And the above explains the sometimes curious error "unitxyz.pas not found", even if that file clearly exists.

Due to a bug in the compiler, sometimes when a package is written, one of the PPU files gets the wrong checksum. Or actually get a wrong "I require Foo with checksum 123".

I don't know the details on the compiler issue, but you end up with
e.g. LazUtils/LazClasses having checksum 123
LazUtils/Foo saying: I was build with LazUtils/LazClasses that has a checksum 456

So Foo is wrong. The compiler build all those units in a single go, but it wrote Foo too early, when the checksum was not yet complete. So that got wrong.

Now you build SynEdit. Remember the compiler can see only the PPU of LazUtils. It does not see the pas files.
And now the compiler
- loads Foo.pp
- checks if all uses are ok
=> load LazClasses.ppu => ups different checksum
- Compiler goes Foo must be recompiled
- Compiler can not find Foo.pas

And there comes the error it can't find the pas file.


Do not try to fix that by adding the folder to the "paths" config.

Yes, then the compiler can see the pas file => but it will create a new 2nd ppu in the current package, and it will not replace/update the original ppu.
Then there are 2 ppu for the same package. And if further down the project wants that unit, the compiler has to chose between 2 ppu.
And you will all kind of other issues ....

Do not play with the "paths" settings, unless you really know what the IDE and the compiler do with that info.
;D  %)  :'(

...

 

TinyPortal © 2005-2018