неопределенные ссылки - PullRequest
       11

неопределенные ссылки

2 голосов
/ 02 апреля 2010

Я пытаюсь скомпилировать некоторый код на фортране, и я сталкиваюсь с некоторыми запутанными ошибками компоновки. У меня есть код, который я компилирую и помещаю в статическую библиотеку:

>gfortran -c -I../../inc -o bdout.o bdout.F
>ar rv libgeo.a bdout.o

Затем я пытаюсь скомпилировать эту библиотеку с помощью простого тестового кода и получить следующее:

>gfortran -o mytest -L -lgeo mytest.F
/tmp/cc4uvcsj.o: In function `MAIN__':
mytest.F:(.text+0xb0): undefined reference to `ncwrite1_'
collect2: ld returned 1 exit status

Это не в именовании объектов, потому что все выглядит хорошо:

>nm -u libgeo.a

bdout.o:
     U _gfortran_exit_i4
     U _gfortran_st_write
     U _gfortran_st_write_done
     U _gfortran_transfer_character
     U _gfortran_transfer_integer
     U ncobjcl_
     U ncobjwrp_
     U ncopencr_
     U ncopenshcr_
     U ncopenwr_
     U ncwrite1_
     U ncwrite2_
     U ncwrite3_
     U ncwrite4_
     U ncwritev_

Я тоже могу проверить исходный объектный файл:

>nm -u bdout.o

     U _gfortran_exit_i4
     U _gfortran_st_write
     U _gfortran_st_write_done
     U _gfortran_transfer_character
     U _gfortran_transfer_integer
     U ncobjcl_
     U ncobjwrp_
     U ncopencr_
     U ncopenshcr_
     U ncopenwr_
     U ncwrite1_
     U ncwrite2_
     U ncwrite3_
     U ncwrite4_
     U ncwritev_

Тестовый код просто содержит один вызов функции, определенной в bdout.o:

program hello
        print *,"Hello World!"
        call ncwrite1( istat, f, ix2, ix3, ix4, ix5, ih )
end program hello

Я не могу понять, в чем проблема. У кого-нибудь есть предложения? Может быть, даже просто способ отследить проблему?

Приветствие.

Ответы [ 4 ]

1 голос
/ 02 апреля 2010

Проблема в том, что вы не связываетесь с библиотекой , которая содержит эту функцию. Для этого есть две возможные причины:

  1. Функция ncwrite1 не определена в библиотеках, с которыми вы ссылаетесь. Используйте nm, чтобы убедиться, что это (или нет) случай.
  2. Библиотеки помещаются перед файлами объектного / исходного кода в командной строке (!). Линкеры - самые глупые вещи, и они не пытаются сопоставить все с остальными (и это иногда полезно для продвинутых методов) но это означает, что вам нужно поставить библиотеки после всего остального . Если у вас много библиотек, вам нужно использовать топологическую сортировку по зависимостям между ними, чтобы определить правильный порядок их перечисления компоновщику.

Если мы предполагаем, что в гео-библиотеке есть функция, которую вы ищете (проверьте это!), Тогда вы должны построить и скомпоновать так:

gfortran -o mytest -L. mytest.F -lgeo
1 голос
/ 02 апреля 2010

Не знаю, помогает ли это этой конкретной проблеме, но обычно всегда помещайте команды компоновщика ПОСЛЕ объектных файлов. Во-вторых, если libgeo.a находится в текущем каталоге, вам нужно добавить это явно, пустой -L AFAIK ничего не делает. * 1001 Т.е. *

gfortran -o mytest mytest.F -L. -lgeo

РЕДАКТИРОВАТЬ: также обратите внимание, что «U» в выводе нм означает, что символ не определен. То есть что файл .o ссылается на указанный символ, но на самом деле этот символ находится в каком-то другом файле. То есть вам может понадобиться явно указать ссылку в библиотеке, которая определяет символ ncwrite1_.

0 голосов
/ 07 апреля 2010

Во-первых, спасибо всем, кто ответил. Я пишу, чтобы официально закончить эту тему. Оказывается, что человек, который написал библиотеку (libgeo.a), поместил несколько операторов #ifdef в код, которые были включены с помощью макроса флага компилятора -D (макрос). Эти # ifdef будут затем использоваться для расширения имен функций с конкретными параметрами. Без предоставления соответствующих макросов компилятору имена функций остались нерасширенными, и символы, таким образом, не были определены. Grrrr ...

0 голосов
/ 02 апреля 2010

Проблема может заключаться в том, что вызов ncwrite1 не соответствует сигнатуре определения библиотеки подпрограммы, и сообщение об ошибке действительно пытается вам сказать, что он не может найти версию ncwrite1 с подписью сопоставить вызов. Кажется, ваша программа не использует явный интерфейс для ncwrite1, поэтому ошибки типа, подобные этой, не будут обнаружены во время компиляции.

...