Я использую библиотеку с открытым исходным кодом, которая, кажется, имеет множество директив предварительной обработки для поддержки многих языков, отличных от C. Чтобы я мог изучить, что делает библиотека, я хотел бы увидеть код C, который я компилирую после предварительной обработки , больше похоже на то, что я напишу.
Может ли gcc (или любой другой инструмент, обычно доступный в Linux) читать эту библиотеку, но выводить код C, в котором предварительная обработка преобразована во что угодно и который также может читать человек?
gcc -E
это более полезно, чем необходимость переписывать строку, чтобы она работалаcpp
.Ответы:
Да. Передайте gcc
-E
опцию. Это выведет предварительно обработанный исходный код.источник
-o something.o
вы также можете изменить его на-o something.i
. В противном случае предварительно обработанный вывод будет в.o
файле.gcc -E file1.c file2.c ...
cpp
препроцессор.Запустить
cpp filename.c
для вывода предварительно обработанного кода или, лучше, перенаправить его в файл с расширениемcpp filename.c > filename.preprocessed
.источник
diff
оказывается никакой разницы в файлах. Это также выглядит как полезный способ предварительной обработки кода для поиска ошибок в ваших макросах. Отличный вопрос и отличный ответ (IALCTHW).Я использую gcc в качестве препроцессора (для файлов html). Он делает именно то, что вы хотите. Он расширяет директивы «# -», а затем выводит читаемый файл. (НИ ОДИН из других препроцессоров C / HTML, которые я пробовал, не делает этого - они объединяют строки, подавляются специальными символами и т. Д.) Если у вас установлен gcc, командная строка выглядит так:
gcc -E -xc -P -C -traditional-cpp code_before.cpp> code_after.cpp
(Не обязательно должно быть cpp.) На http://www.cs.tut.fi/~jkorpela/html/cpre.html есть отличное описание этого использования .
"-Traditional-cpp" сохраняет пробелы и табуляции.
источник
-save-temps
Это еще один хороший вариант, о котором следует помнить:
main.c
и теперь, помимо обычного вывода
main.o
, текущий рабочий каталог также содержит следующие файлы:main.i
желаемый предварительно настроенный файл, содержащий:main.s
это бонус :-) и содержит сгенерированную сборку:Если вы хотите сделать это для большого количества файлов, рассмотрите возможность использования вместо этого:
который сохраняет промежуточные файлы в том же каталоге, что и
-o
выходные данные объекта, а не в текущем рабочем каталоге, что позволяет избежать потенциальных конфликтов базовых имен.Преимущество этого варианта в
-E
том, что его легко добавить в любой скрипт сборки, не влияя при этом на саму сборку.Еще одна интересная особенность этой опции - если вы добавите
-v
:он фактически показывает явно используемые файлы вместо уродливых временных файлов
/tmp
, поэтому легко узнать, что именно происходит, включая этапы предварительной обработки / компиляции / сборки:Протестировано в Ubuntu 19.04 amd64, GCC 8.3.0.
источник
Бегать:
или
источник
Предположим, у нас есть файл Message.cpp или файл .c
Шаги 1: предварительная обработка (аргумент -E)
g ++ -E. \ Message.cpp> P1
Сгенерированный файл P1 имеет расширенные макросы и содержимое файла заголовка, а комментарии удалены.
Шаг 2: Преобразуйте предварительно обработанный файл в сборку (аргумент -S). Эту задачу выполняет компилятор
g ++ -S. \ Message.cpp
Создается ассемблер (ASM) (Message.s). В нем есть весь ассемблерный код.
Шаг 3. Переведите ассемблерный код в объектный код. Примечание. Message.s был создан на шаге 2. g ++ -c. \ Message.s
Создается объектный файл с именем Message.o. Это двоичная форма.
Шаг 4: Связывание объектного файла. Эту задачу выполняет компоновщик
g ++. \ Message.o -o MessageApp
Здесь создается exe-файл MessageApp.exe.
источник