My project's directory structure is as follows:
My Makefile looks like this:
dir1_contents = $(shell ls dir1/*)
dir3_contents = $(shell ls dir3/*)
all: clean_dir1 clean_dir3
clean_dir1:
echo 'dir1_contents = $(dir1_contents)'
clean_dir3:
echo 'dir3_contents = $(dir3_contents)'
When I run make, this is what I get:
$ pwd
make-test
$ make -s
dir1_contents = dir1/file2.junk dir1/dir2: file1.junk
dir3_contents = dir3/file3.junk
I want to get the contents of dir1
in dir1_contents
. But I don't want the recursive contents. Just the contents that are immediately below the dir1
directory. How can I do it?
If I remove the /*
from the first two lines of the Makefile, I get the right contents I want. But then they are missing their paths which I also need:
$ pwd
make-test
$ make -s
dir1_contents = dir2 file2.junk
dir3_contents = file3.junk
How can I get the right contents I want with the file paths that I need also?
The problem you're having is related to the way ls
works, it's nothing to do with GNU make. If you run ls dir1/*
then the shell expands the wildcard before invoking ls
, so this is the same as running:
ls dir1/dir2 dir1/file2.junk
And when you ls
a directory it shows the contents of the directory by default, so the output is:
$ ls dir1/dir2 dir1/file2.junk
dir1/file2.junk
dir1/dir2:
file1.junk
(go ahead and try this at the command prompt). Since that's what the shell prints, that's the result you get back.
If you just want to see the directories but not the files in the directories, you can add the -d
option to the ls
command:
$ ls -d dir1/dir2 dir1/file2.junk
dir1/file2.junk dir1/dir2
Or, in the makefile:
dir1_contents = $(shell ls -d dir1/*)
dir3_contents = $(shell ls -d dir3/*)
However, I think this is not a great way to do it anyway. Why not use GNU make's built-in wildcard
function instead? In addition to being simpler to understand it's a LOT more portable and much more efficient (the above version requires invoking a shell and the ls
program). I also recommend you use :=
not =
, so that you only perform the wildcard operation one time:
dir1_contents := $(wildcard dir1/*)
dir3_contents := $(wildcard dir3/*)