Сделать: Приоритет -L (или: Игнорировать содержимое, доставляемое pkg-config)

#makefile #pkg-config

Вопрос:

Я хочу в make библиотеку, которая зависит от других библиотек.

Мне удалось получить доступ к make статическим .a файлам зависимостей, и они вместе с заголовочными файлами легко доступны в каталоге. Их просмотр file подтверждает, что я успешно скомпилировал их для всех архитектур.

Когда я пытаюсь создать окончательную библиотеку, она говорит мне

ld: warning: ignoring file /usr/local....dylib, building for architecture-A but attempting to link with file built for architecture-B

Правильно, что библиотека по указанному пути скомпилирована только для архитектуры хоста A (устанавливается через диспетчер пакетов). Тем не менее, в LDFLAGS папке у меня есть -L${libdir}/libs (папка, в которой находятся библиотеки), но make , похоже, заботятся только о тех, которые находятся в моей usr/local/.. папке.

Есть ли другие способы специально указать make на проверку {libdir}/libs папки или даже заставить make игнорировать пути, из pkg-config которых она сначала выполняет поиск там, находит неподходящие файлы и никогда не попробует те, которые я передал в своем LDFLAGS ?

Ответ №1:

Ты пишешь …

Мне удалось создать статические файлы зависимостей .a и сделать их вместе с файлами заголовков доступными в каталоге.

… но это, вероятно, не имеет значения, потому что вы, похоже, пытаетесь создать общую (т. Е. динамическую) библиотеку. Статические библиотеки и общие библиотеки не очень хорошо сочетаются.

Есть ли другие способы специально указать make на проверку {libdir}/libs папки или даже заставить make игнорировать пути, из pkg-config которых она сначала выполняет поиск там, находит неподходящие файлы и никогда не попробует те, которые я передал в своем LDFLAGS ?

Вы фокусируетесь на make чем-то , но make не имеете к этому особого отношения. Это компоновщик, а не make тот , кто выполняет поиск и фактическую ссылку. make просто выполняет команду link, которую вы ей велели выполнить.

Но да, вы можете управлять порядком поиска библиотеки компоновщика, управляя порядком его параметров командной строки. Каталоги библиотек, указанные с помощью -L параметров, ищутся в том порядке, в котором они отображаются в командной строке, и все они находятся перед каталогами библиотек компоновщика по умолчанию.* Если обеспечение правильного порядка аргументов не приведет вас к нужной ссылке, то, скорее всего, это связано с тем, что компоновщик игнорирует ваши статические библиотеки, пытаясь создать динамическую.

Однако вы должны быть в состоянии полностью обойти поиск, указав полный путь и имя файла библиотеки, которую вы хотите связать, вместо использования -L или -l параметров. Например, вместо -L/path/to -lfoo , вы могли бы использовать /path/to/libfoo.dylib (или /path/to/libfoo.a ). Обычно вы не хотите жестко кодировать пути таким образом, но в этом случае это может служить диагностической цели.

Обратите также внимание, что редко рекомендуется связываться с динамическими библиотеками, которые не установлены в их предполагаемом местоположении, особенно если библиотеки не являются частью одного и того же проекта. Поначалу может показаться, что это работает нормально, но это приводит к проблемам с поиском библиотек во время выполнения (и динамические библиотеки тоже нужно находить во время выполнения). То же самое не относится к статическим библиотекам, но у этого есть свой набор преимуществ и недостатков.


* Это еще не все, но этот ответ уже длинный. Прочитайте документы компоновщика, если хотите получить более подробную информацию.

Комментарии:

1. Благодаря вашему намеку относительно ввода полного пути я понял, что компоновщик действительно видел файлы .a. Оказывается, один из пакетов создает несколько библиотек — как только я принял это во внимание при повторном создании зависимости, это не вызвало дальнейших проблем с «окончательной» библиотекой. Все статично, кстати, ничего динамичного, если под динамикой вы подразумеваете .so . Что касается ваших заявлений — каков был бы рекомендуемый способ действий здесь? Установка пакетов оставляет меня только с архитектурой моей системы — как бы вы указали компоновщику, например, на исходные файлы, чтобы я не

2. нужно ли компилировать все зависимости для целевых архитектур перед компиляцией библиотеки, которая мне действительно нужна? Есть ли способ настроить make/link/build таким образом, чтобы он просматривал и компилировал исходные файлы зависимостей и создавал их перед созданием окончательной библиотеки вместо того, чтобы ожидать скомпилированных зависимостей в папке lib? Например, создавать зависимости из исходного кода вместо доступа к их скомпилированным состояниям?

3. @user2161301, в сообщении об ошибке, которое вы представили в вопросе, упоминается библиотека, заканчивающаяся на dylib . Это соглашение Mac для именования общих (также называемых динамическими) библиотек. Если вы думаете, что создаете только статические библиотеки, то что-то не складывается. Но если вы действительно создаете только статические библиотеки и исполняемые файлы, то единственная проблема со связыванием этих библиотек-это их поиск.

4. Что касается создания только нужной вам архитектуры(ов), то для системы сборки далеко не обычно создавать что-либо, кроме собственной архитектуры узла сборки, особенно без явного запроса на это. И еще более необычно, когда система сборки компилируется для нескольких архитектур в одной сборке. Если вы работаете с проектами, которые делают такие странные вещи, вам нужны советы, адаптированные к этим конкретным проектам.