【问题标题】:How to include file containing declared gcc wrap functions using autotools?如何使用自动工具包含包含声明的 gcc 包装函数的文件?
【发布时间】:2021-11-25 08:50:26
【问题描述】:

我正在尝试将 socket() 系统调用与我自己的自定义 __wrap_socket() 系统调用包装在 lighttpd(Web 服务器应用程序)中的 wrap.c 文件中。

Lighttpd 使用自动工具来构建,我正在尝试使用 musl 完全静态地构建它。

我传递的configure脚本如下:

CC="/home/riscv64-linux-musl-cross/bin/riscv64-linux-musl-gcc" CFLAGS="-g -Wl,--wrap=socket -static --static -static-libstdc++ -static-libgcc /home/lighttpd/wrap.c" LDFLAGS="-L/musl/lib/ -lcrypt -lc" ./configure --prefix=/lighttpd/install/ --enable-static --without-zlib --without-bzip2 --without-pcre

但是,由于 lighttpd 的构建脚本和由 autotools 生成的 Makefile,我收到以下错误(我只包含了许多错误中的一部分):

/home/riscv64-linux-musl-cross/bin/riscv64-linux-musl-gcc -DHAVE_CONFIG_H -DHAVE_VERSIONSTAMP_H -DLIBRARY_DIR="\"/home/lighttpd/install/lib\"" -DSBIN_DIR="\"/home/lighttpd/install/sbin\"" -I. -I..  -DDEBUG_PROC_OPEN -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES   -g -Wl,--wrap=socket -static --static -static-libstdc++ -static-libgcc /home/lighttpd/wrap.c -Wall -W -Wshadow -pedantic -MT proc_open-proc_open.o -MD -MP -MF .deps/proc_open-proc_open.Tpo -c -o proc_open-proc_open.o `test -f 'proc_open.c' || echo './'`proc_open.c
riscv64-linux-musl-gcc: fatal error: cannot specify ‘-o’ with ‘-c’, ‘-S’ or ‘-E’ with multiple files

但是,如果我没有在 CFLAGS 参数中包含 wrap.c 文件的路径,我会收到以下错误:

/home/riscv64-linux-musl-cross/bin/../lib/gcc/riscv64-linux-musl/10.2.1/../../../../riscv64-linux-musl/bin/ld: /home/musl/lib//libc.a(if_nametoindex.lo):/home/musl-1.1.23/src/network/if_nametoindex.c:13: more undefined references to `__wrap_socket' follow

和

/home/riscv64-linux-musl-cross/bin/../lib/gcc/riscv64-linux-musl/10.2.1/../../../../riscv64-linux-musl/bin/ld: /home/lighttpd/src/fdevent.c:491: undefined reference to `__wrap_socket'

我在文件 wrap.h 中有 wrap.c 函数 (__wrap_socket()),该文件已包含在 lighttpd 的主文件 (server.c) 中。任何帮助将不胜感激。

【问题讨论】:

    标签: c linux gcc autotools lighttpd


    【解决方案1】:

    这里有很多问题。其中:

    • 您正在使用 CC 变量在交叉编译器中进行子编译,但这是使用 Autotools 构建系统执行 cross build 的错误方法。正确的方法是通过--host triplet 指定交叉编译的系统类型。看起来您可能特别想要--host=riscv64-linux-musl。只要交叉工具在可执行搜索路径中,并且具有预期的名称,configure 就会找到它们——包括工具链的正确 链接器,其使用应该会减少标志的数量您需要指定。 configure 的行为也会与配置普通构建时有所不同。

    • 您在 CFLAGS 变量中指定链接标志,该变量用于编译标志。这在实践中可能并不总是会导致问题,但您应该避免这是一个混乱。 LDFLAGS 是链接标志的正确变量除了-l 和-L 选项,包括-Wl,--wrap=socket、-static、--static、-static-libstdc++ 和-static-libgcc ,尽管其中一些根本不需要。

    • 您已将源文件名放入您的CFLAGS。这完全行不通。构建系统将使用 CFLAGS 将每个源文件分别构建为一个目标文件,其中这些是 C 源文件。您正在欺骗它尝试使用每个此类命令编译两个源代码,这与构建系统选择的其他一些标志冲突。

    • 您似乎有一个 C++ 项目,但您指定了 C 编译器标志 (CFLAGS) 并且没有指定 C++ 编译器标志 (CXXFLAGS)。如果两种语言都有资源,那么您可能需要两种语言。不要期望在编译 C++ 源代码时使用 CFLAGS。

    • 您在 LDFLAGS 中指定链接库。这可能不会破坏您的构建本身,但也不会获得您可能期望的链接行为,因为链接命令对命令行参数的顺序很敏感。您应该为此使用LIBS。

    您无法在不修改自动工具的情况下将源文件添加到 Autotools 构建中。如果您想避免这种情况,那么我的建议是将额外的源代码(交叉)构建到库中,并将其添加到链接中。我将构建库留给您,但假设您将其构建为 libsocket_wrap.a,然后您可以通过配置以下内容将其注入 lighthttpd:

    CFLAGS="-g" \
      CXXFLAGS="-g" \
      LDFLAGS="-Wl,--wrap=socket -static-libstdc++ -static-libgcc" \
      LIBS="/path/to/libsocket_wrap.a -lcrypt" \
    ./configure \
      --host=riscv64-linux-musl \
      --prefix=/lighttpd/install \
      --enable-static \
      --disable-shared \
      --without-zlib \
      --without-bzip2 \
      --without-pcre
    

    我不能保证它会按原样工作,因为很大程度上取决于您的构建环境的细节以及您尝试构建的项目的细节。但这比问题中提出的位置要好得多。

    【讨论】:

    • 非常感谢您的详细评论。对此,我真的非常感激。但是,我遇到的一件事是在 musl 的库文件中未定义对 __wrap_socket 的引用。例如:/home/riscv64-linux-musl-cross/bin/../lib/gcc/riscv64-linux-musl/10.2.1/../../../../riscv64-linux-musl /bin/ld: /home/lib/libc.a(if_nametoindex.lo):/home/musl-1.1.23/src/network/if_nametoindex.c:13: 更多未定义的“__wrap_socket”引用如下
    • @ballsmahoney,你在被你的包装器包裹的 libc 中得到了 socket() 调用。这很可能是由于静态链接该库而引起的,这对我来说非常重要。如果你想继续推进,那么你可以尝试在LIBS 的前面添加-lc,在包装库之前:LIBS="-lc /path/to/libsocket_wrap.a -lcrypt"。最后,您可能还需要再次添加它。
    • 或者——这是推测性的——你可以考虑将-Wl,--no-wrap=socket添加到LIBS的末尾,得到LIBS="/path/to/libsocket_wrap.a -lcrypt -Wl,--no-wrap=socket"。这很 hacky,它可能根本不起作用,但如果它确实起作用,那么我希望它首先解决 C 库内部使用 socket() 的问题。
    猜你喜欢
    • 1970-01-01
    • 2016-06-18
    • 2012-01-28
    • 1970-01-01
    • 2018-03-28
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多