Автоматически генерировать зависимости объектного файла (компоновщика) для исполняемых файлов C / C ++
======================================================================================================

В настоящее время я работаю над гибкой средой сборки C / C ++, которую (надеюсь) скоро открою. (увидеть[этот](https://stackoverflow.com/questions/7606604/build-system-for-an-embedded-c-c-project) вопрос для некоторого фона).

Я использую приведенную ниже команду для генерации зависимостей файла #include для файлов исходного кода / заголовка.

Есть ли способ умело выводить зависимости компоновщика (.o файл) для**executables** (модульные тесты + основной исполняемый файл для целевой платформы в моем случае) с использованием утилит gcc / GNU аналогично описанному выше? В настоящее время структура делает много предположений и довольно глупа в определении этих зависимостей.

Я слышал об одном подходе, гдеnm Команда может быть использована для создания списка неопределенных символов в объектном файле. Например, при запуске nm в объектном файле (скомпилированном с помощью gcc -c) получается что-то вроде этого -

Затем можно было бы искать другие объектные файлы, где эти неопределенные символы**are** определено для составления списка зависимостей объектных файлов, необходимых для успешного связывания файла.

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

й файл), которым требуются разные наборы зависимостей, тогда обычный, классический способ обработки - использование библиотеки & # x2014; статический`.a` или поделился`.so` (или эквивалентный) & # x2014; хранить объектные файлы, которые могут использоваться более чем одной программой, и связывать программы с этой библиотекой. Компоновщик автоматически извлекает правильные объектные файлы из статического архива. Процесс с общей библиотекой немного отличается, но общий результат тот же: исполняемый файл имеет правильные объектные файлы, доступные ему во время выполнения.

Для любой программы существует, по меньшей мере, один файл, уникальный для этой программы (обычно это файл, который содержит`main()` программа). Там может быть несколько файлов для этой программы. Эти файлы, вероятно, известны и могут быть легко перечислены. Те из них, которые вам могут понадобиться в зависимости от конфигурации и параметров компиляции, вероятно, используются совместно программами и легко обрабатываются с помощью механизма библиотеки.

Вы должны решить, хотите ли вы использовать статические или общие библиотеки. Хорошо создать общие библиотеки сложнее, чем создавать статические библиотеки. С другой стороны, вы можете обновить общую библиотеку и сразу же повлиять на все программы, которые ее используют, тогда как статическая библиотека может быть изменена, но изменения принесут пользу только тем программам, которые связаны с новой библиотекой.



`nm` вывод для всех объектных файлов в текущем каталоге:

Скрипт ищет текущий каталог и все подкаталоги для`.o` файлы, звонки`nm` для каждого найденного файла и анализирует полученный результат. Символы, которые не определены в одном`.o` Файл и определяется в другом интерпретируются как зависимость между двумя файлами. Символы, определенные нигде (обычно предоставляемые внешними библиотеками), игнорируются. Наконец, скрипт выводит список прямых зависимостей для всех объектных файлов.

Если символ предоставляется несколькими объектными файлами, этот сценарий произвольно предполагает зависимость от объектного файла с самым коротким именем файла (и помечает выбранный файл как`*` в выходной). Это поведение можно изменить, изменив функцию`pick`.

Скрипт работает для меня в Linux и MacOS, я не пробовал другие операционные системы, и скрипт только слегка протестирован.



 такие как библиотеки .a), используя libbfd. Я думаю, что вы действительно хотите сделать, это обработать базу данных открытых символов, определенных в библиотеках, о которых вы знаете, и в объектных файлах, которые являются частью этого проекта, так что при создании каждого нового объектного файла вы можете посмотреть на неопределенные символы в нем и определить, какой объект - обычный или в библиотеке - вам нужно создать ссылку для разрешения ссылок. По сути, вы выполняете ту же работу, что и компоновщик, но в некотором роде наоборот, чтобы определить, какие символы вы можете найти.

Если вы работаете с GCC, вы всегда можете заглянуть в пакеты с исходными текстами для вашего "binutils". найти источники в нм, и даже в лд, если вы этого хотите. Вы, конечно, не хотите запускать nm и анализировать вывод, когда он просто использует libbfd под капотом, просто вызовите libbfd самостоятельно.