4

I have a folder for various testing of C code, containing many files named *.c. My aim is to have a Makefile search for any filename ending in .c and add the root of that filename to the targets.

Makefile:

TARGETS = $(shell ls *.c | sed "s/\.c$//g")
all: $(TARGETS)

The issue is that the shell command works as expected in sh:

$ sh -c 'ls *.c | sed "s/\.c$//g"'
hello

...while it fails with make:

$ make
sed: 1: "s/\.c/g": unterminated substitute in regular expression
make: Nothing to be done for `all'.

I tried escaping the $ as \$, which instead yields:

`sed: 1: "s/\.c\/g": unterminated substitute pattern`

The same goes for replacing the double quotes (") with single quotes (').

2 Answers 2

8

You need to escape the $. In make, you do so by using $$. Your line should be:

TARGETS = $(shell ls *.c | sed "s/\.c$$//g")

Although this one answers the questions directly, @cas's solution appears to be better.

1
  • How silly of me. I guess all the cunfusion surrounding make is somewhat justified. It’s like a shell, but with slight tweaks here and there. Thanks for helping a poor noob out!
    – gnucchi
    Commented Nov 1, 2015 at 14:27
4

With GNU Make:

objects := $(patsubst %.c,%.o,$(wildcard *.c))

all : $(objects)

See info make or pinfo make and search for the wildcard and patsubst functions for more details. Depending on your distro, you may need to install the make-doc package (or similar name) first to get the full make documentation.

1
  • TARGETS = $(subst .c,,$(wildcard *.c)) worked nicely for me. Thanks!
    – gnucchi
    Commented Nov 1, 2015 at 14:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .