2

I need to run a multi-command recipe for my object. But the subsequent command must not be run if a grep of the previous command results in a particular string being found. How can I write this?

run_sim:
    $(MAKE) compile; \
    (Here I need grep of results of log of compile command) && $(MAKE) elaborate; \
    (Here I need grep of results of log of elaborate command) && $(MAKE) simulate;

If grep comes back with the string being found, then make must not execute the next command but stop.

  • `grep of results of log of compile command` - why would you do that? Why would it matter what any command prints? – KamilCuk Oct 25 '19 at 21:56
  • I need to know the results of the compile. Usually there is a particular string in the compile log if the compile fails. So if I find that string, then I know not to move forward in the Make recipe. Any suggestions on how to do this? – novice_make_user Oct 26 '19 at 16:00
  • `the results of the compile` - the result of compilation is a file, not stdout output. `make` is a tool that checks dependencies between a file. Also, if previous command fails, make will not continue the work. So just remove all the \ backslashes and remove the `grep` things and just `$(MAKE) compile` and `$(MAKE) elaborate` and `$(MAKE) simulate` on 3 separate lines.... – KamilCuk Oct 26 '19 at 18:58
  • I already have the 3 separate make objects (compile, elaborate, simulate). I now need to put all 3 together into one make object so it runs all three when i run 'make run_sim'. How do I do that? – novice_make_user Oct 26 '19 at 21:58

2 Answers2

0

I already have the 3 separate make objects (compile, elaborate, simulate). I now need to put all 3 together into one make object so it runs all three when i run 'make run_sim'. How do I do that?

Just like that:

.PHONY: run_sim
run_sim:
    $(MAKE) compile
    $(MAKE) elaborate
    $(MAKE) simulate

But it would be better to create a proper dependency tree:

.PHONY: compile
compile: output.out ;

output.out: something.c
     gcc something.c -o output.out

.PHONY: elaborate
elaborate: compile
    do_the_elaboration


.PHONY: simulate
simulate: compile
    do_the_simulation

.PHONY: run_sim
run_sim: compile elaborate simulate ;

It would be wise to review an GNU make introduction, GNU make manual and review the information about GNU make: error handling. Info about phony targets can be found at GNU make: phony targets, stackoverflow: What is the purpose of .PHONY target?,

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • How is this different from what I had originally? Will this not execute elaborate if compile output file has a problem? That is what I need. – novice_make_user Oct 26 '19 at 22:22
  • https://www.gnu.org/software/make/manual/html_node/Errors.html#Errors `If there is an error (the exit status is nonzero), make gives up on the current rule, and perhaps on all rules.` The "gives up" literally means to stop the execution on the current recipe and exit with nonzero exit status. – KamilCuk Oct 26 '19 at 22:22
  • But that is the whole problem. The compile step does not exit with an error status as far as make is concerned. The compile step has no return status back to the Make shell that ran it. The error of the compile step is an error to another tool outside of make, not to make itself. That is why I need to do an intermediate grep or some such to find if there is an error in the compile in order to continue make. It appears that this is not possible? – novice_make_user Oct 26 '19 at 23:10
  • Then you I would turn to fix the compile step. `grep` returns with a nonzero exit status if a string is not found. How do you compile then? One way, would be to save the compile output to a file by piping it to `tee` and then check if it contains output with `grep`. So, what is your compile command? – KamilCuk Oct 26 '19 at 23:11
0

Verilog?

What I did in a similar situation, and it may be a Make novice/electrical engineer error of my own, is this:

compile.summary: compile.log
    @echo Making $@
    @grep -q PASSES $<
    @echo Compile PASSES > $@

Because the grep -q will fail if 'PASSES' is not present in compile.log, Make will screech to a halt.

You simply make elaborate dependent on compile.summary.

If you were searching for something like '*E' or 'Error', you could instead use grep -qv 'Error' where '-v' will have grep return an error if it finds the string in compile.log.

This isn't all that user friendly, though. In the failure case, you'll simply see "Making compile.log" followed by... nothing.

In my case, it was actually dealing with programs that never return 0, so the logs have to be grepped for acceptable fails versus fatal fails.

As the other answer is getting at, it's a lot easier to manage dependencies with actual files as targets. A PHONY compile target might mean that you always re-compile when you elaborate... because it has no file+timestamp to know the freshness of the last compile vs. the inputs to the compile. It's better to have compile.log be the actual file that elaborate is dependent upon.

stevesliva
  • 5,351
  • 1
  • 16
  • 39
  • Excellent. Thanks. This is what I am looking for. Yes, VHDL/Verilog compilation/simulation. My problem is that the simulation step will load all the simulator windows and perform all the pre-sim actions which takes up a lot of time even when i know the compile failed way back. That is why I would like to cut the whole thing off before getting past each stage if there are any errors. Even if its not user friendly, its better to stop earlier to save time so I know for sure that everything is correct if/when the simulation actually starts running. I will try doing what you suggested. – novice_make_user Oct 27 '19 at 03:08