1

我正在尝试为我在 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"。我做了一些搜索,最常见的方法是使用递归制作。然后我看到很多页面抱怨递归生成。任何人都可以帮我解决这个问题吗?谢谢

4

2 回答 2

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)))
# (...)

数据包/模块.mk:

SRC += Packet/pkt_ip.c Packet/pkt_tcp.c
LIBS += -lsome_library

这些模块生成文件当然也可以定义它们自己的模块目标,或特殊的构建要求。

与递归 make 不同,“make”只会被调用一次,这对于大多数用例会导致更快的构建。然而,对于大多数较小的项目来说,构建时间和复杂性都不是主要问题,所以使用感觉最自然的东西。

于 2012-04-17T12:03:07.767 回答
2

有几种方法可以做到这一点,但您当然可以使用VPATH:=Packet来告诉 make 在 'Packet' 目录中查找源文件。参见制作手册

于 2012-04-17T11:15:17.260 回答