I tried "gcc -Bstatic -c foo.c" , "gcc -non_shared -c foo.c", "gcc -Zso -c
foo.c" but it always links to the RTL dynamically.
Or do I have to specify those options in the link step ? If yes, how ?
Lars
Rightly or wrongly, I use "-s -static -Zomf -lc_omf386" at the link stage.
I am not a GCC expert, but the above works for me and produces an executable
which is massive compared to any other compiler, but which has no unexpected
DLL dependencies.
Hi,
very strange, my results are different (for gcc 3.3.5 at least).
Even though I only have one source file I decided to go for a separate
compile and link step:
gcc -Zomf -o lostKingdom.obj lostKingdom.c
gcc -static -Zomf -Zmt -Zmap=lostKingdom.map -Zlinker /STACK:0x10000
-Zlinker /BASE:0x10000 -Zlinker /EXEPACK:2 -lc_omf386 -o lostKingdom.exe
lostKingdom.obj
This gives a VERY SMALL executable which links the C library statically
! It only imports from doscalls.dll, libuni.dll and uconv.dll.
The only problem I have is this warning:
D:\HOME\buildenv\usr\lib\libc_omf386.lib(src/lib/sys/386/signal16bit.asm)
: warning LNK4008: aliased fix-up to non-alias object near F in object
CODE32
However, the executable runs just fine. By the way: Compiling and
linking in one step also does not make a difference.
gcc --version yields:
gcc (GCC) 3.3.5 (Bird Build 2007-06-10 14:30)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Lars
>> Rightly or wrongly, I use "-s -static -Zomf -lc_omf386" at the link stage.
> gcc -Zomf -o lostKingdom.obj lostKingdom.c
That should be "-c" not "-o"
> gcc -static -Zomf -Zmt -Zmap=lostKingdom.map -Zlinker /STACK:0x10000
> -Zlinker /BASE:0x10000 -Zlinker /EXEPACK:2 -lc_omf386 -o lostKingdom.exe
> lostKingdom.obj
>
> This gives a VERY SMALL executable which links the C library statically
> ! It only imports from doscalls.dll, libuni.dll and uconv.dll.
Define "VERY SMALL".
I tried all that with just a simple printf("Hello world\n"); and it gave
me an executable 250K in size. With VAC++ 3.08 it was about 30K.
Fiddling with the options made no significant difference. The only things that
reduced it to a reasonable size also introduced a dependency on libc063.dll
> D:\HOME\buildenv\usr\lib\libc_omf386.lib(src/lib/sys/386/signal16bit.asm)
>: warning LNK4008: aliased fix-up to non-alias object near F in object
> CODE32
Yeah, I got that as well.
> However, the executable runs just fine. By the way: Compiling and
> linking in one step also does not make a difference.
Nor would I expect it to.
> gcc --version yields:
> gcc (GCC) 3.3.5 (Bird Build 2007-06-10 14:30)
Likewise.
"VERY SMALL" for the prog I was testing.
But you are right: generating a map file for a build linking statically
to C RTL lists about everything that is contained in the C RTL. I guess
the problem is that the linker (which is one of IBM's) is not capable of
pulling out of libc_s.lib only the modules it needs (because it does not
recognize the library format ?) and therefore links in EVERYTHING that
is contained in libc_s.lib.
I CAN say that libc_s.lib is sensibly modularized, it contains about a
hundred separate modules.
However, running
ilib.exe libc_s.lib,con;
against the static library traps ilib.exe. That's why I believe the IBM
linker cannot properly analyze libc_s.lib ....
Adding -Zlinker /OPTF does not make a bit of a difference either ...
Lars
I do not know how to use `a simple printf("Hello world\n")', but
gcc -O2 -Zomf -Zsys -s hello_static.c
with
#include <stdlib.h>
#include <stdio.h>
int
main (int argc, char* argv[], char* envp[])
{
printf("Hello world\n");
exit(0);
}
gives 43K executable with EMX.
> "VERY SMALL" for the prog I was testing.
> But you are right: generating a map file for a build linking statically
> to C RTL lists about everything that is contained in the C RTL. I guess
> the problem is that the linker (which is one of IBM's) is not capable of
> pulling out of libc_s.lib only the modules it needs (because it does not
> recognize the library format ?) and therefore links in EVERYTHING that
> is contained in libc_s.lib.
> I CAN say that libc_s.lib is sensibly modularized, it contains about a
> hundred separate modules.
> However, running
> ilib.exe libc_s.lib,con;
> against the static library traps ilib.exe. That's why I believe the IBM
> linker cannot properly analyze libc_s.lib ....
> Adding -Zlinker /OPTF does not make a bit of a difference either ...
Hmm, I do not *want* to buy it. ;-)
EMX uses link386. Can you retry with link386?
Thanks,
Ilya
There is also emxomfar; it is coded to work standalone; won't delegate
the work to any IBM program...
> That's why I believe the IBM linker cannot properly analyze
> libc_s.lib ....
Just another data point: I retried EMX link with ilink instead of
link386, and it produced executable of practically the same size -
without any problem. Of course, EMX would link with different libraries...
Hope this helps,
Ilya
You are not linking to the C RTL statically (you need to specify
-static) . Create a map file with -Zmap=... and see the result. You are
linking against libc063.dll.
>
>> "VERY SMALL" for the prog I was testing.
>> But you are right: generating a map file for a build linking statically
>> to C RTL lists about everything that is contained in the C RTL. I guess
>> the problem is that the linker (which is one of IBM's) is not capable of
>> pulling out of libc_s.lib only the modules it needs (because it does not
>> recognize the library format ?) and therefore links in EVERYTHING that
>> is contained in libc_s.lib.
>> I CAN say that libc_s.lib is sensibly modularized, it contains about a
>> hundred separate modules.
>> However, running
>> ilib.exe libc_s.lib,con;
>> against the static library traps ilib.exe. That's why I believe the IBM
>> linker cannot properly analyze libc_s.lib ....
>> Adding -Zlinker /OPTF does not make a bit of a difference either ...
>
> Hmm, I do not *want* to buy it. ;-)
>
> EMX uses link386. Can you retry with link386?
No, not true (I am talking about gcc 3.3.5). This is controlled via the
EMXOMFLD_TYPE, EMXOMFLD_LINKER environment variables.
They default to VAC365 and ilink.exe (from VAC 365) respectively.
Lars
> You are not linking to the C RTL statically
Yes, I am.
> (you need to specify -static).
-static is, AFAIK, NOOP with EMX.
> Create a map file with -Zmap=... and see the result. You are
> linking against libc063.dll.
Thanks, but I know how to use chk4dlls...
> > Hmm, I do not *want* to buy it. ;-)
> >
> > EMX uses link386. Can you retry with link386?
>
> No, not true (I am talking about gcc 3.3.5).
It is hard to understand what you mean is "not true" in my statement. ;-)
Especially since it is true... ;-) ;-) ;-)
> This is controlled via the
> EMXOMFLD_TYPE, EMXOMFLD_LINKER environment variables.
> They default to VAC365 and ilink.exe (from VAC 365) respectively.
These variables have no effect on EMX. So my question stands: could
you retry with link386? (BTW, I retried my with ilink instead of
link386, and it also gives a small executable. But EM had a major
overstock of clue...)
Thanks,
Ilya
I am not talking about EMX. I am talking about gcc >= 3.3.5. It does not
make use of EMX (at least not of its libraries, static or not).
Lars
??? Why? I was talking about EMX. EMX works as expected; newer
gcc's fail to work as expected. Since there is more than one
difference, I proposed to eliminate differences one-by-one, to find
which one is relevant.
The simplest thing to eliminate is which under-the-cover-linker is used.
Hope this helps,
Ilya
Setting these correspondingly, I have tried both, ilink.exe from VAC365
as well as link386.exe. ilink.exe leads to slightly smaller exe,
link386.exe to slightly larger exe. However, both of them are huge if
you link the C RTL statically.
For older versions of gcc making use of EMX this might be different.
Lars
Thanks, that helps. Now, if on linking, the linker would omit from the
library the modules that are not used ...
Lars
> > The simplest thing to eliminate is which under-the-cover-linker is used.
> And I don't care about EMX,
Who cares what you care about? What I told you is a simple way to
start investigating the problem YOU have with static linking. (See
below...)
> it's history (at least if you want to stick to newer versions of gcc).
??? Is not 4.3.2 new enough for you? I'm using EMX with 4.3.2 now
(my setup currently has only -Zmtd supported, though, so I can't check
static linking).
> Setting these correspondingly, I have tried both, ilink.exe from VAC365
> as well as link386.exe. ilink.exe leads to slightly smaller exe,
> link386.exe to slightly larger exe. However, both of them are huge if
> you link the C RTL statically.
So we established that it is the structure of the library which
matters; with large probability the linker's problems are not
relevant...
I wonder if the architecture of EMX's __syscall() matters here: in
EMX, unless one uses -Zsys, (almost) all calls to OS's "services" are
routed through a __syscall() interface, which decides which API to
call basing on "syscall number". If klibc has anything analoguous, it
may lead to "everything" being pulled in through the code of
__syscall()...
Yours,
Ilya
It should be, are you sure it isn't? I'm using LINK386 on a project
that uses a static library built by WLIB (was EMXOMFAR), and it works
correctly.
Maybe there's something in the library generating EXTERNs for
everything, which causes it to be included. This wouldn't show up using
the DLL.
Lars
Are you sure?
Extract manually the modules from the library which you think should
be enough (if your ilink crashes, try emxomfar). Create a library
from them, and link against it. *IF* this creates a small executable,
THEN your assumption is verified.
Otherwise, it may be just a tangle of cross-dependencies inside the library...
> Therefore I assume that the OMF type library format that emxomf.exe
> generates is not 100% compatible with the OMF type libraries that IBM's
> ilib.exe creates.
As you know, this is not true, since EMX static libraries work without
any problem.
Yours,
Ilya
Libraries created by EMXOMFAR work fine. I'm not familiar with what
emxomf is doing. It's best not to make too many assumptions.
If you create a map file using -Zmap you will see that a lot of modules
are pulled in.
Dave