交叉编译c应用程序库,以符号链接方式引用其他库 [英] Cross compiling c application library referring other libraries symbolically linked

查看:54
本文介绍了交叉编译c应用程序库,以符号链接方式引用其他库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个依赖于共享库(libnode.so)的应用程序(libnodeapplication),而该库又依赖于我粘贴在同一位置的另一个共享库(libgentoo-5.so.100)作为libnode(在/usr/lib/里面)

I am trying to build an application(libnodeapplication) which is dependent on a shared library(libnode.so) which in turn depends on another shared library(libgentoo-5.so.100) which I have pasted at the same location as the libnode(inside /usr/lib/)

问题是第二个从属库符号连接到另一个文件

Problem is second dependent library is symbolically linked to another file

要成功构建它,必须在compile命令中进行哪些更改(对于共享库中已刷新的符号链接文件)

what changes are needed in the compile command to build it successfully(for symbolically linkd files refrened in the shared library)

我尝试使用-Wl,-rpath =< usr/lib/path_to_libgentoo-5.so.100的路径(也没有文件名):

I tried with -Wl,-rpath=<path to usr/lib/path_to_libgentoo-5.so.100 (also without file name) as well :

命令2:

gcc main.o -o libnodeapplication -L/usr/lib/-lnode -Wl,-rpath=/usr/lib/

错误

以下是错误

ld: warning: libgentoo-5.so.100, needed by /usr/lib/libnode.so, not found (try using -rpath or -rpath-link)
usr/lib/libnode.so: undefined reference to `symbol1 in libgentoo-5.so.100'
usr/lib/libnode.so: undefined reference to `symbol2 in libgentoo-5.so.100'
usr/lib/libnode.so: undefined reference to `symbol3 in libgentoo-5.so.100'
.
.
.
and so on

(为简单起见,我使用了gcc代替了arm linux交叉编译器)所以我的最终应用程序是libnodeapplication,它依赖于共享lib =>libnode.so

(for simplicity i have used gcc instead of arm linux cross compiler) so my end application is libnodeapplication which depends on shared lib => libnode.so

libnode.so使用libgentoo-5.so.100(位于/usr/lib中,并与libgentoo-5.so.100.20.0符号链接:libgentoo-5.so.100-构建)-> libgentoo-5.so.100.20.0)

libnode.so is being built using the libgentoo-5.so.100 (which is present in the /usr/lib and symbolically linked to libgentoo-5.so.100.20.0 : libgentoo-5.so.100 -> libgentoo-5.so.100.20.0)

我使用此 command1 :

gcc obj1.o obj2.o obj3.o -shared -o libnode.so/usr/lib/libgentoo-5.so.100

当我尝试使用objdum -t libnode.so时,当我尝试通过上述 command2

When i try to use the objdum -t libnode.so , I can find all those symbols which are reported as undefined symbols when I try to build the libnodeapplication by above command2

我的Makefile(用于libnodeapplication)

CC=<path to tool chain>arm-linux-gnueabihf-gcc
CFLAGS=-Wall
LIB_NAME=-lnode
LIBS=-L$(TARGET_DIR)/usr/lib
INCS=-I./include/

OBJS=libnodeapplication.o

libnodeapplication: $(OBJS)
            $(CC) $(OBJS) -o libnodeapplication $(LIBS) $(LIB_NAME)

main.o: main.c
    $(CC) $(INCS) $(CFLAGS) -c $< -o $@

clean:
    -rm -rf *.o libnodeapplication
    -rm -rf $(TARGET_DIR)/root/libnodeapplication

install:
    cp libnodeapplication $(TARGET_DIR)/root
    chmod +x $(TARGET_DIR)/root/libnodeapplication

为libnode.so制作文件

CC=<path to tool chain>arm-linux-gnueabihf-gcc
CFLAGS=-Wall -fPIC
INCS=-I./include/
LIBS=$(TARGET_DIR)/usr/lib/libgentoo-5.so.100
OBJS=libnode.o helper.o

libnode: $(OBJS)
        $(CC) $(OBJS) -shared -o a.so $(LIBS)

libnode.o: libnode.c
        $(CC) $(INCS) $(CFLAGS) -c $< -o $@     

helper.o: helper.c
        $(CC) $(INCS) $(CFLAGS) -c $< -o $@

clean:
        -rm -rf *.o 
        -rm -rf libnode.so
        -rm -rf $(TARGET_DIR)/usr/lib/libnode.so
        -rm -rf $(TARGET_DIR)/usr/include/libnode.h

install:
        -cp libnode.so $(TARGET_DIR)/usr/lib
        -cp libnode.h $(TARGET_DIR)/usr/include

推荐答案

您的 command1 是正确的-您只需在 command2 中使用相同的方法即可:为库命名直接.

Your command1 was right - you just have to use the same way in command2: name the library directly.

命令2: gcc main.o -o libnodeapplication/usr/lib/node.so

完整的示例:

$ cat b.c     # (= libgentoo)
int b(int x) {
        return x%4;
}

$ cat a.c     # (= libnode)
int b(int);
int a(int x) {
        return b(x+3);
}

$ cat main.c  # (= nodeapplication)
int a(int);
int main() {
        return a(2);
}

$ pwd
/mounts/compilepartition/a-b-main/
$ mkdir -p ../toomuch  # (Just for fun)
$ gcc -shared -o b.so b.c
$ gcc a.c -shared -o a.so $PWD/b.so
$ gcc main.c -o app /mounts/compilepartition/toomuch/../a-b-main/a.so
$ ldd app
    linux-gate.so.1 (0xf7...)
    /mounts/compilepartition/toomuch/../a-b-main/a.so (0xf7...)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7...)
    /mounts/compilepartition/a-b-main/b.so (0xf7...)
    /lib/ld-linux.so.2 (0x56...)
$ ./app; echo $?
1
$ 

提示:要进行交叉编译,您可以隐藏构建路径,例如与

Tip: For cross compiling, you can hide your build path, e.g. with

gcc a.c -shared -o a.so -L/my/complex/build/path -l:b.so

  • 链接时路径/my/complex/build/path/b.so
  • 运行时路径???->必须在运行时找到

提示:对于交叉编译,您可以替换您的构建路径,例如与

Tip: For cross compiling, you can replace your build path, e.g. with

gcc a.c -shared -o a.so -L/my/complex/build/path -l:b.so -W,-rpath =/usr/lib

  • 链接时路径/my/complex/build/path/b.so
  • 运行时路径/usr/lib/b.so

(好的,这不能替代,您只是添加了一个提示.也许您实际上会得到一个不同的 b.so )

(OK, it's no replacement, you're just adding a hint. Maybe you will actually get a different b.so)

提示:要相对于对象/可执行文件进行运行时搜索,请使用'$ ORIGIN'(用单引号引起来!(在GNU/Linux或GNU/*中,甚至在Windows中也可以))

Tip: For runtime searching relative to the object/executable, use '$ORIGIN' (quoted in single quotes! (in GNU/Linux or GNU/*, probably even in Windows))

gcc ac -shared -o a.so -L/my/complex/build/path -l:b.so -W,-rpath ='$ ORIGIN'/sub

  • 链接时路径/my/complex/build/path/a.so
  • 链接时路径/my/complex/build/path/b.so
  • 运行时路径/usr/lib/a.so (例如)
  • 运行时路径/usr/lib/sub/b.so
  • Link-time path /my/complex/build/path/a.so
  • Link-time path /my/complex/build/path/b.so
  • Run-time path /usr/lib/a.so (for instance)
  • Run-time path /usr/lib/sub/b.so

(警告:这很复杂,因为您可能需要在链接时将子子库存储在所需的相对路径 中,以链接例如最终的可执行文件.)

(Warning: this gets complicated because you may need to store the sub-sub-libraries in the required relative path at link-time for linking e.g. a final executable.)

提示:您可以使用 ldd ./a.so ldd ./app(主机=目标).如果host!= target,请使用 strings./a.so strings./app ->在这里,您会看到"b.so"/"a.so"和"/usr/lib",以及许多神秘的东西.

Tip: You can look on shared objects' and final executables' load dependencies with ldd ./a.so or ldd ./app (host=target). If host!=target use strings ./a.so or strings ./app -> here you see "b.so"/"a.so" and "/usr/lib", amongst lots of cryptic stuff.

这篇关于交叉编译c应用程序库,以符号链接方式引用其他库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆