gpt4 book ai didi

c - 在 Alpine Docker 中编译时,什么可能导致链接错误?

转载 作者:行者123 更新时间:2023-12-03 19:23:00 31 4
gpt4 key购买 nike

我正在尝试在从 Alpine 3.7 基础镜像构建的 docker 容器中编译程序。程序使用 argp.h ,并将其包含为 #include <argp.h> .我已经安装了 argp-standalone 并验证它正在制作图像。文件 argp.h位于usr/include ,但是当我使用以下命令编译我的程序时:

gcc -W -Wall -Wextra -I/usr/include   -c -o progname.o progname.c
gcc -largp -o progname progname.o
我收到以下错误:
progname.o: In function `parse_opt':
progname.c:(.text+0x4c9): undefined reference to `argp_failure'
progname.c:(.text+0x50f): undefined reference to `argp_failure'
progname.c:(.text+0x555): undefined reference to `argp_failure'
progname.c:(.text+0x59b): undefined reference to `argp_failure'
progname.c:(.text+0x5ce): undefined reference to `argp_error'
progname.c:(.text+0x5f4): undefined reference to `argp_error'
progname.o: In function `main':
progname.c:(.text+0x1397): undefined reference to `argp_parse'
collect2: error: ld returned 1 exit status
make: *** [Makefile:9: progname] Error 1
我有:
  • 确保版本argp.h图像上的实际上包括 argp_failure , argp_parse , 和 argp_error职能。
  • 试过搬家 argp.h进入机器上的不同位置(例如进入正在编译的同一目录中,进入 /usr/lib )
  • 尝试编译 -l-L .

  • 镜像中也安装的相关包是 build-base , make , 和 gcc .
    在 Ubuntu 镜像上编译时,即使没有 -largp,这些相同的命令也能正常工作。和 -I/usr/include标志。 在 Alpine 图像中可能会发生什么不同的情况,这会导致它不起作用?
    编辑
    根据@Pablo 的评论,我现在将其编译如下:
    gcc -W -Wall -Wextra -I/usr/include -L/usr/lib -c -o progname.o progname.c
    gcc -largp -o progname progname.o
    验证静态库后, libargp.a ,位于 /usr/lib .然而,同样的问题仍然存在。
    编辑 2
    编译如下(再次按照@Pablo 的建议)解决了我遇到的错误:
    gcc -W -Wall -Wextra -I/usr/include -L/usr/lib -c -o progname.o progname.c
    gcc -o progname progname.o /usr/lib/libargp.a
    但是,我仍然很好奇为什么使用完全相同的库和指令,这将无法在 Alpine 镜像中编译,而在 Ubuntu 镜像中编译没有问题。

    最佳答案

    I am still curious why, using the exact same library and instructions, this would fail to compile in an Alpine image while compiling without issue in an Ubuntu image.


    Alpine 链接错误的原因可能有点令人惊讶,实际上并不是 Alpine 特有的。
    虽然这无法链接:
    gcc -largp -o progname progname.o
    这有效:
    gcc -o progname progname.o -largp
    原因是传递给链接器的参数顺序,它与链接算法有关。通常,在链接命令行中首先指定对象(可能还有用户的静态库),然后使用 -l 指定库。 . Eli Bendersky 的文章 Library order in static linking 中完美地解释了标准链接器算法。 :

    Object files and libraries are provided in a certain order on the command-line, from left to right. This is the linking order. Here's what the linker does:

    • The linker maintains a symbol table. This symbol table does a bunch of things, but among them is keeping two lists:
      • A list of symbols exported by all the objects and libraries encountered so far.
      • A list of undefined symbols that the encountered objects and libraries requested to import and were not found yet.
    • When the linker encounters a new object file, it looks at:
      • The symbols it exports: these are added to the list of exported symbols mentioned above. If any symbol is in the undefined list, it's removed from there because it has now been found. If any symbol has already been in the exported list, we get a "multiple definition" error: two different objects export the same symbol and the linker is confused.
      • The symbols it imports: these are added to the list of undefined symbols, unless they can be found in the list of exported symbols.
    • When the linker encounters a new library, things are a bit more interesting. The linker goes over all the objects in the library. For each one, it first looks at the symbols it exports.
      • If any of the symbols it exports are on the undefined list, the object is added to the link and the next step is executed. Otherwise, the next step is skipped.
      • If the object has been added to the link, it's treated as described above - its undefined and exported symbols get added to the symbol table.
      • Finally, if any of the objects in the library has been included in the link, the library is rescanned again - it's possible that symbols imported by the included object can be found in other objects within the same library.

    -largp首先出现,链接器在链接过程中不包括它的任何对象,因为它还没有任何 undefined symbol 。如果静态库是通过路径提供的,而不是通过 -l ,然后它的所有对象都被添加到链接过程中。

    关于c - 在 Alpine Docker 中编译时,什么可能导致链接错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58775599/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com