является ли пустой файл разрешенным для компиляции файлом исходного кода
Исходные файлы
Исходные файлы
Текст программы на языке Си может быть разделен на несколько исходных файлов. Исходный файл представляет собой текстовый файл, который содержит либо всю программу, либо ее часть. При компиляции исходной программы каждый из составляющих ее исходных файлов должен быть скомпилирован отдельно, а затем связан с другими файлами компоновщиком. Отдельные исходные файлы можно объединять в один исходный файл, компилируемый как единое целое, посредством директивы препроцессора #include.
Исходный файл может содержать любую целостную комбинацию директив, указаний компилятору, объявлений и определений. Под целостностью подразумевается, что такие объекты, как определения функций, структуры данных либо набор связанных между собой директив условной компиляции, должны целиком располагаться в одном файле, т. е. не могут начинаться в одном файле, а продолжаться в другом.
Исходный файл не обязательно должен содержать выполняемые операторы. Иногда удобно размещать определения переменных в одном файле, а в других файлах использовать эти переменные путем их объявления. В этом случае определения переменных становятся легко доступными для поиска и модификации. Из тех же соображений именованные константы и макроопределения обычно собирают в отдельные файлы и включают их посредством директивы препроцессора #include в те исходные файлы, в которых они требуются.
Указания компилятору обычно действуют только для отдельных участков исходного файла. Специфические действия компилятора, задаваемые указаниями, определяются конкретной реализацией компилятора языка Си.
В нижеследующем примере исходная программа состоит из двух исходных файлов. Функции main и max представлены в отдельных файлах. Функция main использует функцию max в процессе своего выполнения.
/* исходный файл 1 — функция main */
extern int max (int, int); /* объявление функции */
Процесс компиляции программ на C++
Цель данной статьи:
В данной статье я хочу рассказать о том, как происходит компиляция программ, написанных на языке C++, и описать каждый этап компиляции. Я не преследую цель рассказать обо всем подробно в деталях, а только дать общее видение. Также данная статья — это необходимое введение перед следующей статьей про статические и динамические библиотеки, так как процесс компиляции крайне важен для понимания перед дальнейшим повествованием о библиотеках.
Все действия будут производиться на Ubuntu версии 16.04.
Используя компилятор g++ версии:
Состав компилятора g++
Мы не будем вызывать данные компоненты напрямую, так как для того, чтобы работать с C++ кодом, требуются дополнительные библиотеки, позволив все необходимые подгрузки делать основному компоненту компилятора — g++.
Зачем нужно компилировать исходные файлы?
Исходный C++ файл — это всего лишь код, но его невозможно запустить как программу или использовать как библиотеку. Поэтому каждый исходный файл требуется скомпилировать в исполняемый файл, динамическую или статическую библиотеки (данные библиотеки будут рассмотрены в следующей статье).
Этапы компиляции:
driver.cpp:
1) Препроцессинг
Самая первая стадия компиляции программы.
Препроцессор — это макро процессор, который преобразовывает вашу программу для дальнейшего компилирования. На данной стадии происходит происходит работа с препроцессорными директивами. Например, препроцессор добавляет хэдеры в код (#include), убирает комментирования, заменяет макросы (#define) их значениями, выбирает нужные куски кода в соответствии с условиями #if, #ifdef и #ifndef.
Хэдеры, включенные в программу с помощью директивы #include, рекурсивно проходят стадию препроцессинга и включаются в выпускаемый файл. Однако, каждый хэдер может быть открыт во время препроцессинга несколько раз, поэтому, обычно, используются специальные препроцессорные директивы, предохраняющие от циклической зависимости.
Получим препроцессированный код в выходной файл driver.ii (прошедшие через стадию препроцессинга C++ файлы имеют расширение .ii), используя флаг -E, который сообщает компилятору, что компилировать (об этом далее) файл не нужно, а только провести его препроцессинг:
Взглянув на тело функции main в новом сгенерированном файле, можно заметить, что макрос RETURN был заменен:
В новом сгенерированном файле также можно увидеть огромное количество новых строк, это различные библиотеки и хэдер iostream.
2) Компиляция
На данном шаге g++ выполняет свою главную задачу — компилирует, то есть преобразует полученный на прошлом шаге код без директив в ассемблерный код. Это промежуточный шаг между высокоуровневым языком и машинным (бинарным) кодом.
Ассемблерный код — это доступное для понимания человеком представление машинного кода.
Используя флаг -S, который сообщает компилятору остановиться после стадии компиляции, получим ассемблерный код в выходном файле driver.s:
Мы можем все также посмотреть и прочесть полученный результат. Но для того, чтобы машина поняла наш код, требуется преобразовать его в машинный код, который мы и получим на следующем шаге.
3) Ассемблирование
Так как x86 процессоры исполняют команды на бинарном коде, необходимо перевести ассемблерный код в машинный с помощью ассемблера.
Ассемблер преобразовывает ассемблерный код в машинный код, сохраняя его в объектном файле.
Объектный файл — это созданный ассемблером промежуточный файл, хранящий кусок машинного кода. Этот кусок машинного кода, который еще не был связан вместе с другими кусками машинного кода в конечную выполняемую программу, называется объектным кодом.
Далее возможно сохранение данного объектного кода в статические библиотеки для того, чтобы не компилировать данный код снова.
Получим машинный код с помощью ассемблера (as) в выходной объектный файл driver.o:
Но на данном шаге еще ничего не закончено, ведь объектных файлов может быть много и нужно их всех соединить в единый исполняемый файл с помощью компоновщика (линкера). Поэтому мы переходим к следующей стадии.
4) Компоновка
Компоновщик (линкер) связывает все объектные файлы и статические библиотеки в единый исполняемый файл, который мы и сможем запустить в дальнейшем. Для того, чтобы понять как происходит связка, следует рассказать о таблице символов.
Таблица символов — это структура данных, создаваемая самим компилятором и хранящаяся в самих объектных файлах. Таблица символов хранит имена переменных, функций, классов, объектов и т.д., где каждому идентификатору (символу) соотносится его тип, область видимости. Также таблица символов хранит адреса ссылок на данные и процедуры в других объектных файлах.
Именно с помощью таблицы символов и хранящихся в них ссылок линкер будет способен в дальнейшем построить связи между данными среди множества других объектных файлов и создать единый исполняемый файл из них.
Получим исполняемый файл driver:
5) Загрузка
Последний этап, который предстоит пройти нашей программе — вызвать загрузчик для загрузки нашей программы в память. На данной стадии также возможна подгрузка динамических библиотек.
Запустим нашу программу:
Заключение
В данной статье были рассмотрены основы процесса компиляции, понимание которых будет довольно полезно каждому начинающему программисту. В скором времени будет опубликована вторая статья про статические и динамические библиотеки.
py_compile — Компиляция исходных файлов Python¶
Модуль py_compile предоставляет функцию для генерации файла байт-кода из исходного файла и другую используемую функцию, когда исходный файл модуля вызывается в качестве сценария.
Хотя он не часто необходим, он может быть полезен, устанавливая модули для общего использования, особенно если у некоторых пользователей может не быть разрешения написать байту-код файлы кэш в справочнике, содержащем исходный код.
exception py_compile. PyCompileError ¶
Исключение при возникновении ошибки при попытке компиляции файла.
py_compile. compile ( file, cfile=None, dfile=None, doraise=False, optimize=-1, invalidation_mode=PycInvalidationMode.TIMESTAMP, quiet=0 ) ¶
Изменено в версии 3.2: Измененный по умолчанию значение cfile, чтобы быть PEP 3147-соответствующим. Предыдущее значение по умолчанию: file + ‘c’ ( ‘o’ если была включена оптимизация). Также добавлен параметр optimize.
Изменено в версии 3.7.2: Переменная окружения SOURCE_DATE_EPOCH больше не отвергает значение аргумента invalidation_mode и определяет его по умолчанию значение вместо этого.
Изменено в версии 3.8: Добавлен параметр quiet.
Добавлено в версии 3.7.
py_compile. main ( args=None ) ¶
Модуль compileall Утилиты для компиляции всех исходных файлов Python в дереве каталогов.
Исходный файл не скомпилирован Dev C ++
Я только что установил Dev C ++ и изучаю программирование на C. код, который я использовал, был
Я использую windows 8
У меня была эта проблема, и я исправил ее, перейдя в: C: \ Dev-Cpp \ libexec \ gcc \ mingw32 \ 3.4.2, затем удалив collect2.exe
Установите новую версию Dev c ++. Он отлично работает в Windows 8. Он также поддерживает 64-битную версию.
Ссылка для скачивания: http://sourceforge.net/projects/orwelldevcpp/.
Я думаю, вы используете Windows 7 с Orwell Dev CPP
Эта версия Dev CPP подходит только для Windows 8. Однако в Windows 7 вам понадобится более старая версия, которая называется devcpp-4.9.9.2_setup.exe. Загрузите ее по ссылке и используйте. (Не забудьте удалить любую другую версию, уже установленную на вашем компьютере) Также обратите внимание, что более старая версия не работает с Windows 8.
Причина в том, что вы использовали компиляторы, созданные для Linux.
Вы всегда можете попробовать сделать это вручную из командной строки. Перейдите к пути к файлу и введите:
Я нашел решение. Пожалуйста, выполните следующие действия:
Щелкните правой кнопкой мыши на My comp. Икона
Щелкните Advanced Setting.
Щелкните переменную среды. В верхней части переменной среды нажмите New
Я столкнулся с той же проблемой, что и описанная выше.
Это можно решить, создав новый проект и новый файл в этом проекте. Сохраните файл, а затем попробуйте собрать и запустить.
Надеюсь, это поможет. 🙂
Эта ошибка возникла из-за неправильных настроек.
Например, я получаю
Русские Блоги
Автор: Yeh
Источник:http://lxWei.github.io/posts/262.html
Отказ от ответственности: Пожалуйста, укажите автора и источник перепечатки.
Жизненный цикл программы начинается с программы на языке высокого уровня C. Эта форма может быть понятна людям, но не может быть понята машинами. Чтобы запустить эту программу в системе, исходная программа должна быть преобразована в ряд машинных языков низкого уровня другими программами. Инструкции, которые затем упаковываются в виде исполняемых объектных программ и хранятся в виде двоичных файлов на диске.
В системе Linux следующие инструкции могут быть использованы для завершения преобразования исходной программы в целевую программу:
Драйвер компилятора gcc считывает исходные файлы hello.c и main.c и производит предварительную обработку, компиляцию, сборку и ссылки (с использованием препроцессора, компилятора, ассемблера и компоновщика соответственно. Эти четыре программы составляют систему компиляции ) Четыре шага, чтобы перевести его в исполняемую целевую программу привет. Как показано ниже:
Запустите следующую команду:
Как показано на рисунке ниже, соответствует четырем этапам на рисунке выше:
1. Пример программы
2. Предварительная обработка
Выполните следующую команду, чтобы увидеть изменения программы:
Посмотрите на hello.i, как показано ниже (аналогично main.i):
Как видно из приведенного выше рисунка, предварительная обработка является только расширением исходного файла, и исходная программа на языке C все еще получается.
3. Компилировать
Компилятор (CCL) переводит текстовые файлы hello.i и main.i, обработанные препроцессором, в hello.s и main.s, которые содержат программы на языке ассемблера. Программы на языке ассемблера находятся точно в стандартном текстовом формате. Описывает низкоуровневую инструкцию машинного языка.
Выполните следующую команду для компиляции:
Посмотрите на main.s и hello.s:
4. Компиляция
Выполните следующие инструкции, чтобы получить программы ретаргетинга main.o и hello.o:
Откройте main.o и hello.o в текстовом редакторе и найдите, что файлы искажены, потому что они уже являются двоичными файлами.
5. Ссылка
Компоновщик (LD) объединяет main.o и hello.o и некоторые другие необходимые объектные файлы для создания исполняемого объектного файла.
Получите исполняемую программу привет.