【发布时间】: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-linkerld 标志指定的解释器 - 如果默认一个被破坏,这不是一个好兆头。 -
make 可以很好地处理
*通配符,它只是在变量赋值时不做任何事情。但是,当在规则体或先决条件中使用时,它会对其进行评估(但要重复而不是一次)。