Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何动态查找和包含库_C++_Linker_Autotools_Autoconf_Automake - Fatal编程技术网

C++ 如何动态查找和包含库

C++ 如何动态查找和包含库,c++,linker,autotools,autoconf,automake,C++,Linker,Autotools,Autoconf,Automake,我有一个库,我正在开发用于使用Autotools suite的配置和生成文件。该库需要在编译它的系统上有一个外部库(特别是fftw3),我希望Autoconf/Automake在编译之前/编译时(在configure.ac或Makefile.am中)自动查找并链接/包含外部库 目前,我只是使用autoconf“-with-”标志让用户在其系统上提供库文件和外部库的include文件夹的位置,但这对用户来说似乎很麻烦。我正在为其构建配置文件和makefiles的库将部署在各种共享系统上,因此很难假

我有一个库,我正在开发用于使用Autotools suite的配置和生成文件。该库需要在编译它的系统上有一个外部库(特别是fftw3),我希望Autoconf/Automake在编译之前/编译时(在configure.ac或Makefile.am中)自动查找并链接/包含外部库

目前,我只是使用autoconf“-with-”标志让用户在其系统上提供库文件和外部库的include文件夹的位置,但这对用户来说似乎很麻烦。我正在为其构建配置文件和makefiles的库将部署在各种共享系统上,因此很难假设必要的外部库始终位于同一位置


最好的方法是什么?

你可能想得太多了。库可能安装在不同系统的不同位置本身并不是问题。开发工具链知道使用它们的系统的布局。基本情况相当稳健;只是(例如)

这将识别
libfftw3
在搜索路径中可用(如果确实可用),在这种情况下,将为
LIBS
变量预先添加适当的链接选项,并定义
HAVE_libfftw3

只有当您希望提供不在链接器默认搜索路径中的库的使用,或者在该路径的前面找到不同版本的库时,才会出现问题。这就是提供
——带有foo
选项的情况,生成器可以通过这些选项指定位置。但请注意,这是一个有点特殊的问题,至少在链接动态库时是这样,因为dev库通常与运行库一起安装,如果静态链接器在构建时找不到dev库,然后,通常需要为动态链接器在运行时找到的运行时库提供某种特殊的设置

尽管如此,如果您想检查编码到
configure
中的可能库位置列表,那么这可以相对容易地完成。生成的
configure
是一个shell脚本,您可以将它的文字代码写入
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
    )中使用的变量
  • 使用shell循环测试各种选项
  • 使用
    AC\u CHECK\u LIB的on success/on error操作
    
    • 理解
      AC\u CHECK\u LIB
      是一个宏,而不是一个函数,因此,例如,您可以将
      break
      放入其参数中,该参数将退出使用
      AC\u CHECK\u LIB
      的循环
  • 使用输出变量将结果报告为一组链接选项。通过将
    $(FFTW3_LIBS)
    添加到相应的
    *LIBADD
    *LDADD
    变量中,可以在
    Makefile.am
    中使用它。(或者,如果您没有使用Automake,则以任何合适的方式将其添加到link命令。)

当然,您可以将其与使用
--with foo
选项结合使用,以支持您预期之外的情况(作为练习使用)。

fftw3
似乎要安装
*.pc
文件时,我将使用
configure.ac
中的基本宏,类似于

PKG_CHECK_MODULES([FFTW3], [fftw3])
或者,如果您想对编译您的库的人提供多一点帮助,比如

PKG_CHECK_MODULES([FFTW3], [fftw3], [],
                  [AC_MSG_ERROR([fftw3 devel package not found])])
当然,这需要在
autoreconf
configure
时间安装
pkg config

如果有人碰巧在不寻常的地方安装了
fftw3
,他们可以将
*.pc
文件的安装目录添加到
PKG\u CONFIG\u路径
环境变量中

在定义
libfoo
库的
Makefile.am
文件中,可以添加如下行

libfoo_CFLAGS += $(FFTW3_CFLAGS)
libfoo_LIBADD += $(FFTW3_LIBS)
如果您想及早发现有人试图在源代码上运行
autoeconf
,而没有安装
pkg config
,您可以在
configure.ac
中添加一行,以确保定义了
pkg\u CHECK\u MODULES
autoconf m4宏:

m4_pattern_forbid([PKG_CHECK_MODULES])dnl
不过,这在野外是很常见的

与内置的
AC\u CHECK\u LIB
&Co宏相比,它的优势在于
*.pc
文件可以定义更多信息。例如

[user@host ~]$ pkg-config --libs fftw3
-lfftw3 
没有惊喜,但是

[user@host ~]$ pkg-config --libs fftw3q
-lfftw3q -lquadmath 
可能包含令人惊讶的附加标志。分发包也可能在其中添加了特定于系统的信息

依我看,当依赖项附带
*.pc
文件时,使用
PKG\u CHECK\u MDOULE
比使用
AC\u CHECK\u LIB
更可取

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