生成文件:子目录的模式规则
makefile: pattern rules for subdirectory
这是我的项目:
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
.
可以只写一次吗?
我已经尝试过如下方法,但它不起作用:
$(OBJDIR)/%.o: $(foreach PATH,$(PATHS),$(wildcard $(PATH)/%.cpp))
$(g++1x) -c -o $@ $< -g
我什至尝试过这样,但它仍然不起作用:
$(OBJDIR)/%.o: %.cpp ./test/%.cpp
$(g++1x) -c -o $@ $< -g
您应该将源代码树保留在对象树中。这样,创建全局规则和保留依赖项将更加容易。
# 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
<小时 />编辑:您可以通过将对象目录添加为仅订单来将mkdir
数量减少到最小 先决条件:
# 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))))
因为我无法编辑 jmlemetayer 的答案,所以下面介绍如何扩展同时使用 C 和 CPP 源的项目的命令:
首先要生成对象列表,只需应用 patsubst 两次,每个扩展一次:
SRC_LST := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES)))
OBJECTS := $(addprefix $(OBJDIR)/,$(SRC_LST))
然后,要在用于编译的隐式规则中处理 .cpp 和 .c 文件,请执行以下操作:
.SECONDEXPANSION:
$(OBJECTS): $(OBJDIR)/%.o: $$(wildcard %.c*)
mkdir -p $(@D)
ifeq "$(suffix $<)" ".cpp"
$(CPP) -MMD -MP -c $< -o $@
else
$(CC) -MMD -MP -c $< -o $@
endif
如果有更好的方法,我很乐意更新它。
相关文章:
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 此代码是否违反一个定义规则
- 为什么在保护模式下继承升级不起作用
- 如何在全屏模式下(在OpenGL中)使背景透明
- 生成文件不对文件使用隐式规则
- 生成文件匹配规则和配方中的模式
- 需要帮助了解Makefile模式规则%:%.o
- 生成文件:子目录的模式规则
- NMake 模式规则
- 将Javascript正则表达式模式转换为C++std::regex的规则
- 错误:"混合的隐式和静态模式规则"在我的生成文件中
- Makefile:已忽略模式规则
- 具有混合依赖项的生成文件模式规则
- 如何在makefile中扩展模式规则
- 如何编写模式规则来分隔对象文件和源文件的位置
- 是否存在用于在子类的数据上实施规则的设计模式
- 生成文件模式规则:循环生成文件.o < - 删除生成文件依赖项
- 生成文件模式规则差异
- 使用stack,编写一个程序,该程序使用以下规则确定字符模式是否有效:a ^N B^N
- 如何使用std::string的值作为Flex规则的模式