TIL: filter-out in GNU Make

2022-06-04 00:00:00 +0000 UTC

GNU Make includes a large set of text functions that allow the manipulation of strings in a Makefile. These functions allow the easy manipulation of, for example, generated lists of build objects.

In ccask I wanted to provide two executable targets: the KV store itself and a test executable. The test executable just takes advantage of the C assert() macro to effectively run unit tests. Here is the relevant chunk of the Makefile:

main=./build/./src/main.c.o
test=./build/./src/test/test.c.o

SRCS := $(shell find $(SRC_DIRS) -name '*.c')
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)

MAIN_OBJS := $(filter-out $(test),$(OBJS)) 
TEST_OBJS := $(filter-out $(main),$(OBJS)) 

First, a list of SRCS is generated by a call out to the find utility. Next, a list of object files OBJS is generated. Then tthis list is filtered using $(filter-out pattern...,text). The first argument is a whitespace-separated list of pattern words. The second argument is the text to be filtered. filter-out means we keep only the text that does not match.

So now the build targets for the test executable and the target executable can successfully build without running into a conflict during linking due to their both defining int main(...){ ... }!

There are a ton more text manipulation functions implemented in GNU Make listed on this page, linked in the first paragraph.

Tags: til make devops