Ошибка ссылки на символ UNIX - PullRequest
1 голос
/ 19 марта 2009

Приветствую Всех.

В настоящее время я пытаюсь скомпилировать многоязычную программу (C, C ++ и FORTRAN) с использованием компиляторов GNU в UNIX (g ++, gcc и f77 соответственно).

Все мои источники компилируются в объекты без ошибок, однако я сталкиваюсь с ошибкой ссылки на символ, поскольку они связаны, как показано ниже:

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'

со следующим 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

Я читал, что это, как правило, ошибка отсутствующих библиотек. Я знаю, что код C & FORTRAN прекрасно компилируется отдельно (включая соответствующие библиотеки), как и код C ++, когда компилируется сам по себе. Это наводит меня на мысль, что именно интерфейс между двумя программами вызывает ошибку. К сожалению, я практически не испытываю отладки такого рода проблем, и без каких-либо подсказок компоновщика трудно продвинуться вперед. Я включу необходимые части моей программы, которые связаны с интерфейсом между двумя сторонами программы.

Сначала часть C ++: 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;
}

Во-вторых, часть C / FORTRAN: 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****    
}

По сути, ObjFunction в SA.cpp вызывается в main.cpp, который содержит main ().

Есть ли видимые неисправности?

Можно ли как-нибудь попросить компоновщика объявить о причинах / причинах возникновения ошибки при компоновке?

Любая помощь будет очень ценной.

Спасибо.

+++ РЕДАКТИРОВАТЬ: Подробная обратная связь +++

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

Ответы [ 3 ]

4 голосов
/ 19 марта 2009

Некоторые из этих неопределенных символов явно относятся к стандартным классам C ++ (т. Е. Ostream).

Вы должны убедиться, что у вас есть хотя бы связанная библиотека C ++ (-lstdc ++).

Для дальнейшей отладки:

  1. Запустите f77, g ++ и т. Д. В подробном режиме (-v) с одноязычными программами и посмотрите, какие библиотеки компилятор автоматически включает в фазу соединения для каждого языка

  2. Для символов, которые находятся в вашем собственном коде, используйте nm, чтобы посмотреть как объявления на родном языке, так и не родные вызовы, чтобы определить их несоответствие. Существуют правила о префиксах подчеркивания и т. Д., Которые обычно применяются.

(Насколько я помню, но прошло 15 лет с тех пор, как я последний раз связывал C и Fortran, символы C всегда имеют внутренний префикс с подчеркиванием, а символы Fortran - нет).

2 голосов
/ 19 марта 2009

Основная проблема заключается в том, что вы выполняете этап связывания с помощью компилятора F77, который по умолчанию не связывается со стандартной библиотекой C ++. Как сказал Альнитак, во время компоновки явно укажите -lg ++, чтобы получить его.

Кроме того, если вы вызываете функции C ++ из кода C (или из кода F77), убедитесь, что вы заключили прототипы этих функций в внешний блок "C" {}, чтобы их имена символов отображались в стандартизированном C форма, а не искаженная форма C ++ (это ограничивает вас от некоторых вещей, таких как перегрузка). См. здесь для получения дополнительной информации.

0 голосов
/ 19 марта 2009

Обычно вам следует связать программу, содержащую любой код C ++, с компилятором C ++, добавляя библиотеки Fortran и C в строку ссылки. Далее, стандартный совет состоит в том, чтобы сделать main () программой C ++ или Fortran, поскольку последовательности запуска для C ++ различны. Превратите код на Фортране в функцию, которую вы вызываете из минимального C ++ main.

int main(void) // Assuming no argument handling - probably incorrect
{
    return(fortran_main_program());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...