C / C ++, FORTRAN, подчеркивание и GNU Autotools - PullRequest
3 голосов
/ 26 декабря 2011

У меня есть вопрос о смешанном программировании (C / C ++ и FORTRAN) с использованием gcc и gfortran.Я много раз искал "смешивание фортрана с языком X" и не смог решить эту проблему.

Я не уверен, является ли это проблемой компоновки или проблемой компилятора, или обеими.

Я создал три файла и использую GNU Autotools для создания сырого приложения, но должен иметь возможность собирать приложение независимо от командной строки.

Файл C (main.c)будет ведущим приложением, которое вызывает несколько функций FORTRAN:

/* this is a simple program */

#include <stdio.h>

/* add the extern function definition */
#include "fooonly.h" 

// this is not working for the mixed language programming stuff yet... 

/* this is the main program section */
int main( int argc, char *argv[] )
{
   int a = 36;
   int b = 24;
   int c = 0;

   printf( "hi mom\n" );

   /* now call a FORTRAN function from C */
   c = NGCD( &a, &b );
   printf( "NGCD(%d,%d)=%d\n", a, b, c );

   return 0;

}

Функция Fortran, которая чаще всего будет содержать FORTRAN 77 (но может также включать в себя код FORTRAN90 / 95),выглядит так:

c$$$      The following introductory example in FORTRAN 77 finds the
c$$$     $     greatest common divisor for two numbers A and B using a
c$$$     $     verbatim implementation of Euclid's algorithm.

      FUNCTION NGCD(NA, NB)
      IA = NA
      IB = NB
 1    IF (IB.NE.0) THEN
         ITEMP = IA
         IA = IB
         IB = MOD(ITEMP, IB)
         GOTO 1
      END IF
      NGCD = IA
      RETURN
      END

Использование Dev.Studio 6 / Compaq Digital Fortran 6.0, это отлично работает.На самом деле мне не нужно использовать #define ifdef __cplusplus / # endif и я могу просто создать файл C, который выглядит следующим образом:

/* this is a simple program */

#include <stdio.h>

/* add the extern function definition */
extern "C" int __stdcall NGCD( int *a, int *b );

/* this is the main program section */
int main( int argc, char *argv[] )
{
   int a = 36;
   int b = 24;
   int c = 0;

   printf( "hi mom\n" );

   /* now call a FORTRAN function from C */
   c = NGCD( &a, &b );
   printf( "NGCD(%d,%d)=%d\n", a, b, c );

   return 0;
}

и скомпилировать его с перечисленным выше списком FORTRAN, ссылки на приложение, запускает и генерирует правильные результаты.

C:\fooonly>fooonly.exe
hi mom
NGCD(36,24)=12

C:\fooonly>

Когда я пытаюсь повторить этот процесс, используя Autotools GNU для MinGW или OSX, я продолжаю получать следующие ошибки:

macbook:makecheck $ make
gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"fooonly\" -DVERSION=\"1.0.2\" -I.     -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gfortran  -g -O2   -o fooonly main.o ngcd.o  
Undefined symbols for architecture x86_64:
  "_NGCD", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [fooonly] Error 1
macbook:makecheck $ 

где Makefile (сгенерированный GNU Autotools), в основном содержит следующие команды:

macbook:makecheck $ gcc -c main.c
macbook:makecheck $ gfortran -c ngcd.f
macbook:makecheck $ gcc -o fooonly main.c ngcd.o
Undefined symbols for architecture x86_64:
  "_NGCD", referenced from:
      _main in cc9uPBWl.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
macbook:makecheck $ 

Мой скрипт configure.in содержит не более:

AC_INIT(main.c)
AM_INIT_AUTOMAKE(fooonly, 1.0.2)

## C/C++ compiler section
AC_PROG_CC

## fortran section
AC_PROG_F77

## output section
AC_OUTPUT(Makefile)

, что по сути,

macbook:makecheck $ gcc -c main.c
macbook:makecheck $ gfortran -c ngcd.f
macbook:makecheck $ gcc -o fooonly main.c ngcd.o

верно?

Я пытаюсь построить это на нескольких платформах (Linux, Win32 / 64, OSX и т. Д.) И хочу использовать GNU Autotools, и я знаю, что это делается с другими проектами с открытым исходным кодом, ноСкрипты configure.in для этих проектов выходят далеко за рамки моих новичков в GNU Autotools, и я немного ошеломлен, пытаясь их декодировать.

Я предполагаю, что это как-то связано с:

1) Определения, которые я использовал в скрипте configure.in, 2) Я не включаю какой-то магический набор переключателей (то есть -fno-second-underscore?), Или 3) Какую комбинацию из двух?

Я близко, и если да, как мне получить приложение?строить?

Ответы [ 2 ]

4 голосов
/ 26 декабря 2011

Поскольку у вас есть компилятор, более новый, чем последние несколько лет, я рекомендую использовать привязку ISO C для смешивания Fortran с другими языками. Затем вы можете пропустить искажение имени с подчеркиванием и аналогичными проблемами, связанными с компилятором / платформой. Если у вас есть устаревший код на языке FORTRAN 77, который вы не хотите изменять, вы можете написать небольшую подпрограмму на языке Fortran 2003 между C и FORTRAN 77. Более старые инструкции описывают предыдущий метод, который требует большего понимания внутренних интерфейсов и требует зависит от компилятора / платформы. Чтобы узнать о новом методе, ознакомьтесь с главой руководства gfortran «Программирование на разных языках» и с предыдущими вопросами / ответами здесь.

С кодом Fortran легче связать с gfortran, потому что это включает библиотеки времени исполнения Fortran. Я думаю, что то же самое относится и к C ++, поэтому, если у вас есть оба, вам придется явно включить библиотеку времени выполнения того или другого.

P.S. Вот пример использования привязки Fortran ISO C:

function NGCD (na, nb) bind (C, name="NGCD")
   use iso_c_binding
   implicit none
   integer (c_int) :: ngcd
   integer (c_int), intent (in) :: na, nb
   integer (c_int) :: ia, ib, itemp
   ia = na
   ib = nb

   do while (ib /= 0)
      itemp = ia
      ia = ib
      ib = mod(itemp, ib)
   end do

   ngcd = ia

   return
end function NGCD

Компиляция / ссылка с:

gcc -c main.c
gfortran main.o ngcd.f90
0 голосов
/ 31 января 2012

Я не получил достаточного ответа, поэтому я собрал временное решение (игнорирует регистр в коде FORTRAN) и разместил его в своем блоге forufus .В будущем мне придется отработать переключатели компилятора.

...