用于混合C / C ++源的Makefile

时间:2018-03-03 09:44:45

标签: c++ c makefile

假设我有以下设置

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来源无法编译)。

如何?

2 个答案:

答案 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