Как компилятор C находит, что -lm указывает на файл libm.a?
Что такое.a файлы в программировании на C в Linux? Это библиотечный файл?
To merge with the math library libm.a you would type
cc -o program_name prog.c -lm
when you compile the program. The -lm means: add in libm. If we wanted to add in the socket library libsocket.a to do some network programming as well, we would type
cc -o program_name prog.c -lm -lsocket
and so on.
Вот как компилятор находит, что -lm указывает на файл libm.a, а -lsocket как libsocket.a?
И если мы добавим файл заголовка в программу, мы должны упомянуть библиотеку при компиляции?
4 ответа
Как говорит Игнасио, файлы.a являются статическими библиотеками. "A" означает "архив", а файлы.a создаются программой с именем "ar".
Каждый файл.a содержит один или несколько файлов.o и индекс имен. В процессе компоновки в конечную программу включаются только файлы.o, которые содержат используемые имена. Это связано с тем, что вместо включения всей библиотеки C копируются только используемые функции, такие как "printf".
Как компилятор находит библиотеки? Он имеет встроенную коллекцию путей поиска библиотек. Например, GCC сообщит вам пути поиска, если их спросят:
# gcc -print-search-dirs
install: /usr/lib/gcc/i686-redhat-linux/4.4.4/
programs: =/usr/libexec/gcc/i686-redhat-linux/4.4.4/:/usr/libexec/gcc/i686-redhat-linux/4.4.4/:/usr/libexec/gcc/i686-redhat-linux/:/usr/lib/gcc/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/:/usr/libexec/gcc/i686-redhat-linux/4.4.4/:/usr/libexec/gcc/i686-redhat-linux/:/usr/lib/gcc/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../i686-redhat-linux/bin/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../i686-redhat-linux/bin/
libraries: =/usr/lib/gcc/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../i686-redhat-linux/lib/i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../i686-redhat-linux/lib/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../i686-redhat-linux/4.4.4/:/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../:/lib/i686-redhat-linux/4.4.4/:/lib/:/usr/lib/i686-redhat-linux/4.4.4/:/usr/lib/
Вы можете добавить дополнительные пути поиска в библиотеке, используя опцию "-L /path".
В этих путях он сначала ищет "динамические библиотеки", имена которых имеют расширение ".so". Затем он ищет статические библиотеки с расширением ".a". Он всегда добавляет "lib" в начале имени.
.a
файлы являются статическими библиотеками, в отличие от .so
файлы, которые являются динамическими библиотеками. Обычно gcc ищет динамические библиотеки, если они доступны, если не переданы -static
,
Заголовок содержит определения, которые нужны компилятору для встраивания исходного кода в объектный файл, но библиотеки содержат фактические процедуры, необходимые компоновщику для превращения объектного файла в исполняемый файл.
Компилятор "знает" искать libm.a (или libm.so), когда вы передаете ему опцию -lm
потому что так -l
опция задокументирована и реализована: взять следующие символы -l
(вот только m
), префикс lib
и суффикс .a
получить libm.a
Каждая библиотека может иметь свое собственное отношение между заголовочными файлами и используемыми библиотечными файлами. Для файла заголовка не требуется вообще никакой библиотеки, но для библиотеки более характерно иметь несколько файлов заголовка.
Это может работать из-за соглашения GNU. Когда разработчик выпускает библиотеку (статическую или разделяемую), согласно соглашению, имя библиотеки должно быть:
lib + name of library + .a(or .so)
GCC также работает с этим соглашением. Так что вариант-lm
означает, что вы хотите связать библиотеку с именемm
. Таким образом, имя файла библиотекиlibm.a
(илиlibm.so
).
Понимание соглашения GNU может упростить вашу разработку.