2013-08-27 109 views
2

我正在構建一個小的OpenWRT應用程序,我想靜態鏈接一個庫到它。c - 建立OpenWrt包的鏈接程序錯誤

編輯:這也發生在其他庫,以及libcurl。

,同時建立它,我得到這個錯誤:

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 

這很奇怪,因爲我有libgcc_s.so搜索路徑:

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 

我嘗試了一些黑客用-rpath和-rpath-link,但得到了相同的結果。據我所知,libcurl不需要libgcc_s。

我創建了一個簡單的例子來重現此:

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

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 [email protected] 

應用程序本身是單個文件:

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

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

回答

1

增加(使用-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. 

貌似的libgcc_s靜態版本丟失。

無論如何,我改變了我的包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 

對我的作品=)

我明白爲什麼有靜態庫鏈接需要一個依賴靜態版本,但我沒」不要期待鏈接器在我背後做它,而不會首先退回動態版本。

+1

你如何增加鏈接器的冗長度?像這樣:* TARGET_LIBS = -Wl, - verbose = 99 *? –

+1

已經很長時間了,但我很確定這是正確的。 爲了100%正確,傳遞標誌的正確變量是LDFLAGS =) –