Поиск инструмента 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 в финальной ссылке, хотя это может повлиять на длительность процесса компиляции)