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

rtu*_*tur 3 c c++ makefile

是否可以从与特定扩展名匹配的变量中选择文件,并丢弃其余的?

SRCS = file1.c file2.c file3.cpp

OBJS = $(SRCS:%.c=%.o)
OBJS += $(SRCS:%.cpp=%.o)
Run Code Online (Sandbox Code Playgroud)

问题是$(SRCS:%.c=%.o)将.c文件转换为.o文件,保留.cpp文件.

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

file1.o file2.o file3.cpp file1.c file2.c file3.o
Run Code Online (Sandbox Code Playgroud)

而我想要的是

file1.o file2.o file3.o
Run Code Online (Sandbox Code Playgroud)

那么,有可能吗?或者唯一干净的方法是拥有SRCS_CSRCS_CPP变量?

小智 6

我可以看到两种可能的解决方法(但它们会为您带来一个略有不同的项目组织).首先是要:

SRCS := file1 file2 file3
OBJS := $(SRCS:%=%.o)
Run Code Online (Sandbox Code Playgroud)

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

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

%.o: %.c
    gcc $< [...]
Run Code Online (Sandbox Code Playgroud)

或者你可以拥有像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 $< [...]
Run Code Online (Sandbox Code Playgroud)

希望我帮助:)

  • 我也认为@ Cakeisalie5的答案是更好的方法. (2认同)

G. *_*pen 5

使用GNU make,可以使用多种文本处理功能。您可以尝试以下方法:

CSRCS = $(filter %.c,$(SRCS))
CPPSRCS = $(filter %.cpp,$(SRCS))
Run Code Online (Sandbox Code Playgroud)

这会将对象列表一分为二。然后可以分别处理每个:

OBJS = $(CSRCS:%.c=%.o)
OBJS += %(CPPSRCS:%.cpp=%.o)
Run Code Online (Sandbox Code Playgroud)

另一种选择是一次性应用两个过滤器:

OBJS = $($(SRCS:%.c=%.o):%.cpp=%.o)
Run Code Online (Sandbox Code Playgroud)

但是,这不太可读。