Reputation: 4611
I am currently working through a c++ textbook; I'd like to have separate folders for exercises in the book, and a single makefile in the root, so that in the root directory I can type
make directoryName
and it will compile all the sources in that directory, and output a binary into the root. Here is what I have so far:
FLAGS= -Wall -Wextra -Wfloat-equal
OUT=helloworld.out
%: $(wildcard $@/*.cpp)
g++ $@/$(wildcard *.cpp) -o $(OUT) $(FLAGS)
But when I try to run it, all I get is
pc-157-231:Section2$ make helloWorld
make: `helloWorld' is up to date.
Any help appreciated
Edit Note; the problem is not that I haven't changed the target file; I did...
Upvotes: 5
Views: 861
Reputation: 7292
I have written a replacement for make that makes this very easy, but it is otherwise very experimental / not-officially-supported etc. You can download it from https://github.com/dascandy/bob .
You would probably be able to write this as:
FLAGS= -Wall -Wextra -Wfloat-equal
# Take all cpp files in a folder & compile it to executable with that folder name as name.
(.*)/.*\.cpp => \1.out
g++ -o $@ $^ $(FLAGS)
or alternatively, with intermediate objects (better for large projects, but probably useless for small exercises)
FLAGS= -Wall -Wextra -Wfloat-equal
# Read as, compile any CPP file to a file with the same root but .o as extension
(.*)\.cpp => \1.o
g++ -c -o $@ $^ $(FLAGS)
# read as, take all objects in a subfolder together and compile into executable with folder name as name.
(.*)/.*\.o => \1.out
g++ -o $@ $^
The tool itself requires Boost.Filesystem to be installed.
If you want to have a default target that compiles all executables, add these lines:
.*.out => all
echo -n
(the echo is because it expects all rules to have a command)
Upvotes: 0
Reputation: 8537
Your problem is that automatic GNU make variables such as $@
only have a value within the body of the rule. From GNU make documentation.
[Automatic variables] cannot be accessed directly within the prerequisite list of a rule. A common mistake is attempting to use
$@
within the prerequisites list; this will not work. (source)
Additonally, you do not need the $(wildcard ...)
function in your rule (both in body and in prerequisite list), although it's not a mistake either:
Wildcard expansion happens automatically in rules. (source)
Upvotes: 1