Mail Archives: cygwin/2001/04/21/14:48:13
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
- Raw text -