我正在尝试为我在Linux下用C编写的小规模应用程序编写一个makefile。目前我的所有源文件.c
都在顶级目录中,所有头文件都在
包含目录。这是我用于此的makefile。
IDIR =include
CC=gcc
CFLAGS=-I$(IDIR)
ODIR=obj
_OBJ = main.o kernel.o user_app.o myargs.o ofp_msgs.o pkt_ip.o pkt_ether.o pkt_tcp.o pkt_udp.o pkt_icmp.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
#DEPS = ofp_msgs.h
$(ODIR)/%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)
all: jam
jam: $(OBJ)
gcc -o $@ $^ $(CFLAGS) -lpthread
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ jam
它工作正常,但我想要的是,例如我创建一个名为"Packet"
的子目录,我的所有数据包解析文件,即"pkt_ip.c, pkt_tcp.c etc"
应该在该目录中,因为它们的头文件应该仍然是在顶级目录中"toplevel/include"
。我做了一些搜索,最常见的方法是使用递归make。然后我看到很多网页抱怨递归制作。任何人都可以帮助我这个如何正确吗?
谢谢
答案 0 :(得分:3)
我建议查看Recursive Make Considered Harmful中描述的方法。 我已经在几个项目(小到中等)上使用它,并且发现它比使用递归方法更容易使用,并且更容易包裹它们。
基本上,你在根目录中有一个Makefile,它包含来自每个子目录的(部分)makefile:
SRC := main.c
MODULES := Packet lib etc
-include $(patsubst %, %/module.mk, $(MODULES))
OBJ := $(patsubst %.c, %.o, $(filter %.c,$(SRC)))
# (...)
分组/ module.mk:
SRC += Packet/pkt_ip.c Packet/pkt_tcp.c
LIBS += -lsome_library
这些模块makefile当然也可以定义自己的模块目标或特殊构建要求。
与递归make不同,“make”只会被调用一次,对于大多数用例,这将导致更快的构建。 然而,对于大多数较小的项目来说,既不是建立时间也不是复杂性将是一个主要问题,所以使用最自然的东西。
答案 1 :(得分:2)
有几种方法可以做到这一点,但你当然可以使用VPATH:=Packet
告诉make在'Packet'目录中查找源文件。见make manual