Неопределенные символы при связывании со смешанными C и Fortran в OS X 10.6.4

Я пытаюсь скомпилировать код (не мой), состоящий из смешанных исходных файлов Fortran и C, которые скомпилированы в библиотеку. Эта библиотека может быть связана напрямую или (более полезно) управляться из класса Python. Ранее я успешно создавал 32-разрядный код с помощью g77 и gcc, но столкнулся с ситуацией, когда код использует большие куски памяти и должен быть 64-разрядным.

Я пытался собрать как только 64-битную систему, так и как универсальный двоичный файл с помощью gfortran 4.2.3 (двоичный дистрибутив из проекта AT&T R) и системы gcc (4.2). Исходные файлы создаются правильно, но когда я пытаюсь скомпоновать библиотеку, я получаю много ошибок «Неопределенные символы» для ряда функций Fortran. Метка nm в библиотеке показывает, что символы существуют, но очевидно, что компоновщик их не находит.

Вот две (из многих) команды компиляции (которые не вызывают ошибок):

/usr/local/bin/gfortran -arch ppc -arch i386 -arch x86_64  -fPIC -fno-strength-reduce -fno-common -ff2c -Wall -c  lsame.f

gcc -c -I/Users/keriksen/Research/atomic_data/fac -I/Users/keriksen/Research/atomic_data/fac/faclib -O2 -fPIC -fno-strength-reduce -fno-common pmalloc.c

И шаг ссылки, который бомбит:

gcc -o sfac sfac.c stoken.c -I/Users/keriksen/Research/atomic_data/fac -I/Users/keriksen/Research/atomic_data/fac/faclib -O2 -fPIC -fno-strength-reduce -fno-common -L/Users/keriksen/Research/atomic_data/fac -lfac -lm -lgfortran -lgcc

Пример неопределенного символа:

  "_acofz1", referenced from:
      _HydrogenicDipole in libfac.a(coulomb.o)
      _HydrogenicDipole in libfac.a(coulomb.o)

и соответствующий nm, который показывает, что этот символ существует:

    niobe:atomic_data/fac[14] nm libfac.a | grep acof

0000000000000000 T _acofz1_
0000000000002548 S _acofz1_.eh
                 U _acofz1

Я делаю что-то глупое, например, не включаю необходимый переключатель в компоновщик, или здесь происходит что-то более тонкое?


person Kris Eriksen    schedule 23.08.2011    source источник
comment
U _acofz1 означает, что _acofz1 не определено. То, что определено, это T _acofz1_ с другим конечным _. Совершенно самостоятельно обновите пожалуйста до 10.6.8. И мне жаль, что я не могу вам помочь... есть ли исходный код, который воспроизводит проблему, которую мы можем скомпилировать здесь, чтобы увидеть больше проблем?   -  person Yuji    schedule 23.08.2011
comment
На самом деле, ты немного помог, Юджи. Отсутствующий завершающий _ (не могу поверить, что пропустил это — слишком долго смотрел на этот код) был ключом. Первоначальный автор использовал заголовочный файл с именем cfortran.h для обработки интерфейса C/Fortran. Он не поддерживал gfortran, и хак, который я использовал для компиляции кода, был неправильным. Для справки: при использовании cfortran.h с gfortran убедитесь, что флаг -Df2cFortran установлен во время компиляции. (Я установил его в переменной окружения CPPFLAGS). Макросы CPP cfortran.h добавят необходимое подчеркивание в конце.   -  person Kris Eriksen    schedule 23.08.2011
comment
Почему бы тебе самому не написать это как ответ, Крис? Это может помочь кому-то еще, кто найдет эту запись в Google/Bing.   -  person Yuji    schedule 23.08.2011


Ответы (1)


По предложению Юдзи:

Заголовочный файл cfortran.h (доступен в Интернете и, по-видимому, довольно широко используется), который решает проблемы совместимости с C/Fortran, не обрабатывает gfortran из коробки. Я взломал его (неправильно), чтобы проигнорировать этот факт, и поплатился за свою наглость.

Конкретная проблема заключается в том, что gfortran генерирует объектный код, содержащий символы с подчеркиванием в конце, а gcc — нет.

Правильным было установить для переменной среды CPPFLAGS значение -Df2cFortran. Как только этот макрос установлен, cfortran.h добавляет необходимое подчеркивание к символам в объектном коде вызывающих функций C, и компоновщик доволен.

Еще одна удивительная вещь в этом конкретном случае заключалась в том, что скрипт configure ищет в переменной окружения F77 имя компилятора fortran. Как только я установил F77 на «/usr/local/bin/gfortran -arch x86_64», сгенерированный Makefile был правильным, и он создавал только 64-битный объектный код. Я не уверен, является ли это стандартным поведением при настройке или особенностью этого конкретного скрипта.

В результате у меня теперь есть 64-битная разделяемая библиотека, которая отлично работает с 64-битным python, который я скачал. Я наполовину подумываю вернуться и попытаться создать универсальную библиотеку, которая будет работать с системным python, но я не уверен, что хочу испытывать судьбу.

person Kris Eriksen    schedule 23.08.2011