Процесс компиляции программ на c++

Введение

Один из самых распространённых компиляторов с языков C и C++ на многих современных Unix-подобных системах, таких как GNU/Linux, члены семейства систем BSD и Mac OS X, это GCC. Первоначально эта аббревиатура расшифровывалась как GNU C Compiler (компилятор языка C от организации GNU), в свою очередь GNU является «рекурсивным акронимом», то есть расшифровывается через самое себя: GNU=GNU is Not UNIX, имея ввиду свою открытость в отличие от оригинальных систем UNIX (таких как UNIX System V от компании AT&T и BSD UNIX, разрабатывавшемся в Университете Беркли, Калифорния). После его появления в 1987 году к GCC был дописан ряд фронт-ендов (front-ends, трансляторов исходных кодов во внутреннее представление GCC, рассчитанное на дальнейшую трансляцию в исполняемый двоичный код бек-ендом, back-end) для других языков программирования:

  • C++,
  • Objective-C,
  • Objective-C++,
  • Fortran,
  • Java,
  • Ada,

Простейший способ задействовать средства GCC — выполнить в командной строке команду:

$ gcc имя_файла

$‘.C’, ‘.cc’, ‘.cpp’, ‘.CPP’, ‘.c++’, ‘.cp’ или ‘.cxx’;
‘.hh’, ‘.hpp’, ‘.H’, или (иногда для разделяемого шаблонного кода) ‘.tcc’

$ gcc имя_файла -x тип
  • c c-header c-cpp-output
  • c++ c++-header c++-cpp-output
  • objective-c objective-c-header objective-c-cpp-output
  • objective-c++ objective-c++-header objective-c++-cpp-output
  • assembler assembler-with-cpp
  • ada
  • f95 f95-cpp-input
  • java
  • treelang
$ gcc -v
// first.cpp
#include <iostream>

int main() {
    std::cout << "Здравствуй, Мир!" << std::endl;
}
$ gcc ./first.cpp
/tmp/cc6dArpT.o: In function `main':
first.cpp:(.text+0x1c): undefined reference to `std::cout'
first.cpp:(.text+0x21): undefined reference to `std::basic_ostream >& std::operator >(std::basic_ostream >&, char const*)'
first.cpp:(.text+0x29): undefined reference to `std::basic_ostream >& std::endl >(std::basic_ostream >&)'
first.cpp:(.text+0x31): undefined reference to `std::basic_ostream >::operator >& (*)(std::basic_ostream >&))'
/tmp/cc6dArpT.o: In function `__static_initialization_and_destruction_0(int, int)':
first.cpp:(.text+0x60): undefined reference to `std::ios_base::Init::Init()'
first.cpp:(.text+0x65): undefined reference to `std::ios_base::Init::~Init()'
/tmp/cc6dArpT.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
collect2: выполнение ld завершилось с кодом возврата 1
$ ls
first.cpp

std::coutgcc

$ gcc ./first.cpp -lstdc++
$ ls
a.out  first.cpp
$ ./a.out 
Здравствуй, Мир!

-lgcc

$ rm ./a.out 
$ g++ ./first.cpp 
$ ls
a.out  first.cpp

g++

Если имя ‘a.out’ кажется вам не очень выразительным, то вы наверняка захотите указать другое, делается это так:

$ g++ ./first.cpp -o helloworld
$ ls
first.cpp  helloworld

Приведённые выше примеры должны натолкнуть на мысль о том, что поведением компилятора можно управлять посредством ключей (наподобие -l, -o). На самом деле, искусство использования конкретного компилятора на конкретных платформах определяется умением использовать такой набор ключей компиляции, который позволит создавать корректные и максимально эффективные программы по возможности быстро. Мы познакомимся с несколькими группами ключей GCC, приближающими к этой цели.

Поддерживаемые языки

По состоянию на май 2021 года последняя версия GCC 11.1 включает интерфейсы для языков программирования C ( ), C ++ ( ), Objective-C , Fortran ( ), Ada ( GNAT ), Go ( ) и D ( начиная с версии 9.1) с в OpenMP и OpenACC расширения параллельного языка поддерживается , так как GCC 5.1. Версии до GCC 7 также поддерживали Java ( ), что позволяло компилировать Java в собственный машинный код.

Что касается поддержки языковых версий для C ++ и C, так как GCC 11.1 целью по умолчанию является gnu ++ 17 , надмножество C ++ 17 , и gnu11 , надмножество C11 , также доступна строгая стандартная поддержка. GCC также обеспечивает экспериментальную поддержку C ++ 20 и предстоящего C ++ 23 .

Сторонние интерфейсы существуют для многих языков, таких как Pascal ( ), Modula-2 , Modula-3 , PL / I и VHDL ( ). Существует несколько экспериментальных веток для поддержки дополнительных языков, таких как компилятор GCC UPC для Unified Parallel C или Rust .

Практические задания

  1. Просмотреть информацию и список файлов пакета AnotherLevel. Найти в списке
    файлов, какие к этому пакету прилагаются man-страницы.
  2. Выдать на экран список всех пакетов, в имени которых есть «ftp«.
  3. Посмотреть, от каких пакетов зависит пакет AnotherLevel.
  4. Выполнить проверку пакета xterm-color, сначала как обычный
    пользователь, а затем как «root«. Объяснить полученные результаты.
  5. Установить из бинарного дистрибутива программу NEdit (не забыв про man!), дистрибутив лежит по
    адресу

  6. Собрать и установить программу lftp,
    дистрибутив лежит по адресу

  7. Собрать и установить программу xtetris,
    дистрибутив лежит по адресу

    Для
    этого надо предварительно установить пакет XFree86-devel. Его
    .-rpm-файл расположен в директории

1999

Debian: Anatomy of An Open Source Project

Debian: Anatomy of An Open Source Project

Коллекция компиляторов GNU (GCC) — это коллекция компиляторов и библиотек с открытым исходным кодом, поддерживающая языки программирования C, C ++, Objective-C, Fortran, Ada, Go и D. Ядро Linux, утилиты GNU и многие другие проекты скомпилированы с GCC.

В этом руководстве объясняется, как установить компилятор GCC на Debian 10, Buster. Те же инструкции применимы к Debian 9 и любому дистрибутиву на основе Debian.

Установка GCC на Debian

Репозитории Debian по умолчанию содержат метапакет с именем , содержащий компилятор GCC и другие библиотеки и утилиты, необходимые для компиляции программного обеспечения.

Для установки Debian 10 GCC Compiler выполните следующие действия:

  1. Сначала обновите список пакетов:

    Установите пакет , выполнив:

    Вы также можете установить страницы справочника, которые включают документацию по использованию GNU / Linux для разработки:

    Чтобы подтвердить, что компилятор GCC успешно установлен, введите :

    На момент написания этой статьи версия GCC по умолчанию, доступная в репозиториях Debian 10, была :

Вот и все. Вы успешно установили GCC на свой компьютер Debian.

Компиляция примера Hello World

Компилировать базовую программу на C или C ++ с помощью GCC довольно просто. Откройте ваш текстовый редактор и создайте следующий файл:

Привет

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

Компилятор создаст двоичный файл с именем в том же каталоге, где была выполнена команда.

Для запуска программы выполните:

Вывод будет выглядеть так:

Вывод

Вы успешно установили GCC на Debian 10. Для получения дополнительной информации о GCC посетите официальную документацию GCC.

gcc debian

Коллекция компиляторов GNU (GCC) — это коллекция компиляторов и библиотек для языков программирования C, C ++, Objective-C, Fortran, Ada, Go и D. В этом руководстве рассматриваются шаги, необходимые для установки компилятора GCC в CentOS 7.

Коллекция компиляторов GNU (GCC) — это коллекция компиляторов и библиотек для языков программирования C, C ++, Objective-C, Fortran, Ada, Go и D. В этом руководстве рассматриваются шаги, необходимые для установки компилятора GCC в Ubuntu 18.04.

VirtualBox — это кроссплатформенная программа виртуализации с открытым исходным кодом, которая позволяет одновременно запускать несколько гостевых операционных систем. В этом руководстве объясняется, как установить последнюю версию VirtualBox на Debian 10, Buster.

Разработка

Текущая стабильная версия GCC 6.2 была выпущена 22 августа 2016 г.

Начиная с версии 4.8, GCC реализован в C ++.

GCC 4.6 поддерживает множество новых Objective-C функций, таких как объявление и синтезирование свойств, точечный синтаксис,быстрое перечисление,
опциональные методы протокола, атрибуты метод / протокол / класс, расширение классов и новый GNU Objective-C во время выполнения API. Он также поддерживает язык программирования Go и включает в себя библиотеку , которая обеспечивает четырехкратную точность математических функций, поддерживающих тип данных. Библиотека используется для обеспечения типа в GNU Fortran.
GCC использует множество стандартных инструментов в своей сборке, в том числе Perl, Flex Bison и другие. Кроме того, он в настоящее время требует трех дополнительных библиотек, чтобы построить: GMP, MPC и MPFR.

Debug helloworld.cpp

Next, you’ll create a file to configure VS Code to launch the GDB debugger when you press F5 to debug the program.

From the main menu, choose Run > Add Configuration… and then choose C++ (GDB/LLDB).

You’ll then see a dropdown for various predefined debugging configurations. Choose g++ build and debug active file.

VS Code creates a file, opens it in the editor, and builds and runs ‘helloworld’.

In the JSON above, specifies the program you want to debug. Here it is set to the active file folder and active filename without an extension , which if is the active file will be .

By default, the C++ extension won’t add any breakpoints to your source code and the value is set to .

Change the value to to cause the debugger to stop on the method when you start debugging.

Start a debugging session

  1. Go back to so that it is the active file.
  2. Press F5 or from the main menu choose Run > Start Debugging. Before you start stepping through the code, let’s take a moment to notice several changes in the user interface:
  • The Integrated Terminal appears at the bottom of the source code editor. In the Debug Output tab, you see output that indicates the debugger is up and running.

  • The editor highlights the first statement in the method. This is a breakpoint that the C++ extension automatically sets for you:

  • The Run view on the left shows debugging information. You’ll see an example later in the tutorial.

  • At the top of the code editor, a debugging control panel appears. You can move this around the screen by grabbing the dots on the left side.

Установка GCC на Ubuntu

Репозитории Ubuntu по умолчанию содержат метапакет с именем, который содержит компилятор GCC и множество библиотек и других утилит, необходимых для компиляции программного обеспечения.

Выполните следующие шаги, чтобы установить компилятор GCC Ubuntu 18.04:
 

  1. Начните с обновления списка пакетов:
     

  2. Установите пакет, набрав:
     

    Команда устанавливает кучу новых пакетов , включая , и .

    Вы также можете установить справочные страницы об использовании GNU / Linux для разработки:
     

  3. Чтобы убедиться, что компилятор GCC успешно установлен, используйте команду, которая выводит версию GCC:
     

    Версия GCC по умолчанию, доступная в репозиториях Ubuntu 18.04 :
     

Вот и все. GCC теперь установлен в вашей системе, и вы можете начать его использовать.
 

Что такое компилятор C++?

Итак, давайте начнем с основ. Любой компьютер понимает только машинный код или ассемблер, который состоит из нулей и единиц. Это самый низкий, базовый уровень работы компьютера. Однако программировать таким образом весьма сложно и неудобно. Даже использовать низкоуровневый ассемблер — это то еще удовольствие. Хотя, впрочем, на нем есть даже своя операционная система.

Однако большинство разработчиков предпочитают высокоуровневые языки программирования, такие как C++. «Высокий уровень» означает, что они работают на уровне операционной системы, а не машинных кодов. И вот именно компилятор обеспечивает взаимодействие между кодом на C++ или любом другом высокоуровневом языке, и собственно, машинным кодом. Это утилита-посредник, которая обеспечивает преобразование вот такого кода:

#include <iostream>
int main() {
    std::cout << "Hello World!";
    return 0;
}

Примерно в такой, понятный процессору:

 global _main
    extern  
    extern  
    extern  

    section .text
_main:
    ; DWORD  bytes;    
    mov     ebp, esp
    sub     esp, 4

    ; hStdOut = GetstdHandle( STD_OUTPUT_HANDLE)
    push    -11
    call    
    mov     ebx, eax    

    ; WriteFile( hstdOut, message, length(message), &bytes, 0);
    push    0
    lea     eax, 
    push    eax
    push    (message_end - message)
    push    message
    push    ebx
    call    

    ; ExitProcess(0)
    push    0
    call    

    ; never here
    hlt
message:
    db      'Hello, World', 10
message_end:

Подобным образом работают и другие языки, к примеру, Python, JavaScript и так далее. Только они преобразовываются сначала в C++, а уже затем в ассемблерные коды.

И потому важным вопросом был, есть и остается — какой же компилятор C++ самый лучший. Сегодня мы постараемся подробно разобрать эту тему и выяснить ответ.

How to Install GCC Compiler on Ubuntu 18.04

3 Марта 2021
&vert;

Ubuntu

Коллекция компиляторов GNU (GCC) — это набор компиляторов и библиотек для языков программирования C, C ++, Objective-C, Fortran, Ada, Go и D. Многие проекты с открытым исходным кодом, включая инструменты GNU и ядро ​​Linux, скомпилированы с помощью GCC.

Те же инструкции применимы для Ubuntu 16.04 и любого дистрибутива на основе Ubuntu, включая Kubuntu, Linux Mint и Elementary OS.
 

Прежде чем вы приступите

Чтобы добавлять новые репозитории и устанавливать пакеты в вашей системе Ubuntu, вы должны войти в систему как пользователь root или пользователь с привилегиями sudo .
 

Установка GCC на Ubuntu

Репозитории Ubuntu по умолчанию содержат метапакет с именем, который содержит компилятор GCC и множество библиотек и других утилит, необходимых для компиляции программного обеспечения.

Выполните следующие шаги, чтобы установить компилятор GCC Ubuntu 18.04:
 

  1. Начните с обновления списка пакетов:
     

  2. Установите пакет, набрав:
     

    Команда устанавливает кучу новых пакетов , включая , и .

    Вы также можете установить справочные страницы об использовании GNU / Linux для разработки:
     

  3. Чтобы убедиться, что компилятор GCC успешно установлен, используйте команду, которая выводит версию GCC:
     

    Версия GCC по умолчанию, доступная в репозиториях Ubuntu 18.04 :
     

Вот и все. GCC теперь установлен в вашей системе, и вы можете начать его использовать.
 

Компиляция примера Hello World

Скомпилировать базовую программу на C или C ++ с помощью GCC довольно просто. Откройте текстовый редактор и создайте следующий файл:

Сохраните файл и скомпилируйте его в исполняемый файл с помощью следующей команды:
 

Это создаст двоичный файл с именем в том же каталоге, где вы запускаете команду.

Запустите программу с помощью:
 

Программа должна напечатать:
 

Установка нескольких версий GCC

В этом разделе приведены инструкции по установке и использованию нескольких версий GCC в Ubuntu 18.04. Новые версии компилятора GCC включают поддержку новых языков, лучшую производительность и расширенные функции.

На момент написания этой статьи репозитории Ubuntu по умолчанию включают несколько версий GCC, от до . Последняя версия GCC, доступная в PPA Ubuntu Toolchain.

В следующем примере мы установим последние три версии GCC и G ++.

Сначала добавьте PPA в вашу систему с помощью:
 

Установите нужные версии GCC и G ++, набрав:
 

Приведенные ниже команды настраивают альтернативу для каждой версии и связывают с ней приоритет. Версия по умолчанию — это версия с наивысшим приоритетом, в нашем случае это так .
 

Позже, если вы захотите изменить версию по умолчанию, используйте команду:
 

Вам будет представлен список всех установленных версий GCC в вашей системе Ubuntu. Введите номер версии, которую вы хотите использовать по умолчанию, и нажмите .

Команда создаст символические ссылки на определенные версии GCC и G ++.
 

Вы успешно установили GCC на свой Ubuntu 18.04. Теперь вы можете посетить официальную страницу документации GCC и узнать, как использовать GCC и G ++ для компиляции программ на C и C ++

Компилируем мини-программу с анализом Coverage

Создайте файл и скопируйте или перепишите в него код:

Теперь откройте терминал в каталоге, где находится , и скомпилируйте программу одной командой:

Если компиляция не удалась, прочитайте текст ошибки и исправьте ошибку. Если всё в порядке, то в каталоге появится ещё два файла: исполняемый файл и файл , содержащий базовую информацию для запуска Code Coverage.

Теперь надо запустить программу, чтобы в процессе работы она записала информацию о фактическом покрытии кода на данном запуске. В UNIX и в Windows запуск выглядит по-разному:

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

Установка GCC на Debian

Репозитории Debian по умолчанию содержат метапакет с именем , содержащий компилятор GCC и другие библиотеки и утилиты, необходимые для компиляции программного обеспечения.

Для установки Debian 10 GCC Compiler выполните следующие действия:

  1. Сначала обновите список пакетов:

    Установите пакет , выполнив:

    Вы также можете установить страницы справочника, которые включают документацию по использованию GNU / Linux для разработки:

    Чтобы подтвердить, что компилятор GCC успешно установлен, введите :

    На момент написания этой статьи версия GCC по умолчанию, доступная в репозиториях Debian 10, была :

Вот и все. Вы успешно установили GCC на свой компьютер Debian.

Introduction

Generally speaking, a cross-compiler is a compiler that runs on platform A (the host), but generates executables for platform B (the target). These two platforms may (but do not need to) differ in CPU, operating system, and/or executable format. In our case, the host platform is your current operating system and the target platform is the operating system you are about to make. It is important to realize that these two platforms are not the same; the operating system you are developing is always going to be different from the operating system you currently use. This is why we need to build a cross-compiler first, you will most certainly run into trouble otherwise.

Why cross-compilers are necessary

Main article: Why do I need a Cross Compiler?

You need to use a cross-compiler unless you are developing on your own operating system. The compiler must know the correct target platform (CPU, operating system), otherwise you will run into trouble. If you use the compiler that comes with your system, then the compiler won’t know it is compiling something else entirely. Some tutorials suggest using your system compiler and passing a lot of problematic options to the compiler. This will certainly give you a lot of problems in the future and the solution is build a cross-compiler. If you have already attempted to make an operating system without using a cross-compiler, please read the article Why do I need a Cross Compiler?.

Which compiler version to choose

Main article: Building GCC

The newest GCC is recommended as it is the latest and greatest release. For instance, you may run into trouble if you use GCC 4.6.3 to build a GCC 4.8.0 cross-compiler. If you are not using the latest major GCC release for your system compiler, we recommend that you build the newest GCC as your system compiler.

You can also use older releases as they are usually reasonably good. If your local system compiler isn’t too terribly old (at least GCC 4.6.0), you may wish to save yourself the trouble and just pick the latest minor release (such as 4.6.3 if your system compiler is 4.6.1) for your cross-compiler.

You can view your current compiler version by invoking:

gcc --version

You may be able to use an older major GCC release to build a cross-compiler of a newer major GCC release. For instance, GCC 4.7.3 may be able to build a GCC 4.8.0 cross-compiler. However, if you want to use the latest and greatest GCC version for your cross-compiler, we recommend that you bootstrap the newest GCC as your system compiler first. Individuals using OS X 10.7 or earlier might want to invest in either building a system GCC (that outputs native Mach-O), or upgrading the local LLVM/Clang installation. Users with 10.8 and above should install the Command Line Tools from Apple’s developer website and use Clang to cross-compile GCC.

Which binutils version to choose

Main article: Cross-Compiler Successful Builds

We recommend that you use the latest and greatest Binutils release. Note, however, that not all combinations of GCC and Binutils work. If you run into trouble, use a Binutils that was released at roughly the same time as your desired compiler version. You probably need at least Binutils 2.22, or preferably the latest 2.23.2 release. It doesn’t matter what Binutils version you have installed on your current operating system. You can find out the binutils version for example by this command:

ld --version

Deciding on the target platform

Main article: Target Triplet

You should already know this. If you are following the Bare Bones tutorial, you wish to build a cross-compiler for i686-elf.

Note on arm-none-eabi-gcc

There is the prebuilt package gcc-arm-none-eabi on apt-get for Debiab/Ubuntu, but you shouldn’t use it because it neither contains a libgcc.a nor freestanding C header files like stdint.h.
Instead you should build it yourself with arm-none-eabi being the $TARGET.

Интерпретатор C / C++ Ch Embeddable (стандартная версия)

Интерпретатор C / C++, поддерживающий стандарт ISO 1990 C (C90), основные функции C99, классы C++, а также расширения к языку С, такие как вложенные функции, строковый тип и т. д. Он может быть встроен в другие приложения и аппаратные средства, использоваться в качестве языка сценариев. Код C / C++ интерпретируется напрямую без компиляции промежуточного кода. Поскольку этот интерпретатор поддерживает Linux, Windows, MacOS X, Solaris и HP-UX, созданный вами код можно перенести на любую из этих платформ. Стандартная версия бесплатна для личного, академического и коммерческого использования. Для загрузки пакета необходимо зарегистрироваться.

Структура

Внешний интерфейс GCC является стандартом для компиляторов на платформе UNIX. Пользователь вызывает управляющую программу, которая называется gcc. Она интерпретирует аргументы командной строки, определяет и запускает для каждого входного файла свои компиляторы нужного языка, запускает, если необходимо, ассемблер и компоновщик.

Компилятор каждого языка является отдельной программой, которая получает исходный текст и порождает вывод на язык ассемблера|языке ассемблера. Все компиляторы имеют общую внутреннюю структуру: front end, который производит синтаксический разбор и порождает абстрактное синтаксическое дерево, и back end, который конвертирует дерево в Register Transfer Language (RTL), выполняет различные оптимизации, затем порождает программу на языке ассемблера, используя архитектурно-зависимое сопоставление с образцом.

До версии 4.7.2 GCC был почти полностью написан на Си, хотя значительная часть front-end для Ады написана на Аде. С 14.08.2012 разработка была переведена на язык C++, версия 4.8 и более поздние требуют для своей сборки наличия C++ компилятора, поддерживающего С++ 2003.

Какие ошибки может определить компилятор?

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

  • ошибки объявления переменных или отсутствие их начальных значений
  • ошибки несоответствия типов
  • ошибки неправильной записи операторов и функций

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

Такая реакция компилятора больше похожа на рекомендации, но на них стоит обратить внимание. Программист сам решает оставить код с предупреждением или изменить программу.
Анализируя текст программы, компилятор не только ищет ошибки, но еще и упрощает ее код

Такой процесс называется оптимизацией.
Во время оптимизации компилятор изменяет программный код, но функции, которые выполняла программа, остаются прежними.

Составляем отчёт о Code Coverage с помощью lcov

После предыдущего шага у нас есть всё, что надо для lcov, и теперь стало намного проще! Введите в терминале команду lcov с несколькими опциями:

Пояснения по поводу опций:

  • устанавливает имя отчёта, при измерении покрытия кода тестами можно указать имя теста или набора тестов
  • устанавливает имя выходного файла с промежуточной информацией
  • указывает, что lcov должен использовать существующие данные о coverage
  • устанавливает каталог, в котором надо искать данные о coverage, и мы передаём текущий каталог “.”

Теперь можно сгенерировать отчёт в виде HTML-страницы с помощью утилиты , входящей в состав пакета программ lcov:

Теперь вы можете перейти в каталог , открыть файл в браузере и посмотреть отчёт. Вы увидите страницу, на которой показан статичный отчёт о покрытии различных каталогов, и можно перейти по ссылкам для просмотра отдельных каталогов:

Вы можете перейти к конкретному файлу и посмотреть покрытие этого файла:

Языки

В версии 4.1.1 (выпущенной 24 мая, 2006), стандартный компилятор включал в себя front-end’ы для:

  • Ada (GCC для Ada aka GNAT)
  • C
  • C++ (GCC для C++ aka G++)
  • Fortran (GCC для Fortran aka GFortran)
  • Java (GCC для Java aka GCJ)
  • Objective-C
  • Objective-C++

Front end для CHILL был добавлен ранее, но из-за недостаточной поддержки был исключен из набора. До релиза версии 4.0 front-end’ом для Fortran был G77, который поддерживал лишь Fortran 77. В новых версиях G77 был исключён в пользу нового GFortran frontend который поддерживает Fortran 95.

Так же существуют front-end’ы для Pascal, D, Modula-2, Modula-3, Mercury, VHDL и PL/I.

Обзор

Начало GCC было положено Ричардом Столлмэном, который реализовал первый вариант GCC в 1985 на нестандартном и непереносимом диалекте языка Паскаль; позднее компилятор был переписан на языке Си Леонардом Тауэром (Шаблон:Lang-en) и Р. Столлмэном, и выпущен в 1987 как компилятор для проекта GNU, который сам по себе являлся свободным программным обеспечением. Разработка GCC курируется Free Software Foundation.

В настоящее время GCC поддерживается группой программистов со всего мира. GCC является лидером по количеству процессоров и операционных систем, которые он поддерживает.

Будучи официальным компилятором системы GNU, включая варианты системы, построенные на ядре Linux (GNU/Linux), GCC также является главным компилятором для сборки ряда других операционных систем, среди них: различные варианты BSD, Mac OS X, NeXTSTEP и BeOS.

GCC часто выбирается для разработки программного обеспечения, которое должно работать на большом числе различных аппаратных платформ. Различия между «родными» для каждой из аппаратных платформ компиляторами приводят к трудностям при разработке кода, который бы корректно компилировался разными компиляторами, а кроме того, при использовании различных компиляторов сильно усложняются сборочные скрипты, которые должны собирать ПО для всех аппаратных платформ. При использовании GCC для компиляции кода под разные платформы будет использован один и тот же синтаксический анализатор. Поэтому если удалось собрать программу для одной из целевых платформ, то велика вероятность, что программа нормально соберётся и для других платформ.

Using the new Compiler

Now you have a «naked» cross-compiler. It does not have access to a C library or C runtime yet, so you cannot use any of the standard includes or create runnable binaries. But it is quite sufficient to compile the kernel you will be making shortly. Your toolset resides in $HOME/opt/cross (or what you set $PREFIX to). For example, you have a GCC executable installed as $HOME/opt/cross/bin/$TARGET-gcc, which creates programs for your TARGET.

You can now run your new compiler by invoking something like:

$HOMEoptcrossbin$TARGET-gcc --version

Note how this compiler is not able to compile normal C programs. The cross-compiler will spit errors whenever you want to #include any of the standard headers (except for a select few that actually are platform-independent, and generated by the compiler itself). This is quite correct — you don’t have a standard library for the target system yet!

The C standard defines two different kinds of executing environments — «freestanding» and «hosted». While the definition might be rather fuzzy for the average application programmer, it is pretty clear-cut when you’re doing OS development: A kernel is «freestanding», everything you do in user space is «hosted». A «freestanding» environment needs to provide only a subset of the C library: float.h, iso646.h, limits.h, stdalign.h, stdarg.h, stdbool.h, stddef.h, stdint.h and stdnoreturn.h (as of C11). All of these consist of typedef s and #define s «only», so you can implement them without a single .c file in sight.

To use your new compiler simply by invoking $TARGET-gcc, add $HOME/opt/cross/bin to your $PATH by typing:

export PATH="$HOME/opt/cross/bin:$PATH"

This command will add your new compiler to your PATH for this shell session. If you wish to use it permanently, add the PATH command to your ~/.profile configuration shell script or similar. Consult your shell documentation for more information.

You can now move on to complete the Bare Bones tutorial variant that lead you here and complete it using your new cross-compiler. If you built a new GCC version as your system compiler and used it to build the cross-compiler, you can now safely uninstall it unless you wish to continue using it.

Как выполняется компиляция?

Компиляция программы Linux — это довольно сложный процесс. Все еще сложнее, потому что код программы содержится не в одном файле и даже не во всех файлах ее исходников. Каждая программа использует множество системных библиотек, которые содержат стандартные функции. К тому же один и тот же код должен работать в различных системах, содержащих различные версии библиотек.

На первом этапе, еще до того как начнется непосредственно компиляция, специальный инструмент должен проверить совместима ли ваша система с программой, а также есть ли все необходимые библиотеки. Если чего-либо нет, то будет выдана ошибка и вам придется устранить проблему.

Дальше идет синтаксический анализ и преобразование исходного кода в объектный код, без этого этапа можно было бы и обойтись, но это необходимо, чтобы компилятор мог выполнить различные оптимизации, сделать размер конечной программы меньше, а команды процессора эффективнее.

Затем все объектные файлы собираются в одну программу, связываются с системными библиотеками. После завершения этого этапа программу остается только установить в файловую систему и все. Вот такие основные фазы компиляции программы, а теперь перейдем ближе к практике.

Языки

C версии 4.6 стандартный компилятор включает в себя front-end’ы для языков:

  • C (gcc)
  • C++ (g ++)
  • Objective-C
  • Objective-C++
  • Fortran (gfortran)
  • Java (gcj)
  • Ada (GNAT)
  • Go (gccgo)
  • Параллельное расширение языка, OpenMP
  • Cilk Plus (с версии 5.0)
  • OpenACC (с версии 5.1)

Fortran front-end был G77 до версии 4.0, которая поддерживает только FORTRAN 77. В новых версиях G77 отбрасывается в пользу нового GNU Fortran front-end (сохранив большую часть расширений языка G77), что поддерживает Fortran 95 и большинство частей Fortran 2003 и Fortran 2008, а также front-end для CHILL был понижен из-за отсутствия технического обслуживания.

Разные способы установки программ

При установке ПО в Unix используется один из трех вариантов:

  1. Из готового пакета (в RedHat Linux — при помощи rpm).
  2. Разворачивание из файла .tar.gz или .tgz, содержащего готовые исполняемые
    файлы.
  3. Компиляция из исходных текстов.

Первый вариант — самый удобный и предпочтительный. Но при этом надо, чтобы
нужное ПО существовало именно в виде .rpm-пакета.

Второй вариант очень часто используется с программами «от третьих
поставщиков». К примеру, самая последняя версия Netscape обычно становится
доступна в виде .tar.gz-архива (и лишь несколько позже появляется .rpm-пакет).

Третий вариант до недавнего времени был самым распространенным, да и до сих
пор множество программ научного и развлекательного назначения распространяются
именно в виде исходных текстов. Достоинство этого способа — то, что собрать
программу из исходных текстов можно практически под любым Unix, даже если сам
автор этого не сделал. К недостаткам же относится то, что «сходу» программа
может и не откомпилироваться (или даже просто не заработать), так что могут
потребоваться навыки программиста.

Если дистрибутив берется из .tar.gz-архива, то чаще всего его может
установить не только «root«, но и любой пользователь (естественно, в
свою личную директорию, а не в системную). В случае же .rpm-пакета обычному
пользователю придется повозиться, чтобы извлечь оттуда файлы для «ручной»
установки.

Раздельная трансляция

Реальные программы сильно превышают размеры нашего первого примера ‘first.cpp’ по количеству строк кода. Когда оно увеличивается достаточно сильно, появляются проблемы:

  • любое изменение в тексте файла с программой приводит к его полной перекомпиляции, что занимает ощутимое время;
  • сложно организовать коллективную разработку (согласовать внесение изменений в один файл несколькими программистами);
  • затрудняется навигация по созданному коду.

Начнём с простого случая, когда программа представляет из себя набор функций, и мы хотим вынести их часть в отдельный ‘.cpp’-файл. Возьмём уже использовавшийся пример с программой ‘first.cpp’ и добавим в неё вызов функции, определение которой помещается в файле ‘second.cpp‘:

// first.cpp
#include <iostream>

using std::endl;

int f();

int main() {
    std::cout << "Здравствуй, Мир!" << endl
        << f() << endl;
}
// second.cpp
int f() {return 42;}

int f();#includemain

// first.cpp
#include <iostream>
#include "second.hpp"

using std::endl;

int main() {
    std::cout << "Здравствуй, Мир!" << endl
        << f() << endl;
}
// second.hpp
#ifndef SECOND_HPP
#define SECOND_HPP
int f();
#endif
// second.cpp
int f() {return 42;}

#SECOND_HPP

Вернёмся от увлекательных особенностей C++ к использованию GCC. Оба указанных выше варианта компилируются и линкуются в один исполняемый файл одинаково, при помощи простого перечисления:

$ g++ ./first.cpp ./second.cpp -o hw42
$ ./hw42
Здравствуй, Мир!
42
$ g++ ./*.cpp -o hw42

Итак, мы сумели разнести код в несколько файлов, но пока еще не добились того, чтобы изменения в одном файле не приводили к перекомпиляции всех. Здесь снова придется вспомнить о том, что используемые до этого момента вызовы gcc (g++) приводят не только к компиляции, но и к линковке полученных после компиляции объектных фалов в один исполняемый файл. Нам потребуется явно разбить создание исполняемого файла на две стадии, используя ключ gcc -с, который просит оставить получившиеся объектные файлы на диске и не линковать их:

$ g++ ./*.cpp -c
$ ls | grep '\.o$'
first.o
second.o
$ g++ ./*.o -o hw-from-o
$ ./hw-from-o 
Здравствуй, Мир!
42
$ g++ ./second.cpp -c
$ g++ ./*.o -o hw42-v.2

Заключение

Не всегда установка из бинарного дистрибутива проходит так гладко и просто —
мы выбрали самые несложные примеры, чтобы проиллюстрировать процесс установки.

Многие программы кроме собственно исполняемого файла (а чаще файлов) содержат
еще некоторое количество файлов конфигурации и библиотек, которые следует
поместить в строго определенные места (обычно внутри директории lib/) и
man-страниц.

Кроме того, часто после установки требуется выполнить «руками» некоторые
дополнительные действия — например, добавить в стартовые файлы shell установку
некоторых переменных окружения, модифицировать конфигурацию window manager’а
(добавить программу в меню или настроить ее автоматический запуск).

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Мой редактор ОС
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: