При установке компилятора стандартные файлы заголовков и библиотеки также устанавливаются в известные места. Например, в системе Linux или Unix стандартные заголовки обычно устанавливаются под /usr/include
или /usr/local/include
, а стандартные библиотеки обычно устанавливаются под /usr/lib
или /usr/local/lib
.
Когда вы #include
заголовочный файл, компилятор будет искать его в разных местах в зависимости от того, используете ли вы угловые скобки (#include <stdio.h>
) или кавычки (#include "myfile.h"
). Например, если вы включите файл заголовка в угловые скобки, gcc
будет искать этот заголовок в следующих каталогах:
/usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include
Если вы включаете заголовочный файл с кавычками, gcc
сначала будет искать в текущем рабочем каталоге, затем в дополнительных каталогах, как указано в параметрах командной строки, и, наконец, в стандартных путях включения, указанных выше.
Большинство компиляторов позволяют указать дополнительные пути включения в качестве аргументов для команды компиляции, например
gcc -o executable-name -I /additional/include/path source-files
Но иногда .h отсутствует:
#include <iostream>
Это соглашение C++1; Стандартные заголовки C++ не имеют расширения .h
, я полагаю, чтобы оно выглядело более объектно-ориентированным, чем оно есть на самом деле (то есть вы можете притвориться, что импортируете класс напрямую, а не включаете текст файла, описывающего класс).
Я уже знаю, что заголовочный файл содержит только сигнатуры функций и некоторые команды препроцессора. Но когда и как компилятор включает математические функции, если я включаю math.h?
Реализации математических функций обычно хранятся в отдельной библиотеке (код, который уже скомпилирован и заархивирован в один двоичный файл); в зависимости от компилятора математическая библиотека может или не может быть автоматически связана с исполняемым файлом. Например, gcc
не связывается автоматически ни с одной функцией математической библиотеки, даже если вы включаете заголовочный файл math.h
. Вы должны явно включить математическую библиотеку как часть команды сборки:
gcc -o executable-name command-line-options source-files -lm
При использовании gcc
соглашение заключается в том, что -lname
ссылается на библиотеку с именем libname.a
2. Стандартный файл математической библиотеки называется libm.a
, поэтому -lm
сообщает gcc
, что следует связать машинный код, содержащийся в libm.a
.
Как и стандартные заголовки, компилятор будет искать стандартные библиотеки в известных местах. Вы можете указать дополнительные пути поиска для библиотек, которые не входят в стандартную установку, например:
gcc -o executable-name command-line-options source-files -L /additional/library/path -ladditional-library
Если я создам библиотеку, то куда положить файлы .c/.cpp/.h и как их подключить?
Вы можете поместить файлы куда угодно; вы укажете, где они находятся, как часть команды сборки. Итак, скажем, вы создаете новую библиотеку с именем mylib
. Вы создаете новый каталог в своем домашнем каталоге:
mkdir ~/mylib
cd ~/mylib
Затем вы создаете и редактируете свои исходные файлы и заголовки:
cd ~/mylib
vi mylib.h
vi mylib.c
Чтобы собрать mylib
как статическую библиотеку, сделайте следующее:
cd ~/mylib
gcc -c mylib.c
ar libmylib.a mylib.o
Итак, когда вы закончите, каталог ~/mylib
будет содержать следующее:
libmylib.a
mylib.c
mylib.h
mylib.o
Чтобы использовать функции, собранные в mylib
, в программе, вы должны указать пути включения заголовка и библиотеки как часть команды компиляции:
gcc -o executable-name command-line-options source-files -I ~/mylib -L ~/mylib -lmylib
Таким образом, если вы include "mylib.h"
в другой программе, это скажет компилятору искать этот заголовок в ~/mylib
, и он сообщит компоновщику, что библиотека libmylib.a
будет найдена в ~/mylib
.
В реальной ситуации вы бы обрабатывали все сборки с помощью make-файлов, а не собирали все вручную. Вы также, вероятно, настроили бы его так, чтобы в процессе сборки все заголовки, которые кому-либо еще понадобятся для использования вашей библиотеки, копировались в отдельный подкаталог include
, а библиотека записывалась в отдельный подкаталог lib
, чтобы вы могли распространять свою библиотеку, не раскрывая исходный код. В этом случае приведенная выше команда сборки будет выглядеть примерно так:
gcc -o executable-name command-line-options source-files -I ~/mylib/include -L ~/mylib/lib -lmylib
1. Так было не всегда; самые ранние реализации C++ использовали iostream.h
, vector.h
и т. д. Я не уверен, когда именно это соглашение изменилось, но это было давно.
2. На самом деле, я больше не уверен, является ли это gcc
конвенция или *nix
конвенция; эти двое были соединены на бедре так долго, что иногда трудно вспомнить.
person
John Bode
schedule
18.11.2015