rAAbert
rAAbert

Reputation: 35

How do I make a Makefile to log both command and its output to a file?

I want to log both the command and its output to a log file. It seems easy. Just redirect stdout to the log file.

myrule:  
  mycommand >> logfile  

But this only logs the output of the command. Not the command itself.
Do I also echo the command and redirect that output to the log file?

myrule:
  @echo mycommand >> logile
  mycommand >> logfile

This duplication of 'mycommand' doesn't look good and it takes up space in the recipe. Especially if the recipe is long.

Should I create a function and call it for every command I want to log?

define log_and_run
@echo $(1) >> logfile
$(1) >> logfile
endef

myrule:
  $(call log_and_run,mycommand)

Now I don't have to duplicate 'mycommand'. But now 'mycommand' is less visible in the recipe. Attention is on the 'call', not on 'mycommand'.

And what if 'mycommand' is something like

$(CC) -o $@ -Wl,--linkeroption $<

The comma will split the command into two arguments when calling 'log_and_run'.

Does anybody have a solution for this that doesn't take attention away from the commands and works for arbitrary commands?

Upvotes: 3

Views: 20684

Answers (2)

Stefan Becker
Stefan Becker

Reputation: 5962

Let the shell do all the heavy lifting, maybe? I.e. something like this:

.PHONY: all myrule myrule-with-macro
all: myrule myrule-with-macro

mycommand = echo "Running $@..."

myrule:
    (set -x; $(mycommand)) >>[email protected] 2>&1

define log_and_run
(set -x; $(1)) >>[email protected] 2>&1
endef

myrule-with-macro:
    $(call log_and_run,$(mycommand))

Test run:

$ make
(set -x; echo "Running myrule...") >>myrule.log 2>&1
(set -x; echo "Running myrule-with-macro...") >>myrule-with-macro.log 2>&1

$ ls myrule*.log
myrule.log  myrule-with-macro.log

$ cat myrule*.log
+ echo 'Running myrule...'
Running myrule...
+ echo 'Running myrule-with-macro...'
Running myrule-with-macro...

Upvotes: 3

battlmonstr
battlmonstr

Reputation: 6290

It is a default behaviour of make to print both the command and its output to stdout. An obvious solution is to just have

myrule:  
    mycommand 

but then call make myrule > logfile.

If you want to do the redirection from within the Makefile, you can invoke make recursively from a special target based on some variable being set (or not set).

Upvotes: 1

Related Questions