I compiled two versions of 'Hello World!', one in C and the other in Pascal in the ctgwin environment, as follows:
C source hello.c: int main() {printf("Hello World!\n");} command line: gcc hello.c -o helloc.exe
Pascal source: program Hello; begin writeln('Hello World!') end. command line: gpc hello.pas -o hellopas.exe
The sizes of the binaries I obtained were, respectively (copied from the DOS prompt dir command):
HELLOC EXE 11.296 bytes HELLOPAS EXE 283.531 bytes
Why the sizes of these files are so different? What must be done in order to obtain a hellopas.exe file of reasonable size?
Thanks in advance. Claudio
On 7 Mar 2004 at 9:47, Claudiozm@aol.com wrote:
I compiled two versions of 'Hello World!', one in C and the other in Pascal in the ctgwin environment, as follows:
C source hello.c: int main() {printf("Hello World!\n");} command line: gcc hello.c -o helloc.exe
Pascal source: program Hello; begin writeln('Hello World!') end. command line: gpc hello.pas -o hellopas.exe
The sizes of the binaries I obtained were, respectively (copied from the DOS prompt dir command):
HELLOC EXE 11.296 bytes HELLOPAS EXE 283.531 bytes
Why the sizes of these files are so different?
This is a FAQ. The gpc executable is so big because the whole of the RTS (libgpc.a) has to be linked.
What must be done in order to obtain a hellopas.exe file of reasonable size?
Not much that you can do at the moment.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof. Abimbola A. Olowofoyeku (The African Chief) wrote:
On 7 Mar 2004 at 9:47, Claudiozm@aol.com wrote:
I compiled two versions of 'Hello World!', one in C and the other in Pascal in the ctgwin environment, as follows:
C source hello.c: int main() {printf("Hello World!\n");} command line: gcc hello.c -o helloc.exe
Pascal source: program Hello; begin writeln('Hello World!') end. command line: gpc hello.pas -o hellopas.exe
The sizes of the binaries I obtained were, respectively (copied from the DOS prompt dir command):
HELLOC EXE 11.296 bytes HELLOPAS EXE 283.531 bytes
Why the sizes of these files are so different?
This is a FAQ. The gpc executable is so big because the whole of the RTS (libgpc.a) has to be linked.
What must be done in order to obtain a hellopas.exe file of reasonable size?
Not much that you can do at the moment.
The size may be much smaller if the runtime is made into shared library (dll). On Linux this is very simple: Copy libgpc.a to a working directory ar x libgpc.a gcc -shared *.o -o libgpc.so
Then libgpc.so may be used in place of libgpc.a. In principle similar thing should work on Windows:
i386-pc-mingw32-x libgpc.a rm libgpc.a i386-pc-mingw32-dllwrap --export-all-symbols --output-lib=libgpc.a --dllname=gpc.dll
that creates gpc.dll and the import library libgpc.a, but linking hello.exe fails. Appearently references to functions are resolved, but data gives unresloved references:
i386-pc-mingw32-gcc hello.o libgpc.a -o hello.exe Info: resolving __p_stdout by linking to __imp___p_stdout (auto-import) Info: resolving __p_InOutRes by linking to __imp___p_InOutRes (auto-import) Info: resolving ___GPC_RTS_VERSION_20021111__ by linking to __imp____GPC_RTS_VERSION_20021111__ (auto-import) fu000001.o(.idata$3+0xc): undefined reference to `libgpc_a_iname' fu000003.o(.idata$3+0xc): undefined reference to `libgpc_a_iname' fu000005.o(.idata$3+0xc): undefined reference to `libgpc_a_iname' nmth000000.o(.idata$4+0x0): undefined reference to `_nm___p_stdout' nmth000002.o(.idata$4+0x0): undefined reference to `_nm___p_InOutRes' nmth000004.o(.idata$4+0x0): undefined reference to `_nm____GPC_RTS_VERSION_20021111__'
I am not an export on Windows linking, so I do not know if the problem is deep or a trivial one.
Waldek Hebisch wrote:
The size may be much smaller if the runtime is made into shared library (dll). On Linux this is very simple: Copy libgpc.a to a working directory ar x libgpc.a gcc -shared *.o -o libgpc.so
Don't you have to use `-fPIC' when building the RTS?
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
The size may be much smaller if the runtime is made into shared library (dll). On Linux this is very simple: Copy libgpc.a to a working directory ar x libgpc.a gcc -shared *.o -o libgpc.so
Don't you have to use `-fPIC' when building the RTS?
On i386 `-fPIC' is not needed. ELF format contains enough information to relocate library at load time. On other architectures dynamic linker does not support position dependent code, but on i386 it just works. Since relocation involves writing to library code sharing is reduced.
On 7 Mar 2004 at 20:21, Waldek Hebisch wrote:
[...]
The size may be much smaller if the runtime is made into shared library (dll). On Linux this is very simple: Copy libgpc.a to a working directory ar x libgpc.a gcc -shared *.o -o libgpc.so
Then libgpc.so may be used in place of libgpc.a. In principle similar thing should work on Windows:
i386-pc-mingw32-x libgpc.a rm libgpc.a i386-pc-mingw32-dllwrap --export-all-symbols --output-lib=libgpc.a --dllname=gpc.dll
that creates gpc.dll and the import library libgpc.a, but linking hello.exe fails. Appearently references to functions are resolved, but data gives unresloved references:
i386-pc-mingw32-gcc hello.o libgpc.a -o hello.exe Info: resolving __p_stdout by linking to __imp___p_stdout (auto-import) Info: resolving __p_InOutRes by linking to __imp___p_InOutRes (auto-import) Info: resolving ___GPC_RTS_VERSION_20021111__ by linking to __imp____GPC_RTS_VERSION_20021111__ (auto-import) fu000001.o(.idata$3+0xc): undefined reference to `libgpc_a_iname' fu000003.o(.idata$3+0xc): undefined reference to `libgpc_a_iname' fu000005.o(.idata$3+0xc): undefined reference to `libgpc_a_iname' nmth000000.o(.idata$4+0x0): undefined reference to `_nm___p_stdout' nmth000002.o(.idata$4+0x0): undefined reference to `_nm___p_InOutRes' nmth000004.o(.idata$4+0x0): undefined reference to `_nm____GPC_RTS_VERSION_20021111__'
I am not an export on Windows linking, so I do not know if the problem is deep or a trivial one.
It is a big problem. Windows dlls export only routines. Data is normally internal to the dll itself (which is actually a special form of executable rather than a proper library) and must be retrieved in other ways (best by access routines). C programmers I apparently can use "__delcspec(dllimport)" to get access to dll data - e.g., #define _DL_IMPORT __delcspec(dllimport) _DL_IMPORT extern void *(*my_malloc)(int sz);
I got this example from the documentation of "a2dll" which converts a static library to a Windows dll. I wouldn't have a clue as to whether this can be done with GPC or not, and, if it can be done, how to do it. Assuming it could be done, it would be wonderful.
BTW: the "a2dll" program very helpfully provides a list of the data items that it thinks it found in libgpc.a while converting it to a dll - as follows; Counter Cparametersdummy Currentreturnaddr Currentreturnaddrcounter DllHandle __GPC_RTS_VERSION_20030830__ _p_AbortOnError _p_CParamCount _p_CParameters _p_CurrentStdin _p_DirSeparatorVar _p_EOLnResetHack _p_Environment _p_ErrorAddr _p_ErrorFD _p_ErrorFileName _p_ErrorMessageString _p_ExitCode _p_FPE_DECOVF_TRAP _p_FPE_FLTDIV_TRAP _p_FPE_FLTOVF_TRAP _p_FPE_FLTUND_TRAP _p_FPE_INTDIV_TRAP _p_FPE_INTOVF_TRAP _p_FPE_SUBRNG_TRAP _p_FakeHighLetters _p_FileAssociation _p_FileMode _p_FirstNonOption _p_ForceDirectFiles _p_FormatStringTransformPtr _p_FreeMemPtr _p_GetMemPtr _p_GetOptErrorFlag _p_HasOptionArgument _p_HeapChecking _p_HeapHigh _p_HeapLow _p_InOutRes _p_InOutResCErrorString _p_InOutResString _p_InitProc _p_Input _p_LowInteger _p_OpenErrorCode _p_OptionArgument _p_Output _p_RTSWarnFlag _p_RandIntPtr _p_RandRealPtr _p_RandomizePtr _p_ReAllocMemPtr _p_SIGABRT _p_SIGALRM _p_SIGBUS _p_SIGCHLD _p_SIGCONT _p_SIGEMT _p_SIGFPE _p_SIGHUP _p_SIGILL _p_SIGINFO _p_SIGINT _p_SIGIO _p_SIGIOT _p_SIGKILL _p_SIGLOST _p_SIGPIPE _p_SIGPOLL _p_SIGPROF _p_SIGPWR _p_SIGQUIT _p_SIGSEGV _p_SIGSTKFLT _p_SIGSTOP _p_SIGSYS _p_SIGTERM _p_SIGTRAP _p_SIGTSTP _p_SIGTTIN _p_SIGTTOU _p_SIGURG _p_SIGUSR1 _p_SIGUSR2 _p_SIGVTALRM _p_SIGWINCH _p_SIGXCPU _p_SIGXFSZ _p_SIG_DFL _p_SIG_ERR _p_SIG_IGN _p_SeedRandomPtr _p_StdErr _p_TtyDeviceNameVar _p_UnknownOptionCharacter info2 pNetApiBufferFree pNetUserEnum set_result_Filename_0 set_result_Gpc_151 uid2
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof. Abimbola A. Olowofoyeku (The African Chief) wrote:
On 7 Mar 2004 at 20:21, Waldek Hebisch wrote:
[...]
The size may be much smaller if the runtime is made into shared library (dll). On Linux this is very simple: Copy libgpc.a to a working directory ar x libgpc.a gcc -shared *.o -o libgpc.so
It is a big problem. Windows dlls export only routines. Data is normally internal to the dll itself (which is actually a special form of executable rather than a proper library) and must be retrieved in other ways (best by access routines). C programmers I apparently can use "__delcspec(dllimport)" to get access to dll data - e.g., #define _DL_IMPORT __delcspec(dllimport) _DL_IMPORT extern void *(*my_malloc)(int sz);
I got this example from the documentation of "a2dll" which converts a static library to a Windows dll. I wouldn't have a clue as to whether this can be done with GPC or not, and, if it can be done, how to do it. Assuming it could be done, it would be wonderful.
I looked at "a2dll" and AFAIKS the procedure works for GPC too:
bash-2.04$ i386-pc-mingw32-gcc --shared -Wl,--export-all -o libgpc.dll -Wl,--output-def=libgpc.def -Wl,--out-implib=libgpc.dll.a -Wl,--whole-archive libgpc.a -Wl,--no-whole-archive Creating library file: libgpc.dll.a bash-2.04$ i386-pc-mingw32-gpc -c hello.p bash-2.04$ i386-pc-mingw32-gcc hello.o libgpc.dll.a Info: resolving __p_stdout by linking to __imp___p_stdout (auto-import) Info: resolving __p_InOutRes by linking to __imp___p_InOutRes (auto-import) Info: resolving ___GPC_RTS_VERSION_20021111__ by linking to __imp____GPC_RTS_VERSION_20021111__ (auto-import) bash-2.04$ wine a.exe Hello World bash-2.04$
So probably "dllwrap" used incorrect options. The executable is still large, but after stripping gets much smaller: bash-2.04$ ls -l a.exe -rwxr-xr-x 1 hebisch users 216302 Mar 8 15:31 a.exe bash-2.04$ i386-pc-mingw32-strip a.exe bash-2.04$ ls -l a.exe -rwxr-xr-x 1 hebisch users 4096 Mar 8 15:38 a.exe
On 8 Mar 2004 at 15:43, Waldek Hebisch wrote:
[...]
I looked at "a2dll" and AFAIKS the procedure works for GPC too:
bash-2.04$ i386-pc-mingw32-gcc --shared -Wl,--export-all -o libgpc.dll -Wl,--output-def=libgpc.def -Wl,--out-implib=libgpc.dll.a -Wl,--whole-archive libgpc.a -Wl,--no-whole-archive
[...]
Yes, it worked here too (cool!). I am able to compile all sorts of programs, that are quite tiny - a first for me with GPC under Windows (a suite of program that would normally compile to a total of about 2.7mb compiled to 390kb).
However, I found that when compiling a program uses the system unit, I get an error about not being able to auto-import "_p_ErrorMessageString". I was directed to the "ld" documentation on "--enable-auto-import", which indicated a number of ways in which the problem could be solved. Declaring the variable as "volatile" (as suggested) didn't help. In the end, I used "-enable-runtime-pseudo-reloc", and that solved the problem.
So, I guess that this is the next best thing after sliced bread ;)
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
I looked at "a2dll" and AFAIKS the procedure works for GPC too:
Yes, it worked here too (cool!). I am able to compile all sorts of programs, that are quite tiny - a first for me with GPC under Windows (a suite of program that would normally compile to a total of about 2.7mb compiled to 390kb).
Whoa, whoa, whoa... Hold on, Chief. Where can I get a2dll, and is there an equivalent for GNU/Linux, and how big is the universe?
Oh, wait... Screw the first two questions; I just want to know the answer to the last one. :D
So, I guess that this is the next best thing after sliced bread ;)
No, no... First, it's sliced bread, then caffeine, then GNU/Linux. If this a2dll beast has a GNU/Linux equivalent (a2so?), then I'll consider it a far fourth.
Until then, cigarettes stay in the fourth place. :)
On 10 Mar 2004 at 2:30, Neil Santos wrote:
I looked at "a2dll" and AFAIKS the procedure works for GPC too:
Yes, it worked here too (cool!). I am able to compile all sorts of programs, that are quite tiny - a first for me with GPC under Windows (a suite of program that would normally compile to a total of about 2.7mb compiled to 390kb).
Whoa, whoa, whoa... Hold on, Chief. Where can I get a2dll, and is there an equivalent for GNU/Linux, and how big is the universe?
Oh, wait... Screw the first two questions; I just want to know the answer to the last one. :D
So, I guess that this is the next best thing after sliced bread ;)
No, no... First, it's sliced bread, then caffeine, then GNU/Linux. If this a2dll beast has a GNU/Linux equivalent (a2so?), then I'll consider it a far fourth.
I actually did not use a2dll for the final stuff - I used Waldek's alternative. With respect to Linux, this is what Waldek had to say on 7 March:
The size may be much smaller if the runtime is made into shared library (dll). On Linux this is very simple: Copy libgpc.a to a working directory ar x libgpc.a gcc -shared *.o -o libgpc.so
Then libgpc.so may be used in place of libgpc.a. In principle similar thing should work on Windows:
Until then, cigarettes stay in the fourth place. :)
Hmm ... you should quit ...
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
No, no... First, it's sliced bread, then caffeine, then GNU/Linux. If this a2dll beast has a GNU/Linux equivalent (a2so?), then I'll consider it a far fourth.
I actually did not use a2dll for the final stuff - I used Waldek's alternative. With respect to Linux, this is what Waldek had to say on 7 March:
The size may be much smaller if the runtime is made into shared library (dll). On Linux this is very simple: Copy libgpc.a to a working directory ar x libgpc.a gcc -shared *.o -o libgpc.so
Then libgpc.so may be used in place of libgpc.a. In principle
A one-liner can do the trick also:
ld -o /usr/local/lib/atlas/liblapack.so -shared --whole-archive \ -export-dynamic lib/Linux_ATHLONSSE1/liblapack.a
So ld can function as `a2so`
Marten Jan
My 0.02 euro ... Rumours are that the 1 and 2 eurocent coins are to disappear, and prices will be rounded. Guess what my contributions then will be ;-)
* [070304 :: 2333] Claudiozm@aol.com Claudiozm@aol.com wrote:
Why the sizes of these files are so different? What must be done in order to obtain a hellopas.exe file of reasonable size?
I was wondering about this myself. Also, why is it that when I compile with the --shared switch, and then do a strip on the resulting executable, the compiled executable aborts due to a segfault?
On 10 Mar 2004 at 2:30, Neil Santos wrote:
- [070304 :: 2333] Claudiozm@aol.com Claudiozm@aol.com wrote:
Why the sizes of these files are so different? What must be done in order to obtain a hellopas.exe file of reasonable size?
I was wondering about this myself. Also, why is it that when I compile with the --shared switch, and then do a strip on the resulting executable, the compiled executable aborts due to a segfault?
Who knows? Perhaps strip is doing something dodgy. Instead of using strip, just use "gpc -s" instead.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Neil Santos wrote:
I was wondering about this myself. Also, why is it that when I compile with the --shared switch, and then do a strip on the resulting executable, the compiled executable aborts due to a segfault?
The `-shared' switch is to make a shared library. The executable is linked without `-shared' switch. Linking to shared libraries is a default, unless there is no shared library. Shared library is treated by system as executable but AFAIKS it is normal that one gets a crash. If you get a crash from normal executable after stripping, then you have bug in strip (it should be smart enough to retain symbols needed at runtime).