gpt4 book ai didi

c++ - 在单个 makefile 目标中编译 C 和 CPP 源代码

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:06:21 25 4
gpt4 key购买 nike

我有一个 makefile,我在其中使用 C 源代码和 CPP 源代码。下面是 makefile 中的一段代码。有没有办法结合以下两个目标来编译这两种文件类型?

#definitions
OBJ_DIR := obj
DEP_DIR := dep

CXX := g++
DEBUG := -g -O0
OPT := -std=c++11 -Wextra -Wall -pthread
LFLAGS = $(DEBUG) $(OPT) $(INC)
CFLAGS = $(LFLAGS) -c

#auto-dependency generation (part 1)
DEP_FLAGS = -MT $@ -MMD -MP -MF $(DEP_DIR)/$*.Td
POSTCOMPILE = @mv -f $(DEP_DIR)/$*.Td $(DEP_DIR)/$*.d && touch $@

#compile object files from CPP source
$(OBJ_DIR)/%.o: %.cpp $(DEP_DIR)/%.d
$(CXX) $(CFLAGS) $(DEP_FLAGS) $< -o $@
$(POSTCOMPILE)

#compile object files from C source
$(OBJ_DIR)/%.o: %.c $(DEP_DIR)/%.d
$(CXX) $(CFLAGS) $(DEP_FLAGS) $< -o $@
$(POSTCOMPILE)

#auto-dependency generation (part 2)
$(DEP_DIR)/%.d: ;
.PRECIOUS: $(DEP_DIR)/%.d
include $(wildcard $(DEP_DIR)/*.d)

我曾尝试使用具有多种不同格式的通配符函数使用二次扩展,但无济于事。

我正在使用 Make 4.2。自动依赖生成代码取自 http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ .

提前致谢

最佳答案

使用正确的变量以及 define , calleval特征,以​​下是可能的:

EXT := c cpp

define rule =
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.$(1)
$$(COMPILE.$(1)) $$< -o $$@
endef

$(foreach ext, $(EXT), $(eval $(call rule,$(ext)))) # NO SPACE before $(ext)!!!

make 具有隐式变量和规则,尤其是许多 COMPILE.* 规则(您可以通过发出 shell 命令 make -p | grep ' 来查看它们编译。* ='):

COMPILE.c   = $(CC)  $(CFLAGS)   $(CPPFLAGS) $(TARGET_ARCH) -c
COMPILE.cpp = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

CPPFLAGS 用于预处理器标志(cpp 是 GNU GCC 工具链中的预处理器可执行文件)。 TARGET_ARCH 在大多数平台上默认为空。


这是一个完整但极简主义的工作 Makefile,具有更好的自动依赖性生成(请注意,将 .d 文件放在与 .o 分开的文件夹中毫无意义地使生成文件):

TARGET  := executable
EXT := c cpp

SRC_DIR := .
OBJ_DIR := obj
DEP_DIR := dep

CPPFLAGS = -MMD -MP -MF $(@:$(OBJ_DIR)/%.o=$(DEP_DIR)/%.d)
CFLAGS := -Wall -Wextra -pthread
CXXFLAGS := -std=c++11 $(CFLAGS)
LDFLAGS := -pthread

SOURCE := $(foreach ext, $(EXT), $(wildcard $(SRC_DIR)/*.$(ext)))
OBJECT := $(SOURCE:$(SRC_DIR)/%=$(OBJ_DIR)/%.o)
DEPEND := $(OBJECT:$(OBJ_DIR)/%.o=$(DEP_DIR)/%.d)

define rule =
$(OBJ_DIR)/%.$(1).o: $(SRC_DIR)/%.$(1) | $(OBJ_DIR) $(DEP_DIR)
$$(COMPILE.$(1)) $$< -o $$@
endef

.PHONY: all clean

all: $(TARGET)

$(TARGET): $(OBJECT)
$(CXX) $(LDFLAGS) $^ -o $@

$(foreach ext, $(EXT), $(eval $(call rule,$(ext))))

$(OBJ_DIR) $(DEP_DIR):
mkdir -p $@

-include $(DEPEND)

clean:
$(RM) -r $(TARGET) $(OBJ_DIR) $(DEP_DIR)

另请注意,我选择将原始源文件扩展名(ccpp)添加到目标文件名(.c.o.cpp.o) 来解决我们可能遇到扩展名不同但名称相同的源文件的情况。

关于c++ - 在单个 makefile 目标中编译 C 和 CPP 源代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49667011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com