Как динамически находить и включать библиотеки - PullRequest
0 голосов
/ 30 апреля 2019

У меня есть библиотека, в которой я разрабатываю конфигурацию и make-файлы для использования пакета Autotools.Для библиотеки требуется внешняя библиотека (в частности, fftw3) в системе, в которой она компилируется, и я хочу, чтобы Autoconf / Automake автоматически находил и связывал / включал внешнюю библиотеку до / при компиляции (либо в configure.ac, либо в Makefile.am).

В настоящее время я просто использую флаги autoconf "--with-" для пользователя, чтобы указать расположение как файла библиотеки, так и папки include внешней библиотеки в своей системе, но это кажется такой проблемойдля пользователя.Библиотека, для которой я создаю файл конфигурации и make-файлы, будет развернута в различных общих системах, поэтому сложно предположить, что необходимая внешняя библиотека всегда будет находиться в одном и том же месте.

Каков наилучший способ для этого?

Ответы [ 2 ]

1 голос
/ 30 апреля 2019

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

AC_CHECK_LIB([fftw3], [fftw_plan_dft])

Это признает, что libfftw3 доступно в пути поиска, если это действительно так, и в этом случае добавит соответствующий параметр ссылки к переменной LIBS и определит HAVE_LIBFFTW3.

Проблема возникает только в том случае, если вы хотите предоставить для использования библиотеки, которых нет в пути поиска компоновщика по умолчанию, или если ранее в этом пути была найдена другая версия библиотеки. Это случай для предоставления --with-foo опций, с помощью которых строитель может указать местоположение. Но обратите внимание, что это несколько особая проблема, по крайней мере, при компоновке с динамическими библиотеками, поскольку библиотеки dev обычно устанавливаются вместе с библиотеками времени выполнения, и если статическая компоновщик не находит dev lib во время сборки, то обычно вам нужно немного своего рода специальное условие для динамической компоновки, которая будет найдена динамической компоновщиком во время выполнения.

Тем не менее, если вы хотите проверить список возможных местоположений библиотеки, закодированных в configure, то это можно сделать относительно легко. Сгенерированный configure является сценарием оболочки, и вы можете без проблем записать буквальный код для него в свой configure.ac. Например,

# Preserve the original value of LIBS
LIBS_save=$LIBS

# This is how we will report out the result
FFTW3_LIBS=

# Check the default locations first
AC_CHECK_LIB([fftw3], [fftw_plan_dft], [
  # libfftw3 found in the library search path
  FFTW3_LIBS=-lfftw3
], [
  # libfftw3 not found in the library search path; try some other paths
  # make the linker search the chosen path by adding an `-L` option to the LDFLAGS
  LDFLAGS_save=$LDFLAGS
  for fftw_libdir in
      /usr/lib/fftw
      /usr/lib/fftw3
      /usr/local/lib/fftw3
  do
    LDFLAGS="${LDFLAGS_save} -L${fftw_libdir}"
    AC_CHECK_LIB([fftw3], [fftw_plan_dft], [
      # library found
      FFTW3_LIBS="-L${fftw_libdir} -lfftw3"
      break
    ])
  done

  # restore the original LDFLAGS
  LDFLAGS=$LDFLAGS_save
])

# restore the original LIBS
LIBS=$LIBS_save

AS_IF([test x = "x${FFTW3_LIBS}"], [
  # configure fails if it does not find libfftw3
  AC_MSG_ERROR([libfftw3 not found])
])

# Make FFTW3_LIBS an output variable
AC_OUTPUT([FFTW3_LIBS])

Известные характеристики этого кода включают

  • сохранение и восстановление переменных, используемых configure при выполнении тестов (LDFLAGS) и создание отчетов о результатах (LIBS)
  • использование цикла оболочки для проверки различных параметров
  • с использованием действий при успехе / при ошибке AC_CHECK_LIB
    • понимая, что AC_CHECK_LIB - это макрос , а не функция, поэтому, например, вы можете поместить break в его параметры, которые будут выходить из цикла, в котором используется AC_CHECK_LIB
  • использование выходной переменной для отчета о результате в виде набора параметров ссылки. Вы можете использовать это в своем Makefile.am, добавив $(FFTW3_LIBS) к соответствующей переменной *LIBADD или *LDADD. (Или, если вы не используете Automake, добавьте его в команду ссылки любым подходящим способом.)

Конечно, вы можете комбинировать это с использованием опции --with-foo для поддержки случаев, которые вы не ожидаете (оставлено в качестве упражнения).

0 голосов
/ 19 июня 2019

Поскольку fftw3 появляется для установки *.pc файлов, я бы использовал макросы на основе pkg-config в configure.ac аналогично

PKG_CHECK_MODULES([FFTW3], [fftw3])

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

PKG_CHECK_MODULES([FFTW3], [fftw3], [],
                  [AC_MSG_ERROR([fftw3 devel package not found])])

Конечно, для установки pkg-config потребуется autoreconf и configure времени.

Если кто-то установил fftw3 в необычном месте, он может добавить каталог установки файлов *.pc в переменную среды PKG_CONFIG_PATH.

В файле Makefile.am, где задайте вашlibfoo библиотека, вы можете добавить строки, такие как

libfoo_CFLAGS += $(FFTW3_CFLAGS)
libfoo_LIBADD += $(FFTW3_LIBS)

Если вы хотите поймать людей, которые пытаются запустить autoreconf в вашем исходном коде без установки pkg-config, вы можете добавить строкуна configure.ac, чтобы убедиться, что макрос PKG_CHECK_MODULES autoconf m4 определен:

m4_pattern_forbid([PKG_CHECK_MODULES])dnl

Хотя это редко встречается в дикой природе.

Преимущество перед встроенным AC_CHECK_LIBМакросы & Co состоят в том, что файлы *.pc могут определять больше информации.Например,

[user@host ~]$ pkg-config --libs fftw3
-lfftw3 

не содержит сюрпризов, но

[user@host ~]$ pkg-config --libs fftw3q
-lfftw3q -lquadmath 

может содержать неожиданные дополнительные флаги.В дистрибутивные пакеты также может быть добавлена ​​информация, специфичная для системы.

ИМХО, когда зависимость доставляет *.pc файлов, использование PKG_CHECK_MDOULE очень предпочтительнее использования AC_CHECK_LIB.

...