0

我有以下 Makefile,我想用它serial.c在 Linux 中构建一个位于当前目录中的项目,但它使用内部的 C++ 库,src并且include应该构建到一个目录obj中,以保持所有文件清晰和分离。

#define some paths
DHOME      = ${HOME}/Serial
SRC        = ${DHOME}/src
INCLUDE    = ${DHOME}/include
BIN        = ${DHOME}/bin
OBJ        = ${DHOME}/obj

# compiler
CFLAGS        = -I$(INCLUDE)
CXX           = g++ -g ${INCLUDE} 
MAKE          = ${CXX} -O -Wall -fPIC -c

$(OBJ)/%.o: $(SRC)/%.cc
    $(MAKE) $(CFLAGS) $< -o ${OBJ}/$@ 

serial: $(OBJ)/%.o
    ${CXX} -o $@ $@.c $< $(CFLAGS) 


.PHONY: clean
clean:
    @rm -f serial $(OBJ)/*.o

make serial尝试或只是时的错误消息make

make: *** No rule to make target `/home/alex/Serial/obj/%.o', needed by `serial'.  Stop.

但是在查看 Makefile 时,似乎我已经指定了这个规则(规则之上的serial规则)。我可能错过了一些基本的东西。也许有更好的方法来处理这样的项目并将不同的部分清楚地分开在目录中?

谢谢,亚历克斯

4

2 回答 2

2

问题是你的规则:

serial: $(OBJ)/%.o

由于%此规则的 TARGET 中没有,因此这不是模式规则。所以它会寻找一个名为/home/alex/Serial/obj/%.o(字面意思)的文件,该文件不存在且无法制作。

您需要serial依赖于实际对象文件名的列表。然后模式规则 $(OBJ)/%.o: $(SRC)/%.cc可以匹配其中的每一个并将用于编译它。

编辑

如果要自动生成该列表,可以在源文件上使用 glob 规则,然后使用模式替换来生成目标文件:

SOURCES = $(wildcard $(SRC)/*.cc)
OBJECTS = $(SOURCES:$(SRC)/%.cc=$(OBJ)/%.o)
于 2012-09-27T16:57:27.860 回答
0

模式匹配规则作用于目标

您没有提供要构建的目标列表,因此模式匹配不会像您假设的那样工作。

模式匹配构造为在命令行上用作通配符。您不能要求 make 寻找目标,您必须提供它们。

所以,如果serial依赖于一些特定的.o文件,你需要提供这些。最简单的方法是重写你的规则:

serial: $(OBJ)/foo.o $(OBJ)/bar.o $(OBJ)/fie.o
    #Insert build command here, as needed

这将触发模式匹配,因为每个目标文件在链接之前都被设置为目标serial

于 2012-09-27T16:56:58.910 回答