问题描述
这是我的项目:
Here is my project:
project
|--- main.cpp
|--- makefile
|--- test
|--- Test.cpp
|--- Test.h
这是makefile
:
g++1x:=g++ -std=c++14 -stdlib=libc++ -MMD -MP
cflags:= -Wall -lncurses
PATHS:=./ ./test/
TARGET:=matrix.out
SRC:=$(foreach PATH,$(PATHS),$(wildcard $(PATH)/*.cpp))
OBJDIR:=.obj
OBJ:=$(addprefix $(OBJDIR)/,$(notdir $(SRC:.cpp=.o)))
.PHONY: install
install: $(OBJDIR) $(TARGET)
$(OBJDIR):
mkdir -p $(OBJDIR)
$(TARGET): $(OBJ)
$(g++1x) $(cflags) -o $@ $^ -g
$(OBJDIR)/%.o: %.cpp
$(g++1x) -c -o $@ $< -g
$(OBJDIR)/%.o: ./test/%.cpp
$(g++1x) -c -o $@ $< -g
-include $(addprefix $(OBJDIR)/,$(notdir $(SRC:.cpp=.d)))
.PHONY: clean
clean:
rm -f $(TARGET)
rm -rf $(OBJDIR)
效果很好,但我有两个问题:
1)是否可以避免将foreach
用于PATHS
,以便我可以对所有cpp项目使用相同的makefile
?2)如您所见,为生成main.o
和Test.o
,我编写了两个块:$(OBJDIR)/%.o: ./test/%.cpp
和$(OBJDIR)/%.o: %.cpp
.
只能写一次吗?
我已经尝试过如下操作,但是不起作用:
It works well but I have two questions:
1) Is it possible to avoid foreach
for PATHS
so that I can use the same makefile
for all of cpp projects?
2) As you see, to generate main.o
and Test.o
I write two blocks:$(OBJDIR)/%.o: ./test/%.cpp
and $(OBJDIR)/%.o: %.cpp
.
Is it possible to write only once?
I've tried as below but it doesn't work:
$(OBJDIR)/%.o: $(foreach PATH,$(PATHS),$(wildcard $(PATH)/%.cpp))
$(g++1x) -c -o $@ $< -g
我什至尝试过这种方法,但仍然无法正常工作:
I've even tried like this but it doesn't work still:
$(OBJDIR)/%.o: %.cpp ./test/%.cpp
$(g++1x) -c -o $@ $< -g
推荐答案
您应将源树保留在对象树中.这样,创建 global 规则并保持依赖关系将变得更加容易.
You should keep the source tree into your object tree. This way it will be easier to create global rules and keep dependencies.
# Use the shell find command to get the source tree
SOURCES := $(shell find * -type f -name "*.c")
OBJDIR := .objects
# Keep the source tree into the objects tree
OBJECTS := $(addprefix $(OBJDIR)/,$(SOURCES:.c=.o))
all: mytarget
mytarget: $(OBJECTS)
$(CC) $^ -o $@
# As we keep the source tree we have to create the
# needed directories for every object
$(OBJECTS): $(OBJDIR)/%.o: %.c
mkdir -p $(@D)
$(CC) -MMD -MP -c $< -o $@
-include $(OBJECTS:.o=.d)
$ make
mkdir -p .objects
cc -MMD -MP -c main.c -o .objects/main.o
mkdir -p .objects/test
cc -MMD -MP -c test/test.c -o .objects/test/test.o
cc .objects/main.o .objects/test/test.o -o mytarget
$ tree -a
.
├── main.c
├── Makefile
├── mytarget
├── .objects
│ ├── main.d
│ ├── main.o
│ └── test
│ ├── test.d
│ └── test.o
└── test
├── test.c
└── test.h
3 directories, 9 files
编辑:您可以通过将对象目录添加为仅订购先决条件:
EDIT: You can reduce the number of mkdir
to the minimum by adding the object directory as an order only prerequisites:
# Do not create the directory
$(OBJECTS): $(OBJDIR)/%.o: %.c
$(CC) -MMD -MP -c $< -o $@
# Every target finishing with "/" is a directory
$(OBJDIR)%/:
mkdir -p $@
# Add the "directory/" as an order only prerequisite
$(foreach OBJECT,$(OBJECTS),$(eval $(OBJECT): | $(dir $(OBJECT))))
这篇关于makefile:子目录的模式规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!