Search code examples
unixg++

UNIX symbol referencing error


Greetings Everyone.

I'm currently trying to compile a multiple-language program (C, C++ and FORTRAN) using GNU compilers in UNIX (g++, gcc & f77 respectively).

All my sources are compiling into objects with no errors however I encounter a symbol referencing error as they are linked as shown below:

f77 -L/usr/sfw/lib -R/usr/sfw/lib -lgcc_s -o SlowDynamic.exe main.o \
        SA.o mersenne.o CFE.o MA_57.o blas.o MA_57_Depend.o Metis.o\
        BCs.o EMatrix.o Numbering.o KMatrix.o Solve.o
NOTICE: Invoking /usr/bin/f90 -f77 -ftrap=%none -L/usr/sfw/lib -R/usr/sfw/lib -lgcc_s -o SlowDynamic.exe main.o SA.o mersenne.o CFE.o MA_57.o blas.o MA_57_Depend.o Metis.o BCs.o EMatrix.o Numbering.o KMatrix.o Solve.o
Undefined                       first referenced
 symbol                             in file
_Znwj                               SA.o
_ZNSt14basic_ofstreamIcSt11char_traitsIcEED1Ev SA.o
_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1Ev SA.o
_ZNKSsixEj                          main.o
_ZNSolsEPFRSoS_E                    SA.o
_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode SA.o
_ZNSolsEd                           SA.o
_ZNSolsEi                           SA.o
__cxa_end_catch                     SA.o
__cxa_begin_catch                   SA.o
_ZdlPv                              SA.o
_ZNSt14basic_ofstreamIcSt11char_traitsIcEE7is_openEv SA.o
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c SA.o
_ZSt4cerr                           SA.o
_ZSt4cout                           SA.o
_ZNSt14basic_ofstreamIcSt11char_traitsIcEE5closeEv SA.o
_ZNSt8ios_base4InitD1Ev             main.o
_ZNSt8ios_base4InitC1Ev             main.o
_ZNKSt9basic_iosIcSt11char_traitsIcEEntEv SA.o
__gxx_personality_v0                main.o
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc SA.o
__cxa_rethrow                       SA.o
_ZNKSs4sizeEv                       main.o
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ SA.o
ld: fatal: Symbol referencing errors. No output written to SlowDynamic.exe
*** Error code 1
make: Fatal error: Command failed for target `SlowDynamic.exe'

With the Following Makefile:

products: SlowDynamic.exe

SlowDynamic.exe: main.o SA.o mersenne.o CFE.o BCs.o EMatrix.o Numbering.o KMatrix.o Solve.o MA_57.o blas.o MA_57_Depend.o Metis.o
    f77 -L/usr/sfw/lib -R/usr/sfw/lib -lgcc_s -o SlowDynamic.exe main.o \
        SA.o mersenne.o CFE.o MA_57.o blas.o MA_57_Depend.o Metis.o\
        BCs.o EMatrix.o Numbering.o KMatrix.o Solve.o

main.o: main.cpp
    g++ -c -o main.o main.cpp

SA.o: SA.cpp
    g++ -c -o SA.o SA.cpp

mersenne.o: mersenne.cpp
    g++ -c -o mersenne.o mersenne.cpp

CFE.o: CFE.c
    gcc -c -o CFE.o CFE.c

MA_57.o: MA_57.f
    f77 -c -o MA_57.o MA_57.f

blas.o: blas.f
    f77 -c -o blas.o blas.f

MA_57_Depend.o: MA_57_Depend.f
    f77 -c -o MA_57_Depend.o MA_57_Depend.f

Metis.o: Metis.f
    f77 -c -o Metis.o Metis.f

BCs.o: BCs.c
    gcc -c -o BCs.o BCs.c

EMatrix.o: EMatrix.c
    gcc -c -o EMatrix.o EMatrix.c

Numbering.o: Numbering.c
    gcc -c -o Numbering.o Numbering.c

KMatrix.o: KMatrix.c
    gcc -c -o KMatrix.o KMatrix.c

Solve.o : Solve.c
    gcc -c -o Solve.o Solve.c

clean: 
    rm *.o Main.exe *.gpi

I have read that this is typically the fault of missing libraries. I know the C & FORTRAN code compiles fine seperatly (respective libraries included) as does the C++ code when compiled on its own. This leads me to believe that it is the interface between the two programs that causes the error. Unfortunatly I've little to no experiance debugging this sort of problem and without any clues from the linker its hard to move forward. I'll include the necessary parts of my program that deal with the interface between the two sides of the program.

First the C++ part: SA.h, SA.cpp

SA.h:

class SimAnneal {
    ...
    std::vector<float> DensityArray; 
    std::vector<float> EnergyArray;
  public
    double ObjFunction ();
    ...
}

SA.ccp:

#include <math.h>
#include <iostream>
#include <fstream>          
#include <time.h>           
#include <vector>
#include "SA.h"
#include "CFE.h"
#include "randomc.h"  //Includes mersenne.cpp

double SimAnneal::ObjFunction () 
{
    CFE(&DensityArray[0], &EnergyArray[0]); 

      // sends pointers of both arrays to CFE.c and modifies EnergyArray as 
      // shown in CFE.c

    double SumStrainEnergy = 0;

    for (int i = 0; i < EnergyArray.size(); i++)
    {
        SumStrainEnergy += EnergyArray[i];  //Effectively sum of array 
                                                //engy[] from CFE.c
    }

    return SumStrainEnergy;
}

Secondly the C/FORTRAN part: CFE.h, CFE.c

CFE.h:

#ifdef __cplusplus
extern "C" {
#endif 

void CFE(float density[], float energy[]);

#ifdef __cplusplus
 }
#endif 

CFE.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "BCs.h"
#include "EMatrix.h"
#include "Numbering.h"
#include "KMatrix.h"
#include "fg_types.h"
#include "Solve.h"

void CFE(float density[], float energy[])
{
    ...stuff...

    float * dens;
    dens = density;  //pass pointer of array density[0] in SA.cpp to CFE.c

    ...more stuff....

    float * engy;
    engy = energy; //pass pointer of array energy[0] in SA.cpp to CFE.c

    ***Modify engy in some respects****    
}

Essentially the ObjFunction in SA.cpp is called in main.cpp, which contains main().

Is there any visible fault?

Is there any way I can ask the linker to announce what causes / where the error occours in the linking?

Any help will be much appriciated.

Thank you.

+++ EDIT: Verbose feedback +++

birch $ g++ -v Hello.cpp
Reading specs from /usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/specs
Configured with: /sfw10/builds/build/sfw10-patch/usr/src/cmd/gcc/gcc-3.4.3/configure --prefix=/usr/sfw --with-as=/usr/ccs/bin/as --without-gnu-as --with-ld=/usr/ccs/bin/ld --without-gnu-ld --enable-languages=c,c++ --enable-shared
Thread model: posix
gcc version 3.4.3 (csl-sol210-3_4-branch+sol_rpath)
 /usr/sfw/libexec/gcc/sparc-sun-solaris2.10/3.4.3/cc1plus -quiet -v Hello.cpp -quiet -dumpbase Hello.cpp -mcpu=v7 -auxbase Hello -version -o /var/tmp//cc2JwHRb.s
ignoring nonexistent directory "/usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/../../../../sparc-sun-solaris2.10/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/../../../../include/c++/3.4.3
 /usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/../../../../include/c++/3.4.3/sparc-sun-solaris2.10
 /usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/../../../../include/c++/3.4.3/backward
 /usr/local/include
 /usr/sfw/include
 /usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/include
 /usr/include
End of search list.
GNU C++ version 3.4.3 (csl-sol210-3_4-branch+sol_rpath) (sparc-sun-solaris2.10)
        compiled by GNU C version 3.4.3 (csl-sol210-3_4-branch+sol_rpath).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Hello.cpp:6:2: warning: no newline at end of file
 /usr/ccs/bin/as -V -Qy -s -xarch=v8 -o /var/tmp//ccvAshv7.o /var/tmp//cc2JwHRb.s
/usr/ccs/bin/as: Sun Compiler Common 10 Patch 09/04/2007
 /usr/sfw/libexec/gcc/sparc-sun-solaris2.10/3.4.3/collect2 -V -R/usr/sfw/lib -Y P,/usr/ccs/lib:/usr/lib -Qy /usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/crt1.o /usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/crti.o /usr/ccs/lib/values-Xa.o /usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/crtbegin.o -L/usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3 -L/usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/../../../../sparc-sun-solaris2.10/lib -L/usr/ccs/lib -L/usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/../../.. /var/tmp//ccvAshv7.o -lstdc++ -lm -R/usr/sfw/lib -lgcc_s -lgcc -lc -R/usr/sfw/lib -lgcc_s -lgcc -lc /usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/crtend.o /usr/sfw/lib/gcc/sparc-sun-solaris2.10/3.4.3/crtn.o
ld: Software Generation Utilities - Solaris Link Editors: 5.10-1.490

Solution

  • Some of those undefined symbols clearly relate to standard C++ classes (i.e. ostream).

    You need to ensure that you've got at least the C++ library linked (-lstdc++).

    To debug further:

    1. Run f77, g++, etc, in verbose mode (-v) with single language programs and see which libraries the compiler automatically includes in the link phase for each language

    2. For symbols that are in your own code, use nm to look at both the native language declarations and non-native invocations to determine how they mismatch. There are rules about underscore prefixes, etc, which are commonly applied.

    (As far as I can remember, but it's 15 years since I last linked C and Fortran, C symbols are always internally prefixed with an underscore, but Fortran symbols are not).