2015-10-20 3 views
0

У меня есть модуль в проекте C с кучей больших файлов источника и заголовка. Они включают в себя множество внешних файлов заголовков, из libc и других модулей одного и того же проекта. Я хотел бы собрать список идентификаторов фактически, используемый из этих внешних файлов заголовков. Не только символы, но и все внешние определения типов, встроенные функции, макросы и т. Д.Как перечислить внешние идентификаторы в gcc?

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

Ближайшей вещь, которую я получил, это временно удалить включают директивы, как это:

sed -i s/"#include <.*>"//g *.c 
sed -i s/"#include <.*>"//g *.h 

Затем компилировать файлы с -Wno-неиспользованным, так что я могу видеть сообщения об ошибках из-за недостающие заголовки , Но он все еще далек от легко читаемого списка внешних идентификаторов.

+1

Почему вы так сильно заботитесь об используемых идентификаторах? Какова точная мотивация вашего вопроса? Пожалуйста, ** отредактируйте свой вопрос **, чтобы улучшить его! –

+0

Даже с редактированием я до сих пор не понимаю вашу мотивацию. Как только вы используете какую-либо внешнюю библиотеку, вы, вероятно, не используете все имена в ней ... –

+0

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

ответ

0

Это на самом деле сложнее, чем то, что вы верите (в частности, из-за preprocessor трюки, как concatenation могут строить символы, а также потому, что некоторые компилятор конкретные заголовки -notably <stdarg.h> - может полагаться на GCC или встроенных команд расширений, а также GCC принимает asm labels и т.д. ..).

Обратите также внимание, что компилятор может сделать optimizations как преобразование простой printf в puts (что имя не считать в этом случае?) ...

Если вы на самом деле означает, что вы хотите, вы можете настроить GCC, например используя MELT, чтобы соответствовать вашим целям. Это может занять несколько недель.

Другой подход может заключаться в том, чтобы проанализировать приблизительно предварительно обработанную форму, собрать в ней лексические маркеры и отсортировать их. Вы могли бы flex сгенерировать лексер и написать свою утилиту в C++ (или Python, или Ocaml) или что угодно; но тогда это приведет только к приближению используемых имен ... Если вы хотите разобрать код на C++, это намного сложнее (пространства имен, шаблоны, name mangling ...).

Если вы ограничиваете себя видимыми символами компоновщика, вы можете, конечно, использовать nm(1) на объектных файлах и без разделительных исполняемых файлов.

BTW, GCC может обрабатывать -Mpreprocessor options, чтобы автоматически производить зависимости make.

Наконец-то я не могу понять ваши мотивы (даже с вашим последним правлением): если у вас есть #include <gtk/gtk.h> в каком-то графическом приложении, вы, скорее всего, не будете использовать каждый символ или идентификатор, определенный в GTK ... (и аналогичным образом вы вероятно, не используют каждый идентификатор от <stdio.h> или <unistd.h> ...). На практике, вы вполне вероятно, не использовать всех символ, предоставляемых большинство внешних библиотек вы используете (GTK, SQLite, Libcurl, ....)

Возможно, некоторые cross-referencing инструмента, как cxref может быть полезен.

+0

Да, конкатенация действительно может сделать это сложнее. К счастью, в этом конкретном коде нет меток asm, и мне не нужны встроенные расширения gcc. Для таких оптимизаций, как printf -> puts change, я забочусь об исходном идентификаторе. Но по мере того, как я обновлялся в исходном вопросе, зависимости libc не так интересны для меня в этом конкретном случае. –

+0

Я тоже пробовал, но на самом деле огромная часть функций встраивается. И он не показывает макросы, определения типов. –

+0

Опция -M gcc также почти то, что я хочу: она может дать мне список файлов заголовков, но не то, что используется от них. –

Смежные вопросы