X-Spam-Check-By: sourceware.org From: "Dave Korn" To: Subject: RE: G77, libg2c and a linking problem Date: Thu, 21 Sep 2006 19:42:01 +0100 Message-ID: <039501c6ddad$a0848d40$a501a8c0@CAM.ARTIMI.COM> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Office Outlook 11 In-Reply-To: Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com 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 AT 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? ---------------------------------------------------------------- $ 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 AT 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 ---------------------------------------------------------------- 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: ---------------------------------------------------------------- $ 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 ---------------------------------------------------------------- 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:- ---------------------------------------------------------------- $ 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 AT 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 AT rainbow /tmp/g77> ---------------------------------------------------------------- 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: ---------------------------------------------------------------- /* 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 2 => last two args were -l -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. ---------------------------------------------------------------- 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/