Old Fortran Program: ld returned 1 exit status

j0h picture j0h · Aug 9, 2013 · Viewed 7.6k times · Source

I have an old FORTRAN 77 program that I am having trouble compiling / building as normal with: gfortran -Wall -o "filename" filename.f

It keeps giving me the linker error:

$ gfortran -Wall  ljewald.f 

/usr/lib/gcc/i686-linux-gnu/4.7/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status

Eventually, I tried: gfortran -Wall -c -o "filename" filename.f which gives me compiled binary file. Ok great, but the man page for gfortran is sketching me out. here is the material for the -c option that makes this all seem to work:

   -C  Do not discard comments. All comments are passed through to the output file, except for comments in processed directives, which are deleted
       along with the directive.

       You should be prepared for side effects when using -C; it causes the preprocessor to treat comments as tokens in their own right. For example,
       comments appearing at the start of what would be a directive line have the effect of turning that line into an ordinary source line, since the
       first token on the line is no longer a '#'.

       Warning: this currently handles C-Style comments only. The preprocessor does not yet recognize Fortran-style comments.

So, after building this, using: gfortran -Wall -c -o "ljewald" ljewald.f

I get an output file, but its isn’t an executable...?

$ls -l
...
-rw-rw-r--  1 j0h j0h    647 Aug  9 16:36 ljewald 
...

I cant execute this file, even if i change the mode with chmod +x ljewald

what can I do to avoid the -c option, since using it has quirks? And how can I build an executable of this program? Can someone explain, and tell me how to fix this:?

/usr/lib/gcc/i686-linux-gnu/4.7/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status

link to source: http://nanocluster.umeche.maine.edu/ljewald.f

Answer

user1220978 picture user1220978 · Aug 13, 2013

Edit: the problem obviously does not come from a lacking program (sorry, I was not awake :-)).

Actually, line endings are causing the problem: when properly converted to CRLF on Windows, gcc-4.8.1 successfuly compiles (after commenting out the ACCEPTs).

However:

  • there are many warnings (unused variables or formats)
  • ACCEPT should be equivalent to READ, then label 777 is missing (for a READ format)
  • there are some lines with tabulations, which should really be avoided, especially when almost all the code is indented with spaces.

If you have access to a Windows box, you may use Notepad++ to convert line endings and replace tabs.

If you have many files to repair, you may try a python script. You can elaborate on the following, which I use often to clean files according to given rules (you can change the cleanfile function according to your needs, here it translates to CRLF, and removes useless blanks). It's in Python 3, but easy to convert to Python 2 if needed.

# encoding: ISO-8859-15

import sys, os, hashlib

def filehash(name):
   f = open(name, "rb")
   h = hashlib.sha512()
   n = 4 * 1024 * 1024
   while True:
      r = f.read(n)
      h.update(r)
      if len(r) < n:
         break
   f.close()
   return h.hexdigest()

def cleanfile(name):
   v = os.stat(name)
   a = filehash(name)
   atime = v[7]
   mtime = v[8]
   f = open(name, "rt", encoding="ISO-8859-1")
   u = f.readlines()
   f.close()

   n = len(u)
   for i in range(n):
      u[i] = u[i].rstrip()

   while n > 0 and u[n - 1] == "":
      n -= 1

   if n == 0:
      print("EMPTY FILE {}".format(name))
      os.remove(name)
      return

   #f = open(name, "wt", newline="\n")
   f = open(name, "wt", encoding="ISO-8859-1")
   for i in range(n):
      s = u[i]
      f.write("{}\n".format(s))
   f.close()

   os.utime(name, (atime, mtime))
   b = filehash(name)
   if a != b:
      print("MODIF {}".format(name))

def manfile(name):
   global exts
   n = name.rfind(".")
   if n < 0:
      print("PASS {}".format(name))
   e = name[n + 1:].lower()

   if e in ["f"]:
      cleanfile(name)
   else:
      print("SKIP {}  -  {}".format(e, name))


########### recursive directory traversal, don't whange after this line ###########

def mandir(path):
   try:
      li = os.listdir(path)
   except:
      print("ERRD {}".format(path))
      return
   li.sort()
   lilnk = [ ]
   lifil = [ ]
   lidir = [ ]
   for name in li:
      c = os.path.join(path, name)
      if os.path.islink(c):
         lilnk.append(c)
      elif os.path.isfile(c):
         lifil.append(c)
      elif os.path.isdir(c):
         lidir.append(c)
      else:
         print("UNKN {}".format(c))
   for c in lilnk:
      os.remove(c)
      pass
   for c in lifil:
      manfile(c)
   for c in lidir:
      mandir(c)
   li = os.listdir(path)
   if len(li) == 0:
      try:
         os.rmdir(path)
      except OSError:
         pass

mandir(sys.argv[1])