мета-данные страницы
  •  

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Следующая версия
Предыдущая версия
soft:gcc [2025/03/17 16:45] – создано radi0devsoft:gcc [2026/03/03 15:27] (текущий) radi0dev
Строка 1: Строка 1:
 +====== gcc ======
 +
 +GCC- GNU Compiler Collection
  
 (https://www.opennet.ru/docs/RUS/gcc/) (https://www.opennet.ru/docs/RUS/gcc/)
  
-___ +===== Состав компилятора g++ ===== 
-## Состав компилятора g++ + 
-- **cpp** — препроцессор +''cpp'' — препроцессор\\ 
-- **as** — ассемблер +''as'' — ассемблер\\ 
-- **g++** — компилятор +''g++'' — компилятор\\ 
-- **ld** — линкер+''ld'' — линкер 
 + 
 +===== Работа с GCC =====
  
-___ 
-## Работа с GCC 
 (https://www.opennet.ru/docs/RUS/gcc/gcc1-2.html) (https://www.opennet.ru/docs/RUS/gcc/gcc1-2.html)
-#### Общие опции + 
-```shell+==== Общие опции ==== 
 + 
 +<code bash>
 -Dname=value # Определить имя name в компилируемой программе, как значение value. Эффект такой же, как наличие строки #define name value в начале программы -Dname=value # Определить имя name в компилируемой программе, как значение value. Эффект такой же, как наличие строки #define name value в начале программы
 -o filename # Использовать filename в качестве имени для создаваемого файла -o filename # Использовать filename в качестве имени для создаваемого файла
 -Wall # Вывод сообщений о всех предупреждениях или ошибках, возникающих во время компиляции программы -Wall # Вывод сообщений о всех предупреждениях или ошибках, возникающих во время компиляции программы
-``` +</code> 
-#### Остановка на промежуточной стадии + 
-```shell+==== Остановка на промежуточной стадии ==== 
 + 
 +<code bash>
 -E # Остановиться после стадии препроцессирования -E # Остановиться после стадии препроцессирования
 -S # Остановиться после собственно компиляции -S # Остановиться после собственно компиляции
 -c # Компилировать или ассемблировать исходные файлы, но не линковать -c # Компилировать или ассемблировать исходные файлы, но не линковать
-```+</code> 
 Компиляция может включать до четырех стадий: препроцессирование, компиляцию, ассемблирование и линковку (всегда в этом порядке). Первые три стадии **применяются к отдельному** исходному файлу и заканчиваются получением объектного файла; линковка **объединяет все** объектные файлы. Компиляция может включать до четырех стадий: препроцессирование, компиляцию, ассемблирование и линковку (всегда в этом порядке). Первые три стадии **применяются к отдельному** исходному файлу и заканчиваются получением объектного файла; линковка **объединяет все** объектные файлы.
 +
 Для любого имени входного файла суффикс определяет какая компиляция требуется: Для любого имени входного файла суффикс определяет какая компиляция требуется:
-```shell+ 
 +<code bash>
 file.c        # Исходный код на C, который нуждается в препроцессировании. file.c        # Исходный код на C, который нуждается в препроцессировании.
 file.i        # Исходный код на C, который не нуждается в препроцессировании. file.i        # Исходный код на C, который не нуждается в препроцессировании.
Строка 39: Строка 49:
 file.S        # Ассемблерный код, который  нуждается в препроцессировании. file.S        # Ассемблерный код, который  нуждается в препроцессировании.
 другие         # Объектный файл, который нужно отдать прямо на линковку. Так поступают с любым именем файла с нераспознанным суффиксом. другие         # Объектный файл, который нужно отдать прямо на линковку. Так поступают с любым именем файла с нераспознанным суффиксом.
-``` + 
-Так же язык можно указать явно: `-x язык` +</code> 
-Принимаются следующие языки: `c``objective-c`c++`c-header`cpp-output`c++-cpp-output`assembler`assembler-with-cpp` +Так же язык можно указать явно: ''-x язык''\\ 
-#### Опции, которые управляют оптимизацией +Принимаются следующие языки: ''c''''objective-c'' ''c++'' ''c-header'' ''cpp-output'' ''c++-cpp-output'' ''assembler'' ''assembler-with-cpp'' 
-```shell+ 
 +==== Опции оптимизации ==== 
 + 
 +<code bash>
 -O0 # Не оптимизировать -O0 # Не оптимизировать
 -O1 # Оптимизировать. Оптимизированная трансляции требует несколько больше времени и несколько больше памяти для больших функций -O1 # Оптимизировать. Оптимизированная трансляции требует несколько больше времени и несколько больше памяти для больших функций
Строка 50: Строка 63:
  
 # Если вы используете многочисленные -O опции с номерами или без номеров уровня, действительной является последняя такая опция. # Если вы используете многочисленные -O опции с номерами или без номеров уровня, действительной является последняя такая опция.
-```+</code> 
 + 
 +==== Опции управления зависимостями ====
  
-#### Опции управления зависимостями +<code bash>
-```shell+
 -lfoo # Использовать при компоновке динамическую библиотеку foo.so -lfoo # Использовать при компоновке динамическую библиотеку foo.so
 # аналогично для статической библиотеки foo.a # аналогично для статической библиотеки foo.a
Строка 59: Строка 73:
 -Llibpath # Добавить к стандартным каталогам поиска библиотек путь libpath -Llibpath # Добавить к стандартным каталогам поиска библиотек путь libpath
 -Iincludepath # Добавить к стандартным каталогам поиска заголовочных файлов путь includepath -Iincludepath # Добавить к стандартным каталогам поиска заголовочных файлов путь includepath
-```+</code>
  
-Опция `-I/foo/includeне осуществляет сама инклудивание. Она лишь указывает папку, где нужно искать, поэтому нужен ещё и `#include`. То есть нужен и `-I/foo/include`, и `#include`, одного из них недостаточно.  +Опция ''-I/foo/include'' не осуществляет сама инклудивание. Она лишь указывает папку, где нужно искать, поэтому нужен ещё и ''#include''. То есть нужен и ''-I/foo/include'', и ''#include'', одного из них недостаточно.
      
-Линковка. `-L/foo/lib— это указание папки, где нужно искать бинарные файлы библиотеки, т. е. файлы .so и .a. `-lfoo— это указание на то, что нужно, собственно, прилинковать эту библиотеку к результирующему бинарнику. Имя библиотеки, указанное в опции `-lfoo`, соединится с папкой, указанной в `-L/foo/libи получится `/foo/lib/libfoo(в начало названия файла вставляется слово «lib»), затем сюда прибавится .so (или .a) и опционально номер версии и получится `/foo/lib/libfoo.soили, скажем, `/foo/lib/libfoo.so.1`. Это и будет тем именем .so-файла, который будет искаться.  +Линковка. ''-L/foo/lib'' — это указание папки, где нужно искать бинарные файлы библиотеки, т. е. файлы .so и .a. ''-lfoo'' — это указание на то, что нужно, собственно, прилинковать эту библиотеку к результирующему бинарнику. Имя библиотеки, указанное в опции ''-lfoo'', соединится с папкой, указанной в ''-L/foo/lib'' и получится ''/foo/lib/libfoo'' (в начало названия файла вставляется слово «lib»), затем сюда прибавится .so (или .a) и опционально номер версии и получится ''/foo/lib/libfoo.so'' или, скажем, ''/foo/lib/libfoo.so.1''. Это и будет тем именем .so-файла, который будет искаться.  
      
-Так же, как и при компиляции (a.o из a.c), нужны обе опции `-L/foo/libи `-lfoo``-L/foo/libуказывает, где искать. А `-lfooдаёт окончательную команду на прилинковку.+Так же, как и при компиляции (a.o из a.c), нужны обе опции ''-L/foo/lib'' и ''-lfoo''''-L/foo/lib'' указывает, где искать. А ''-lfoo'' даёт окончательную команду на прилинковку. 
 + 
 +Вместо ''-lfoo'' можно прямо написать целиком путь до файла библиотеки, который нужно слинковать, например, ''/foo/lib/libfoo.so.1''. Тогда опция ''-L/foo/lib'' не нужна. Получится так:  
 +''cc -o a a.o /foo/lib/libfoo.so.1'' 
 + 
 +===== Примеры ===== 
 + 
 +==== Простая компиляция ====
  
-Вместо `-lfoo` можно прямо написать целиком путь до файла библиотеки, который нужно слинковать, например, `/foo/lib/libfoo.so.1`. Тогда опция `-L/foo/lib` не нужна. Получится так:  
-`cc -o a a.o /foo/lib/libfoo.so.1` 
-___ 
-## Примеры 
-#### Простая компиляция 
 Чтобы скомпилировать исходный код, необходимо компилятору gcc передать в качестве параметра исходный код (файл hello.cpp): Чтобы скомпилировать исходный код, необходимо компилятору gcc передать в качестве параметра исходный код (файл hello.cpp):
  
-```shell+<code bash>
 g++ hello.cpp -o prog g++ hello.cpp -o prog
-```+</code>
  
-Дополнительный необязательный параметр `-o progуказывает, что скомпилированный файл будет называться prog.exe. Если не указать этот параметр, то файл будет называться по умолчанию - a.exe.+Дополнительный необязательный параметр ''-o prog'' указывает, что скомпилированный файл будет называться prog.exe. Если не указать этот параметр, то файл будет называться по умолчанию - a.exe.
  
-#### Отдельная компиляция+==== Отдельная компиляция ====
  
 C++ допускает раздельную компиляцию, а это означает, что каждый исходный файл может быть независимо скомпилирован в объектный файл. Эти объектные файлы затем можно соединить вместе, чтобы сформировать окончательный исполняемый файл. Это обеспечивает более быстрое время сборки при внесении изменений в один исходный файл, поскольку необходимо перекомпилировать только этот файл, а другие объектные файлы можно использовать повторно. C++ допускает раздельную компиляцию, а это означает, что каждый исходный файл может быть независимо скомпилирован в объектный файл. Эти объектные файлы затем можно соединить вместе, чтобы сформировать окончательный исполняемый файл. Это обеспечивает более быстрое время сборки при внесении изменений в один исходный файл, поскольку необходимо перекомпилировать только этот файл, а другие объектные файлы можно использовать повторно.
Строка 86: Строка 102:
 Пример раздельной компиляции и компоновки: Пример раздельной компиляции и компоновки:
  
-```shell+<code bash>
 # Скомпилируем исходные файы в объектные файлы # Скомпилируем исходные файы в объектные файлы
 g++ -c main.cpp -o main.o g++ -c main.cpp -o main.o
Строка 93: Строка 109:
 # Линкуем объектные файлы вместе, чтобы создать исполняемый файл # Линкуем объектные файлы вместе, чтобы создать исполняемый файл
 g++ main.o funcs.o -o my_program g++ main.o funcs.o -o my_program
-``` +</code> 
-#### Создание статической библиотеки + 
-Допустим, у нас есть исходники с реализациями функций `first.cpp``second.cppи заголовочник `libmy.hс объявлением ф-ий из исходников. Скомпилируем и заархивируем: +==== Создание статической библиотеки ==== 
-```shell+ 
 +Допустим, у нас есть исходники с реализациями функций ''first.cpp''''second.cpp'' и заголовочник ''libmy.h'' с объявлением ф-ий из исходников. Скомпилируем и заархивируем: 
 + 
 +<code bash>
 # компилируем # компилируем
 gcc -c first.cpp -o first.o gcc -c first.cpp -o first.o
Строка 104: Строка 123:
 # проверим: # проверим:
 file libmy.a # вывод: libmy.a: current ar archive file libmy.a # вывод: libmy.a: current ar archive
-``` +</code> 
-архиватор ar - утилита "склеивает" несколько файлов в один, не сжимая их содержимое. + 
-`-c <filename>`: создать архив, если архив с именем "filename" не существует он будет создан, в противном случае файлы будут добавлены к имеющемуся архиву. +архиватор ar - утилита "склеивает" несколько файлов в один, не сжимая их содержимое.\\ 
-`-r`: Pадает режим обновления архива, если в архиве файл с указанным именем уже существует, он будет удален, а новый файл дописан в конец архива. +''-c <filename>'': создать архив, если архив с именем "filename" не существует он будет создан, в противном случае файлы будут добавлены к имеющемуся архиву.\\ 
-`-s`: Добавляет (обновляет) индекс архива. В данном случае индекс архива это таблица, в которой для каждого определенного в архивируемых файлах символического имени (имени функции или блока данных) сопоставлено соответствующее ему имя объектного файла. Индекс архива необходим для ускорения работы с библиотекой - для того чтобы найти нужное определение, отпадает необходимость просматривать таблицы символов всех файлов архива, можно сразу перейти к файлу, содержащему искомое имя. Просмотреть индекс архива можно с помощью уже знакомой утилиты nm воспользовавшись её опцией `-s`.+''-r'': Pадает режим обновления архива, если в архиве файл с указанным именем уже существует, он будет удален, а новый файл дописан в конец архива.\\ 
 +''-s'': Добавляет (обновляет) индекс архива. В данном случае индекс архива это таблица, в которой для каждого определенного в архивируемых файлах символического имени (имени функции или блока данных) сопоставлено соответствующее ему имя объектного файла. Индекс архива необходим для ускорения работы с библиотекой - для того чтобы найти нужное определение, отпадает необходимость просматривать таблицы символов всех файлов архива, можно сразу перейти к файлу, содержащему искомое имя. Просмотреть индекс архива можно с помощью уже знакомой утилиты nm воспользовавшись её опцией ''-s''. 
 + 
 +Для создания индекса архива существует специальная утилита ranlib. Библиотеку libmy.a можно было сотворить и так:
  
-Для создания индекса архива существует специальная утилита ranlib. Библиотеку libmy.a можно было сотворить и так:   +<code bash>
-```shell+
 ar cr libmy.a first.o second.o   ar cr libmy.a first.o second.o  
 ranlib libmy.a ranlib libmy.a
-```+</code> 
 Впрочем библиотека будет прекрасно работать и без индекса архива. Впрочем библиотека будет прекрасно работать и без индекса архива.
-#### Подключение статической библиотеки + 
-Допустим, у нас есть файл `main.cpp, содержащий `#include "libmy.h"`. Соберём (компиляция+линковка) программу: +=== Подключение статической библиотеки === 
-```shell+ 
 +Допустим, у нас есть файл ''main.cpp'' , содержащий ''#include "libmy.h"''. Соберём (компиляция+линковка) программу: 
 + 
 +<code bash>
 gcc -Wall -c main.c # компиляция программы gcc -Wall -c main.c # компиляция программы
 gcc -o mainprog main.o -L. -llibmy # линковка программы вместе с архивом с реализациями функций gcc -o mainprog main.o -L. -llibmy # линковка программы вместе с архивом с реализациями функций
-``` +</code> 
-Повторю:  + 
-`-L/путь/к/каталогу/с/библиотекамиуказывает путь к каталогу содержащему подключаемые библиотеки. +Повторю:\\ 
-`-l<name>имя библиотеки задается как "name" без приставки "lib" +''-L/путь/к/каталогу/с/библиотеками'' указывает путь к каталогу содержащему подключаемые библиотеки.\\ 
 +''-l<name>'' имя библиотеки задается как "name" без приставки "lib" 
  
-%% 
 Компиляция либы: Компиляция либы:
-```cpp+<code cpp>
 // компиляция lib.cpp в объектный файл // компиляция lib.cpp в объектный файл
 g++ -c lib.cpp -o lib.o g++ -c lib.cpp -o lib.o
 // архивируем в статическую библиотеку // архивируем в статическую библиотеку
 ar rcs libmylib.a lib.o ar rcs libmylib.a lib.o
-```+</code> 
 Использование либы: Использование либы:
-```cpp+<code cpp>
 // компилим файл main с подключением либы // компилим файл main с подключением либы
 g++ main.cpp -o prog -L. -lmylib g++ main.cpp -o prog -L. -lmylib
-```+</code>
 Здесь: Здесь:
-`-L .указывает компилятору искать библиотеку в текущем каталоге. +''-L .'' указывает компилятору искать библиотеку в текущем каталоге. 
-`-lmylibговорит компилятору использовать библиотеку `libmylib.a`.+''-lmylib'' говорит компилятору использовать библиотеку ''libmylib.a''.
  
-Эти шаги создадут исполняемый файл `prog`, содержащий код из `main.cpp`, а также функции из вашей статической библиотеки `libmylib.a`.+Эти шаги создадут исполняемый файл ''prog'', содержащий код из ''main.cpp'', а также функции из вашей статической библиотеки ''libmylib.a''.
  
-Если вы хотите создать динамическую библиотеку, то процесс будет немного отличаться. Для этого вместо создания статической библиотеки (`libmylib.a`) вы создадите разделяемую библиотеку (`libmylib.soили `.dllв зависимости от вашей операционной системы и компилятора) и при компиляции программы вместо флага `-lmylibвы будете использовать флаг `-lmylib.soили `-lmylib.dll`, соответственно. +Если вы хотите создать динамическую библиотеку, то процесс будет немного отличаться. Для этого вместо создания статической библиотеки (''libmylib.a'') вы создадите разделяемую библиотеку (''libmylib.so'' или ''.dll'' в зависимости от вашей операционной системы и компилятора) и при компиляции программы вместо флага ''-lmylib'' вы будете использовать флаг ''-lmylib.so'' или ''-lmylib.dll'', соответственно. 
-%%+ 
 + 
 +==== Создание динамической библиотеки ====
  
-#### Создание динамической библиотеки 
 Набор исходных файлов аналогичен примеру сверху. Набор исходных файлов аналогичен примеру сверху.
-```shell+ 
 +<code bash>
 gcc -fPIC -c first.cpp gcc -fPIC -c first.cpp
 gcc -fPIC -c second.cpp gcc -fPIC -c second.cpp
 gcc -shared -o libhello.so.2.4.0.5 -Wl,-soname,libhello.so.2 first.o second.o gcc -shared -o libhello.so.2.4.0.5 -Wl,-soname,libhello.so.2 first.o second.o
-``` +</code> 
-`-fPIC- требует от компилятора, при создании объектных файлов, порождать позиционно-независимый код (PIC - Position Independent Code), его основное отличие в способе представления адресов. Вместо указания фиксированных (статических) позиций, все адреса вычисляются исходя из смещений заданных в глобальной таблицы смещений (global offset table - GOT). Формат позиционно-независимого кода позволяет подключать исполняемые модули к коду основной программы в момент её загрузки. Соответственно, основное назначение позиционно-независимого кода - создание динамических (разделяемых) библиотек. + 
-`-shared- указывает `gcc`, что в результате должен быть собран не исполняемый файл, а "разделяемый объект" - динамическая библиотека. +''-fPIC'' - требует от компилятора, при создании объектных файлов, порождать позиционно-независимый код (PIC - Position Independent Code), его основное отличие в способе представления адресов. Вместо указания фиксированных (статических) позиций, все адреса вычисляются исходя из смещений заданных в глобальной таблицы смещений (**g**lobal **o**ffset **t**able - GOT). Формат позиционно-независимого кода позволяет подключать исполняемые модули к коду основной программы в момент её загрузки. Соответственно, основное назначение позиционно-независимого кода - создание динамических (разделяемых) библиотек.\\ 
-`-Wl- Обычно, компилятор сам вызывает линковщик и передает ему параметры по своему усмотрению. Этот параметр позволяет передать линковщику опции руками. Общий вид: `gcc -Wl,-option,value1,value2...что означает передать линковщику (`-Wl`) опцию `-optionс аргументами `value1, value2`+''-shared'' - указывает ''gcc'', что в результате должен быть собран не исполняемый файл, а "разделяемый объект" - динамическая библиотека.\\ 
-`-soname- опция линковщика (передаваемая через `-W`... ==надо дописать, но не здесь, а выше==+''-Wl'' - Обычно, компилятор сам вызывает линковщик и передает ему параметры по своему усмотрению. Этот параметр позволяет передать линковщику опции руками. Общий вид: ''gcc -Wl,-option,value1,value2...'' что означает передать линковщику (''-Wl'') опцию ''-option'' с аргументами ''value1, value2''.\\ 
 +''-soname'' - опция линковщика (передаваемая через ''-W''{{fixme}}
  
-(https://uzverss.livejournal.com/57883.html) +([[https://uzverss.livejournal.com/57883.html]]
-#### Подключение динамической библиотеки +=== Подключение динамической библиотеки === 
-#недописанное +{{fixme}}