Поиск инструмента Static Link Order для Linux
Есть ли подходящие инструменты для определения оптимального статического порядка ссылок с g++ под Linux? Я знаком с общими проблемами, в том числе (при необходимости) использованием повторяющихся ссылок на одну библиотеку или -start-group и -end-group для разрешения круговых зависимостей, но то, что я хотел бы, по возможности, это инструмент, который возьмет кучу файлов .a и выплюнет хороший статический порядок ссылок для них, при необходимости повторив библиотеки, сохранив при этом повторение до минимума.
Справочная информация. Я работаю над проектом с около 800K строк унаследованного кода на С++ и пытается реорганизовать его на более мелкие и более управляемые фрагменты. Некоторые из существующих файлов - огромные монолиты - сегодня я борюсь с одним 34K-строчным файлом .h, который определил 113 классов и структур. Многие из классов были определены почти полностью inline в файле .h. Поскольку я разбил это на более мелкие куски и перенести часть кода реализации в файлы .cpp, требуемый порядок ссылок в Linux продолжает меняться. Это, вероятно, потому, что каждая библиотека, в которую включен файл .h, используется для компиляции собственной реализации любых классов, в которых она нуждается, и теперь им приходится ссылаться на общую реализацию в одном файле библиотеки. Долгосрочно мы, вероятно, реорганизуем некоторые из классов в разные библиотеки и сломаем некоторые из цепочек зависимостей, но сейчас зависимости довольно запутаны, и я пытаюсь свести к минимуму возмущения кода, которые могут изменить поведение. Я бы предпочел, чтобы каждый раз, когда он менялся, нужно вручную определять правильный порядок ссылок. Предложения?
Ответы
Ответ 1
Я не знаю об одном, но вы можете реализовать его самостоятельно. Просто используйте nm
, чтобы получить список символов из каждой статической библиотеки, используйте это для построения графика зависимостей, затем выполните топологическую сортировку по графику для правильного порядка ссылок.
В качестве альтернативы вместо статических библиотек используйте частичные ссылки (ld -r
). Поскольку это выводит объединенный файл .o, ваша конечная ссылка может объявлять библиотеки в любом порядке, и все они будут связаны правильно. Недостатком является то, что компоновщик не сможет отбросить неиспользуемые исходные файлы, поскольку они уже связаны с монолитными файлами до того, как будут доступны данные об использовании (вы можете обойти это, передав -ffunction-sections -fdata-sections
во время компиляции и -Wl,--gc-sections
в финальной ссылке, хотя это может повлиять на длительность процесса компиляции)
Ответ 2
Вы можете использовать разделяемые библиотеки вместо статического и скомпилировать с опцией -fPIC
.