Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile : select files by extension, from a variable

Tags:

c++

c

makefile

Is it possible to select the files from a variable that match a specific extension, and discard the rest?

SRCS = file1.c file2.c file3.cpp

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

The problem with that is that the $(SRCS:%.c=%.o) transforms the .c files into .o files, but keeps the .cpp files.

In this case, the OBJS variable is going to be equal to

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

And what I want is

file1.o file2.o file3.o

So, is it possible? Or the only clean way is to have SRCS_C and SRCS_CPP variables?

like image 596
rtur Avatar asked Jan 27 '17 11:01

rtur


2 Answers

With GNU make, there are several text processing functions available. You could try this:

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

This splits the list of objects in two. You can then process each individually:

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

Another option is to just apply two filters in one go:

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

This is less readable though.

like image 53
G. Sliepen Avatar answered Nov 17 '22 14:11

G. Sliepen


I can see two possible workarounds (but they'll bring you a slightly different project organisation). First is to just have:

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

Then you can define the targets using the dependencies to check either the source file is a C or a C++ file:

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

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

Or you could have the object files like file1.c.o/file3.cpp.o. That means you can have a C and a C++ file with the same name, which could be useful. Then you would just have to do:

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

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

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

Hope I helped :)

like image 20
Cakeisalie5 Avatar answered Nov 17 '22 13:11

Cakeisalie5