We've been fixing bugs in the VCL in Delphi XE6. So far the folder contains:
| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas
And we add the folder to our Library search path:
Along the way, we learned that we have to confine our fixes to the implementation
section only. Otherwise the hash signatures of symbols in the interface
section change. This causes the linker to realize that the symbols inside the DCU are not the same version they expect.
Barry Kelly had a good explanation for this behavior:
The important concept is that of symbol version. When saving a DCU, Delphi calculates a hash based on the interface declaration of the symbol and associates it with the symbol. Other units that use the symbol also store the symbol version. In this way, link-time conflicts caused by stale symbols are avoided, unlike most C linkers.
The upshot of this is that you should be able to add Classes.pas to your project and modify its implementation section almost to your heart's content, and still be able to statically link with the rest of the RTL and VCL and third-party libraries, even those provided in object format only.
Things to be careful of:
- Inlined routines; the body of inlined routines are part of the symbol version
- Generics; the implementation side of generic types and methods are part of the respective symbol versions
So we took pains to confine the bugfixes to the implementation section (e.g. introducing new cracker classes, rather than overriding the method in the public-facing class).
And then
Then I went to make a fix in Vcl.Themes.pas
. I start simple, copying the file and placing it in the fixes folder:
| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas
|----- Vcl.Themes.pas
Even though I have not (yet) even modified Vcl.Themes.pas
, the compiler chokes on it:
[dcc32 Fatal Error] Vcl.Themes.pas(2074): F2051 Unit Vcl.Forms was compiled with a different version of Vcl.Themes.TMouseTrackControlStyleHook
Why
The important question is:
Why is this happening?
What is going on that the compiler is unable to realize that the exact same file is the exact same file? Is it possible that the VCL source shipped with XE6 is incorrect, and doesn't match what ships in the DCUs? Does it have something to do with library search order? Does it have something to do with inlining, generics, iterators, platforms, debug dcus, 64-bit compiler, ifdefs, code completion, synergy, outside the box?
There are the other, implicit, questions that go along with trying to answer the why:
Why does it work for two other files, but not this one?
Why does it fail when I didn't even change the file?
What have you tried?
- tried moving
VCL Source Fixes
higher and lower in the search path - tried turning on Use debug dcus
- tried switching to 64-bit platform
- tried deleting all
dcu
files in my project's folder (although not deleting theD:\Programs\Embarcadero\Studio\14.0\lib\win32\release\Vcl.Themes.dcu
that ships with Delphi XE6) - closing XE6 and re-running it
- going to Wendy's for lunch
Of course I want to fix it. But more than wanting to fix it I want to understand why it's failing. The compiler isn't employing magic, voodoo, or Q-like powers. It's a deterministic machine, and is operating according to a fixed set of (undocumented) rules.
Why is this happening?
Ctrl+O+O
to insert the "standard" compiler options at the top of the replacement pas file. That's why i was going to answer it here: so it has an answer rather than random stumblings elsewhere :) – Muscovado