Компилятор c89 в Ubuntu: сборка ANSI C с примерами

Введение

Стандарт POSIX определяет интерфейс c89 в качестве унифицированной утилиты для компиляции исходного кода на языке Си в строгом соответствии со спецификацией ANSI C (C89/C90). В данном руководстве наглядно разбирается практическая работа с этой утилитой в дистрибутиве Ubuntu: от базовой компиляции одиночных исходников до раздельного создания объектных модулей и линковки с системными библиотеками.

Установка инструментария c89 и диагностика окружения

Перед началом работы требуется актуализировать локальные индексы репозиториев apt и развернуть пакеты компилятора gcc вместе с обёрткой c89.

sudo apt-get update -qq && sudo apt-get install -y gcc c89

Чтобы убедиться в наличии исполняемого файла в системных путях поиска $PATH, запросим его точное расположение вызовом which c89.

which c89

Утилита c89 служит для сборки Си-программ по каноническим правилам стандарта ANSI C (C89/C90). В среде Ubuntu она реализована в виде специального сценария-обёртки поверх gcc. Для инспекции базового компилятора и вывода подробных сведений о конфигурации сборочной среды выполним c89 --version 2>/dev/null || gcc -v.

⚙️ [Ключевые флаги сборки]

-c : останавливает процесс после этапа компиляции, генерируя объектный файл (.o) без вызова компоновщика.
-o : задаёт произвольное имя для результирующего бинарного файла.
-O : включает оптимизацию сгенерированного машинного кода для повышения производительности программы.
-s : удаляет отладочные символы и таблицу символов из исполняемого файла для минимизации его объёма.
-g : внедряет расширенную отладочную информацию для последующего анализа в gdb.
-D : определяет макрос препроцессора на этапе вызова сборщика.
-U : отменяет ранее установленное определение макроса препроцессора.
-I : добавляет указанную директорию в список путей поиска заголовочных файлов.
-L : расширяет перечень каталогов, в которых линкер ищет бинарные библиотеки.
-l : подключает внешнюю библиотеку на этапе компоновки исполняемого файла.

c89 –version 2>/dev/null || gcc -v

Написание базовой программы C89 и сборка исполняемого файла

Подготовим минимальный пример исходного кода hello.c, строго выдержанный в рамках требований классического стандарта ANSI C.

printf ‘#include <stdio.h>\nint main(void) {\n    printf(“Hello, C89 Standard!\n”);\n    return 0;\n}\n’ > hello.c

Выведем содержимое созданного файла hello.c на экран через cat hello.c, чтобы проконтролировать корректность записи.

cat hello.c

Запустим компиляцию исходника hello.c посредством c89, указав ключ -o для формирования исполняемого файла с именем hello.

c89 -o hello hello.c

Запустим полученный бинарник hello и убедимся в правильности его выполнения в терминале.

./hello

Раздельная компиляция в объектный файл (-c) и последующая компоновка

Для демонстрации двухэтапной сборки создадим отдельный файл с исходным кодом calc.c, также соответствующий стандарту ANSI C.

printf ‘#include <stdio.h>\nint main(void) {\n    int count = 5;\n    printf(“Count: %%d\n”, count);\n    return 0;\n}\n’ > calc.c

Передадим c89 ключ -c: в этом режиме утилита преобразует исходный текст в машинные инструкции и запишет объектный модуль calc.o, минуя стадию связывания.

c89 -c calc.c

С помощью команды ls -l calc.o проверим атрибуты и сам факт успешного появления объектного модуля в текущей директории.

ls -l calc.o

Теперь передадим сформированный объектный файл calc.o утилите c89 с флагом -o, инициируя этап компоновки для сборки готового бинарника calc.

c89 -o calc calc.o

Протестируем финальный исполняемый файл calc в рабочей среде и сопоставим вывод с ожидаемым поведением алгоритма.

./calc

Передача макросов препроцессора (-D) и подключение математической библиотеки (-lm)

Для отработки условной компиляции и компоновки с внешними модулями сформируем исходный файл app.c, задействующий математические вычисления.

printf ‘#include <stdio.h>\n#include <math.h>\nint main(void) {\n#ifdef DEBUG\n    printf("[DEBUG MODE]\n");\n#endif\n    printf(“sqrt(49.0) = %%.2f\n”, sqrt(49.0));\n    return 0;\n}\n’ > app.c

Соберём программу командой c89, активировав диагностический макрос параметром -DDEBUG и подключив системную математическую библиотеку ключом -lm.

c89 -DDEBUG -o app app.c -lm

Запустим итоговый файл app, чтобы подтвердить срабатывание отладочной ветки препроцессора и корректность вычисления функции квадратного корня.

./app

Мы подробно рассмотрели практические приёмы сборки программ по стандарту ANSI C с использованием интерфейса c89 в среде Ubuntu. Данный инструментарий незаменим при сопровождении легаси-кодовой базы, портировании старых системных утилит и обеспечении гарантированной переносимости C-проектов.