Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefiles: using `wildcard` vs. `find` for specifying source files

TL;DR: How can I use find in a Makefile in order to identify the relevant source files (e.g., all .c files)? I know how to use a wildcard but I'm not able to get find to work.

Longer version: I'm putting together a Makefile as part of an exercise on shared libraries; I noticed that when I use the following lines to specify the source and object files (i.e., .c files) for my shared library, I get an error after running make (gcc fatal error: no input files):

SRC=$(find src/ -maxdepth 1 -type f -regex ".*\.c")
OBJ=$(patsubst %.c,%.o,$(SRC))
*rest-of-makefile*

However, it compiles correctly when I use wildcard instead of find:

SRC=$(wildcard src/*.c)
OBJ=$(patsubst %.c,%.o,$(SRC))
*rest-of-makefile*

(As reference, included below is confirmation that the find command does indeed return the intended file when run from the shell.)

What is the correct syntax for using the find command (in my Makefile) to search for my source files (if it's at all possible)?

(Why would I prefer to use find?: I like the fact that I can quickly double-check the results of a find statement by running the command from the shell; I can't do that with wildcard. Also, I'd like to rely on regexes if possible. )


As reference, below is the relevant tree structure. As you can see (from the second code-block below), running the find command as specified in the Makefile (i.e., from above) does indeed return the intended file (src/libex29.c). In other words, the issue described above isn't because of a syntax problem in the find options or the regex.

.
├── build
├── Makefile
├── src
│   ├── dbg.h
│   ├── libex29.c
│   └── minunit.h
└── tests
    ├── libex29_tests.c
    └── runtests.sh

Results of running find from the . folder above:

~/lchw30$ find src/ -maxdepth 1 -type f -regex ".*\.c"
src/libex29.c

P.S. I know this post technically violates the rule that all posted code must compile - I just thought that including the entire code for the both the Makefile as well as the libex29.c source file would be overkill. Let me know if that's not the case - happy to post the files in their entirety, if folks prefer.

like image 737
iceman Avatar asked Nov 01 '14 23:11

iceman


1 Answers

Make doesn't have a find function. You have to use the shell function to run find. Also you should always use := not = for shell (and wildcard, for that matter) for performance reasons. And you should put spaces around assignments in make, just for clarity:

SRC := $(shell find src/ -maxdepth 1 -type f -regex ".*\.c")

Also I don't see why you want to use find here. find is good if you want to search and entire subdirectory structure which contains more than one level, but wildcard is far more efficient for simple directory lookups.

like image 141
MadScientist Avatar answered Oct 11 '22 12:10

MadScientist