Подтвердить что ты не робот

Создание списка всех символов препроцессора, определенных в заголовках

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

В заголовках библиотеки (десятки... или сотни файлов) определены некоторые макросы/символы.

Теперь я хочу использовать эту библиотеку в проекте, который также определяет некоторые макросы и символы. Конечно, я хочу избежать столкновений имен, как это сообщалось иногда, особенно с windows.h. Но в целом я хочу сохранить контроль над тем, что действительно экспортируется из этого заголовка.

Я могу создать список определенных символов с опциями препроцессора gcc:

gcc -E -dM include/great_lib.h | sort -V >symbols.txt

Это выводит в файле symbol.txt отсортированный список всех определенных символов, включенных в файл пользователя, когда он включает этот заголовок.

Однако он дает только символ не файл, в котором он был определен.

У меня такое ощущение, что это может быть полезной информацией. Например, чтобы проверить, переопределен ли какой-либо системный макрос в "great_lib.h" или его потомках. Несчастье, после проверки опций препроцессора gcc, я не вижу способа сделать это с помощью gcc.

Например, вместо того, чтобы указывать только мне:

#define M_PI 3.14159265358979323846

он произведет

#define M_PI 3.14159265358979323846; /usr/include/math.h

Возможно, что-то с опцией -dN? Но его вывод запутан для меня, он требует дальнейшей обработки текста, и я не понимаю, как информация накладывается. Или более простой способ?

Похожие вопросы:

4b9b3361

Ответ 1

Опция -dD выводит предварительно обработанный источник вместе с макросами. Сюда входят строки, указывающие текущий исходный файл, например

# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.5.2/../../../../include/_mingw.h" 1 3

Вы можете написать небольшую программу, которая (i) отслеживает текущий исходный файл, анализируя эти строки; (ii) выводит все строки, начинающиеся с #define\t# define и т.д.), за которым следует текущее имя исходного файла; (iii) отбрасывает все другие строки (исходный код, декларации и т.д.).

Ответ 2

Быстрый способ unix:

find "$PATH_TO_LIB" -name "*.h" | xargs grep "^[ \t]*#[ \t]*define"

Затем вы можете использовать sed и sort, чтобы немного почистить форматирование.

Кроме того, согласно руководству gcc, gcc предупредит вас об этом.

http://gcc.gnu.org/onlinedocs/cpp/Undefining-and-Redefining-Macros.html

Если макрос переопределяется с определением, которое не так же, как и предыдущее, препроцессор выдает предупреждение и изменяет макрос, чтобы использовать новое определение. Если новое определение фактически одинаково, переопределение тихо игнорируется. Это позволяет, например, двум различным заголовкам определять общий макрос. Препроцессор будет жаловаться только в том случае, если определения не совпадают.

Ответ 3

Не изобретайте колесо, неуклюже. Все, что gcc -dM дает вам квадратное колесо: -)

Любая программа ctags (для vi) или etags (для emacs) будет извлекать эту информацию (какой идентификатор определен/объявлен в каком файле). В качестве бонуса вы получите его в форме, которая непосредственно понимается редакторами, позволяя вам поместить курсор на идентификатор, а затем перейти к его объявлению/определению.

Используйте инструменты в панели инструментов, используйте философию Unix, чтобы один инструмент хорошо справился.