我有一个关于在 Makefile 中编译和链接的问题(也许是一般的)。
我有一个 server.c 文件,它由具有 main()
函数的主程序组成。 server.c
包含 rio.c。我有一个名为 rio
的模块,它由 rio.c
和 rio.h
组成。它没有 main()
函数。
我有两个问题,如何实际编写 Makefile,以及执行此类操作的最佳实践。
Q1:如何编写Makefile
我有以下 Makefile:
CC = gcc
CFLAGS = -Wall -Werror -Wmissing-prototypes
OBJS = server.o rio.o
all: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o sysstatd
server.o: server.c
$(CC) $(CFLAGS) -c server.c
rio.o: rio.c rio.h
$(CC) $(CFLAGS) -c rio.c
clean:
rm -f *~ *.o sysstatd
我遇到了与此相关的问题。它说我对 C 中使用的所有函数都有多个定义。我不确定这是怎么可能的,因为 server.c 是用 -c
标志编译的,所以实际上没有任何链接。它应该知道某些函数存在但实际上并没有链接它们,直到 all
规则将两个目标文件编译在一起并生成一个包含所有链接的目标文件。
这里有什么问题?
Q2:最佳实践
由于我有一个模块,然后是另一个包含主程序的文件,我是否应该将主程序 server.c
编译为一个单独的模块,然后在 all
中一起编译>,或者全部编译 server.c 并在那里添加 rio.o 模块?请注意,这仍然会产生与上面相同的链接问题,因此我很确定我的问题出在其他地方。
最佳答案
你应该稍微修改一下结构:
CC = gcc
CFLAGS = -Wall -Werror -Wmissing-prototypes
OBJS = server.o rio.o
all: sysstatd
sysstatd: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o sysstatd
server.o: server.c
$(CC) $(CFLAGS) -c server.c
rio.o: rio.c rio.h
$(CC) $(CFLAGS) -c rio.c
clean:
rm -f *~ *.o sysstatd
区别在于伪规则all
依赖于sysstatd
是最新的,而sysstatd
是最新的到目前为止 w.r.t 对象文件。
现在它相当冗长,显式地编写编译操作。使用就足够了:
CC = gcc
CFLAGS = -Wall -Werror -Wmissing-prototypes
OBJS = server.o rio.o
all: sysstatd
sysstatd: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o sysstatd
server.o: server.c
rio.o: rio.c rio.h
clean:
rm -f *~ *.o sysstatd
你也可以辩论:server.c
不使用 rio.h
吗?如果是,则应列出依赖项。如果不是,为什么 rio.h
存在? make
将假定 server.o
依赖于 server.c
,因此您不必指定它(但它不会关于标题的假设)。您还可以使用宏来防止重复程序名称:
CC = gcc
CFLAGS = -Wall -Werror -Wmissing-prototypes
OBJS = server.o rio.o
PROG = sysstatd
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $@
server.o: rio.h
rio.o: rio.h
clean:
rm -f *~ *.o $(PROG) core a.out
如果您需要其他库,那么您可以使用:
CC = gcc
CFLAGS = -Wall -Werror -Wmissing-prototypes
OBJS = server.o rio.o
PROG = sysstatd
LOCALLIBDIR = /usr/local/lib
LDFLAGS = -L$(LOCALLIBDIR)
LDLIBS = -lone -ltwo
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $@ $(LDFLAGS) $(LDLIBS)
server.o: rio.h
rio.o: rio.h
clean:
rm -f *~ *.o $(PROG) core a.out
关于c - Makefile、编译和链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13664693/