How do I remove unnecesary VCRT code in my EXE?

New to FreeBASIC? Post your questions here.
Post Reply
Ben321
Posts: 1
Joined: Feb 12, 2023 9:54

How do I remove unnecesary VCRT code in my EXE?

Post by Ben321 »

When I'm not using certain features of the C runtime that FreeBASIC uses, I'd like to have those parts of the code stripped from my EXE. My test code literally contains just these two lines.

Code: Select all

dim u8 as ubyte
dim s8 as byte
But the output is a 15kByte file. Those 2 lines of code should simply translate to allocating enough room on the stack for those variables, and initializing them to zero (default behavior for BASIC programming language). That would literally be just a few bytes of machine code in the EXE file. The smallest an EXE file can be (due to header and block alignment) is I think 1kByte in size. So such small code shouldn't output an EXE file that's 15kBytes in size. Since I'm not making any calls to BASIC functions like Print, absolutely no FreeBASIC or C runtime functions need to be embedded in my EXE's code. Nor should any code that would call to functions in an external runtime DLL file. Yet I have 15kBytes of code in my EXE for some reason, and that makes no sense at all. Ideally, any runtime code that isn't used in a particular EXE, should be stripped from the EXE. If there's already a way to do this, please tell me how.

If there's not already a way to do this, please consider this post to be a feature request.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: How do I remove unnecesary VCRT code in my EXE?

Post by coderJeff »

Ben321 wrote: Feb 12, 2023 10:04 Yet I have 15kBytes of code in my EXE for some reason, and that makes no sense at all. Ideally, any runtime code that isn't used in a particular EXE, should be stripped from the EXE. If there's already a way to do this, please tell me how.
The fb run time system (which uses c run time system), expects that by the time the user portion of the program is loaded and ready to run, certain initialization will be done and certain facilities will be available: stack alignment, memory management, thread management, command line arguments, console / file redirection, etc, are all expected to be initialized to allow the rest of the run time system to work. And all of fb's built-in commands and features usually require some parts of the run time system to be up and running. Since most user programs tend to need the same kinds of facilities, there is some minimal amount of start-up code that gets added to all executables. Automatically including / excluding only parts of the start-up would be hard to do since the run-time system startup and support code is not written in a way that can arbitrarily select which facilities to support or not.

However, to completely disable fb's and c's run time system (actually gcc / mingw run time system in the typical fbc installation), here is an example that should produce 2048 byte executable on windows 32-bit:

Code: Select all

'' minimal executable example for windows 32-bit
''   should produce a 2048 byte excecutable
''
'' compile with:
''   fbc -c minimal.bas
''
'' link with:
''   ld minimal.o -s -L d:/fbc/lib/win32 -l kernel32 -o minimal.exe

#include "windows.bi"

sub mainCRTStartup cdecl alias "mainCRTStartup" ()
    dim u8 as ubyte
    dim s8 as byte
    ExitProcess(0)
end sub
marcov
Posts: 3454
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: How do I remove unnecesary VCRT code in my EXE?

Post by marcov »

Just for my general feel for things: Does smartlinking (dead-code-elimination using gc-sections) now works ok with binutils ? On a section rather than a whole .o level I mean. The last time I heard (2016-18ish) it was still a mess.

Note that while a problem, this puts it outside of the scope of the FB project.

p.s. Some things like the init of thread support can be deferred to e.g. the first thread creation. Then it can be smartlinked out. And of course it also means that the linker must eliminate import sections when the part using the import is smartlinked out.
Vortex
Posts: 118
Joined: Sep 19, 2005 9:50

Re: How do I remove unnecesary VCRT code in my EXE?

Post by Vortex »

Hi Ben,

Here is a quick example to create small executables :

Code: Select all

#include "windows.bi"
#include "crt.bi"

#ifdef __FB_64BIT__

    #define CallConvention

#else

    #define CallConvention Cdecl

#endif


Sub wmain CallConvention Alias "wmain" ()

Dim As Integer i

For i=1 To 3

   printf !"This is a test.\n"

Next i

   ExitProcess(0)

End Sub
Batch file to compile the source code :

Code: Select all

\FreeBASIC\fbc32 -nodeflibs -c SmallExe.bas

IF EXIST C:\msys64\mingw32\bin\objcopy.exe C:\msys64\mingw32\bin\objcopy.exe --remove-section .fbctinf --remove-section .ctors SmallExe.o
\FreeBASIC\bin\win32\ld -e _wmain -subsystem console -o SmallExe.exe SmallExe.o -L\FreeBASIC\lib\win32 -lkernel32 -luser32 -lgdi32 -lmsvcrt -s

\FreeBASIC\fbc64 -nodeflibs -c SmallExe.bas -o SmallExe64.o
IF EXIST C:\msys64\mingw64\bin\objcopy.exe C:\msys64\mingw64\bin\objcopy.exe --remove-section .rdata$zzz --remove-section .ctors --remove-section .fbctinf SmallExe64.o
\FreeBASIC\bin\win64\ld -e wmain -subsystem console -o SmallExe64.exe SmallExe64.o -L\FreeBASIC\lib\win64 -lkernel32 -luser32 -lgdi32 -lmsvcrt -s
Size of the executables :

Code: Select all

SmallExe.exe : 2560 Bytes
SmallExe64.exe : 2048 Bytes
Post Reply