Найти все символы в каталоге

Я хочу выяснить, какую библиотеку 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

С этим связаны два вопроса:

  1. Есть ли более простой способ найти символы в пакете файлов (некоторые из которых не являются файлами elf)? Например, что-то вроде objdump -t *? Или что ближе всего к этому?
  2. Есть ли лучший способ узнать, какова ценность библиотеки -l<library>? Или, как обычно, когда кто-то загружает новую программу C, он знает, что добавить в свою командную строку, чтобы программа работала? (Что касается меня, я только что потратил последний час, выясняя, что это -lpcre2-8, а не -lpcre или -lpcre2.

Документация библиотеки обычно должна включать эту информацию.

Barmar 09.04.2021 23:48

Обычно пакеты поставляются с README или другой документацией, в которой описывается, на что нужно ссылаться.

kaylum 09.04.2021 23:48
gcc myfile.c -lpcre2-8 -0 myfile; ./myfile -> gcc myfile.c -lpcre2-8 -o myfile; ./myfile. -0 («ноль тире») является допустимым нет. Вы хотите, чтобы -o («тире o») создавал исполняемый файл с именем «myfile».
Craig Estey 10.04.2021 00:10

@CraigEstey Да ладно, извините, это была опечатка.

David542 10.04.2021 00:48

Иногда вы можете использовать pkg-config, например. pkg-config --libs pcre.

Olaf Dietsche 10.04.2021 00:59

При нормальной полной установке файлы .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, чтобы увидеть, какие каталоги проверяются.

Craig Estey 10.04.2021 03:04

@OlafDietsche Понятно, спасибо за предложение. Это очень хорошо работает с $ pkg-config --list-all | grep pcre, но если я сделаю это как --libs pcre, он скажет, что пакет не найден. Как мне заставить pkg-config распознавать pcre?

David542 10.04.2021 04:55

@CraigEstey, да, это был каталог build. Для установки сделал: $ mkdir build; cd build; cmake ../; make; sudo make install. Что касается опций I, l и L (к сожалению, все они выглядят одинаково ...) l ссылается на файл, L делает то же самое, но для каталога, который затем ищет файл там, а затем зачем нужен I?

David542 10.04.2021 05:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
40
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обычно функция, которую вы вызываете из библиотеки, будет символом, определенным этой библиотекой. Но в 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-config returns 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.

[...]

--libs8 Writes to the standard output the command line options required to link with the 8-bit PCRE2 library (-lpcre2-8 on many systems).

[...]

--cflags Writes to the standard output the command line options required to compile files that use PCRE2 (this may include some -I options, but is blank on many systems).

Итак, для этой конкретной библиотеки рекомендуемый способ сборки и компоновки:

gcc -c $(pcre2-config --cflags) test.c -o test.o
gcc test.o -o test $(pcre2-config --libs8)

Другие вопросы по теме