Я хочу выяснить, какую библиотеку C включить при компиляции программы, которая включает ее в качестве заголовка, в данном случае #include <pcre2.h>. Единственный способ выяснить, где находится файл, - это проверить наличие определенного символа, который, как я знаю, необходимо экспортировать. Например:
$ ls
CMakeCache.txt Makefile install_manifest.txt libpcre2-posix.pc pcre2_grep_test.sh
CMakeFiles a.out libpcre2-8.a pcre2-config pcre2_test.sh
CTestCustom.ctest cmake_install.cmake libpcre2-8.pc pcre2.h pcre2grep
CTestTestfile.cmake config.h libpcre2-posix.a pcre2_chartables.c pcre2test
$ objdump -t libpcre2-8.a|grep pcre2_compile
pcre2_compile.c.o: file format elf64-x86-64
0000000000000000 l df *ABS* 0000000000000000 pcre2_compile.c
00000000000100bc g F .text 00000000000019dd pcre2_compile_8
0000000000000172 g F .text 00000000000000e3 pcre2_compile_context_create_8
0000000000000426 g F .text 0000000000000055 pcre2_compile_context_copy_8
0000000000000557 g F .text 0000000000000032 pcre2_compile_context_free_8
И поскольку символ pcre2_compile_8 существует в этом файле (после проверки каждого другого файла ...), я знаю, что библиотека, которую мне нужно включить, - это pcre2-8, то есть я компилирую свой код с помощью:
$ gcc myfile.c -lpcre2-8 -o myfile; ./myfile
С этим связаны два вопроса:
objdump -t *? Или что ближе всего к этому?-l<library>? Или, как обычно, когда кто-то загружает новую программу C, он знает, что добавить в свою командную строку, чтобы программа работала? (Что касается меня, я только что потратил последний час, выясняя, что это -lpcre2-8, а не -lpcre или -lpcre2.Обычно пакеты поставляются с README или другой документацией, в которой описывается, на что нужно ссылаться.
gcc myfile.c -lpcre2-8 -0 myfile; ./myfile -> gcc myfile.c -lpcre2-8 -o myfile; ./myfile. -0 («ноль тире») является допустимым нет. Вы хотите, чтобы -o («тире o») создавал исполняемый файл с именем «myfile».
@CraigEstey Да ладно, извините, это была опечатка.
При нормальной полной установке файлы .h попадают (например) в /usr/include/local, а .a или .so идут в /usr/local/lib64. Итак, ваш ls показывает, что они находятся в том же каталоге, как и каталог, в котором вы делаете make? Если вам не нужно / вы не хотите устанавливать, вы можете сделать (например) pcdir=/home/me/pcre_build_directory ; gcc myfile.c -I $pcdir -L $pcdir -lpcre2-8 -o myfile. Иногда лучше указать -lwhatever в качестве аргумента последний для gcc. Вы также можете запустить gcc под strace, чтобы увидеть, какие каталоги проверяются.
@OlafDietsche Понятно, спасибо за предложение. Это очень хорошо работает с $ pkg-config --list-all | grep pcre, но если я сделаю это как --libs pcre, он скажет, что пакет не найден. Как мне заставить pkg-config распознавать pcre?
@CraigEstey, да, это был каталог build. Для установки сделал: $ mkdir build; cd build; cmake ../; make; sudo make install. Что касается опций I, l и L (к сожалению, все они выглядят одинаково ...) l ссылается на файл, L делает то же самое, но для каталога, который затем ищет файл там, а затем зачем нужен I?





Обычно функция, которую вы вызываете из библиотеки, будет символом, определенным этой библиотекой. Но в PCRE2 из-за разных размеров кодовых единиц вызываемая вами функция (например, pcre2_compile) фактически становится другим символом через макросы препроцессора (например, pcre2_compile_8). Вы можете найти нужный символ в библиотеке, скомпилировав свою программу и проверив неопределенные символы:
$ cat test.c
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
int main() {
pcre2_compile("",0,0,NULL,NULL,NULL);
}
$ gcc -c test.c
$ nm -u test.o
U _GLOBAL_OFFSET_TABLE_
U pcre2_compile_8
Is there a simpler way to find a symbols in a batch of files?
Вы можете выполнить поиск в каталоге (/usr/lib/ ниже) для файлов библиотеки (.a или расширение .so ниже), запустив nm для каждого и поиск неопределенного символа (адаптированного из этот вопрос):
$ for lib in $(find /usr/lib/ -name \*.a -o -name \*.so)
> do
> nm -A --defined-only $lib 2>/dev/null| grep pcre2_compile_8
> done
/usr/lib/x86_64-linux-gnu/libpcre2-8.a:libpcre2_8_la-pcre2_compile.o:0000000000007f40 T pcre2_compile_8
Is there a better way to find out what the library value of -l is?
Обычно это передается через документацию библиотеки. Для PCRE2 вторая страница документации говорит об инструменте pcre-config, который выдает соответствующие флаги:
pcre2-configreturns the configuration of the installed PCRE2 libraries and the options required to compile a program to use them. Some of the options apply only to the 8-bit, or 16-bit, or 32-bit libraries, respectively, and are not available for libraries that have not been built.[...]
--libs8Writes to the standard output the command line options required to link with the 8-bit PCRE2 library (-lpcre2-8on many systems).[...]
--cflagsWrites to the standard output the command line options required to compile files that use PCRE2 (this may include some-Ioptions, but is blank on many systems).
Итак, для этой конкретной библиотеки рекомендуемый способ сборки и компоновки:
gcc -c $(pcre2-config --cflags) test.c -o test.o
gcc test.o -o test $(pcre2-config --libs8)
Документация библиотеки обычно должна включать эту информацию.