9 10 alphabetically like this (here I use GNU Make's $(warning) function to print out the result of calling my-sort):
NUMBERS := 1 12 4 6 8 3 4 5 9 10
$(warning $(call my-sort,,$(NUMBERS))
which will output (the Makefile:2: part was generated by $(warning); the rest is the actual sorted list):
Makefile:2: 1 10 12 3 4 4 5 6 8 9
Or you could sort numerically with the -n option:
NUMBERS := 1 12 4 6 8 3 4 5 9 10
$(warning $(call my-sort,-n,$(NUMBERS))
which will output
Makefile:2: 1 3 4 4 5 6 8 9 10 12
Or even numerically, but in reverse order:
NUMBERS := 1 12 4 6 8 3 4 5 9 10
$(warning $(call my-sort,-n -r,$(NUMBERS))
which will output:
Makefile:2: 12 10 9 8 6 5 4 4 3 1
Dealing with duplicates
Since $(sort) always removes duplicates it's unsuitable for use if you need to sort a list but preserve duplicated entries. However, my-sort above works just fine for that purpose. If no options are specified in the first argument of my-sort then duplicates are not removed.
For example, you can sort the list a b a a c with my-sort like this:
DUPS := a b a a c
$(warning $(call my-sort,,$(DUPS)))
and the output is:
Makefile:2: a a a b c
In fact, the only way my-sort will remove duplicates is if the -u option is specified:
DUPS := a b a a c
$(warning $(call my-sort,-u,$(DUPS)))
and the output is:
Makefile:2: a b c
Another way to handle list deduplication is with the GNU Make Standard Library. It includes a function called uniq which removes duplicates from a list without sorting it. The first occurrence of each duplicated element is preserved.
For example, with the GNU Make Standard Library included (see http://gmsl.sf.net/ for more details) using include gmsl , the list b a c a a d can be deduplicated while preserving order:
include gmsl
DUPS := b a c a a d
$(warning $(call uniq,$(DUPS)))
which will output:
Makefile:4: b a c d
Searching for a file
Enough sorting, let's look at searching. First, searching for a file. As with sorting there are two options: use a built-in function and spawn a shell and use a shell program.
The built-in file searching function is called $(wildcard). Its argument is a pattern to search for on the file system and it returns a list of files and directories that match the pattern. It uses the same wild card patterns as the Bourne shell and so it's possible to use *, ? and ranges and character classes.
For example, to return a list of all files ending .c in the current directory you would write $(wildcard *.c) . To search all subdirectories of the current directory for .c files you can write $(wildcard */*.c) and so on.
$(wildcard) can also be used to find directories. If the pattern ends with / then the function only returns directories that match the pattern, and each directory will be suffixed with /. For example, to get a list of all the directories in the current directory do $(wildcard */) .
There are a few of $(wildcard) gotchas though:
1. $(wildcard) does not provide any way to recursively search a tree of directories.
2. $(wildcard) interacts in a surprising way with GNU Make's built-in directory cache mechanism which can mean that $(wildcard) doesn't reflect the actual state of the file system (for more on this see my article The Trouble with $(wildcard) :
3. $(wildcard) doesn't work correctly






