假设我有以下设置
CPPSRC+=path1/foo.cpp
CPPSRC+=path2/main.cpp
CSRC+=path3/zoo.c
CSRC+=path4/bar.c
我想将所有目标文件.o
生成到build/
文件夹中(所以我想要同时需要pathsubst和模式匹配)。
我还需要使用.cpp
和相关g++
编译CXXFLAGS
,而.c
需要使用gcc
和简化版{{}}进行编译1}}。
我到目前为止:
CFLAGS
但无法达到CPPOBJ := $(CPPSRC:%.cpp=%.o)
COBJ := $(CSRC:%.c=%.o)
OBJ := $(COBJ) $(CPPOBJ)
BUILTOBJ := $(addprefix $(BUILD_PATH)/,$(notdir $(OBJ)))
$(APP): $(OBJ)
[...]
$(CPPOBJ): %.o: %.cpp
@echo "[g++" $(BUILD_PATH)$(notdir $@)"]"
$(SILENT)$(GPP) $(CXXFLAGS) $(INCLUDES) -c $< -o $(BUILD_PATH)$(notdir $@)
$(COBJ): %.o: %.c
@echo "[gcc " $(BUILD_PATH)$(notdir $@)"]"
$(SILENT)$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $(BUILD_PATH)$(notdir $@)
先决条件(简而言之,$(COBJ): %.o: %.c
来源无法编译)。
如何?
答案 0 :(得分:1)
使用gmake的模式规则尝试实现的目标是不可能的,因为当您从目标文件中剥离源子目录时,您将丢失路径信息。
因此像%.o: %.cpp
这样的通用模式规则永远不会知道要编译build/foo.o
它需要查看path1/foo.cpp
。
更不用说命名冲突的可能性增加了。
您可以通过在build/
下重新创建子目录结构来解决它,即将path1/foo.cpp
编译为build/path1/foo.o
等。
一旦对其进行了排序,gmake足够聪明,可以解决看似模棱两可的规则,即在编译混合的.c
和.cpp
文件时完全没有问题,如下例所示:
APP = app
BUILD_PATH = build
CPPOBJ := $(CPPSRC:%.cpp=%.o)
COBJ := $(CSRC:%.c=%.o)
OBJ := $(COBJ) $(CPPOBJ)
BUILTOBJ := $(addprefix $(BUILD_PATH)/,$(OBJ))
$(APP): $(BUILTOBJ)
$(CXX) $(CPPFLAGS) -o $@ $(BUILTOBJ) $(LDLIBS)
$(BUILD_PATH)/%.o: %.cpp
mkdir -p $(@D)
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
$(BUILD_PATH)/%.o: %.c
mkdir -p $(@D)
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
答案 1 :(得分:0)
我多么天真..因为我确实在原始路径中有.o文件(不在build/
中)而我的clean:
只删除了build/
路径,{{ 1}}从未调用的先决条件和.c
未生成但未放在.o
文件夹中的情况。
确实,我的伎俩试图通过使build/
文件的位置与定义的先决条件不同来愚弄make。
次要插件:我不需要使用单独的C / C ++源列表登陆到makefile;我可以通过以下方式实现分离:
.o