Recent

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

Hartmut

  • Hero Member
  • *****
  • Posts: 1103
By accident I made an unwanted change in a Lazarus sourcefile (I assume to lazarus/components/lazutils/lconvencoding.pas but not 100% sure). Then I compiled, which saved this unwanted change and as a result > 500 Lazarus / LCL files were recompiled.

The problem is: all my fpc.cfg files include
Code: Text  [Select][+][-]
  1. # Set default codegeneration checks (iocheck, overflow, range, stack)
  2. -Ci
  3. -Co
  4. -Cr
  5. -Ct
  6. -CR
to be sure that all compiles have these defaults (even if they are made with FPC compiler directly without Lazarus). BUT: unfortunately many Units of Lazarus / the LCL don't work with these settings (especially not with '-CR': they cause many "Range check" runtime-errors).

To repair my damaged Lazarus installation I replaced all > 500 changed files (including all '*.compiled' files and the damaged sourcefile) from a backup. Mostly this worked, but there are 6 files left, which are recompiled after each restore, although their content and their timestamp (exactly to the seconds) before were identically with the backup:
Code: Text  [Select][+][-]
  1. lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.compiled
  2. lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.o
  3. lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.ppu
  4. lazarus/components/synedit/units/x86_64-linux/gtk2/allsynedit.o
  5. lazarus/components/synedit/units/x86_64-linux/gtk2/allsynedit.ppu
  6. lazarus/components/synedit/units/x86_64-linux/gtk2/synedit.compiled
Even if I restore fpc.cfg with it's original after installation (so it does not contain my above changes) and restore above 6 recompiled files from it's backup and in Lazarus / Compilersettings / Debugging I additionally deactivated these 5 checks and all other files in this Lazarus installation (except folder 'config_lazarus') are identically with the backup (with content and timestamp exactly to the seconds), always above 6 files are recompiled once (their new content is identically with the backup, but their timestamps of course are from today).

I fear, that these 6 new timestamps can lead in the future, that other Units of Lazarus / the LCL, which depend on these 6 files, are someday recompiled too (with wrong settings in fpc.cfg and/or in Compilersettings / Debugging).

So I want a) to repair this Lazarus installation and b) understand, how/why/who decides, that these 6 files are "always" recompiled, although I can't see a reason for that.

I'm on Linux (Ubuntu 24.04 64-bit) and Lazarus/FPC version is 3.4.0/3.2.2. The Lazarus installation was made by fpcupdeluxe in July 2024, a 32-bit cross compiler exists (since that time), but the current project, which recompiles above 6 files automatically, is 64-bit.

Summary of my questions:
 - how does Lazarus/FPC decide, whether a Unit belonging to Lazarus / the LCL has to be recompiled?
 - has someone an idea, what could cause the "unneccessary" recompile in my case?
Thanks in advance.
« Last Edit: February 11, 2026, 04:19:44 pm by Hartmut »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12195
  • Debugger - SynEdit - and more
    • wiki
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #1 on: February 10, 2026, 01:15:14 pm »
I don't know the answer to most of it, but at least one observation...

the 2 files you pointed out are the packages "main" files.

I.e. they are autogenerates files. The IDE generates them from the lpk, and includes all units in it (well all that are configured as "used" in the package). This is the file that is then given to the compiler when the package is compiled.

The (re-)generation of that pas file is not done by the compiler, so -UR etc wont stop that.
If the IDE thinks the lpk changed.... Then that is what happens.

You may want to check menu: view > ide internals > what needs building

maybe it has hints....

Hartmut

  • Hero Member
  • *****
  • Posts: 1103
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #2 on: February 10, 2026, 02:24:26 pm »
Thanks a lot Martin_fr for your fast reply. I used packages only once and long ago, so my knowledge about is very small.

In my current project (which recompiles above 6 files "without need") I try to use a part of foreign code (a part of the Double Commander). To be able to compile this part I had to add these packages to the Projectinspector:
Code: Text  [Select][+][-]
  1. DateTimeCtrls
  2. LazControls
  3. SynEdit
  4. LCLBase
  5. LazUtils

I used this Lazarus installation not often. I never compiled any package in it (only what the installation itself did). It might be, that packages DateTimeCtrls and SynEdit now are "used" the 1st time.
But their 6 compiled files already did exist all the time since installation time (July 19th 2024, 4:52:07 pm).
I checked their lpk files:
Code: Text  [Select][+][-]
  1. lazarus/components/datetimectrls/datetimectrls.lpk
  2. lazarus/components/synedit/synedit.lpk
They have exactly the same timestamp (exactly to the seconds) as above 6 "always" changed files (July 19th 2024, 4:52:07 pm) and their contents are identically with the backup.
So from my understanding I see no reason to recompile them.
And why are the 3 other packages not recompiled?

I checked menu "view > ide internals > what needs building" after my project was compiled, that means above 6 files already have a timestamp from today and now they are not recompiled again, when I call Menu Run / Compile (I just shortened the list a bit):

Target: FCL 1.0.1 Clean build needed. File: /opt/lazarus_340/lazarus/packager/registration/fcl.lpk
Target: LazUtils 1.0 Clean build needed. File: /opt/lazarus_340/lazarus/components/lazutils/lazutils.lpk
Target: freetypelaz 1.0 Clean build needed. File: /opt/lazarus_340/lazarus/components/freetype/freetypelaz.lpk
Target: LCLBase 3.4 Clean build needed. File: /opt/lazarus_340/lazarus/lcl/lclbase.lpk
Target: DateTimeCtrls 1.5.1 Clean build needed. File: /opt/lazarus_340/lazarus/components/datetimectrls/datetimectrls.lpk
Target: LCL 3.4 Clean build needed. File: /opt/lazarus_340/lazarus/lcl/interfaces/lcl.lpk
Target: LazControls 1.0.1 Clean build needed. File: /opt/lazarus_340/lazarus/components/lazcontrols/lazcontrols.lpk
Target: SynEdit 1.0 Clean build needed. File: /opt/lazarus_340/lazarus/components/synedit/synedit.lpk
Target: Project codpag No build needed. File: /media/D/FPC/work/einmal/codpag_Lx.lpi

You see, that all but the last report "Clean build needed". Strange...

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12195
  • Debugger - SynEdit - and more
    • wiki
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #3 on: February 10, 2026, 02:32:48 pm »
I don't really know much more. There are usually modification, creation and a 3rd time. I don't know which is used where....
And they may be timezone sensitive / there is this "all file changed" when the clock changes from/to summertime.

Another idea (but just blindly guessing), the times are diff on each install anyway. there is on hardcoded time. Times are compared between sets of 2 (or more???) files. So there must then be another file with a time...

If you have write protected sources, then there will be a shadow build area in the PCP (usually ~/.lazarus).

creaothceann

  • Sr. Member
  • ****
  • Posts: 278
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #4 on: February 10, 2026, 02:50:34 pm »
Not sure about Linux, but on Windows I can simply uninstall Lazarus, clear out the directory from any leftover files, and reinstall it to the same directory. The config files are stored elsewhere.

Bart

  • Hero Member
  • *****
  • Posts: 5706
    • Bart en Mariska's Webstek
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #5 on: February 10, 2026, 06:17:29 pm »
unfortunately many Units of Lazarus / the LCL don't work with these settings (especially not with '-CR': they cause many "Range check" runtime-errors).

-CR is not about RangeChecking, it is "Verify object method call validity" (the LCL does not like that either though)
-Cr is RangeChecking

Bart

Hartmut

  • Hero Member
  • *****
  • Posts: 1103
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #6 on: February 10, 2026, 07:03:22 pm »
I made a mistake, so one of the details I wrote above is wrong, but I don't see, that this could explain the problem. When I had done the check for the 2 .lpk files:
Code: Text  [Select][+][-]
  1. lazarus/components/datetimectrls/datetimectrls.lpk
  2. lazarus/components/synedit/synedit.lpk
I wrote, that they are absolute identically with the backup (in content and timestamp), that was true.
But I wrote too, that their timestamp (July 19th 2024) was identically with the 6 above changed files (after restoring them from the backup), but that was wrong (I had checked so many things so many times, that I made this mistake). The timestamp of the 6 above changed files inside the backup is July 27th 2024, so they are 8 days jounger then their .lpk files. And all .pas files of the 2 packages have July 19th 2024 too (same timestamp as the .lpk files).
So again I can't see a reason to recompile them.

Not sure about Linux, but on Windows I can simply uninstall Lazarus, clear out the directory from any leftover files, and reinstall it to the same directory. The config files are stored elsewhere.
This is not the 1st time where I damaged accidently a Lazarus / LCL sourcefile and fall into trouble and I assume not the last time. I hope (with the help of this Forum) to understand the problem, so that I can solve it - now and in the future - without always reinstalling everything again, which should be the very very last option...

-CR is not about RangeChecking, it is "Verify object method call validity" (the LCL does not like that either though)
-Cr is RangeChecking
Of course, you are right, my mistake. But I had disabled both, so it should not matter.

There are usually modification, creation and a 3rd time. I don't know which is used where....
And they may be timezone sensitive / there is this "all file changed" when the clock changes from/to summertime.
From my understanding only the "last modified" timestamp would make sense here. I would expect, that this timestamp is compared between a sourcefile and it's already compiled *.o or *.ppu files, but in reality it seems not to be so easy.

Quote
Another idea (but just blindly guessing), the times are diff on each install anyway. there is on hardcoded time. Times are compared between sets of 2 (or more???) files. So there must then be another file with a time...
Additionally there are a lot of '*.compiled' files, which include a timestamp like
<Compiler Value="/opt/lazarus_340/fpc/bin/x86_64-linux/fpc.sh" Date="1721400717"/>
I assume, this is a Unix timestamp in seconds after 1970. But as I said, I had compared the complete Lazarus installation with the backup and all files had the same content and same timestamp.

Quote
If you have write protected sources, then there will be a shadow build area in the PCP (usually ~/.lazarus).
No, my sources are not write protected (but it would be great, if they were). But they are split over so many folders, that it would be much work to write protect all of them, without to write protect all unit folders.

Questions:
Is there anybody who knows in detail, how the compiler definitively decides, in which case an existing unit is recompiled or not?
Maybe one of the compiler experts? Maybe @PascalDragon?

And if it would be, that packages DateTimeCtrls and SynEdit now are "used" the 1st time in this Lazarus installation: wohld this be a reliable reason, to recompile above 6 files, although they already exist and although their timestamp is younger then the .lpk files and all their .pas files?

Hartmut

  • Hero Member
  • *****
  • Posts: 1103
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #7 on: February 11, 2026, 09:26:21 am »
I made a test to find an answer to this question:
Quote
if it would be, that packages DateTimeCtrls and SynEdit now are "used" the 1st time in this Lazarus installation: would this be a reliable reason, to recompile above 6 files, although they already exist and although their timestamp is younger then the .lpk files and all their .pas files?
I used a Lazarus trunk installation from Feb. 2024 where I was sure, that I never used package DateTimeCtrls with this installation. I created a small project with a TDateTimePicker, so package DateTimeCtrls was added automatically to the project. Before I compiled, I made a backup of these 5 files:
Code: Text  [Select][+][-]
  1. 15.02.2024 09:53:11 2011 lazarus/components/datetimectrls/datetimectrls.lpk
  2. 15.02.2024 09:53:11  425 lazarus/components/datetimectrls/datetimectrls.pas
  3. 15.02.2024 10:40:44  638 lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.compiled
  4. 15.02.2024 10:40:44 4320 lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.o
  5. 15.02.2024 10:40:44 1128 lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.ppu

After compiling I checked, that these 5 files had exactly the same content and timestamp as before.
This makes me conclude, that if a package is "used" the 1st time in a Lazarus installation, that there is no need to recompile it (if it already exists and the timestamp of the unit files is younger than the .lpk file and the .pas file, which is the normal case after the installation procedure made by fpcupdeluxe).

After this I compiled the same project (which caused the recompile of above 6 files in my "damaged" Lazarus installation) in above trunk installation from Feb. 2024. Result: above 6 files were not recompiled (and no other unit file in this Lazarus installation was recompiled).

So again I don't understand, why in my Lazarus/FPC 3.4.0/3.2.2 installation above 6 files from packages DateTimeCtrls and SynEdit are recompiled (once after each restore of them from the backup).

Still open question:
Is there anybody who knows in detail, how the compiler definitively decides, in which case an existing unit is recompiled or not?
Maybe one of the compiler experts? Maybe @PascalDragon?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12195
  • Debugger - SynEdit - and more
    • wiki
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #8 on: February 11, 2026, 12:15:53 pm »
Still open question:
Is there anybody who knows in detail, how the compiler definitively decides, in which case an existing unit is recompiled or not?
Maybe one of the compiler experts? Maybe @PascalDragon?

Are you sure the issue is what the compiler does?

You do list the files
- datetimectrls.lpk
- datetimectrls.pas

The compiler never sees the lpk file. Anything that is about the lpk file is done by code inside Lazarus, not by the compiler.

So, if for some reason the datetimectrls.pas file is re-created, then that is done by the IDE, not the compiler.

(And once that file has been recreated, and has a newer date, then if the IDE calls "fpc datetimectrls.pas" that will have the compiler recompile it because it is by then "changed/newer"). I don't know so if FPC should ignore the IDE if it was compiled with -Ur. Or if the IDE passes any flags to force it, or ....



All that said, no idea how the IDE decides to rewrite the file.

Hartmut

  • Hero Member
  • *****
  • Posts: 1103
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #9 on: February 11, 2026, 12:39:24 pm »
So, if for some reason the datetimectrls.pas file is re-created, then that is done by the IDE, not the compiler.

Seems that we misunderstood Martin_fr. File datetimectrls.pas was never re-created nor changed in any way nor was it's timestamp changed ever. The 6 "always" recompiled files (see my very 1st post) are these:
Code: Text  [Select][+][-]
  1. lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.compiled
  2. lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.o
  3. lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.ppu
  4. lazarus/components/synedit/units/x86_64-linux/gtk2/allsynedit.o
  5. lazarus/components/synedit/units/x86_64-linux/gtk2/allsynedit.ppu
  6. lazarus/components/synedit/units/x86_64-linux/gtk2/synedit.compiled

File datetimectrls.pas has and always had this properties and it's content was always identical with the backup:
Code: Text  [Select][+][-]
  1. 19.07.24 15:52:07  2011 lazarus/components/datetimectrls/datetimectrls.lpk
  2. 19.07.24 15:52:07   425 lazarus/components/datetimectrls/datetimectrls.pas

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12195
  • Debugger - SynEdit - and more
    • wiki
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #10 on: February 11, 2026, 12:44:41 pm »
Ok, then
  -va

Well, I don't know. You have to add it so the IDE does not see it, or the IDE will force recompilations.

And, I don't know if the compiler sees that as "different options as the previous build"....
If not, then it will tell the compiler to output tons of details, and maybe in that output is a hint.  Maybe... or maybe not. But its the best next thing to try, that I can think of.

Hartmut

  • Hero Member
  • *****
  • Posts: 1103
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #11 on: February 11, 2026, 04:18:17 pm »
Hello Martin, to try '-va' was a very good suggestion, although it was not easy to get the result...
 - setting '-va' in fpc.cfg did not work, because it is overridden by the Compiler Options of the .lpi file
 - so in Lazarus / Compiler Options / Verbosity "Show everything (-va)" must be enabled
 - to see the resulting output, I started Lazarus from a Console, but nothing of interest was displayed there
 - but with "lazbuild --pcp=... --verbose filename.lpi > outputfile" it worked (wrote 87 MB with 947000 lines)

The output contains:
Code: Text  [Select][+][-]
  1. ...
  2. Hint: (lazarus) [TBuildManager.SetBuildTarget] Old=x86_64-linux-gtk2 New=x86_64-linux-gtk2 Changed: OS/CPU=True LCL=False
  3. Hint: (lazarus) [TBuildManager.SetBuildTarget] Old=x86_64-linux-gtk2 New=x86_64-linux-gtk2 Changed: OS/CPU=True LCL=False
  4. Hint: (lazarus) State file of LCLBase 3.4 is newer than state file of Package: DateTimeCtrls 1.5.1
  5. Hint: (lazarus) State file of LCL 3.4 is newer than state file of Package: SynEdit 1.0
  6. Hint: (lazarus) [TBuildManager.MacroFuncInstantFPCCache] CacheDir=
  7. Info: (lazarus) Execute Title="Compile Package DateTimeCtrls 1.5.1"
  8. ...
  9. Info: (lazarus) Execute Title="Compile Package SynEdit 1.0"
  10. ...

I assume the "state file" is the *.compiled file. For packages LCLBase and LCL they are:
Code: Text  [Select][+][-]
  1. 01.01.2025 16:00:30 701 lazarus/lcl/units/x86_64-linux/gtk2/lcl.compiled
  2. 01.01.2025 16:00:29 698 lazarus/lcl/units/x86_64-linux/lclbase.compiled
while for packages DateTimeCtrls and SynEdit (after restoring from the backup) they are older:
Code: Text  [Select][+][-]
  1. 15.02.2024 10:40:44  638 lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.compiled
  2. 15.02.2024 10:40:44 4320 lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.o
  3. 15.02.2024 10:40:44 1128 lazarus/components/datetimectrls/lib/x86_64-linux/gtk2/datetimectrls.ppu
  4. 27.07.2024 12:53:08 4592 lazarus/components/synedit/units/x86_64-linux/gtk2/allsynedit.o
  5. 27.07.2024 12:53:08 6802 lazarus/components/synedit/units/x86_64-linux/gtk2/allsynedit.ppu
  6. 27.07.2024 12:53:08  716 lazarus/components/synedit/units/x86_64-linux/gtk2/synedit.compiled

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.
So in my case, having accidently damaged a Lazarus sourcefile, was most probably not the reason for that recompile (unfortunately both events only happend the same time, suggesting a causal relationship, which did not exist).

Thanks a lot to Martin_fr for your continuous and valuable help!

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12195
  • Debugger - SynEdit - and more
    • wiki
Re: Lazarus recompiles some of it's component-units although he should not
« Reply #12 on: February 11, 2026, 04:27:41 pm »
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.

Hartmut

  • Hero Member
  • *****
  • Posts: 1103
Thanks for this expalations.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12195
  • Debugger - SynEdit - and more
    • wiki
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.
« Last Edit: February 11, 2026, 05:35:49 pm by Martin_fr »

 

TinyPortal © 2005-2018