c++ Builder xe5 Error detected (LME288) - c++builder

c++ Builder xe5 [ilink32 Error] Error: Unable to perform link
[ilink32 Warning] Warning: Error detected (LME288)
that happened when i tried to compile a test project
c++ builder xe5 on windows xp

I got some information on this from Embarcadero which may help.
The error is an "out of memory", error. The reason for "Out Of Memory"
errors (which come in different guises) in the linker, is that the linker
has to pre-allocate memory in contiguous heaps that it then uses as it
links, in the past these heaps could not be adjusted, we had to do a best
guess, so in the new 64-bit linker (and has also been added to the 32-bit
linker) we allowed people to be able adjust the size of these heaps manually
when they needed to. Now the reason why these heaps can be problem is that
not all systems are the same, some people use different software that map
DLLs into the linker's address space like Windows Hook DLLs, antivirus
software all these DLLs allocate memory INSIDE the linker's (any application
really) address space and hence has an impact on the size of the heaps the
linker can allocate. So we added this ability to adjust the heaps manually,
but we also allocated the initial heaps quite big .
The 32bit linker has a new switch -GH, see below this is similar to the
ilink64 switch.
The syntax for the switch is:
-GH[heap name]=[number of bytes for the heap]"
This option -GH exists from XE3 Update 1 onwards but evidently is not documented?
To see which heap is out of memory you can try from command line.
MSBuild /p:Platform=Win32 /v:diag XXXX.cbproj
This provides additional information such as:
Overrun on linker heap: code
Linker Heaps
info 0x002d0000 0x0a000000
code 0x000d0000 0x00100000
data 0x00030000 0x08000000
bss 0x08000000 0x08000000
Fatal: Out of memory
The left side of the above output is number of bytes being used at the
moment and on the right the number of bytes allocated for the specific named
heap.
The default heap sizes the linker allocates at start up are:
"system", default size 0x08000000
"info", default size 0x0A000000
"code", default size 0x08000000
"rodata", default size 0x06000000 //readonly data
"data", default size 0x08000000
"bss", default size 0x08000000
"tds", default size 0x0FA00000
When you see the "unknown heap" this is normally the "tds" heap
Example to adjust tds heap to 0x0A000000 you would do -GHtds=0x0A000000
Hopefully this information helps you and others with the LME288 error.

I got it.
I had the same problem with Seattle 10 on Windows 7x64. I tried it all. Everything you can find on SO, EDN, and more. I finally broke down and used my Embarcadero support ticket because I simply couldn't link anything anymore. After what I can only describe as an arduous and valiant effort by one of Embarcadero's senior software engineers, we finally stumbled across this fix:
First, right-click on ilink32.exe, select Properties, then go to the Compatibility tab and tick the "Run this program in compatibility mode for" checkbox and select Windows XP SP3. On my system (64 bit Win7, running Seattle 10) the ilink32.exe file is located in "C:\Program Files (x86)\Embarcadero\Studio\17.0\bin."
Second, force admin rights (even if you're already an admin) by right-clicking the Builder launch icon and selecting "Run as administrator."
Now, open your projects and link to your heart's content! (Your results may vary.)

I found this page looking for the same problem, and the solution for me is a simple trick:
Instead of double click in the project to open it (for example double click in xxxx.cbproj), start the ide and then open the project.
Explication? no idea, but now link correctly.

I had the same problem here C++ Builder XE7 LME288 Error
My solution was simple to clean up all temp files. It seems like the error is connected with corrupt temp files.

I just had this issue with XE4 on Windows 10. Fvel got me on the right track. The issue was being caused by the file being opened with BDSLauncher.exe instead of bds.exe . I set the default program for .groupproj to be bds.exe and the problem went away.

Disable your AntiVirus protection software for the ilink32.exe in the embarcadero bin folder, especially if you are using bitdefender.

The solutions given here did not work for me.
My solution is to set the size of the windows swap file to a fixed value (e.g. min: 1000 MB and max: 10000). After restart I checked the Radio Button to "System managed size" and restart again.
Now I can compile and link without any linker errors. But the LME-error comes up again after some days. Then I have to do the same steps with the swapfile to solve the problem.

For me, in Windows 10, the issue was because there wasn't enough Virtual Memory allocated.
Steps to resolve the issue:
Go to System > Advanced System Settings > Advanced.
Under 'Performance', click 'Settings' > Advanced
Under Virtual Memory click 'Change'
Ensure the currently allocated memory is equal to or greater than the recommended memory. If not, select 'Custom size' and set the initial size to the recommended size, and the Maximum size to a larger value.
See also C++ Builder XE7 LME288 Error

For me the problem started when I switched on Auto increment build number in XE7. The project I had had worked for several months without problem. The project was created by an earlier version of Builder. The first problem that occurred was problem for compiler to find windows.h, and the same for rc compiler. The PATHs was updated to invalid versions by Builder (perhaps these were from earlier Builder). After adding the PATHs the LME288 occurred.
After switching of the Auto increment build number and removed all temporary files it seems to work again.

I had the same linker issue LME288 on RAD Studio XE7 / Windows 10.
Cleaning temporary files using CCleaner fixed it.
Edit: the problem keeps coming back but another run of cleaning fixes it.

Related

Explorer properties slow for large Delphi executable

With our 80MB Delphi app on a network share we are finding that a right mouse click Properties in explorer is very slow (around 30 seconds) Similar sized programs on the same drive don't have the problem.
I'm wondering if the Delphi linker organizes the exe in a way that means explorer needs to read the whole file to find the properties information and if there is a way to change this? I can't see anything obvious in the project settings.
EDIT
We have these options in the project file:
{$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE}
{$SetPEFlags IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP or IMAGE_FILE_NET_RUN_FROM_SWAP}
but I think these will only affect the program when it is executed.
The delay was caused by the PW option flags I mentioned in the question. Taking them out and all is well.
Now I need to find out why they were put there.

Is there any risk in having an exe larger than 100MB built with Delphi?

My Delphi win32 VCL Application is deployed as a single big exe. The application is a Client Server application with a Fat Client that connects to SQL Server.
This is convenient (it is enough to update one file in a shared folder and the application is updated- of course the DB schema gets updated too).
Since I use many "fat" third party components like ReportBuilder and DevExpress at every release the exe size grows mostly because those components become bigger and bigger.
In the dpr I set these flags to ensure when exe is launched from shared folder or from removable device it is always loaded in memory (and avoid odd connections errors):
{$SetPEFlags IMAGE_FILE_NET_RUN_FROM_SWAP}
{$SetPEFlags IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP}
If the exe is built with the Release Build Configuration a normal exe usually reduces the size of about 50% (compared to Debug Build Configuration). But since I use EurekaLog, building with Build instead than Debug just slightly reduces the size.
Currently my exe is 115MB (built with "Build" Build configuration and EurekaLog).
Is it ok in anyone experience? Is it there a known limit that is advisable not to exceed?
Here's how the size has grown in recent years:
2014: 76MB
2015: 82MB
2016: 90MB
2017: 97MB
2018: 115MB
Since I recently exceeded the 100MB limit I started to worry.
I know that it is possible to build with runtime packages but my question focuses on keeping the single big exe approach if possible.
I remember cnPack has a Uses Cleaner feature I tried in the past. This could likely help me remove some non used unit and therefore reduce the exe size, but anyway this cannot stop the trend that brought me over 100MB.
Thanks.
I asked EurekaLog and they replied:
The size of your EXE after EurekaLog processing is mostly determined
by the size of your MAP file. Other things that affect the size of the
EXE include the EurekaLog options you select, such as memory checks,
Senders, JCL support, Etc.
You can reduce the size of the EXE somewhat by selecting the EL
Compression option. Keep in mind that compression can affect startup
time, since the debug information needs to be decompressed when you
launch the EXE.
You can further reduce the MAP file size by turning off debug
information in parts of your program that you don't need to stack
trace after a crash. Large component libraries like DevExpress would
be a good start.
Last, you may have other compiler options like range checking turned
on/off in tandem with EurekaLog. Some compiler options can contribute
to EXE size.
You can use our EurekaLog PE Analyzer to view details on debug
information size, Compression, Etc.
So somehow user Ville Krumlinde is right when he says that debug info is the cause. So to answer the question there are no problems in having a big exe, to reduce exe size the Release Build Configuration must be used, to use Eureka Log one should try to reduce he the map file size, in the above quote most hints are there.
You can use "Store all names externally" option to offload some debug information to external file, but your executables will no longer be self-contained.

What causes a tripling of EXE size in C++ Builder XE4 compared to C++Builder 2010?

I have upgraded a project from RAD Studio 2010 to RAD Studio XE4. The project is mostly C++ using the C++ Builder half of RAD Studio, with smatterings of Delphi.
Under 2010, the Release build was 22MB. Under XE4, the same Release build is 55MB.
This is a problem because:
55MB is remarkably large for an EXE
It takes noticeably longer to start the program (not much, but some.)
Many of our customers download new versions from remote areas or on board ship while at sea. Size matters.
What could cause this, and how do I fix it?
Notes
Oddly enough, the debug build is still only 23MB. Project settings seem very similar. I diffed an export of the option sets and saw only <UsePackages>True</UsePackages> as something present in Release not Debug; removing it made no difference. Beyond that there's code optimisation turned on and lack of a _DEBUG define.
Debug info is generated for the Release build, but goes into an external .tds file. (This will be used for EurekaLog in future, and currently allows us to debug release builds of the program.) I wondered if the linker was linking in debug info, but as far as I know the C++ linker always places the debug info in an external file, which exists, plus EurekaLog is not yet enabled in the build.
The project files (.cbproj) were created in XE4, not upgraded from old 2010 ones. I made new projects and added the old .cpp and .pas files. This was to avoid issues caused by upgrading - on the Embarcadero forums it's often recommended to create projects anew when upgrading IDE versions. Until this occurred, I had indeed encountered fewer issues than in 2010.
There are many mentions of Delphi XE2+ EXEs being noticeably larger than those produced by old versions of Delphi. (1, 2, 3, 4, 5, 6.) While the C++ linker is different to that used by Delphi, it is possible the causes are similar.
The cause there appears to mostly be RTTI used by the Delphi RTL code, which in a Delphi project can be removed by specifying {$WEAKLINKRTTI ON}. The XE4 documentation does not mention an equivalent C++ linker pragma. There is #pragma explicit_rtti (the C++ analog of {$RTTI}) and __declspec(delphirtti) (the C++ analog of {$M}/{$TYPEINFO}).
The project is linked using runtime packages and the dynamic RTL. It is a 32-bit VCL forms application. I have XE4 Update 1 installed on Windows 7.
Edit: David Heffernan asks in a comment below about the .map file sizes of each project.
The release .map size is 17MB, and .tds size is 80MB.
Debug has now stopped linking, with the linker reporting it is out of memory (an old, old bug that should have been fixed years ago.) There are no .map or .tds files generated and so I can't give a comparison size accurately. From memory the .tds was about 100MB, and unfortunately I don't recall the .map size. If I get the project linking I will update the question.
Edit again: I found the answer (sortof) - turning 'Expand inline functions' OFF reduces the EXE size to the expected value. This is puzzling itself though - see my answer below. Note that the debug build already had this turned off and still won't link, giving an out of memory error.
I haven't marked my answer as correct yet, in case someone can provide some insight into exactly what is going on, which would be a much better answer than just 'turn this option off'.
Solved (sortof.)
The Release build had "Expand inline functions" turned on. Turning this off reduced the EXE size from 55MB to 17MB.
This is an astounding difference and I don't know why the difference is so big. I find it unlikely we have 38MB worth of inlined functions, even counting templates and headers, let alone ones using the inline keyword. If there is a way to examine the linker steps, output, or obj files to see what is being expanded, please comment - I'd find this really valuable.

Delphi XE2: EResNotFound exception "Resource "<mainform>" not found" raised on some target machines but not on others

I've been banging my head against this for the past two days and can't seem to make any progress...
Pretty much from one moment to the next, Delphi XE2 won't properly compile one of my projects any more. That is, it actually compiles without errors but at runtime I get resource not found errors for what is essentially the main "form" (it's actually a data module in this case). I have already reverted to older versions of the project from source control that I know were definitely working alright but to no avail. Judging by that it seems it must be something inside Delphi/the IDE itself rather than in the project source. However, I have also not been able to reproduce the issue with a simple test project nor with any other real-life projects... It only happens with this one.
Another strange thing is that when I look at the produced binary with XN Resource Explorer everything looks as it should: The form resource mentioned in the error message is actually there and intact...
At some point I was suspecting this might be caused by a bug in one of the experts I have installed in my IDE (e.g. Uwe's platform and OI experts and VersionInsightPlus, Andreas' IDEFixPack and DDevExtensions, GExperts) but even after disabling all these the problem persisted.
Unfortunately, I am unable to track down exactly when this started to happen as I had been working for some time without actually running the binary, fixing compiler warnings and errors for the x64-target, adjusting build events for updated third-party tools (localization and license protection) and such things...
Has anyone else ever seen anything like this happen? Any more ideas on how to pin this down?
Some more details about the project:
It is an addin for Outlook built using the Add-In-Express framework (i.e. a COM-DLL).
The "main form" is a TDataModule-descendant - we also inserted our own ancestor-class into the hierarchy, i.e. the "addin module" is not directly inheriting from TadxCOMAddInModule - the resources of the custom ancestor forms also appear to be present and intact in the output binary when checking with a resource viewer.
Built without runtime packages for the Win32 and Win64 platforms.
Let me know if you think I missed to mention any other potentially relevant details.
Update:
I have now transferred the sources in question onto a different machine. Interestingly, the DLL I compiled there did not exhibit the problem - on that machine that is... when I transfered it back to the original machine and I tried to call it, the error was back (to stress this: this was the exact same DLL producing a EResNotFound on one machine but not on the other. Of course, once I had discovered this, I also performed the reverse test and lo and behold, the DLL compiled on the original machine works without errors on the other machine...
Seems this might not be a Delphi problem after all... but what is it then?
Differences between the two machines:
Machine 1 (the one were the problem occurs): Windows 7 Ultimate English 64bit with Delphi XE2 Update 4
Machine 2: Windows 7 Professional German 32bit with Delphi XE2 Update 3
On a third machine that is almost identical to the first except that it doesn't have Delphi on it, DLLs produced by both machines work flawlessly.
I am a bit surprised to see your question here. :)
We faced a number of serious issues with recent Update 4 for Delphi XE2. Though we have never run into or been reported of the "resource not found" error, I think this update might be one of the causes. Have you installed it?
One more thing that comes to my mind is images that you use for your Office controls (command bar and ribbon). Probably they got broken somehow, the run-time code cannot load them and reports this error.
Anyway, as you understand, these are just my guesses, if you need our assistance with your office add-in please contact Add-in Express support service, we will try to help.
Update: Seems I was a bit too quick, drawing conclusions. Apparently the Sisulizer solution is also supposed to perform a fallback to the main resource block. I have now taken this issue to the product forum and will report back here, once this is resolved.
Alright, mystery solved at last:
I had turned off the option to "Copy all resources" in Sisulizer in an attempt to reduce the size of the produced resource DLLs and then had forgotten about it...
I hadn't fully realized the implications of the standard Delphi resource DLL approach to localization on which Sisulizer "piggybacks" - especially that it was an all-or-nothing deal: Our previous translation solution implemented a fallback-mechanism that would read any resources not found in the external resource DLL from the host binary instead. This does not appear to be the case with Sisulizer - at least not out of the box... thus, any resource that's not contained in the localized resource DLL does not exist as far as the application is concerned.
I also didn't realize that the mere existence of a file with the same base name as the main binary and an extension matching the current system's default locale (such as .EN or .DE) would automatically cause the VCL to load it...
The machines that did not exhibit the error either still had the older, larger (=complete) resource DLLs on them, or no resource DLLs at all.

What Can I Do To Reduce My Executable's Size (Delphi)?

I release a single executable (.EXE) for a desktop program using Delphi 2009. I have no external DLLs or resources that I need for the program to run.
I use two components: LMD Innovative's ELPack and Sergey Tkachenko's TRichView that are compiled into my executable.
When I build my production version, using the "Release" build configuration, the executable file produced is 13,533 KB.
Prior to using Delphi 2009, I was using Delphi 4. The executable it produced was only 2,671 KB while incorporating the same two components and basically having the same code as my current version.
I do understand that Delphi 2009 is completely Unicode (which is the main reason why I upgraded), and being Unicode can cause up to a doubling of size. But this is about 5 times larger.
Is there a reason why my executable has to remain 5 times larger? Or are there some simple ways to cut down a significant chunk of the executable size?
Please note. Some people are answering with ways to compress the Delphi EXE. That is not what I am trying to do. I am trying to simply see why so much space is being used to remove what might not be necessary. If that is done, compression can still be done afterwards if so desired.
It really doesn't matter how big or small the executable is once it is installed. It is for downloading purposes and to minimize server load and download times that you want to compress it. I prefer to use Inno Setup and compress the program inside the install routine itself. Then when it is installed, it is expanded to full size. That both prevents possible detection as a virus and eliminates the extra startup time needed to uncompress the program in memory. Also I code sign both my executable and my install routine and some compression techniques are incompatible with that.
For more info about compressing, see the StackOverflow question: Delphi EXE compressor?
ldsandon asked me to provide exactly what options I'm using, so here they are:
(source: beholdgenealogy.com)
(source: beholdgenealogy.com)
When moving from Delphi 7 to Delphi 2010., our .exe's grew for example from 16 megs to 35 megs.
I asked a question similar to yours on the Embarcadero forum a few weeks ago. (link) In my OP, I listed a series of links on this subject that you might find helpful.
We tried using UPX to compress our .exe's. Letting it work for hours significantly reduced our .exe, but we probably won't use it in production for these reasons:
We have quite a few .exe's and don't want to wait 1/2-day on each build. (It's possible that we could find a non-brute force set of parameters to UPX that would reduce this...)
Although the size of the .exe is reduced, our shippable was not, because our installer (not surprisingly) is unable squeeze much more compression out of the already compressed file... whereas it was able to reduce the original 16 meg .exe down to 8 megs.
I've read some reports that at some time (rarely, but not never), UPX exe's triggered various anti-virus programs to report the application contained a virus. (I don't recall the date, site, or details of where I saw this, so it's a bit unfair of me to report it here.) But, we are so adverse to taking a risk of that even possibility happening, that UPX is off the table...
The link on the Embarcadero forum also includes a link to another SO thread on this topic.
I continue to be surprised and disappointed at the code bloat we found when moving to Delphi 2010. As Nick notes, 2X for Unicode is quite excessive.
However, the bloat is a relatively minor trade-off when moving to D2010, because, IMO, D2010 is such a terrific upgrade in so many other ways. But, it does mean that we'll probably have to move to shipping 2 CDs rather than one. I'm not looking forward to seeing the reaction to this from our organization...
Without seeing the actual settings that your "Release" build configuration uses explaining this increase in size requires a great deal of speculation.
Beyond some perhaps unlikely factors resulting in a vast increase in the amount of code being "dragged in" even though it isn't used, that magnitude of increase would most easily be explained by the inclusion of debug information.
I would check your compiler and linker settings for:
Debug Information (compiler setting)
TD32 info (linker)
Remote debug info (linker)
Compare these settings in your Delphi 2009 project with the equivalents in Delphi 4.
Factor out the expected 2X increase from Unicode and you end up with a 2.5X increase unaccounted for. This makes sense considering how many versions you've skipped. A lot's been added to the VCL and RTL since Delphi 4, and not all of it is stuff that can be easily smartlinked out, even if you never use it. Depending on how many units you're using, you could be hauling in quite a bit of extra baggage.
Allen Bauer and the compiler team added a new feature into D2010 to help reduce this, but apparently they're treading cautiously and didn't use it in as many places as they could have. Hopefully we'll see more cruft reduction in 2011 and subsequent releases.
I will add my few words.
Linker can remove unused procedures and functions only if it can follow the code hierarchy. The nightmare list for linker listed below:
Message-driven code, the sad news is that this code can't be removed whatsoever, that's why Delphi blank project size continues growing from version to version. Every new windows message (WM_TOUCH for example as long as I know introduced recently) creates procedure call hierarchy that can't be removed (even if you don't have plan to use Touch API at all). This is because every case WM_: fragment is something linker can't decide whether it will be used or not.
Code and data structures accessed from the begin end, initialization, finalization secions of the units. Here you have some control, remove unnecessary calls or object creation. Even if you create objects on demand and only free them in finalization section, make it carefully
Use "upx - compress or expand executable files" # http://upx.sourceforge.net
If you go to tools/configure tools, and set it up like this, you can compress the executable that you're working on easily via a menu item in the IDE.
Another way is to have a look to 'what unit increase the size ?'.
To do this, I use the JCL 'Project Analyser IDE', integrated in the IDE with the JCL/JVCL installation, it show you all the units with their respective size. You can export it in text file.
If you do it with the 2 environnements (D4 & D2009) you will have a lot of pertinent informations.
I've done some tests to see the difference between D2007 and D2010, because we are upgrading to D2010. I've tested a medium sized management GUI application, with about 60 forms (grids with detail forms, frames, etc). We're using TMS components + Remobjects.
D2007:
"normal" compilation: 18.8mb
with debug dcu's: 18.8mb (same size!)
D2010
normal: 23.9
debug dcu's: 48.8mb (!)
So using debug dcu's doubles our exe size...
Test with our business service (no big dfm's):
D2007: 12.3mb
D2010: 17.1mb
So yes, D2010 increases the exe (a bit), but this is not a problem for my customer.
Edit: some information about compiled size:
D2007:
D2010:
So an increase of code size, but a more than doubling of the data!
If you don't want to use an exe compressor then you should give StripReloc a try.
Check format of your dfm-s. They must be in binary format if you want to make your exe smaller.
1) You are generating a detailed map file, and because you've set "used debug dcus" it will also contains symbols for the RTL/VCL units. If it is used by an exception handling systems to generate call stacks and the like, it could be added to the executable. And if not compressed somehow, it could make your .exe size pretty large.
2) Using debug dcus will also make your .exe somewhat larger because usually they are compiled without optimization and debug options set, and they will make also your code slower. They shouldn't be used in a release version.
3) Debug information should add debig info only to the unit and not to the executable, although it is required IIRC to generate the map file.
Since D2010 adds extended RTTI, and RTTI is a notorious factor in increasing exe size, it would be interesting to see how big D2009 binaries are for that application.
If D2009 binaries are significantly smaller, it is not Unicode etc. For my own binaries, I only have a 30% increase or so going from D7 to D2009.
It has been stated earlier that using an executable compresser reduces the size of the exe but not of the install package. However, if you want a good compressor then try ASPack.
#Tom1952: ASPack is pretty fast, just a few seconds to compress a file
Also you can change the Icon. Icon in newest delphi IDE (ie XE3) is Vista/7 compatible and contains all sizes (up to 256x256 as far as I know). So you can reduce exe file size with changing the Icon.
The standard units in you newer delphi may contain more strings and constants such as error strings, that is included even if you disable debug information. Check your uses.
Don't have much of a somution besides not using a specific unit, or removing unneeded data from it.
(My experiences are with Delphi 5)
For Delphi 10.3 Rio with default setiings:
Step 1: Switch from Debug to Release in "Projects" window. This reduced my exe file from 22 MB to 5 MB !
Step 2: Use an exe compresor like ASPack. It further reduced my exe file to 1.3 MB. Unbelievable, isn't it ? :)
Uncheck debug information in project options.
If embarcadero can't provide any solution or explanation!!! I think the solution is simple: don't stuck only with Delphi there is a lot of programming languages, every one is limited only by programmer imagination.

Resources