Autoconf——包括静态库(新手)

发布于 2024-08-30 15:37:14 字数 2655 浏览 11 评论 0原文

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

手动编译正在处理这些(目录不可预测 - 这只是一个例子):(

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

呃,我实际上不明白为什么直接引用 .a 文件,而不是使用 -L 或其他任何东西。是的,我有一半- 加深了对构建 C 程序的理解。)

因此,在我的 configure.ac 中,我可以使用相关的配置参数来使用 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并直接在LDFLAGS中包含.a),但没有运气:

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)])

I am trying to migrate my application from manual build to autoconf, which is working very nicely so far. But I have one static library that I can't figure out how to integrate. That library will NOT be located in the usual library locations - the location of the binary (.a file) and header (.h file) will be given as a configure argument. (Notably, even if I move the .a file to /usr/lib or anywhere else I can think of, it still won't work.) It is also not named traditionally (it does not start with "lib" or "l").

Manual compilation is working with these (directory is not predictable - this is just an example):

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

(Uh, I actually don't understand why the .a file is referenced directly, not with -L or anything. Yes, I have a half-baked understanding of building C programs.)

So, in my configure.ac, I can use the relevant configure argument to successfully find the header (.h file) using AC_CHECK_HEADER. Inside the AC_CHECK_HEADER I then add the location to CPFLAGS and the #include of the header file in the actual C code picks it up nicely.

Given a configure argument that has been put into $location and the name of the needed files are helper.h and helper.a (which are both in the same directory), here is what works so far:

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

Where I run into difficulties is getting the binary (.a file) linked in. No matter what I try, I always get an error about undefined references to the function calls for that library. I'm pretty sure it's a linkage issue, because I can fuss with the C code and make an intentional error in the function calls to that library which produces earlier errors that indicate that the function prototypes have been loaded and used to compile.

I tried adding the location that contains the .a file to LDFLAGS and then doing a AC_CHECK_LIB but it is not found.

Maybe my syntax is wrong, or maybe I'm missing something more fundamental, which would not be surprising since I'm a newbie and don't really know what I'm doing.

Here is what I have tried:

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)])

No dice. AC_CHECK_LIB is looking for -lhelper I guess (or libhelper?) so I'm not sure if that's a problem, so I tried this, too (omit AC_CHECK_LIB and include the .a directly in LDFLAGS), without luck:

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"])

To emulate the manual compilation, I tried removing the -L but that doesn't help:

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

I tried other combinations and permutations, but I think I might be missing something more fundamental....

================ UPDATE

I got it to work with a hard-coded path to the .a file in Makefile.am using _LDADD like this:

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

But I can't predict the location of the .a file. For some reason, defining myprog_LDADD in configure.ac doesn't work (I wish it did, so I can use my dynamic location variable), and no combination of changes to LDFLAGS, myprog_LDFLAGS, AM_LDFLAGS seems to work.

If, in Makefile.am, I try to use the variable location that is defined in configure.ac, it doesn't work

myprog_LDADD=($location)helper.a

================ UPDATE

I think I figured it out, but since I have no idea what I'm doing, I'd REALLY appreciate some feedback. I used AC_SUBST() to get myprog_LDADD to work from configure.ac, so the final solution looks like this:

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)])

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

神爱温柔 2024-09-06 15:37:14

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

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

AC_SUBST 在所有 Makefile.am 中定义变量 $LOCATION s 并将所有出现的 @LOCATION@ 替换为 $LOCATION 的内容。然后在你的Makefile.am中你就可以做

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

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

You can set the location in configure.ac:

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

AC_SUBST defines the variable $LOCATION in all your Makefile.ams and also replaces all occurrences of @LOCATION@ with the contents of $LOCATION. So then in your Makefile.am you can do

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

PS. The reason why you need to reference the library directly is because -l looks for a properly-named library (e.g. libhelper.a) in the system library directories. However, since there's not all that much difference between a static library and an object file, there's no need to magically reference it using -l; you can just compile it into your program like you are doing now.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文