Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com Date: Sat, 21 Apr 2001 20:47:27 +0200 To: gcc-bugs AT gcc DOT gnu, .org AT t-online DOT de CC: cygwin AT cygwin DOT com From: lemkemch AT t-online DOT de (Michael Lemke) Subject: g77: getarg returns nothing if called in dll (cygwin) X-Mailer: Opera 5.10 build 902 X-Priority: 3 (Normal) Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Message-ID: <14r2Pt-0ANBOSC@fwd01.sul.t-online.com> X-Sender: 520098960173-0001 AT t-dialin DOT net I've asked this already on the cygwin mailing list but nobody seems interested there. So I'll try here as this seems to be a libg2c issue. In short I think libg2c needs to be built as a dll (shared library) to solve my problem, see below. I am trying for the first time to build a dll and I've stumbled across this: g77 getarg returns nothing if called from a dll. This is what I did: Test> cat test.f program test implicit none character x*132 integer i call geti( x, i ) end Test> cat geti.f subroutine geti( image, len_image ) implicit none character*(*) image integer len_image character*20 prg_name call getarg( 1, prg_name ) print *, 'getarg''ed: |'//prg_name//'|' end Test> g77 -c test.f Test> g77 -c geti.f Test> g77 test.o geti.o Test> ./a blah getarg'ed: |blah | Test> Ok, that works. Here's the problem: Test> dllwrap --driver-name g77 --implib libgeti.a --export-all -o geti.dll geti.o dllwrap: no export definition file provided dllwrap: creating one, but that may not be what you want Test> ls geti.dll geti.f geti.o libgeti.a test.f test.o Test> g77 test.o -L . -lgeti Test> ./a blah getarg'ed: | | Now there is nothing between |...| Some analysis: A Fortran program calls a main that is defined in libF77 and lives in libg2c. This main looks something like this: int f__argc; char** f__argv; int main( int argc, char **argv ) { f__argc = argc; f__argv = argv; /* call actual Fortran main program */ } And getarg in libF77 does this: extern int f__argc; extern char** f__argv; getarg_(int *n, char *s, long l ) { ... s = f__argv[*n]; ... } Both main.o and getarg.o are statically linked from libg2c. So test.o pulls it in from libg2c and the dll geti.dll gets its own copy from libg2c. Yuck. To solve this the declaration would have to be reversed: extern __declspec(dllimport) int f__argc; /* make this extern and get * it from dll */ extern __declspec(dllimport) char** f__argv; int main( int argc, char **argv ) { f__argc = argc; f__argv = argv; /* call actual Fortran main program */ } and (actually libf2c/libF77/setarg.c) int f__argc; /* this is now defined here instead of in main.c*/ char** f__argv; getarg_(int *n, char *s, long l ) { ... s = f__argv[*n]; ... } If we do this, however, we *have* to link against a shared library because main.c is defined to find f_argc in a dll. So we'd need two different versions depending on whether the Fortran program will link against another Fortran dll or not. The only way out of this I see is to make libg2c itself a dll. Then we wouldn't have to change any definitions except that I don't know if main.o may be in a dll. Are there any plans to make libg2c a shared library? I'd be happy to help with it but I would need help from other people who know the build procedures better (the TODO file talks about a libtool I don;t know) and also maybe libg2c as to where there could be problems if made a shared library. Thanks, Michael -- Want to unsubscribe from this list? Check out: http://cygwin.com/ml/#unsubscribe-simple