[tlbuild] Static linking of C++ runtime library causing problems on x86_64-cygwin

Ken Brown kbrow1i at gmail.com
Wed Feb 19 20:28:38 CET 2014


On 2/19/2014 9:28 AM, Ken Brown wrote:
> On 2/19/2014 2:41 AM, Peter Breitenlohner wrote:
>> the macro in kpse-cxx-hack.m4 jusst reformulates what was done in earlier
>> versions.  For some (obscure?) reasons cygwin is treated differently from
>> all other systems using gcc (including MinGW).  Perhaps this distinction
>> should be removed.  In order to test this please try to change line 17862
>>    *cygwin*)  flags_try0='-static -static-libgcc';
>> of texk/web2c/configure into
>>    NEVER)  flags_try0='-static -static-libgcc';
>> and see if that helps (for cygwin32 and cygwin64).  If that succeeds
>> we can
>> simplify the definition of _KPSE_CXX_HACK in m4/kpse-cxx-hack.m4.
>
> Hi Peter,
>
> It almost works.  The problem is -nodefaultlibs.   I made a test program
> based on the configure test:
>
> $ cat test.cc
> #include <iostream>
> using namespace std;
> int
> main ()
> {
> cout <<"worksok\n";
>    ;
>    return 0;
> }
>
> It builds and runs fine (with static linking of stdc++) if I omit
> -nodefaultlibs from try0:
>
> $ g++ -o test test.cc -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic -lm
>
> $ ./test.exe
> worksok
>
> $ ldd test.exe
>          ntdll.dll => /c/Windows/SysWOW64/ntdll.dll (0x775f0000)
>          kernel32.dll => /c/Windows/syswow64/kernel32.dll (0x75240000)
>          KERNELBASE.dll => /c/Windows/syswow64/KERNELBASE.dll (0x751c0000)
>          cygwin1.dll => /usr/bin/cygwin1.dll (0x61000000)
>          cyggcc_s-1.dll => /usr/bin/cyggcc_s-1.dll (0x6ac50000)
>
> But with -nodefaultlibs, it fails on both x86-cygwin and x86_64-cygwin.
>   Here's the x86 case, but it looks the same on x86_64:
>
> $ g++ -o test test.cc -nodefaultlibs -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
> -lm     /usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../crt0.o: In function
> `mainCRTStartup':
> /usr/src/debug/cygwin-1.7.28-2/winsup/cygwin/crt0.c:29: undefined
> reference to `cygwin_crt0'
> /usr/src/debug/cygwin-1.7.28-2/winsup/cygwin/crt0.c:34: undefined
> reference to `cygwin_premain0'
> /usr/src/debug/cygwin-1.7.28-2/winsup/cygwin/crt0.c:35: undefined
> reference to `cygwin_premain1'
> /usr/src/debug/cygwin-1.7.28-2/winsup/cygwin/crt0.c:36: undefined
> reference to `cygwin_premain2'
> /usr/src/debug/cygwin-1.7.28-2/winsup/cygwin/crt0.c:37: undefined
> reference to `cygwin_premain3'
> /usr/lib/gcc/i686-pc-cygwin/4.8.2/crtbegin.o:cygming-crtbegin.c:(.text+0xa):
> undefined reference to `_imp__GetModuleHandleA at 4'
> /usr/lib/gcc/i686-pc-cygwin/4.8.2/crtbegin.o:cygming-crtbegin.c:(.text+0x2e):
> undefined reference to `_imp__LoadLibraryA at 4'
> /usr/lib/gcc/i686-pc-cygwin/4.8.2/crtbegin.o:cygming-crtbegin.c:(.text+0x47):
> undefined reference to `_imp__GetProcAddress at 8'
> /usr/lib/gcc/i686-pc-cygwin/4.8.2/crtbegin.o:cygming-crtbegin.c:(.text+0x8e):
> undefined reference to `_imp__GetProcAddress at 8'
> /usr/lib/gcc/i686-pc-cygwin/4.8.2/crtbegin.o:cygming-crtbegin.c:(.text+0xd2):
> undefined reference to `_imp__GetProcAddress at 8'
> /usr/lib/gcc/i686-pc-cygwin/4.8.2/crtbegin.o:cygming-crtbegin.c:(.text+0xf4):
> undefined reference to `_imp__FreeLibrary at 4'
> /usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld:
> /usr/lib/gcc/i686-pc-cygwin/4.8.2/crtbegin.o: bad reloc address 0x20 in
> section `.eh_frame'
> /usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld:
> final link failed: Invalid operation
> collect2: error: ld returned 1 exit status
>
> Is it important to use -nodefaultlibs?

I just applied the following patch and rebuilt (after running reautoconf):

--- kpse-cxx-hack.m4.orig	2014-02-19 10:35:24.174867600 -0500
+++ kpse-cxx-hack.m4	2014-02-19 11:30:00.542265100 -0500
@@ -64,8 +64,7 @@
  #endif]],
                                       [[cout <<"worksok\n";]])])
    case $host in
-  *cygwin*)  flags_try0='-static -static-libgcc';
-             flags_try1='-lstdc++'; flags_try2=$flags_try1;;
+  *cygwin*)  flags_try0='-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic';;
    *)  flags_try0='-nodefaultlibs -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic -lm'
        flags_try1='-lgcc_eh -lgcc -lc -lgcc_eh -lgcc'
        flags_try2='-lgcc -lc -lgcc';;


Everything built fine on both x86 and x86_64 [*].  So if other platforms 
really need the -nodefaultlibs flag, then I guess Cygwin will still have 
to be a special case, unless you can find some other way of getting 
around this.  But at least it's not a special case that causes problems 
with other parts of the build

Ken

[*] Actually there are some patches needed, especially for x86_64, but 
they're unrelated to the present discussion so I'll send them in a 
separate email.




More information about the tlbuild mailing list