This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: G77, libg2c and a linking problem


On 19 September 2006 23:05, Angelo Graziosi wrote:

> What would be 'unusual or incorrect' in
> 
> $ cat hello.F
>       program hello
>       implicit none
>       write(*,*) 'Hello!'
>       end
> 
> (1)
> $ g77 hello.F -o hello -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lg2c
>
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libcygwin.a(libcmain.o):(.text+0xab
):
>  undefined reference to `_WinMain@16'
> collect2: ld returned 1 exit status

  Well, the -L option adds a standard library directory to the wrong point in
the library search path, and the -l option adds a standard library to the
wrong point in the link order.  You're meant to leave CRT stuff to the driver,
which *knows* what to do.  If you wanted to do it yourself, and guarantee to
get it right, you'd have to reimplement the entire specs mechanism in your
makefile.

> (2)
> $ g77 hello.F -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lg2c -o hello
> 
> $ ./hello
>  Hello!

  I'll do the -v thing myself then, shall I?

--------------------------------<snip>--------------------------------
$ g77 -v hello.F -o hello -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lg2c

 /usr/lib/gcc/i686-pc-cygwin/3.4.4/collect2.exe -Bdynamic
--dll-search-prefix=cy
g -o hello.exe
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/
crt0.o -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4
-
L/usr/lib/gcc/i686-pc-cygwin/3.4.4
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../
../i686-pc-cygwin/lib -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../..
/win/c/DOCUME
~1/dk/LOCALS~1/Temp/ccOxEzrm.o -lg2c -lgcc -lcygwin -luser32 -lkernel32
-ladvapi
32 -lshell32 -lgcc
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/libcygwin.a(l
ib
cmain.o): In function `main':
/usr/build/src-winsup/winsup/cygwin/lib/libcmain.c:40: undefined reference to
`_
WinMain@16'
collect2: ld returned 1 exit status

$ g77 -v hello.F -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lg2c -o hello

 /usr/lib/gcc/i686-pc-cygwin/3.4.4/collect2.exe -Bdynamic
--dll-search-prefix=cy
g -o hello.exe
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/
crt0.o -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4
-
L/usr/lib/gcc/i686-pc-cygwin/3.4.4
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../
../i686-pc-cygwin/lib -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../..
/win/c/DOCUME
~1/dk/LOCALS~1/Temp/ccwxRLEP.o -lg2c -lfrtbegin -lg2c -lgcc -lcygwin -luser32
-l
kernel32 -ladvapi32 -lshell32 -lgcc
--------------------------------<snip>--------------------------------

  When you snip out all the extraneous options and just look at the input
files and -L and -l options, here's what you get:

--------------------------------<snip>--------------------------------
$ g77 -v hello.F -o hello -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lg2c

/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/crt0.o 
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4 
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4 
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4 
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib 
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.. 
/win/c/DOCUME~1/dk/LOCALS~1/Temp/ccOxEzrm.o 
-lg2c -lgcc -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc

$ g77 -v hello.F -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lg2c -o hello

/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/crt0.o 
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4 
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4 
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4 
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib 
-L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.. 
/win/c/DOCUME~1/dk/LOCALS~1/Temp/ccwxRLEP.o 
-lg2c -lfrtbegin -lg2c -lgcc -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32
-lgcc
--------------------------------<snip>--------------------------------

  A single glance at the last line shows that the difference is -lfrtbegin.

  Further, because you specified -lg2c yourself, the g77 driver specs assume
you know what you're doing, and in particular that -lfrtbegin must be
specified *before* -lg2c.  The specs would have taken care of that, but you
overrode them; you can fix the buggy version of your command line by manually
adding -lfrtbegin:-

--------------------------------<snip>--------------------------------
$ g77 hello.F -o hello -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lg2c
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/libcygwin.a(l
ib
cmain.o): In function `main':
/usr/build/src-winsup/winsup/cygwin/lib/libcmain.c:40: undefined reference to
`_
WinMain@16'
collect2: ld returned 1 exit status
$ g77 hello.F -o hello -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lfrtbegin -lg2c
dk@rainbow /tmp/g77>
--------------------------------<snip>--------------------------------

  For full information, read .../gcc-3.4.4/gcc/f/g77spec.c, look in particular
at the function lang_specific_driver and the variables and comments:

--------------------------------<snip>--------------------------------
  /* This will be NULL if we encounter a situation where we should not
     link in libf2c.  */
  const char *library = FORTRAN_LIBRARY;

  /* 0 => -xnone in effect.
     1 => -xfoo in effect.  */
  int saw_speclang = 0;

  /* 0 => initial/reset state
     1 => last arg was -l<library>
     2 => last two args were -l<library> -lm.  */
  int saw_library = 0;

  /* 0 => initial/reset state
     1 => FORTRAN_INIT linked in */
  int use_init = 0;

 [ ... snip ... ]

  /* First pass through arglist.

     If -nostdlib or a "turn-off-linking" option is anywhere in the
     command line, don't do any library-option processing (except
     relating to -x).  Also, if -v is specified, but no other options
     that do anything special (allowing -V version, etc.), remember
     to add special stuff to make gcc command actually invoke all
     the different phases of the compilation process so all the version
     numbers can be seen.
--------------------------------<snip>--------------------------------

  Ach, there's the bug!  If -lg2c is the very last option on the line, it has
saw_library=1, and then it exits and never does anything about it.  Adding any
option, even another -v, makes it go round the loop again and it all works.
Hmm...  it could try to prepend FORTRAN_INIT if it hadn't got use_init set by
the time it sets saw_librry to 1.  Dunno why it doesn't.  Probably a
corner-case.


    cheers,
      DaveK
-- 
Can't think of a witty .sigline today....


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]