c - Linker错误构建OpenWrt包。

时间:2022-10-14 04:55:48

I'm building a little OpenWRT application and I want to statically link a library to it.

我正在构建一个小的OpenWRT应用程序,我想静态地将一个库链接到它。

EDIT: This happens with other libraries as well, not only libcurl.

编辑:这也发生在其他库中,不仅仅是libcurl。

I'm getting this error while building it:

我在建造时犯了这个错误:

make[3]: Entering directory `/home/md/work/openwrt/build_dir/target-mips_r2_uClibc-0.9.33.2/app'
mips-openwrt-linux-uclibc-gcc -c -Os -pipe -mips32r2 -mtune=34kc -mno-branch-likely -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -msoft-float -Wall -Werror main.c -o main.o
mips-openwrt-linux-uclibc-gcc -Os -pipe -mips32r2 -mtune=34kc -mno-branch-likely -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -msoft-float -Wall -Werror -L/home/md/work/openwrt/staging_dir/target-mips_r2_uClibc-0.9.33.2/usr/lib -L/home/md/work/openwrt/staging_dir/target-mips_r2_uClibc-0.9.33.2/lib -L/home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/usr/lib -L/home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/lib -Wl,-Bstatic -lcurl main.o -o app
/home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/lib/gcc/mips-openwrt-linux-uclibc/4.6.4/../../../../mips-openwrt-linux-uclibc/bin/ld: cannot find -lgcc_s
/home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/lib/gcc/mips-openwrt-linux-uclibc/4.6.4/../../../../mips-openwrt-linux-uclibc/bin/ld: cannot find -lgcc_s
collect2: ld returned 1 exit status
make[3]: *** [app] Error 1

It's weird, because I have libgcc_s.so on the search path:

这很奇怪,因为我有libgcc_s。所以在搜索路径上:

stormbreaker:openwrt> find . -name libgcc_s.*
./build_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/uClibc-0.9.33.2/libc/sysdeps/linux/common/libgcc_s.h
./build_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/gcc-linaro-4.6-2012.12-final/gcc/libgcc_s.so
./build_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/gcc-linaro-4.6-2012.12-final/gcc/libgcc_s.so.1
./build_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/gcc-linaro-4.6-2012.12-final/mips-openwrt-linux-uclibc/libgcc/libgcc_s.so
./build_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/gcc-linaro-4.6-2012.12-final/mips-openwrt-linux-uclibc/libgcc/libgcc_s.so.1
./build_dir/target-mips_r2_uClibc-0.9.33.2/toolchain/ipkg-ar71xx/libgcc/lib/libgcc_s.so.1
./build_dir/target-mips_r2_uClibc-0.9.33.2/toolchain/libgcc_s.so.1
./staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/lib/libgcc_s.so
./staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/lib/libgcc_s.so.1
./staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/lib/libgcc_s.so
./staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/lib/libgcc_s.so.1

I tried some hacks with -rpath and -rpath-link, but got the same result. As far as I know, libcurl doesn't need libgcc_s.

我尝试了一些使用-rpath和- rpathlink的方法,但是得到了相同的结果。据我所知,libcurl不需要libgcc_s。

I created a simple case to reproduce this:

我创建了一个简单的例子来复制这个:

The relevant part of openwrt/package/app/Makefile:

openwrt/package/app/Makefile的相关部分:

TARGET_CFLAGS += -Wall -Werror
TARGET_LIBS = -Wl,-Bstatic -lcurl

define Build/Compile
    CC="$(TARGET_CC)" \
    CFLAGS="$(TARGET_CFLAGS)" \
    LDFLAGS="$(TARGET_LDFLAGS)" \
    LIBS="$(TARGET_LIBS)" \
    $(MAKE) -C $(PKG_BUILD_DIR)
endef

openwrt/package/app/src/Makefile:

openwrt /包/ app / src / Makefile:

APP = app
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)

$(APP): $(OBJECTS)
    $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) $(OBJECTS) -o $(APP)

# Objects
%.o: %.c
    $(CC) -c $(CFLAGS) $< -o $@

The application itself is a single file:

应用程序本身是一个文件:

#include <stdio.h>
#include <curl/curl.h>

int main (void)
{
    curl_global_init(CURL_GLOBAL_ALL);
    printf("Ok!\n");
    return 0;
}

1 个解决方案

#1


1  

Increasing the verbosity of the linker (using -Wl,--verbose=99) gave me these clues:

增加链接器的冗余(使用-Wl,- verbose=99)给了我这些提示:

...
attempt to open /home/md/work/openwrt/staging_dir/target-mips_r2_uClibc-0.9.33/usr/lib/libgcc_s.a failed
attempt to open /home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/lib/gcc/mips-openwrt-linux-uclibc/4.6.3/libgcc_s.a failed
attempt to open /home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/lib/gcc/mips-openwrt-linux-uclibc/4.6.3/../../../../mips-openwrt-linux-uclibc/lib/libgcc_s.a failed
attempt to open /home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/mips-openwrt-linux-uclibc/bin/../../../toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/usr/local/lib/libgcc_s.a failed
attempt to open /home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/mips-openwrt-linux-uclibc/bin/../../../toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/lib/libgcc_s.a failed
attempt to open /home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/mips-openwrt-linux-uclibc/bin/../../../toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/usr/lib/libgcc_s.a failed
etc.

Looks like the static version of libgcc_s is missing.

看起来libgcc_s的静态版本不见了。

Anyway, I changed my package Makefile to:

无论如何,我将我的包Makefile更改为:

TARGET_LIBS = -Wl,-Bdynamic -lgcc_s \
              -Wl,-Bstatic -lcurl

define Build/Compile
    $(TARGET_CONFIGURE_OPTS) \
    CFLAGS="$(TARGET_CFLAGS)" \
    LDFLAGS="$(TARGET_LDFLAGS)" \
    LIBS="$(TARGET_LIBS)" \
    $(MAKE) -C $(PKG_BUILD_DIR)
endef

Works for me =)

适合我=)

I understand why linking with a static library would need a static version of its dependencies, But I wasn't expecting the linker to do it behind my back, without falling back the dynamic version first.

我理解为什么链接静态库需要一个静态版本的依赖,但是我并不期望链接器在背后做它,而不需要先回退动态版本。

#1


1  

Increasing the verbosity of the linker (using -Wl,--verbose=99) gave me these clues:

增加链接器的冗余(使用-Wl,- verbose=99)给了我这些提示:

...
attempt to open /home/md/work/openwrt/staging_dir/target-mips_r2_uClibc-0.9.33/usr/lib/libgcc_s.a failed
attempt to open /home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/lib/gcc/mips-openwrt-linux-uclibc/4.6.3/libgcc_s.a failed
attempt to open /home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/lib/gcc/mips-openwrt-linux-uclibc/4.6.3/../../../../mips-openwrt-linux-uclibc/lib/libgcc_s.a failed
attempt to open /home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/mips-openwrt-linux-uclibc/bin/../../../toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/usr/local/lib/libgcc_s.a failed
attempt to open /home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/mips-openwrt-linux-uclibc/bin/../../../toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/lib/libgcc_s.a failed
attempt to open /home/md/work/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/mips-openwrt-linux-uclibc/bin/../../../toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33/usr/lib/libgcc_s.a failed
etc.

Looks like the static version of libgcc_s is missing.

看起来libgcc_s的静态版本不见了。

Anyway, I changed my package Makefile to:

无论如何,我将我的包Makefile更改为:

TARGET_LIBS = -Wl,-Bdynamic -lgcc_s \
              -Wl,-Bstatic -lcurl

define Build/Compile
    $(TARGET_CONFIGURE_OPTS) \
    CFLAGS="$(TARGET_CFLAGS)" \
    LDFLAGS="$(TARGET_LDFLAGS)" \
    LIBS="$(TARGET_LIBS)" \
    $(MAKE) -C $(PKG_BUILD_DIR)
endef

Works for me =)

适合我=)

I understand why linking with a static library would need a static version of its dependencies, But I wasn't expecting the linker to do it behind my back, without falling back the dynamic version first.

我理解为什么链接静态库需要一个静态版本的依赖,但是我并不期望链接器在背后做它,而不需要先回退动态版本。