может ли компоновщик пропустить объектный файл при компоновке статической библиотеки? - PullRequest
2 голосов
/ 05 декабря 2010

У меня есть статическая библиотека (lib.a) и программа, которая ссылается на нее. В библиотеке нет точки входа, которая всегда вызывалась бы перед ее использованием, но мне нужно выполнить фрагмент кода очень рано в программе (желательно до запуска main ()). Поэтому я подумал, что буду использовать статическую переменную моего собственного класса. Я добавил новый исходный файл, который содержит что-то вроде:

#include <MyClass.h>
static MyClass myVar;

Конструктор MyClass будет выполнять мой код. Когда я связываю lib.a и пытаюсь выполнить «nm», я получаю информацию, что myVar там есть. Однако, когда я связываю свою программу и пробую «nm», я не вижу myVar. Когда я помещаю этот кусок кода в существующий файл, символ виден в конечном исполняемом файле. Это почему? Может ли компоновщик пропустить объектный файл из библиотеки lib.a в этом случае? Я знаю, что на переменную не ссылаются извне (она не может быть статической), но она должна выполнять код самостоятельно, и поэтому я не понимаю, почему ее следует удалить.

На случай, если что-то изменится, я использую старый компилятор SunPro.

Ответы [ 2 ]

1 голос
/ 05 декабря 2010

Технически говоря, компоновщик должен быть вынужден включить этот объектный файл при компиляции вашей программы. Однако во многих компиляторах его поддержка содержит ошибки, например, MSVC ++ . Добавление внешней ссылки где-нибудь в вашей основной программе должно привести к включению этого объектного файла.

Также обратите внимание, что в случае nm возможно, что ваш статический инициализатор был встроен, и, следовательно, символ не должен существовать в вашем конечном двоичном файле. Попробуйте что-то с побочными эффектами (например, оператор std::cout) в вашей статике и убедитесь, что оно не запускается, прежде чем обвинять компилятор:)

0 голосов
/ 20 января 2011

Оказывается, что то, что делает компоновщик, довольно стандартно (я не имею в виду стандарт C ++, просто поведение наблюдателя), и вы можете обойти это. В GNU ld это опция --whole-archive, в моем случае для инструментов Sun это -z allextract. Это на самом деле не сработало, как ожидалось для моего проекта, поэтому я использовал магию со слабыми символами -z weakextract, чтобы добиться того, чего хотел.

...