1

I am trying to link a .o file generated using g++ and another .o file generated using gfortran.

g++ -c mycppcode.cpp

produces the file mycppcode.o and the command

gfortran -c myfortrancode.f

produces the file myfortrancode.o

When I link these two files to get an output file

g++ -O mycppcode.o myfortrancode.o

I get the following error

Undefined symbols for architecture x86_64:
  "__gfortran_pow_c8_i4", referenced from:

Could some one help me with this? Should I use another compiler? Also, I would like to know what functions or subroutines call "__gfortran_pow_c8_i4", so that I can try to avoid these functions or subroutines in fortran in future.

John Smith
  • 161
  • 1
  • 6
  • 1
    Try adding the `-lgfortran` when you run the linker – SethMMorton Oct 02 '13 at 23:24
  • @SethMMorton I get the following: "ld: library not found for -lgfortran" – John Smith Oct 02 '13 at 23:28
  • That's odd. I've used it before with g++ with success. Check out [this answer](http://stackoverflow.com/a/5663224/1399279) to make sure you are entering it correctly. – SethMMorton Oct 02 '13 at 23:41
  • @SethMMorton I actually found some help here (http://stackoverflow.com/questions/7264525/linking-fortran-and-c-objects-files) and the issue has now been fixed. I did `find / -name "libgfortran.*"` and the file was sitting in `/usr/local/Cellar/gfortran/4.8.1/gfortran/lib/`. I added this to the command and works fine now. Thanks. – John Smith Oct 02 '13 at 23:45
  • 2
    Ah! You are using homebrew, which means that your gcc installation doesn't know about your gfortran installation (silly Apple for not including a fortran compiler with XCode). I assumed you were on linux, and in that case just `-lgfortran` should have worked. – SethMMorton Oct 03 '13 at 00:06
  • 1
    Also, out of curiosity, what happens if you do `gfortran -O mycppcode.o myfortrancode.o -lstdc++` instead? I bet you won't need to add a library search path in that case. – SethMMorton Oct 03 '13 at 00:07
  • @SethMMorton Cool. Yes, `gfortran -O mycppcode.o myfortrancode.o -lstdc++` works like a charm. This should probably be a separate question but "is there any difference in the final executable"? Thanks again. If you can add your last comment as an answer, I will accept it. – John Smith Oct 03 '13 at 00:44
  • Might I suggest you change the title to something like "Error linking mixed C++ and Fortran files with g++" so that more people will be likely to find this post? – SethMMorton Oct 03 '13 at 02:50
  • @SethMMorton I have edited the title a bit to capture the essence of the question. Thanks again. – John Smith Oct 03 '13 at 03:53

1 Answers1

4

The following assumes you are using the GNU compiler tools. Things may be slightly different if you are using other compilers.

You can use either compiler to link the two together, but you need to provide the appropriate libraries.

Typically, you can use either

gfortran fortobj.o cppobj.o -lstdc++

or

g++ fortobj.o cppobj.o -lgfortran

This assumes that you are using a setup where both compilers know about each other's libraries (like if you installed through a linux repository).


In the case of the OP the C compilers came from XCode and gfortran is from homebrew. In that case, gfortran knows about the g++ libraries (since they were used to compile the compiler), but g++ doesn't know about the gfortran libraries. This is why using gfortran to link worked as advertised above. However, to link with g++ you need to add the path to libgfortran.* when you call the linker using the -L flag, like

g++ fortobj.o cppobj.o -L/path/to/fortran/libs -lgfortran

If for some reason your gfortran compiler is unaware of your g++ libs, you would do

gfortran fortobj.o cppobj.o -L/path/to/c++/libs -lstdc++

Note that there shouldn't be any difference in the final executable. I'm no compiler expert, but my understanding is that using the compiler to link your objects together is a convenience for calling the linker (ld on UNIX-like OS's) with the appropriate libraries associated with the language you are using. Therefore, using one compiler or the other to link shouldn't matter, as long as the right libraries are included.

SethMMorton
  • 45,752
  • 12
  • 65
  • 86
  • @JohnSmith Regarding the question about how to avoid these subroutines and functions in Fortran, you can't. If you are using *any* Fortran builtin functions, you will get that message if you are missing the Fortran libraries. My guess is you were using the Fortran `POW` function. – SethMMorton Oct 03 '13 at 05:54
  • 2
    Fortran (normally) has no `pow` function but it is probably called from the use of the `**` operator. – Vladimir F Героям слава Oct 03 '13 at 10:30
  • @VladimirF It's been a while since I used Fortran... I'm a little rusty on the intrinsics. Thanks for pointing that out. – SethMMorton Oct 03 '13 at 16:57