Reputation: 1965
I would like to compile and run in one rule. Now I have :
CC = g++
%: %.o
$(LINK.c) $^ -o $@;
./$@
But the make only compiles the source to binary, but do not run it. How to construct make to do this in one step?
Having file foo.cpp
. Applying the makefile:
user@Host:~/Desktop/bin/2$ make foo
g++ foo.cpp -o foo
user@Host:~/Desktop/bin/2$
Compilation is done. After which I want to run it (and see the output of that program), but that will not happen.
EDIT: Please use patterns, I will not accept solution with explicit filenames.
Upvotes: 0
Views: 1905
Reputation: 368181
I suspect you are being tripped up by the implicit rules in make
. It already knows how to a) make an object file from a C++ source and b) how to link.
So I suggest to rewrite the Makefile
to be more explicit. One example would be
all:
g++ -c hello.cpp
g++ -o hello hello.o
./hello
where I redefine the default all
target and (for simplicity) make the steps explicit. With a trivial file such as this
#include <iostream>
int main() {
std::cout << "Hello, world." << std::endl;
exit(0);
}
it works as expected:
$ make
g++ -c hello.cpp
g++ -o hello hello.o
./hello
Hello, world.
$
You can refine and adapt as needed, i.e. with the $^
and $@
variables as needed.
Edit: Here is a second variant. It does "nothing" as building a executable from (same-named) source file is known to make
. So here I just do three things:
all
target to run the programs one-by-oneThe following (minimal) Makefile
does that:
sources := $(wildcard *.cpp)
programs := $(sources:.cpp=)
all: $(programs)
./$^
Works as expected:
$ ls -l
total 8
-rw-rw-r-- 1 edd edd 94 Nov 15 16:36 hello.cpp
-rw-rw-r-- 1 edd edd 88 Nov 15 17:13 Makefile
$ make
g++ hello.cpp -o hello
./hello
Hello, world.
$
I actually use that very same pattern in an example directory with 18 or so example in this repo.
Edit 2: The above actually run one command over all targets in programs
; I copied it from strip
invocation where that makes sense. One may to have them all run after they have been built is to use this:
sources := $(wildcard *.cpp)
programs := $(sources:.cpp=)
all: $(programs)
for p in $(programs); do ./$$p; done
Upvotes: 1