Command chaining in GNU make. Execute next command depending on success or failure (exit code) of previous command.

By neokrates, written on February 24, 2011

howto

  • Join date: 11-30-99
  • Posts: 224
View Counter:
  • 161 views
Rate it
Ad
Poll
  • Which features are most important for perfect CI tool?

    View Results

    Loading ... Loading ...
Feeds:
  • bodytext bodytext bodytext

In my case, I have a very specific problem. I compile large c / c++ project with many makefile’s and sometimes specific failure happens.
I wish to instruct gnu make to wait and then to start again. And in the case that compilation is ok, don’t wait anymore, do next thing.

Given, that file makecommand.mk is to be executed. It contains

$(CC) /nologo $(INCLUDE_FILES) $(C_FILES)

This command is executed each time for different $(INCLUDE_FILES) $(C_FILES). And, many gnu make instances run in parallel.
The compiler which I use is embedded visual studio compiler. And it has specific problem of locking .pdb and .pch files.
Also, I know, that locked header files will be released after some minutes.
So, I want to catch the output of compiler, parse it and if the problem is .pdb or .pch, wait for some minutes.

1

The basic rule, how the commands in GNU make can be chained

$(COMMAND1) || $(COMMAND2) && $(COMMAND3)

Here, I instruct make to run the $(COMMAND2) if $(COMMAND1) has failed.
I also expect $(COMMAND3) to be run ONLY if $(COMMAND2) was successfull.

In my scenario, I would like to:
1. to compile
2. validate the error if there is any or continue if there is none ( previous failed ||)
3. sleep if I expect that error is race condition and resource will be released soon ( previous success &&)
4. try again ( previous success &&)

2

Use make recursion, so that exit code can be evaluated

I write out make commands in extra .mk file. This way, they give return code, but make doesn’t fail automatically.
That is not always needed, but was usefull in case of compile and grep commands.

3

Grep command to identify the .pch\ or \.pdb error:

I will put it in extra file.

@echo .PHONY all: >  grepcommand.mk
@echo 	grep "vc60\.pch\|vc60\.pdb" error.log >> grepcommand.mk

4

Compile command in extra file

@echo .PHONY all: >  makecommand.mk
@echo 	$(CC) /nologo $(INCLUDE_FILES) $(C_FILES)  >> makecommand.mk 

5

Grep for error if there was an error…

$(MAKE) -f makecommand.mk --no-print-directory all > error.log || $(MAKE) -f grepcommand.mk --no-print-directory all 

6

Wait for 180 sec, if grep matches the error we know…

My $(SLEEP) command is custom perl implementation, simple to add into GNU make.
If the grep was successful, then vc60.pch or vc60.pdb files where locked and I want to wait…
I add echo and I add $(SLEEP)

$(MAKE) -f makecommand.mk --no-print-directory all > error.log || $(MAKE) -f grepcommand.mk --no-print-directory all && $(ECHO) pdb/ pch problem, wll wait for 180 sec and retry && $(SLEEP) 180

7

Try to recompile three times …

Sleep is always successful, just add \&& and copy/paste the code line 3 times.

$(MAKE) -f makecommand.mk --no-print-directory all > error.log || $(MAKE) -f grepcommand.mk --no-print-directory all && $(ECHO) pdb/ pch problem, wll wait for 180 sec and retry && $(SLEEP) 180 && \
$(MAKE) -f makecommand.mk --no-print-directory all > error.log || $(MAKE) -f grepcommand.mk --no-print-directory all && $(ECHO) pdb/ pch problem, wll wait for 180 sec and retry && $(SLEEP) 180 && \
$(MAKE) -f makecommand.mk --no-print-directory all > error.log || $(MAKE) -f grepcommand.mk --no-print-directory all && $(ECHO) pdb/ pch problem, wll wait for 180 sec and retry && $(SLEEP) 180 && \
$(MAKE) -f makecommand.mk --no-print-directory all

have fun

Be Sociable, Share!
 
Does that help to solve your problem?
VN:F [1.8.5_1061]
Rating: 0 (from 0 votes)
0 votes 'YES'  0 votes 'NO'


TAGS
No tags for this post.

SOCIAL
Be Sociable, Share!

INCOMING SEARCH TERMS


Leave a Reply