gfortran linking errors on OS X 10.9

Discussion in 'Mac Programming' started by syrenson, Mar 27, 2015.

  1. syrenson macrumors newbie

    Joined:
    Mar 27, 2015
    #1
    Greetings All,

    I am new to the forums here and hoping to find some assistance from folks that have experience with compiling older FORTRAN code on OS X.

    I am using the gfortran compiler on Mac OS X 10.9.5 with Xcode version 6.2 and the Xcode command line tools installed. I am performing the compilation and linking from the command line/Terminal (i.e. not using an Xcode project).

    Here's what I've got:

    Any assistance or input would be greatly appreciated.

    All the best
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    Location:
    Brobdingnag
    #2
    What kind of assistance are you looking for? Are you looking for an explanation of the error message? Are you looking for help in how to fix the cause of the errors?


    Below is a rough explanation of the error message. If you already knew all this, then I apologize. It's the only thing I could come up with given the vagueness of your request. (I say "rough" because I'm not 100% sure of a couple things, so I'm extrapolating based on things I'm sure of.)

    Here's the error message:
    Code:
    Undefined symbols for architecture i386:
    "_date_", referenced from:
    _header_ in header.o
    "_timer_", referenced from:
    _MAIN__ in couple.o
    ld: symbol(s) not found for architecture i386
    collect2: error: ld returned 1 exit status
    make: *** [couple] Error 1
    
    This is telling you that there are functions, subroutines, or global data names that are not defined. That is, the program is referring to something outside the .f file, and that something isn't defined by any other .f file or library.

    I can't tell you what the "something" is. It could be a function, subroutine, or global data name. All of those are termed "symbols", so that's what "Undefined symbols" means.

    Here are the specifics:
    The symbol date is used in the routine named header, which is in the "header.f" file.
    The symbol timer is used in the routine named MAIN, which is in the "couple.f" file.
    I'm giving the symbol name as I suspect it will appear in the Fortran source. It may also be uppercase, i.e. DATE instead of date. And MAIN may be a PROGRAM statement.

    The actual symbol in the compiled object-file has a leading and trailing '_', which are automatically added by the Fortran compiler. The compiler does this so Fortran symbols are distinct from those in other compiled languages, such as C. To get the original symbol name, one must remove these additions.

    The transformation from a Fortran symbol name into a compiled symbol-name is one of the things I'm unsure of. The C convention is to only prepend an '_', so the C function foo() ends up as the compiled symbol _foo. Other languages have other transformations, so I'm guessing that Fortran's is to both prepend and append an '_'.


    I can't explain any more than this, because I can't tell if the Fortran code is expecting date and timer to be provided by a missing source file, or by a library. If it's expecting those to be in a library, then you'll have to explain where the source is from, so we can see what its dependencies are. If you wrote it entirely yourself, then you have to tell us what library it depends on.

    As shown, the command that links the .o files isn't referring to any other libraries, which means that only the standard Fortran library (i.e. builtin functions & such) will be used. If the missing symbols are from another library, you have to tell the linker what that library is.

    If the missing symbols are expected to be in the standard Fortran library, then please post the source from "header.f" and "couple.f" that shows the references to the symbol. The first step to understanding what the code is expecting is to see it in use.

    As an example, if I google for gfortran timer, I find the following:
    https://gcc.gnu.org/onlinedocs/gfortran/CPU_005fTIME.html
    https://gcc.gnu.org/onlinedocs/gfortran/TIME.html
    https://gcc.gnu.org/onlinedocs/gfortran/SYSTEM_005fCLOCK.html
    http://stackoverflow.com/questions/...ines-which-is-better-cpu-time-or-system-clock
    http://people.sc.fsu.edu/~jburkardt/f_src/timer/timer.html

    The first 3 references are the gfortran standard library routines CPU_TIME, TIME, and SYSTEM_CLOCK. None of these are the exact name timer. However, if Fortran is using timer to measure elapsed time, it may allow you (or someone else) to make an equivalent using one of those routines.

    The 4th and 5th links discuss timing of runs. If that's what your code is doing, they may be useful in applying the library routines.
     
  3. mfram macrumors 65816

    Joined:
    Jan 23, 2010
    Location:
    San Diego, CA USA
    #3
    One thing that strikes me as strange is the "-arch i386" that is there. It might be forcing a 32-bit compile. To the O.P.: is there a specific reason for that? If not, I would try taking that out. It could be the problem.
     
  4. syrenson, Mar 27, 2015
    Last edited: Mar 27, 2015

    syrenson thread starter macrumors newbie

    Joined:
    Mar 27, 2015
    #4
    Thank you, chown33 and mfram for your replies. To clarify, yes, I am seeking assistance with getting the code to compile and link without errors.

    The source code is for a program that models the propagation of acoustic energy in the ocean, known as COUPLE, and can be downloaded here:

    http://oalib.hlsresearch.com/Modes/index.html (simply click on the third link down "Couple")

    The makefile included with the source code has a few typos and refers to all of the source files with lowercase filenames while many of the files themselves use uppercase filenames (most likely developed in a Windows environment). This said, I have attached a makefile to this post with the typos fixed should anyone care to give the compilation a try (note: I've appended a .txt extension so that the forum will allow me to attach the file).

    To answer the question about the -arch i386 compiler flag, I added this thinking that perhaps the code simply could not be compiled against x86_64 libraries. Seeing as this didn't seem to make a difference, I've removed this flag.

    Here is the latest output when trying to compile the code:

    Code:
    gfortran -c couple.f
    gfortran -c abortc.f
    gfortran -c amat.f
    gfortran -c backsub.f
    gfortran -c bathy.f
    gfortran -c bdf.f
    gfortran -c bessj0.f
    gfortran -c bessy0.f
    gfortran -c bmat.f
    gfortran -c botdeps.f
    gfortran -c bounds.f
    gfortran -c cdfun.f
    gfortran -c cdj0.f
    gfortran -c cdsrt.f
    gfortran -c cdtan.f
    gfortran -c cexib.f
    gfortran -c cexibd.f
    gfortran -c cexiw.f
    gfortran -c cexiwb.f
    gfortran -c cexiwd.f
    gfortran -c chdh.f
    gfortran -c choldc.f
    gfortran -c cjdj.f
    gfortran -c clineqs.f
    gfortran -c cpres.f
    gfortran -c crscup.f
    gfortran -c csds.f
    gfortran -c csymeig.f
    gfortran -c cupb.f
    gfortran -c cupbw.f
    gfortran -c cupw.f
    gfortran -c cupwb.f
    gfortran -c cvmult.f
    gfortran -c cwns.f
    gfortran -c dreal.f
    gfortran -c file.f
    gfortran -c foresub.f
    gfortran -c egnval.f
    gfortran -c galrkn.f
    gfortran -c gama0.f
    gfortran -c gama00.f
    gfortran -c genabc.f
    gfortran -c header.f
    gfortran -c hk01.f
    gfortran -c hk02.f
    gfortran -c indep.f
    gfortran -c indexx.f
    gfortran -c input.f
    gfortran -c mgs.f
    gfortran -c mmult.f
    gfortran -c propm.f
    gfortran -c prtmat.f
    gfortran -c prttl.f
    gfortran -c rcf.f
    gfortran -c rwprof.f
    gfortran -c tmmult.f
    gfortran -c zcexib.f
    gfortran -c zcexiw.f
    gfortran -o couple couple.o \
    	abortc.o amat.o backsub.o bathy.o bdf.o \
        bessj0.o bessy0.o bmat.o botdeps.o bounds.o \
    	cdfun.o cdj0.o cdsrt.o cdtan.o cexib.o cexibd.o \
        cexiw.o cexiwb.o cexiwd.o chdh.o \
        choldc.o cjdj.o \
        clineqs.o cpres.o \
    	crscup.o csds.o csymeig.o cupb.o \
    	cupbw.o cupw.o cupwb.o cvmult.o cwns.o dreal.o \
    	file.o foresub.o egnval.o galrkn.o gama0.o \
    	gama00.o genabc.o header.o hk01.o hk02.o \
    	indep.o indexx.o input.o mgs.o mmult.o \
    	propm.o prtmat.o prttl.o rcf.o rwprof.o \
    	tmmult.o zcexib.o zcexiw.o
    Undefined symbols for architecture x86_64:
      "_date_", referenced from:
          _header_ in header.o
      "_timer_", referenced from:
          _MAIN__ in couple.o
    ld: symbol(s) not found for architecture x86_64
    collect2: error: ld returned 1 exit status
    make: *** [couple] Error 1
    I'm not sure how helpful this is (it wasn't too helpful for me) but a colleague of mine was able to successfully compile the source code on a 64 bit Windows 7 system using cygwin, with no additional libraries. When I took a look at their makefile I noticed that they appended -O2 -march=nocona to their compile flags. I tried this but still received the same linking error.

    Thank you again for your time and assistance!

    EDIT: Here's a one line script for renaming all of the files in the source folder to lowercase letters:

    Code:
    for i in $( ls | grep [A-Z] ); do mv -i $i `echo $i | tr 'A-Z' 'a-z'`; done
     

    Attached Files:

  5. chown33, Mar 27, 2015
    Last edited: Mar 27, 2015

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    Location:
    Brobdingnag
    #5
    Looking at the source for "couple.for" (the original file's name), I see this:

    Code:
    C
    C     START UNIX OR g95 TIMER
    C
    c      ISTARTS=time()
    C
    C     START LAHEY TIMER
    C
          CALL TIMER(IHU)
          STARTS=.01*IHU
    ...bunch of stuff skipped...
    C 
    C     FIND ELAPSED TIME IN UNIX or g95
    C
    c      IENDS=time()
    c      ELAPSE=IENDS-ISTARTS
    C 
    C     FIND ELAPSED TIME IN LAHEY
    C
          CALL TIMER(IHU)
          ENDS=.01*IHU
          ELAPSE=ENDS-STARTS
    ...
    
    The calls to TIMER are apparently calculating an elapsed time, which subsequent code then prints out.

    There also appears to be commented-out code that calls a time() function. The comments suggest this is the Unix or g95 code to use. I interpret "g95" as the gfortran compiler for Fortran-95. g95 is this open source Fortran compiler:
    http://www.g95.org/

    Googling the search terms fortran lahey timer finds results for a Fortran 77 compiler from Lahey systems. Without looking any further, my guess is that TIMER() is specific to the Lahey F77 compiler. You can do the same search and read the articles, but I strongly suspect the similar gfortran functions for reading the system clock will work for calculating elapsed time, possibly after accounting for any differences in scale factor.

    Or maybe you could write a Lahey-compatible subroutine in a separate .f file, and add it to the compiled files.

    I suspect a similar search for the undefined date routine will produce similar results. I recommend looking at the source first, to understand what it's intended to do.


    Notably, you don't say whether you know Fortran or not. Stating that would go a long way to understanding what level of help you need. Specifically, whether you need someone to write and test the code for you, or whether simply pointing you to relevant links will suffice.

    I'm no Fortran expert, but this doesn't seem like a hard problem to solve if one has some basic Fortran skills, and can understand the gfortran references for the previously linked system-timing routines. Worst-case, comment out the calls to the problematic routines, and don't print elapsed time and current date. The output data won't have those elements, but it hardly seems critical.

    Personally, I'm simultaneously pleased and appalled that I remember as much as I do about it from my long-gone college days, when we punched cards for a Fortran-66 compiler and sent them out overnight to a batch operator. If I never see another Hollerith format I would count my programming days happy.
     
  6. syrenson, Mar 27, 2015
    Last edited: Mar 27, 2015

    syrenson thread starter macrumors newbie

    Joined:
    Mar 27, 2015
    #6
    Thank you once again, chown33, for the very thorough and informative reply!

    While I do have some programming experience, Fortran is not in my repertoire, unfortunately.

    I am currently working on a doctorate degree and need to be able to run this software as a benchmark with which to compare my own model (not written in Fortran, heheh).

    I found the following information with regards to compiling f77 code on OS X:

    http://stackoverflow.com/questions/5470841/how-to-install-f77-on-mac-os-x-10-6

    This site claims that gfortran should be able to compile both f77 code as well as more modern versions of Fortran. This makes me wonder if there is a library somewhere that has these missing "symbols" and I simply need to pass them to the linker.

    I will look into the gfortran timer functions and see if that gets me anywhere.

    Thanks again!

    EDIT: Because this model is the accepted benchmark, if there is a way to get the software running without modifying the code itself, this would be preferable. The possibility of my changes ultimately changing the output of the model is of concern.
     
  7. Madd the Sane macrumors 6502a

    Madd the Sane

    Joined:
    Nov 8, 2010
    Location:
    Utah
    #7
    You'll probably need to link the Fortran library explicitly.
     
  8. syrenson thread starter macrumors newbie

    Joined:
    Mar 27, 2015
    #8
    Following chown33's suggestion I made the following changes, which did result in the code compiling and linking without error:

    In couple.f:
    replaced:
    Code:
    CALL TIMER(IHU)
    with
    Code:
    IHU = TIME()
    (i.e. the gfortran function for getting the current time)

    In header.f
    replaced:
    Code:
    CALL DATE(DA)
    with
    Code:
    call fdate(date_time)
     DA=date_time(5:7)//date_time(9:10)//','//date_time(21:24)
    Since the software includes several test cases with documentation on what results one should get out of the model for each test, I'm hoping it will be obvious if these modifications affect the model output.

    Thanks again to everyone who has contributed to the thread!
     

Share This Page