【问题标题】:Autoconf -- including a static library (newbie)Autoconf——包括一个静态库(新手)
【发布时间】:2011-02-14 15:27:47
【问题描述】:

我正在尝试将我的应用程序从手动构建迁移到 autoconf,目前它运行良好。但是我有一个静态库,我不知道如何集成。该库不会位于通常的库位置 - 二进制文件(.a 文件)和头文件(.h 文件)的位置将作为配置参数给出。 (值得注意的是,即使我将 .a 文件移动到 /usr/lib 或我能想到的任何其他位置,它仍然无法工作。)它也没有传统命名(它不以“lib”或“l ”)。

手动编译正在使用这些(目录不可预测 - 这只是一个示例):

gcc ...  -I/home/john/mystuff  /home/john/mystuff/helper.a

(呃,我其实不明白为什么直接引用 .a 文件,而不是用 -L 或其他任何东西。是的,我对构建 C 程序的理解还不成熟。)

因此,在我的 configure.ac 中,我可以使用相关的 configure 参数通过 AC_CHECK_HEADER 成功找到标头(.h 文件)。在 AC_CHECK_HEADER 中,我将位置添加到 CPFLAGS 中,实际 C 代码中头文件的#include 很好地选择了它。

给定一个已放入 $location 的配置参数,并且所需文件的名称是 helper.h 和 helper.a(它们都在同一个目录中),这是目前有效的:

AC_CHECK_HEADER([$location/helper.h], 
    [AC_DEFINE([HAVE_HELPER_H], [1], [found helper.h]) 
    CFLAGS="$CFLAGS -I$location"])

我遇到困难的地方是获取链接的二进制文件(.a 文件)。无论我尝试什么,我总是会收到关于未定义引用该库的函数调用的错误。我很确定这是一个链接问题,因为我可以对 C 代码大惊小怪,并在对该库的函数调用中故意犯错误,这会产生较早的错误,表明函数原型已被加载并用于编译。

我尝试将包含 .a 文件的位置添加到 LDFLAGS,然后执行 AC_CHECK_LIB 但未找到。

也许我的语法有误,或者我遗漏了一些更基本的东西,这不足为奇,因为我是新手,并不真正知道自己在做什么。

这是我尝试过的:

AC_CHECK_HEADER([$location/helper.h], 
    [AC_DEFINE([HAVE_HELPER_H], [1], [found helper.h]) 
    CFLAGS="$CFLAGS -I$location"; 
    LDFLAGS="$LDFLAGS -L$location"; 
    AC_CHECK_LIB(helper)])

没有骰子。我猜 AC_CHECK_LIB 正在寻找 -lhelper(或 libhelper?),所以我不确定这是否有问题,所以我也尝试了这个(省略 AC_CHECK_LIB 并将 .a 直接包含在 LDFLAGS 中),但没有运气:

AC_CHECK_HEADER([$location/helper.h], 
    [AC_DEFINE([HAVE_HELPER_H], [1], [found helper.h]) 
    CFLAGS="$CFLAGS -I$location"; 
    LDFLAGS="$LDFLAGS -L$location/helper.a"])

为了模拟手动编译,我尝试删除 -L 但这无济于事:

AC_CHECK_HEADER([$location/helper.h], 
    [AC_DEFINE([HAVE_HELPER_H], [1], [found helper.h]) 
    CFLAGS="$CFLAGS -I$location"; 
    LDFLAGS="$LDFLAGS $location/helper.a"])

我尝试了其他组合和排列,但我认为我可能遗漏了一些更基本的东西......

================更新

我使用 _LDADD 将它与 Makefile.am 中的 .a 文件的硬编码路径一起工作,如下所示:

myprog_LDADD=/home/john/mystuff/helper.a

但我无法预测 .a 文件的位置。出于某种原因,在 configure.ac 中定义 myprog_LDADD 不起作用(我希望它这样做,所以我可以使用我的动态位置变量),并且对 LDFLAGS、myprog_LDFLAGS、AM_LDFLAGS 的任何更改组合似乎都不起作用。

如果我在 Makefile.am 中尝试使用 configure.ac 中定义的变量位置,它就不起作用

myprog_LDADD=($location)helper.a

================更新

我想我明白了,但由于我不知道我在做什么,我非常感谢一些反馈。我使用 AC_SUBST() 让 myprog_LDADD 从 configure.ac 工作,所以最终的解决方案如下所示:

AC_CHECK_HEADER([$location/helper.h], 
    [AC_DEFINE([HAVE_HELPER_H], [1], [found helper.h]) 
    CFLAGS="$CFLAGS -I$location" 
    myprog_LDADD="$location/helper.a" 
    AC_SUBST(myprog_LDADD)])

【问题讨论】:

  • 一次性回答的内容很多。如果你一次只问一个问题,你可能会得到更多的答案,如果你正确地格式化代码摘录,它会更容易阅读——在每一行前加上四个空格。

标签: autotools autoconf


【解决方案1】:

您可以在configure.ac中设置位置:

LOCATION=/home/john/mystuff
AC_SUBST(LOCATION)

AC_SUBST 在您的所有Makefile.ams 中定义变量$LOCATION,并将所有出现的@LOCATION@ 替换为$LOCATION 的内容。那么在你的Makefile.am 你可以做

myprog_CPPFLAGS="-I$LOCATION"
myprog_LDADD="$LOCATION/helper.a"

PS。您需要直接引用该库的原因是因为-l 在系统库目录中查找正确命名的库(例如libhelper.a)。但是,由于静态库和目标文件之间没有太大区别,因此无需使用-l 神奇地引用它;您可以像现在一样将其编译到您的程序中。

【讨论】:

  • 好的,谢谢。看到你的建议,看起来我做了几乎同样的事情,通过使用 AC_SUBST() 将 myprog_LDADD 传播到 Makefile。与你的方法相比,我的方法有什么问题吗?谢谢你的帮助!!!!!!
  • 另外,将 helper.a 放入 LDFLAGS 不起作用但将其添加到 myprog_LDADD 是否有某些原因?我显然不明白两者之间的区别。再次,谢谢。
  • 您的方法在所有 makefile 中定义了 myprog_LDADD,而不仅仅是您需要的那个。这可能会导致问题。
  • 抱歉,最后一个问题 - 我注意到人们似乎总是建议将包含路径与 CFLAGS 一起添加到 CXXFLAGS。我只添加到 CFLAGS...这会有问题吗?
  • LDFLAGS 用于链接器标志,LDADD 用于要链接的库。此处的 Automake 手册中解释了不同之处:gnu.org/software/automake/manual/html_node/Linking.html#Linking
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-26
  • 2015-02-23
  • 2013-05-31
相关资源
最近更新 更多