Ошибка соединения при компиляции атомарной операции gcc в 32-битном режиме - PullRequest
17 голосов
/ 25 сентября 2008

У меня есть следующая программа:

~/test> cat test.cc
int main()
{
  int i = 3;
  int j = __sync_add_and_fetch(&i, 1);
  return 0;
}

Я компилирую эту программу, используя GCC 4.2.2 для Linux, работающей на 64-битной машине Intel с несколькими процессорами:

~/test> uname --all
Linux doom 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:56:44 EST 2007 x86_64 x86_64 x86_64 GNU/Linux

Когда я компилирую программу в 64-битном режиме, она компилируется и прекрасно связывается:

~/test> /share/tools/gcc-4.2.2/bin/g++ test.cc
~/test>

Когда я компилирую его в 32-битном режиме, я получаю следующую ошибку:

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 test.cc
/tmp/ccEVHGkB.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status
~/test>

Хотя я никогда не буду работать на 32-битном процессоре, мне нужен 32-битный исполняемый файл, чтобы я мог связываться с некоторыми 32-битными библиотеками.

Мои 2 вопроса:

  1. Почему я получаю сообщение об ошибке при компиляции в 32-битном режиме?

  2. Есть ли какой-нибудь способ заставить программу компилироваться и связываться, при этом все еще имея возможность связываться с 32-битной библиотекой?

Ответы [ 2 ]

24 голосов
/ 25 сентября 2008

Ответ от Дана Удей был близким, достаточно близким, чтобы я мог найти реальное решение.

Согласно man-странице «-mcpu» является устаревшим синонимом «-mtune» и означает просто «оптимизировать для конкретного ЦП (но все же работать на старых ЦП, хотя и менее оптимально)». Я попробовал это, и это не решило проблему.

Однако, «-march =» означает «генерировать код для конкретного ЦП (и не запускать на более старых ЦП)». Когда я попробовал это, это решило проблему: указав процессор i486 или лучше избавился от ошибки ссылки.

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32  test.cc
/tmp/ccYnYLj6.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i386 test.cc
/tmp/ccOr3ww8.o(.text+0x22): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i486 test.cc

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=pentium test.cc
15 голосов
/ 25 сентября 2008

Со страницы GCC на Atomic Builtins :

Не все операции поддерживаются все целевые процессоры. Если конкретный операция не может быть реализована на целевой процессор, предупреждение будет сгенерированный и вызов внешнего функция будет сгенерирована. внешняя функция будет нести то же самое имя как встроенный, с дополнительный суффикс `_n ', где n - это размер типа данных.

Судя по выводу вашего компилятора, который относится к __sync_add_and_fetch_4, это то, что происходит. По какой-то причине GCC не генерирует внешнюю функцию должным образом.

Вероятно, поэтому вы получаете ошибку только в 32-битном режиме - при компиляции в 64-битном режиме он компилируется для вашего процессора более точно. При компиляции для 32-битной системы вполне может использоваться общая арка (например, i386), которая изначально не поддерживает эти функции. Попробуйте указать конкретную архитектуру для вашего семейства чипов (Xeon, Core 2 и т. Д.) Через -mcpu и посмотрите, работает ли это.

Если нет, вам придется выяснить, почему GCC не включает соответствующую функцию, которую он должен генерировать.

...