Reputation: 301
I'm new to makefile. I'm trying to perform some shell operation inside a makefile under a target. I made a new_target without modifying the working code. The code looks like this:
all: new_target existing_target
new_target:
TEST_FILES:=$(wildcard $(HOME)/Test/*.cpp)
for f in $(TEST_FILES); do \
$(shell ls) $$f; \
done
Error:
TEST_FILES:=/docker_home/myhome/Test/b.cpp /docker_home/myhome/Test/file.cpp /docker_home/myhome/Test/a.cpp
/bin/sh: 1: TEST_FILES:=/docker_home/myhome/Test/b.cpp: not found
Makefile:6: recipe for target 'new_target' failed
make: *** [new_target] Error 127
The idea is to perform a shell operation(similar to ls
) on all the .cpp
files in a particular directory
Upvotes: 2
Views: 6529
Reputation: 3076
You need to run it in below way as TEST_FILES
is a make variable and you should not mix make
and shell
:
TEST_FILES:=$(wildcard $(HOME)/Test/*.cpp)
new_target:
for f in $(TEST_FILES); do \
ls $$f; \
done
Note :
When it is time to execute recipes to update a target by make , they are executed by invoking a new sub-shell for each line of the recipe, unless the .ONESHELL special target is in effect. So you dont require a $(shell)
explicitly.
Upvotes: 1
Reputation: 180508
This ...
TEST_FILES:=$(wildcard $(HOME)/Test/*.cpp)
... is (GNU) make
syntax that assigns a value to a make
variable. Your recipe instructs the shell to execute it as if it were a shell command. Obviously, that doesn't work.
Additionally, $(shell ls)
doesn't do what you intend. It will run the ls
command without arguments in make
's working directory, at the time the makefile is parsed, and insert the results into the command to be run. If you want to run a shell command in your recipe then just put the command in the recipe.
The easiest solution would probably be to move that line outside the recipe (and dedent it):
TEST_FILES:=$(wildcard $(HOME)/Test/*.cpp)
new_target:
for f in $(TEST_FILES); do \
ls $$f; \
done
Note that the $(wildcard)
function will be evaluated and the results assigned to TEST_FILES
at the time that the makefile is parsed, not when the new_target
target is built, but that appears unlikely to be an issue in this case.
Of course, unless you need TEST_FILES
for something else, too, a much cleaner way would be to merge it together and get rid of wildcard
:
new_target:
for f in $(HOME)/Test/*.cpp; do \
ls $$f; \
done
Or, best of all for this particular case:
new_target:
ls $(HOME)/Test/*.cpp
Upvotes: 3