Shubham Attri
Shubham Attri

Reputation: 3

Error in a C code which is translated from Fortran using a f2c

I have never coded in Fortran. So I have some work related to Fortran in which I converted that code to C. But when I am running the C code it is giving me the following error :

/usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
/tmp/ccNX2LeT.o: In function `MAIN__':
sinai_static.c:(.text+0x58): undefined reference to `f_open'
sinai_static.c:(.text+0x2ca): undefined reference to `sqrt'
sinai_static.c:(.text+0x400): undefined reference to `sqrt'
sinai_static.c:(.text+0x487): undefined reference to `sqrt'
sinai_static.c:(.text+0x6f1): undefined reference to `atan2'
sinai_static.c:(.text+0x71b): undefined reference to `atan2'
sinai_static.c:(.text+0x777): undefined reference to `sqrt'
sinai_static.c:(.text+0x795): undefined reference to `cos'
sinai_static.c:(.text+0x7bb): undefined reference to `sin'
sinai_static.c:(.text+0x8ef): undefined reference to `s_wsle'
sinai_static.c:(.text+0x908): undefined reference to `do_lio'
sinai_static.c:(.text+0x921): undefined reference to `do_lio'
sinai_static.c:(.text+0x93a): undefined reference to `do_lio'
sinai_static.c:(.text+0x953): undefined reference to `do_lio'
sinai_static.c:(.text+0x96c): undefined reference to `do_lio'
sinai_static.c:(.text+0x974): undefined reference to `e_wsle'
sinai_static.c:(.text+0x9b5): undefined reference to `s_wsle'
sinai_static.c:(.text+0x9ce): undefined reference to `do_lio'
sinai_static.c:(.text+0x9fc): undefined reference to `do_lio'
sinai_static.c:(.text+0xa2e): undefined reference to `do_lio'
sinai_static.c:(.text+0xa60): undefined reference to `do_lio'
sinai_static.c:(.text+0xa92): undefined reference to `do_lio'
sinai_static.c:(.text+0xa9a): undefined reference to `e_wsle'
collect2: error: ld returned 1 exit status

The old Fortran code uses an external method from ran0.f. I think the problem is with opening a file as the translated code is using f_open(&o_1) which is giving an error. But I don't know how to resolve it. I am attaching the C code for reference.

    #include "f2c.h"

/* Table of constant values */

static integer c__3 = 3;
static integer c__1 = 1;
static integer c__5 = 5;

/* Main program */ int MAIN__(void)
{
    /* System generated locals */
    integer i__1;
doublereal d__1, d__2, d__3, d__4;
olist o__1;

/* Builtin functions */
integer f_open(olist *);
double sqrt(doublereal), atan2(doublereal, doublereal), cos(doublereal), 
    sin(doublereal);
integer s_wsle(cilist *), do_lio(integer *, integer *, char *, ftnlen), 
    e_wsle(void);

/* Local variables */
static doublereal a, c__, l, m, r__, e0, u0, u1, w0, x0, x1, z0, z1, x2, 
    z2, w1, u2, w2, t2;
static integer ii;
static doublereal en[500000], pi;
static integer it;
static doublereal ts, total_time__, vel;
extern doublereal ran0_(integer *);
static doublereal enke[500000];
static integer bhit;
static doublereal enpe[500000];
static integer idum, iter, itmin;
static doublereal ttemp, xtemp, ztemp, tstep;
static integer total_itcount__;
static doublereal maxvel, tanglec, tanglei, tangler;
static integer t_write__;

/* Fortran I/O blocks */
static cilist io___43 = { 0, 6, 0, 0, 0 };
static cilist io___44 = { 0, 18, 0, 0, 0 };


o__1.oerr = 0;
o__1.ounit = 18;
o__1.ofnmlen = 24;
o__1.ofnm = "data/sinai_static_r7.txt";
o__1.orl = 0;
o__1.osta = "unknown";
o__1.oacc = 0;
o__1.ofm = 0;
o__1.oblnk = 0;
f_open(&o__1);
pi = 3.14159265358979f;
idum = 120;
/* cc      POLYGON PARAMETERS */
    r__ = .7f;
    l = 4.f;
/* cc      INITIAL CONDITIONS */
    x0 = .3f;
    z0 = .33f;
    u0 = 100.f / sqrt(2.f);
    w0 = u0 * .1f;
/* Computing 2nd power */
    d__1 = u0;
/* Computing 2nd power */
    d__2 = w0;
    e0 = d__1 * d__1 + d__2 * d__2;
/*         write(*,*) "r=",r */

/*         write(*,*) "L=",L */
    tstep = l * .5f / u0;
    itmin = 500000;
    total_itcount__ = 0;
    for (iter = 1; iter <= 500000; ++iter) {
        en[499999] = 0.f;
        enke[499999] = 0.f;
        enpe[499999] = 0.f;
    }
    for (ii = 1; ii <= 1000; ++ii) {
/*            z0=0.3*(1.0+PI*(iI-1)/NI) */
    x0 = ran0_(&idum);
    if (x0 < .5f) {
        x0 = -(r__ + x0 * 2.f * (l - r__));
    } else {
        x0 = r__ + x0 * 2.f * (l - r__);
    }
    z0 = ran0_(&idum);
    if (z0 < .5f) {
        z0 = -(r__ + z0 * 2.f * (l - r__ - a));
    } else {
        z0 = r__ + z0 * 2.f * (l - r__);
    }
/*            write(*,*) iI,x0,z0 */
    x2 = x0;
    z2 = z0;
    u2 = u0;
    w2 = w0;
/* Computing 2nd power */
    d__1 = u2;
/* Computing 2nd power */
    d__2 = w2;
    vel = sqrt(d__1 * d__1 + d__2 * d__2);
    bhit = 0;
    total_time__ = 0.f;
    maxvel = 0.f;
    it = 0;
    t_write__ = 0;
    for (iter = 1; iter <= 500000; ++iter) {
/*            if((mod(iter,100000)).eq.0.0) write(*,*) iter */
        x1 = x2;
        z1 = z2;
        u1 = u2;
        w1 = w2;
        ts = -x1 / u1;
        m = w1 / u1;
        c__ = z1 + w1 * ts;
        if (u1 > 0.f) {
/* Computing 2nd power */
        d__1 = r__;
/* Computing 2nd power */
        d__2 = m;
/* Computing 2nd power */
        d__3 = c__;
/* Computing 2nd power */
        d__4 = m;
        x2 = (-m * c__ - sqrt(d__1 * d__1 * (d__2 * d__2 + 1) - d__3 *
             d__3)) / (d__4 * d__4 + 1);
        } else {
/* Computing 2nd power */
        d__1 = r__;
/* Computing 2nd power */
        d__2 = m;
/* Computing 2nd power */
        d__3 = c__;
/* Computing 2nd power */
        d__4 = m;
        x2 = (-m * c__ + sqrt(d__1 * d__1 * (d__2 * d__2 + 1) - d__3 *
             d__3)) / (d__4 * d__4 + 1);
        }
        t2 = (x2 - x1) / u1;
        if (t2 > 0.f) {
        bhit = 3;
        } else {
        if (u1 > 0.f) {
            ttemp = (l - x1) / u1;
        } else {
            ttemp = (-l - x1) / u1;
        }
        xtemp = x1 + ttemp * u1;
        ztemp = z1 + ttemp * w1;
        t2 = 0.f;
        if (ztemp < -l) {
            t2 = (-l - z1) / w1;
            bhit = 0;
        } else if (ztemp > l) {
            t2 = (l - z1) / w1;
            bhit = 2;
        } else {
            t2 = ttemp;
            bhit = 1;
        }
        }
        x2 = x1 + t2 * u1;
        z2 = z1 + t2 * w1;
        total_time__ += t2;
        if (bhit == 0) {
        u2 = u1;
        w2 = -w1;
        } else if (bhit == 1) {
        u2 = -u1;
        w2 = w1;
        } else if (bhit == 2) {
        u2 = u1;
        w2 = -w1;
        } else if (bhit == 3) {
        tanglec = atan2(z2, x2);
        tanglei = atan2(w1, u1);
        tangler = pi + tanglec * 2.f - tanglei;
    /* Computing 2nd power */
            d__1 = u1;
    /* Computing 2nd power */
            d__2 = w1;
            vel = sqrt(d__1 * d__1 + d__2 * d__2);
            u2 = cos(tangler) * vel;
            w2 = sin(tangler) * vel;
            }
    /*               if(total_time.gt.(iT*tstep)) then */
            ++it;
    /* Computing 2nd power */
            d__1 = u2;
    /* Computing 2nd power */
            d__2 = w2;
            en[it - 1] = en[it - 1] + d__1 * d__1 + d__2 * d__2;
    /* Computing 2nd power */
            d__1 = w2;
            enke[it - 1] += d__1 * d__1;
    /* Computing 2nd power */
            d__1 = u2;
            enpe[it - 1] += d__1 * d__1;
    /*               endif */
    /*               write(18,*) iter,x2,z2,u2,w2 */
        }
    /*            write(18,*) '' */
        if (itmin > it) {
            itmin = it;
        }
        if (ii % 100 == 0) {

        s_wsle(&io___43);
        do_lio(&c__3, &c__1, (char *)&ii, (ftnlen)sizeof(integer));
        do_lio(&c__5, &c__1, (char *)&total_time__, (ftnlen)sizeof(
            doublereal));
        do_lio(&c__3, &c__1, (char *)&iter, (ftnlen)sizeof(integer));
        do_lio(&c__5, &c__1, (char *)&u2, (ftnlen)sizeof(doublereal));
        do_lio(&c__5, &c__1, (char *)&w2, (ftnlen)sizeof(doublereal));
        e_wsle();
    }
    }
    i__1 = itmin;
    for (iter = 1; iter <= i__1; ++iter) {
    s_wsle(&io___44);
    do_lio(&c__3, &c__1, (char *)&iter, (ftnlen)sizeof(integer));
    d__1 = iter * tstep;
    do_lio(&c__5, &c__1, (char *)&d__1, (ftnlen)sizeof(doublereal));
    d__2 = en[iter - 1] / 1000;
    do_lio(&c__5, &c__1, (char *)&d__2, (ftnlen)sizeof(doublereal));
    d__3 = enke[iter - 1] / 1000;
    do_lio(&c__5, &c__1, (char *)&d__3, (ftnlen)sizeof(doublereal));
    d__4 = enpe[iter - 1] / 1000;
    do_lio(&c__5, &c__1, (char *)&d__4, (ftnlen)sizeof(doublereal));
    e_wsle();
    }
    return 0;
} /* MAIN__ */

/* Main program alias */ int main_ () { MAIN__ (); return 0; }

Upvotes: 0

Views: 1148

Answers (1)

jme52
jme52

Reputation: 1123

My understanding is that f2c, at the beginning of the translated file, usually generates the following header (file name and f2c version number may be different):

/* helloworld.f -- translated by f2c (version 20160102).
   You must link the resulting object file with libf2c:
        on Microsoft Windows system, link with libf2c.lib;
        on Linux or Unix systems, link with .../path/to/libf2c.a -lm
        or, if you install libf2c.a in a standard place, with -lf2c -lm
        -- in that order, at the end of the command line, as in
                cc *.o -lf2c -lm
        Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,

                http://www.netlib.org/f2c/libf2c.zip
*/

Please follow these instructions (which coincide with @zwol advice) in order to correctly compile and link your source code.

  • You need to link against the f2c library (-lf2c or libf2c.a) because it provides functions such as f_open, do_lio, e_wsle or s_wsle that are used by code generated by f2c.
  • You need to link against the C math library (-lm) because it provides the mathematical functions used by your code (sqrt, sin, cos, and atan2).

In addition to this, you will also need to compile the other source file, ran0.f, and link against it.

If you are using GCC, as it seems from the form of the errors you report, the steps to follow are:

  1. Compile the Fortran file ran0.f with the Fortran compiler

    $ gfortran ran0.f -c -o ran0.o
    
  2. Compile the file whose source code you provided; assuming its name is foo.c,

    $ gcc foo.c -c -o foo.o
    
  3. Create the binary (foo) by linking against the f2c library; assuming it's installed in a standard location in your operating system,

    $ gcc foo.o ran0.o -lf2c -lm -o foo
    

    Otherwise, you have to find where the file libf2c.a is located in your system (e.g., /home/myuser/code/f2c/lib/libf2c.a) and use that path in the linking command, instead of -lf2c:

    $ gcc foo.o ran0.o /home/myuser/code/f2c/lib/libf2c.a -lm -o foo
    

If you want to also convert file ran0.f to C, instead of step 1. above you should first use f2c to convert the Fortran source file ran0.fto a C source file

$ f2c ran0.f

(this creates file ran0.c) and then compile the C source file to create the object file ran0.o

$ gcc ran0.c -c -o ran0.o

Then proceed with steps 2. and 3. as above.

Upvotes: 1

Related Questions