【问题标题】:Link .so file into an executable file将 .so 文件链接到可执行文件中
【发布时间】:2014-09-08 04:32:15
【问题描述】:

我有我在 clang 中使用 -fPIC 开关编译的目标代码,它也使用了 -shared 开关。然后我将所有这些链接到一个 .so 共享对象中。现在我想将其链接到一个可执行文件中,手册页告诉我应该能够使用 ld 命令和 -l 开关。但是当我这样做时,我收到以下错误:


ld -r -L./ -l:libmymath.so simpleone
ld: attempted static link of dynamic object `libmymath.so'
make: *** [simpleone] Error 1


我尝试使用 -dy 开关做同样的事情,但它给了我同样的错误。 我真的不明白为什么这不起作用。

这是我用来完成所有这些工作的 makefile。

CC= clang 
LD= ld -r
CFLAGS= -std=gnu99 -g -Oz -c 
CSECFL= -fPIC -I -L 
CFLAG3= -shared
RM= /bin/rm -f
OBJ= math.o my*.o
SO= libmymath.so

all: math my_add my_mul 

math: math.c
    $(CC) $(CFLAGS) $@.c $(CSECFL)

my_add: my_add.c
    $(CC) $(CFLAGS) $@.c $(CSECFL)

my_mul: my_mul.c
    $(CC) $(CFLAGS) $@.c $(CSECFL)

simplemath: $(OBJ)
    $(CC) $(OBJ) -o $@ 

simplemath.o: $(OBJ)
    $(LD) $(OBJ) -o $@

lib1: my_add.o
    $(CC) $(CFLAG3) my_add.o -o $(SO)

lib2: $(OBJ)
    $(CC) $(CFLAG3) my_mul.o -o $(SO)

lib3: $(OBJ)
    $(CC) $(CFLAG3) math.o -o $(SO)

simpleone: $(OBJ)
    $(LD) -L./ -l:libmymath.so $@

clean:
    $(RM) *.o simplemath* *.t $(SO)

【问题讨论】:

  • 您应该使用 $(CC) 进行链接。
  • 使用 $(CC) 给了我
    clang -l:libmymath.so -o simpleone libmymath.so: undefined reference to int_mul' libmymath.so:未定义引用 int_add' clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [simpleone] Error 1
    我不明白为什么它说未定义的引用,我链接了将 lib1 和 lib2 相乘并相加。
  • Makefile 完全搞砸了。从哪个文件 .so 创建 - my_add.o、my_mul.o 或 math.o?理论上 - 来自他们所有人,但这不是你写的。
  • 所有三个,我运行 lib1,然后运行 ​​lib2,最后运行 lib3。这将每次重新链接(或重建).so 文件,不是吗?
  • 不,每次都会用新的结果覆盖.so。

标签: c makefile linker shared-libraries clang


【解决方案1】:

您需要将对象 (*.o) 链接到静态可执行文件,而不是共享库 (.so)。so 可以通过运行时动态链接器或通过 dlopen() 调用打开。

【讨论】:

  • 这对我一点帮助都没有。我需要将它们链接到一个 .so 文件中,因为稍后我将在多个文件中使用这些 lib 文件,我想知道为什么这不起作用。
  • 它不起作用,因为将它们链接到静态可执行文件所需的信息不再存在于 .so 中,它只是无法完成。您当然可以创建一个供运行时程序使用的共享库,以及一组具有相同代码的对象,以进行静态链接。为什么或以什么方式需要“稍后在多个文件中使用这些 lib 文件”会阻止您将对象链接到静态二进制文件?
  • 要明确 - ld 的 -l 选项将加载 .so 符号,但它用于链接其他共享库,而不是进行静态链接。但是,您可以愉快地构建 .so 用于运行时使用和 .o 用于静态链接(这些通常与 ar 一起归档到 .a 中)。您不必在它们之间“选择”。
  • @user54590 不可以,但是你的精灵在运行时需要 .so 存在。
  • 谢谢 BadZen 和 keltar;在明确告诉它仅在运行时使用 .so 之后,它起作用了。此外,将 makefile 规则更改为在一个目标下使用 $(OBJ) 也有所帮助。
猜你喜欢
  • 1970-01-01
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 2016-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
相关资源
最近更新 更多