Delphi Compile and Build produce different binary on same project
Asked Answered
C

3

7

In a fresh VCL application Compile and Build operation produce the same binary and map file (with minor differences at the end of .exe file even if "include version information in project" option is switched off - already discussed). Map file is the same byte to byte. But wen I add any third-party component the binary and map(!) file produced by Build and Compile are significantly different!

Tested on two versions of Delphi:
- Version 7.0 (Build 8.1)
- CodeGear™ RAD Studio 2007 Version 11.0.2902.10471 (+December 2007 Update)

Step to reproduce:

  1. Create New VCL Application. Possibly add any native Delphi component (I try all components from Standart, Additional, Win32 and System tab).
  2. Turn on Detailed Map file on Linker tab of the Project Options.
  3. Build project.
  4. Rename output .exe and .map file (for example: project1.exe to project1b.exe and project1.map to project1b.map).
  5. Compile project.
  6. Rename output .exe and .map file (for example: project1.exe to project1c.exe and project1.map to project1c.map).
  7. Compare files from step 4 and 6. (I use WinMerge 2.12.4.0).

We have little different .exe files and fully identical .map files. Then if we repeat all steps again but use in the project third-party component (I try ODAC, DOA, DevExpress and selfmade) we get more different .exe and different .map files.

Why? Any suggestions?

UPDATE
Some information about how I found this and why it's interests me:
Project is build from simple script with MSBuild. When in the project was added translation thru ITE (dll with resources) I found that when project was Build (from script or from IDE) - translated version work wrong - some text on button, labels etc. got from wrong place (literally from another button, labels). When project Compiled from IDE - everything is ok. So I start compare Build and Compile output...

Clench answered 6/1, 2010 at 13:45 Comment(7)
No idea, but start your tests with simpler 3rd party components, and only then go to more complicated ones. Also make sure the sources remain 100% the same. Different USES clauses (including order!) might change the layout of unit initalization tables, and thus the binary.Hormuz
Sources remain 100% the same - I only do build and compile.Eyewitness
You'll also find that Build and Build produce different binaries. It has nothing to do with the difference between compiling and building.Discern
@Rob: What do you mean that Build and Build produce different binaries? Do you mean Compile and Build?Lalonde
No, Ryan. Max said that if you build and then compile, you'll get different results. But if you build and then build again, you'll still get different results. The difference between compiling and building is irrelevant in this case.Discern
@Rob: Ah, ok. I see what you meant, thanks for explaining.Lalonde
I also noticed the binaries are different between two builds without changing anything of the project, I ended up forget about it since the execution of the binaries are the same.Galwegian
L
12

What you're seeing is simply an artifact of the built-in make logic of the compiler. When you do a build, it tells the compiler to build all available sources. So Delphi processes each source file and for each unit in the uses lists for which it finds source, it will then build that file. It does this recursively. When you do a compile, only the existing .dcu files are loaded and if they're found to be up-to-date, nothing is done. This can actually lead to a different order in which the units are discovered since each .dcu will effectively "flatten" the uses list. Since the units are discovered and loaded in a different order, they are in-turn, linked in a different order. This is why your map files look so different. Given the same sources, the map file should be the same if you do two builds in a row or two compiles in a row.

Other causes for differences are more mundane and include things like the PE header time stamp, and other bits of padding and alignments.

Lepidosiren answered 6/1, 2010 at 19:3 Comment(7)
@Allen: Thanks for the details Allen, I didn't know about the DCU portion of it but that makes sense. Thanks for explaining it. Would it be possible then to allow the compiler to make use of a compiler hint direct the compiler to always link in units, either DCU or PAS files, always in a certain order?Lalonde
That would kind of defeat the whole purpose, no? Also, the typical Delphi application links to units that you are probably totally unaware even exist. The linking order is determined by the internal ordering of the compiler symbol table itself. It is key to how the compiler works. Why don't you simply use an automated build process for your "official" builds which are always built from the raw sources (ie. no dcus exist on the building system)?Lepidosiren
@Allen: I use automated build process. But when I added translation to my project (using Delphi Integrated Translation Environment - dll with resources) it broke - when used dll with translated resources UI look like some text captions got from wrong place. So when I (or script) do Build - translation doesn't work. When I do Compile - translation works fine. After some investigation I found the differences between compile and build. I am embarrassed...Eyewitness
Are you using the --drc option from the compiler to generate the .drc file? This is a compiler-generated file that describes all the resource strings and their identifiers. That file can be processed and run through brcc32 to generate a translated resource strings.Lepidosiren
No. I just use Project->Languages->Add... (or File->New->Other...->Delphi Projects->Resource DLL Wizard) and IDE generates new project (dll with resources - not only with resourcestring but with pablished properties from all objects in dfm) based on the master project.Eyewitness
@Allen: BTW, the help file doesn't describe how resource ID may change. Is it okay to use old resource DLL with updated project (+ 3 new resourcestring)? If I don't add resourcestrings/edit DFM, but I edit sources and do many builds - will IDs change?Salaam
@Alex, yes it is possible for the resource ids to change. Most notably, a change in link-order (due to the above described behavior) can change the actual string id allocation. The compiler always allocates resource string ids from the highest value down. Whereas, were you to manually manage resource strings, one would typically count up. This allows for you to manually manage some strings and use resource strings. This minimizes the risk of a string id collision.Lepidosiren
L
3

There is two parts to this answer I believe.

Part of the problem your seeing, IIRC, is that the compiler doesn't zero out memory before doing a compile/build. Thus anything left in uninitialized memory becomes filler in the output for alignment purposes.

I also seem to recall that there is a date time stamp included in the pe header information for the application. that will cause a difference every time.

I'm not the best person to confirm this but this is what I seem to recall from past discussions.

People like Allen Bauer or Barry Kelly would probably be able to give better/more accurate information on this.

Lalonde answered 6/1, 2010 at 15:35 Comment(1)
to Ryan: You are right about date time stamp - every Build on same project generate different executable file (difference placed close to the end of the file) but identical map file. But difference between Build and Compile .exe is more complicated and exist difference between .map files (like some functions placed at different addresses).Eyewitness
S
0

If you use compiler defines in your project and just changed those, if you do a compile, you won't see any changes to the dcu's and the resulting module (exe or dll). If you do a full rebuild the compiler defines are used in the newly created dcu's and modules.

I have seen this in a large project group where we use modules in different projects with different defines and all dcu's are stored in the same directory.

Ergo: The compiler does not enforce the dependancies on the defines in this case.

Perhaps you did see the same issue.

Squawk answered 8/1, 2010 at 15:40 Comment(1)
I think not in this case - my issue repeats even in new fresh vcl application.Eyewitness

© 2022 - 2024 — McMap. All rights reserved.