c - How to properly link gfortran and gcc? -
i trying write c function calls piece of fortran code. thought easier try link fortran code directly versus trying rewrite fortran c. using gcc/g++/gfortran on mac directly downloaded binaries , installed them.
the fortran code @ https://www.ngdc.noaa.gov/iaga/vmod/igrf12.f. specific subroutine want call subroutine igrf12syn (isv,date,itype,alt,colat,elong,x,y,z,f)
the wrapper wrote follows:
#include <stdio.h> extern void igrf12syn( int *isv, double *year, double *itype, double *alt, double *colat, double *elong, double* x,double* y, double* z, double* f ); int main(){ double b[4], babsdervs[3], brdervs[3], bthdervs[3], bphdervs[3]; double r, th, ph,year,alt2,lat,colat,elong,x,y,z,f; int isv; // igrf12syn (isv,date,itype,alt,colat,elong,x,y,z,f) r = 6371e3; th = 0.57; ph = 0; year = 2015; alt2 = 200.0; lat = 33.25; colat = 90.0-lat; elong = 0.0; isv =1; igrf12syn_(&isv,&year,&isv,&r, &th, &ph,x,y,z,f); printf("%0.4e",f); return 0; } the commands using compile , call are:
/usr/local/bin/gcc -lgfortran -c testigrf.c igrf12.f /usr/local/bin/gcc -lgfortran -o b.out testigrf.o igrf12.o the error is:
duplicate symbol _main in: testigrf.o igrf12.o ld: 1 duplicate symbol architecture x86_64 collect2: error: ld returned 1 exit status make: *** [igrf] error 1 i understand error means , can produce nm files .o files shows both of main functions. however, not sure how change fortran code rid of error.
so questions following: 1. how change fortran or c code fix issue? particularly, since fortran code starts program igrf
- am calling
igrf12synroutine properly? worried not calling correctly. may doing poor job passing in variables, has done reference.
thanks help, , please let me know if doing silly in calling routines.
firstly, c program testigrf.c defective. is, have warning:
testigrf.c: in function ‘main’: testigrf.c:23:5: warning: implicit declaration of function ‘igrf12syn_’ [-wimplicit-function-declaration] igrf12syn_(&isv,&year,&isv,&r, &th, &ph,x,y,z,f); ^ which occurs because have declared function called igrf12syn , invoked 1 called igrf12syn_, compiler knows nothing.
change igrf12syn_ igrf12syn, recompile, , errors revealed are:
testigrf.c: in function ‘main’: testigrf.c:23:26: warning: passing argument 3 of ‘igrf12syn’ incompatible pointer type [-wincompatible-pointer-types] igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f); ^ testigrf.c:3:14: note: expected ‘double *’ argument of type ‘int *’ extern void igrf12syn( int *isv, double *year, double *itype, double *alt, ^ testigrf.c:23:44: error: incompatible type argument 7 of ‘igrf12syn’ igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f); ^ testigrf.c:3:14: note: expected ‘double *’ argument of type ‘double’ extern void igrf12syn( int *isv, double *year, double *itype, double *alt, ^ testigrf.c:23:46: error: incompatible type argument 8 of ‘igrf12syn’ igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f); ^ testigrf.c:3:14: note: expected ‘double *’ argument of type ‘double’ extern void igrf12syn( int *isv, double *year, double *itype, double *alt, ^ testigrf.c:23:48: error: incompatible type argument 9 of ‘igrf12syn’ igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f); ^ testigrf.c:3:14: note: expected ‘double *’ argument of type ‘double’ extern void igrf12syn( int *isv, double *year, double *itype, double *alt, ^ testigrf.c:23:50: error: incompatible type argument 10 of ‘igrf12syn’ igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f); ^ testigrf.c:3:14: note: expected ‘double *’ argument of type ‘double’ extern void igrf12syn( int *isv, double *year, double *itype, double *alt, ^ read diagnostics , fix errors before go further. might fixed, example, changing:
double r, th, ph,year,alt2,lat,colat,elong,x,y,z,f; to
double r, th, ph,year,alt2,lat,colat,elong,x,y,z,f,itype; and changing:
igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f); to:
igrf12syn(&isv,&year,&itype,&r, &th, &ph,&x,&y,&z,&f); that satisfy compiler, though may not express intentions, not clear me.
you understand cannot link 2 programs single program, since linker find duplicate main functions. need link c main program fortran subroutine igrf12syn.
next, download , save file https://www.ngdc.noaa.gov/iaga/vmod/igrf12.f. open in text/programming editor. select of lines - complete lines, including leading space - compose subroutine igrf12syn, from:
subroutine igrf12syn (isv,date,itype,alt,colat,elong,x,y,z,f) to:
end save selection copied in new file igrf12syn.f in same directory testigrf.c.
then, open console in directory , execute following commands:
$ gcc -c -o testigrf.o testigrf.c $ gfortran -fno-underscoring -c -o igrf12syn.o igrf12syn.f $ gfortran -o testigrf testigrf.o igrf12syn.o these compile , link program testigrf in same directory.
finally, repeat first 2 commands, each additional option -wall, see warnings not yet aware of. consider fixing program remove warnings, may mean program not behave expect. include -wall in gcc/g++/gfortran compiler options when compiling code of importance you.
Comments
Post a Comment