Подтвердить что ты не робот

Код ссылки GCC изменился?

Я пытаюсь связать модуль С++ с помощью GCC, по существу, как это:

gcc -c hello.c
g++ -c world.cpp
gcc -ohello -lstdc++ hello.o world.o

Обратите внимание, что я использую -lstdc++ для связывания модуля С++, поэтому я могу использовать gcc вместо g++. Проблема в том, что я получаю сообщение об ошибке:

undefined reference to `operator new(unsigned long)'

(Предполагая, что world.cpp содержит хотя бы один вызов new.)

Эта ошибка исправлена, если я положил -lstdc++ в конец линии компоновщика, например:

gcc -ohello hello.o world.o -lstdc++

Я знаю, что этот вопрос задавался много раз здесь, но у меня есть специальное требование. Я напрямую не звоню в GCC. Я использую систему сборки для другого языка программирования (Mercury), который вызывает от меня GCC, и я не могу легко изменить способ его вызова GCC (хотя я могу указать дополнительные библиотеки, используя переменную среды LDFLAGS). Поэтому у меня есть два дополнительных требования:

  • Я не могу использовать g++ для ссылки (только gcc) - вот почему я делаю трюк -lstdc++, а не просто ссылку с g++).
  • Я не думаю, что могу контролировать порядок команд компоновщика - Mercury поместит файлы .o в командной строке после любых библиотек.

Я понимаю основную причину, почему порядок важен, но то, что меня озадачивает, почему это сейчас? Я просто обновился до Ubuntu 11.10/GCC 4.6.1. Я успешно скомпилировал эту программу в течение многих лет, используя именно эту технику (сначала ставил -lstdc++). Только теперь эта ошибка возникла. Несвязанная программа моих ссылок на OpenGL с использованием -lgl, и это тоже сломалось, когда я обновился, и мне пришлось переместить -lgl в конец командной строки. Вероятно, я узнаю, что десятки моих программ больше не компилируются. Почему это изменилось? Что-то не так с моей новой системой, или так, как сейчас? Обратите внимание, что это обычные общие библиотеки, а не статически связанные.

Есть ли что-нибудь, что я могу сделать, чтобы GCC вернулась к старому, где порядок библиотек не имеет значения? Есть ли другой способ, которым я могу убедить GCC правильно связать libstdc++, не перемещая его после файлов .o в командной строке?

4b9b3361

Ответ 1

Если Mercury помещает объектные файлы после библиотек, Mercury нарушается. Библиотеки принадлежат объектным файлам - всегда. Иногда вы можете уйти с обратным порядком, но не надежно. (Статические библиотеки должны идти за объектными файлами, которые ссылаются на символы в статической библиотеке. Иногда линкер отмечает символы, определенные общей библиотекой, даже если ни один из символов не используется, иногда компоновщик будет отмечать только символы общей библиотеки если в общей библиотеке имеется хотя бы один символ.)