【问题标题】:How to use ld to link obj files produced by gcc如何使用ld链接gcc生成的obj文件
【发布时间】:2013-11-11 06:41:12
【问题描述】:

这些天我正在阅读 APUE 并自己设置 Makefile,而不是使用本书网站提供的现有 .mk Makefile。我的 Makefile 是这样的:

CC=gcc
LD=ld
CC_FLAGS= -c -I ./include/ -Wall -Wextra
LD_FLAGS= -e main -lc
LIB_OBJS= ./lib/*.o #There'are about 30 .c files in lib, \
most of which are wrap of error handling routines or simplified APIs. \
So I don't copy them all in the code block

all: 

ls: ls.c $(LIB_OBJS)
        $(CC) $(CC_FLAGS) -o ls.o ls.c
        $(LD) $(LD_FLAGS) -o ls ls.o ./lib/error.o

$(LIB_OBJS):
        cd ./lib; \
        make

clean:
        cd ./lib; \
        make clean
        rm ./ls

./lib 中的 Makefile 与这个非常相似,因为它只是 gcc -c 该目录中的所有 .c 文件,并且不做任何链接工作。 ls.c 是第一章中的第一段代码,它只列出了给定 dirent 的每个元素。 我的问题是,我的 Makefile 可以生成一个可执行文件而不会打印任何错误,但这个文件根本不是可执行文件。每当我 ./ls 使用 x 权限时,bash 都会返回:

bash: ./ls: No such file or directory

但如果我使用 gcc 将 ls.o 和 ./lib/error.o 链接在一起,它可以顺利运行。所以我想知道 gcc 的 ld 调用有什么特别之处。如果我只使用 ld 来链接 gcc 生产的东西,我该怎么办? 预先感谢!

【问题讨论】:

  • 使用$(MAKE) -C lib clean而不是cd ./lib; make clean;和代码LIB_OBJS= $(wildcard lib/*.o) 因为make 不知道* 否则。
  • 另外,没有充分的理由使用ld 而不是gcc 链接(除非您正在破解自己的libc 和编译器工具)。
  • 旁注 - 实际存在的可执行文件上的“没有这样的文件或目录”可能意味着没有找到执行该文件的解释器。您可以使用readelf -a <your program> | grep interpreter 进行验证。但是,使用 -dynamic-linker ld 标志指定的解释器 - 如果默认一个被破坏,这不是一个好兆头。
  • make 可以很好地处理* 通配符,它​​只是在变量赋值时不做任何事情。但是,当在规则体或先决条件中使用时,它会对其进行评估(但要重复而不是一次)。

标签: c linux gcc makefile


【解决方案1】:

我不确定您使用的是什么工具链,但是除了您指定的库之外,gcc 传递给链接器的默认库很少,例如库

这是带有 -v 选项的 gcc 的部分输出,其中介绍了链接器步骤:

GNU 汇编器版本 2.17.50.0.6-12.el5 (i386-redhat-linux) 使用 BFD 版本 2.17.50.0.6-12.el5 20061020 /usr/libexec/gcc/i386-redhat-linux/4.1.2/collect2 --eh-frame-hdr -m elf_i386 --hash-style=gnu -dynamic-linker / lib/ld-linux.so.2 -o y.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crt1.o /usr/lib/ gcc/i386-redhat-linux/4.1.2/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbegin.o -L/usr/lib /gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2/。 ./../.. /tmp/ccS39C4x.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/ lib/gcc/i386-redhat-linux/4.1.2/crtend.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crtn.o

【讨论】:

  • 很好,但从技术上讲,它不仅是 libraries,还有一些 object filescrt*.o)由gcc链接跨度>
  • crt*.o 是用于程序存根的文件。在cross compiler HOWTO 的末尾,他们的功能得到了解释。我认为这些东西是 gcc 插入的汇编代码,所以我不认为它们是问题的原因。感谢回答。
猜你喜欢
  • 2014-12-03
  • 2021-01-27
  • 2010-09-29
  • 2021-04-27
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
  • 2017-10-19
相关资源
最近更新 更多