How can I suppress the 'is up to date' message from Make? - makefile

How can I tell Make to stop logging
make: `foo.o' is up to date
When foo.o is up to date?

You can use the -s / --silent option to make to suppress output; from the documentation:
‘-s’
‘--silent’
‘--quiet’
Silent operation; do not print the recipes as they are executed. See Recipe Echoing.
It doesn't say so explicitly but this also suppresses other types of informative output.

Related

debugging Makefile how to suppress silence

Is there a way to suppress the silence '#' in the rules?
I want to see what the Makefile does but all rules from a given Makefile are defined with the '#' in front like:
go:
#do something here...
I search for an option to see the output as # was not there.
You can run make with the -n flag. You will be able to see which commands are executed. Without actually executing them though!
From GNU make manual:
When make is given the flag ‘-n’ or ‘--just-print’ it only echoes most
recipes, without executing them. See Summary of Options. In this case
even the recipe lines starting with ‘#’ are printed. This flag is
useful for finding out which recipes make thinks are necessary without
actually doing them.
Aside from using -n as suggested you could (if the makefile is under your control to edit) look at using something like my automake-inspired silent make rules stuff.
Which lets you override the silencing at make run time dynamically.
You might be willing to do this:
At the top of the makefile, put silence ?= #
Change all the #-prefixes to $(silence).
Then make will observe the silences by default and make silence= will
be verbose.
If you don't want to do that, there's a pretty good chance that:
cat Makefile | sed 's/\t#/\t/g' | make -f -
will do the trick.

.SHELLFLAGS assignment in makefile

From the docs:
...You can modify .SHELLFLAGS to add the -e option to the shell which will
cause any failure anywhere in the command line to cause the shell to
fail...
So, given the following makefile:
.SHELLFLAGS = -e -c
define cmd
echo true
true
endef
all::
$(shell $(cmd))
Running, I get:
truetrue
/bin/sh: 1: truetrue: not found
makefile:10: recipe for target 'all' failed
make: *** [all] Error 127
Did you see that (in the 1st line of output)? truetrue? Where did it come from?
Let's compare it with the following identical makefile, where -e was not added to .SHELLFLAGS.
The makefile, would be:
# Do you see the difference, from the previous Makefile?
# Here, the value is '-c' alone. No '-e' flag is present here!
.SHELLFLAGS = -c
define cmd
echo true
true
endef
all::
$(shell $(cmd))
Running, I get:
true true
Much better!
So, we have here 2 versions of makefile, both run identical commands, where the first version also added the -e flag to .SHELLFLAGS.
The results however - for the respective runs - were not consistent! We had:
Expands to the trivial command true true, which is analogous to the trivial command : true (i.e "ignore arguments..."), and therefore an exit-status: 0.
This was for the "simple" run, without the change in .SHELLFLAGS. (version 2).
As for the first run, Make went ahead, and condensed the command to truetrue (really?), hence: a meaningless command and a fatal error from the shell.
In summary: It seems that adding -e to .SHELLFLAGS is not that innocent as the documentation suggested above.
In fact, Make, then (when .SHELLFLAGS is modified to include -e), and only then - Make takes the liberty to do some more (unexpected?) modification to the command, resulting - for example - here with the command truetrue for a true true command.
Really?
(Versions-note: All versions supporting .SHELLFLAGS, which is 3.82 and up).
I’ve never understood using $(shell ...) in a recipe. There may be one or two
situations where it’s useful, but I see it constantly and I’ve yet to see one.
However, you’ll note that the documentation says that the value for
.SHELLFLAGS when you want to use the -e flag should be -ec, not -e -c.
Some versions of the Bourne shell do not accept multiple flags on the command
line: they must be a single set of flags. If you use -ec then your example
works.
The difference in behavior you’re seeing is in the treatment of newlines in
recipes: in some situations they’re removed along with the initial TAB, in other
situations they’re converted to a single space. I don’t know why adding a second
option to .SHELLFLAGS causes this but I agree with tripleee: you should
file a bug.

Makefile: what is "#-"?

In a makefile I use there is #-, that is not mentioned in any makefile tutorial I could find.. Could you please explain what #- is for?
For example:
#- $(RM) *.o
The at-sign # tells Make to not print the command line before executing it.
(Manual: Recipe echoing)
The minus sign - tells Make to ignore the result of the command and not fail the target if it was unsuccessful.
(Manual: Errors in recipes)
In your case it's just both of them being used, because somebody did not want to pollute the output with the erase command, and did not want to fail the build if anything goes wrong with the deletion either.

Conditional part of makefile always evaluating to true

I have a legacy makefile based build system that I am trying to make changes to. I am not familiar with make and so was making changes on a trial and error basis.
Not being able to deduce what the problem is I inserted this bit of code in the makefile:
ARG1 = GCC
ARG2 = ARM
ifeq($(ARG1),$(ARG2))
$(warning *** WARNING ***)
endif
When I run make, I always get the print:
\PathToBuildDirectory\makefile.options:54:*** WARNING ***
NOTE: I am using clearmake with the -C gnu option.
How or why does the condition evaulate to true?
If it behaves this way for a makefile consisting of only the above content then it's a bug in clearmake. I know that clearmake's emulation of GNU make is incomplete, but this seems pretty simple.
However, since you're already echoing an error wouldn't it be straightforward to also show the values of ARG1 and ARG2? Maybe they ARE equal. Maybe one or both are set on the command line. Maybe elsewhere one or both was assigned with the override option. Maybe clearmake is invoked with the -e option and one or both of those variables are set in the environment.
If you show their values, then you'll know.
ETA: Maybe the problem is this: in GNU make you must put a space after the ifeq, like this:
ifeq ($(ARG1),$(ARG2))
If you try your original version with GNU make, you'll get an error:
Makefile:3: *** missing separator. Stop.
but I guess clearmake just ignores the line without any error messages.

How to treat a warning as an error in a Makefile?

Is it possible to treat warnings as errors in a Makfile (and thus exit before Makefile proceeds)
Furthermore, is it possible to filter out which warning yields an error?
My use case: I want to use --warn-undefined-variables in combination with this so that Makefile will exit when a variable is undefined, which is a very common source of error. Obviously I don't want to manually check for each variable as this is error-prone/tedious. I couldn't find anything on this, but it's a pretty important/basic feature.
Note: I'm not looking for -Werror which is a gcc specific command not applicable to my use case.
If you're prepared to add a dependency to every target, you can make warnings into errors.
Here is a make file with an error in it ("SRCS" instead of "SRC"):
# Turn on the warning we want
MAKEFLAGS += --warn-undefined-variables
# Make sure MAKECMDGOALS is defined, so it doesn't cause an error itself
ifndef MAKECMDGOALS
MAKECMDGOALS = all
endif
SRC=hello.c
all: compile
# Fails if the Makefile contains any warnings.
# Run this Makefile with the same goals, but with the -n flag.
# Grep for warnings, and fail if any are found.
no-make-warnings:
! make -n $(MAKECMDGOALS) 2>&1 >/dev/null | grep warning
# Targets you want to check must depend on no-make-warnings
compile: no-make-warnings
gcc -o hello $(SRCS)
When I run it, I see this:
$ make
! make -n all 2>&1 >/dev/null | grep warning
Makefile:17: warning: undefined variable `SRCS'
make: *** [no-make-warnings] Error 1
You just need to make every target that you want to be checked depend on the target no-make-warnings.
If someone knows how to do that automatically, please chime in.
The standard version of make does not support what you are looking for. However, it should not be difficult to build your own version of make to fulfill your use case.
Looking at the source code of make 3.82, check out the macro warn_undefined in variable.h:
214 /* Warn that NAME is an undefined variable. */
215
216 #define warn_undefined(n,l) do{\
217 if (warn_undefined_variables_flag) \
218 error (reading_file, \
219 _("warning: undefined variable `%.*s'"), \
220 (int)(l), (n)); \
221 }while(0)
I have not tried this, but I think it should be sufficient to replace error with fatal.

Resources