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.


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"'

...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 (').


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.

| improve this answer | |
  • TARGETS = $(subst .c,,$(wildcard *.c)) worked nicely for me. Thanks! – gnucchi Nov 1 '15 at 14:26

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.

| improve this answer | |
  • 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 Nov 1 '15 at 14:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.