如何在 makefile 指令中同时包含 C 和 C++ 文件

Posted

技术标签:

【中文标题】如何在 makefile 指令中同时包含 C 和 C++ 文件【英文标题】:How to include both C and C++ files in makefile directives 【发布时间】:2017-04-11 20:29:46 【问题描述】:

以下部分在 makefile 中很常见。

OBJS := $(SRCS:%.c=$(OBJDIR)/%.o)

$(OBJDIR)/%.o : %.c
    $(CC) $(DEFS) $(CFLAGS) -o$@ $<

现在我的源文件夹包含 C 和 C++ 文件,我想将使用 g++ 创建的所有目标文件链接在一起。但是我如何指定还包含 *.cpp 文件以进行编译。我的意思是如何修改 OBJS 以包含 *.cpp 文件。

对于 OBJDIR,也许,我可以像这样做 C++ 等价物。我猜 makefile 会正确猜到何时使用 CXX(用于 C++ 文件的 g++)以及何时使用 CC(用于 C 文件的 gcc)。

$(OBJDIR)/%.o : %.cpp
        $(CXX) $(DEFS) $(CFLAGS) -o$@ $<

那么,我该如何将这条规则添加到 OBJS 中呢?

【问题讨论】:

我相信你可以指定两个规则(即$(OBJDIR)/%.o: %.c ... $(OBJDIR)/%.o: %.cpp ...)。 您能否详细说明一下。如果我有 C++ 的 $(OBJDIR_CXX/%.o 和 C 的 $(OBJDIR)/%.o,我如何在此处修改 OBJS? 【参考方案1】:

你想使用:

OBJS := $(addsuffix .o,$(basename $(SRCS)))

然后从.cpp 添加用于构建.o 的模式规则(除非,如此处所述,您可以只使用内置规则)。

上面去掉了后缀,不管它是什么,然后在末尾添加.o

【讨论】:

这缺少一个 ')'。但是,当我尝试编辑时,网站告诉我必须至少编辑 6 个字符。【参考方案2】:

您可能根本不需要从相应的 .cpp 或 .c 文件构建 .o 文件的规则,因为 Make 带有默认规则,这些规则看起来很像您呈现的内容。关键可能是首先指定需要构建哪些.o 文件。

我经常看到通过将 C 源代码与 C++ 源代码分开分类来实现这一点。那么你可能会有这样的事情:

C_SRCS = ...
CPP_SRCS = ...

OBJS = $(C_SRCS:.c=.o) $(CPP_SRCS:.cpp=.o)

all: myprog

myprog: $(OBJS)
    $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)

如果您确实需要自己的规则来从源代码构建 .o 文件,那么您当然可以添加这些规则。

还要注意,以上内容不依赖于 GNU make 扩展,如果这对您很重要,那么您将希望避免使用 GNU 样式模式规则来构建目标文件。这就是传统的后缀规则的用途。

【讨论】:

但是你这里不是用 g++ 编译每个文件吗?我想用gcc编译C文件,用g++编译C++文件,然后用g++链接起来。 不,@pythonic,我不会用g++ 编译每个文件。我将程序与 g++链接,并依靠 Make 的内置规则从相应的 .c 或 .cpp 文件编译每个所需的 .o 文件,使用适合源文件类型的编译规则. @pythonic,但正如我更新的答案所说,如果您需要或想要这样做,您可以将 .c 的规则添加到 .o 和 .cpp 到 .o。 Make 不仅根据所需的 target,而且还根据可用的 sources 选择适当的规则。 所以,你的意思是,如果我将所有目标文件放在一个目录中(比如说 OBJDIR),我可以将规则 $(OBJDIR)/%.o 写 2 次,一个用于 C,然后另一个用于 C++,如我的问题中所写? @MadScientist,嗯,不,不会的,假设$(C_SRCS)只包含C源文件的名称,以.c结尾,而$(CPP_SRCS)只包含C++的名称源文件,以.cpp 结尾,正如名称所暗示的那样。这在很大程度上就是将它们作为单独的变量。

以上是关于如何在 makefile 指令中同时包含 C 和 C++ 文件的主要内容,如果未能解决你的问题,请参考以下文章

Makefile 8——使用依赖关系文件

如何让 Makefile 自动重建包含修改后的头文件的源文件? (在 C/C++ 中)

如何在makefile中写入“或”内部依赖项?

利用makefile实现c语言项目编译

在Linux下的项目如何运行?

如何在 makefile 中添加 .c、.cc 和 .so 文件以创建另一个 .so?