Makefile:";ld:can';t链接到主可执行文件";在C中
我试图将两个c文件,Makefile:";ld:can';t链接到主可执行文件";在C中,c,makefile,C,Makefile,我试图将两个c文件,calutil.c和calutil.h编译成一个可执行文件。这是我的makefile: CC = gcc CFLAGS = -Wall -std=c11 -DNDEBUG all: caltool caltool: calutil.o caltool.o $(CC) $(CFLAGS) calutil.o caltool.o caltool.o: caltool.c $(CC) $(CFLAGS) caltool.c -o caltool.o calu
calutil.c
和calutil.h
编译成一个可执行文件。这是我的makefile:
CC = gcc
CFLAGS = -Wall -std=c11 -DNDEBUG
all: caltool
caltool: calutil.o caltool.o
$(CC) $(CFLAGS) calutil.o caltool.o
caltool.o: caltool.c
$(CC) $(CFLAGS) caltool.c -o caltool.o
calutil.o: calutil.c
$(CC) $(CFLAGS) -c calutil.c -o calutil.o
clean:
rm -rf *.o *.out
calutil.c
没有main
,而caltool.c
有一个main。
我得到了错误
ld:当我make
时,无法链接到主可执行文件。这是什么原因?我刚刚从目录中删除了.o文件,并编辑了我的makefile,将-c
添加到caltool.o
行。主要问题是,链接的一些方法缺少输出文件,而编译缺少-c
如果您正在使用GNU make,那么以下Makefile
就足以完成您想要做的事情:
CFLAGS:=-Wall -std=c11
CPPFLAGS:=-DNDEBUG
.PHONY: all
all: caltool
caltool: caltool.o calutil.o
.PHONY: clean
clean::
$(RM) *.o
说明:
- 当您不使用特定于目标的变量时,您应该使用
:=
而不是=
来分配变量,以便它们在分配时展开,而不是在计算时展开
- 当
Makefile
增长并拆分它时,您可能希望有多个名为clean
的目标,所有这些目标都将被执行。在这种情况下,请使用clean::
而不是clean:
- 有一个预定义变量要调用
rm
,它是$(rm)
,它包括-f
标志,以防止Makefile
在一个或多个要删除的文件不存在的情况下失败
clean
的模式应该是*.[adios]
(这很容易记住,adios是西班牙语,表示再见),这样它就可以删除中间存档(.a
当您构建自己的静态库时)、依赖文件(.d
)、预处理器输出(.i
)和汇编文件(.s
)如果使用-save temps
查看编译器正在执行的操作
- GNU make有内置的编译和链接规则,请参阅
- 编译的内置规则调用
$(CC)$(CFLAGS)$(CPPFLAGS)$(TARGET_ARCH)-c-o$@$您使用哪个版本的make
?对于您想要实现的目标,您的Makefile
可能过于复杂,尤其是当您使用GNUMake时。任何简化都是可怕的。第二条规则缺少-c
,因此caltool.o
是一个完整的程序,而不是一个目标文件。这是一种魔法。我没想到会从这个问题中得到这样的帮助,谢谢Christian!
CPPFLAGS+=-MMD
-include caltool.d calutil.d
objects:=caltool.o calutil.o
caltool: $(objects)
-include $(objects:.o=.d)
sources:=$(wildcard *.c)
objects:=$(sources:.c=.o)