Makefile:根据扩展名从变量中选择文件

5

能否从一个变量中选择与特定扩展名匹配的文件,并丢弃其他文件?

SRCS = file1.c file2.c file3.cpp

OBJS = $(SRCS:%.c=%.o)
OBJS += $(SRCS:%.cpp=%.o)

这样做的问题是$(SRCS:%.c=%.o)会将.c文件转换为.o文件,但是会保留.cpp文件。

在这种情况下,OBJS变量将等于

file1.o file2.o file3.cpp file1.c file2.c file3.o

And what I want is

file1.o file2.o file3.o

那么,这是可能的吗?还是唯一的清晰方法是拥有SRCS_CSRCS_CPP变量?
4个回答

8

使用GNU Make,有多个文本处理函数可用。你可以尝试以下方法:

CSRCS = $(filter %.c,$(SRCS))
CPPSRCS = $(filter %.cpp,$(SRCS))

这将列表对象分成两部分。然后可以分别对每个对象进行处理:

OBJS = $(CSRCS:%.c=%.o)
OBJS += %(CPPSRCS:%.cpp=%.o)

另外一种选择是在一次操作中应用两个过滤器:

OBJS = $($(SRCS:%.c=%.o):%.cpp=%.o)

这段文字虽然不太易读。


我也喜欢你的第二个提案,而且我认为它并不难读。 - Ctx

7

我可以看到两种可能的解决方法(但它们将为您带来略有不同的项目组织)。第一种方法是只有:

SRCS := file1 file2 file3
OBJS := $(SRCS:%=%.o)

然后你可以使用依赖项定义目标,以检查源文件是C文件还是C++文件:

%.o: %.cpp
    g++ $< [...]

%.o: %.c
    gcc $< [...]

或者你可以像file1.c.o/file3.cpp.o这样拥有对象文件。这意味着你可以拥有同名的C和C++文件,这可能很有用。然后你只需要执行:

SRCS := file1.c file2.c file3.cpp
OBJS := $(SRCS:%=%.o)

%.cpp.o: %.cpp
    g++ $< [...]

%.c.o: %.c
    gcc $< [...]

希望我能帮到你:)

太棒了。第二个解决方案正是我想要的。谢谢! - rtur
2
我也认为@Cakeisalie5的答案是更好的方法。 - G. Sliepen

0
set_o_suffix=$(addsuffix .o,$(basename $1))
set_o_suffix_for_cxx=$(addsuffix .o,$(basename $(filter %.c %.cpp,$1)))

SRCS := foo.c buz/bar.cpp main.js
$(info set_o_suffix=$(call set_o_suffix,$(SRCS)))
$(info set_o_suffix_for_cxx=$(call set_o_suffix_for_cxx,$(SRCS)))
all:

输出:

set_o_suffix=foo.o buz/bar.o main.o
set_o_suffix_for_cxx=foo.o buz/bar.o

-3

首先,你使用的是什么操作系统?

如果是Linux系统,则可以使用| grep ext命令。

如果是Windows系统,则使用find | 命令。

如果你使用文件选择器,则在构建文件选择器时可以填写所需的扩展名,其他扩展名将被丢弃...

如果你从命令行运行C++/C程序,则选择上述方法。

如果你想让变量具有特定的扩展名,则使用正则表达式来指定“.”(点)后的字符数,并只允许一个扩展名。

更多信息请访问https://msdn.microsoft.com/en-us/library/bb982727.aspx


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接