when Makefile execute some tasks, il will print many information in console, can we choose to hide them? when I have many .o to generate, these information will be too many to see and they are just meaningless if we don't read them.
The following code
$(obj)environment.o: $(src)environment.c
$(CC) $(AFLAGS) -Wa, --no-warn \
-DENV_CRC=$(shell $(obj)../tools/envcrc) \
-c -o $# $(src)environment.c
will print heavy information like
arm-linux-gcc -g -Os -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float
-D__KERNEL__ -DTEXT_BASE=0x01000000
-I/home/mingzhao/Documents/bootloader/u-boot-1.2.0/include
-fno-builtin -ffreestanding -nostdinc -isystem
/home/mingzhao/Documents/bootloader/arm/4.3.2/bin/../lib/
gcc/arm-none-linux-gnueabi/4.3.2/include -pipe -DCONFIG_ARM
-D__ARM__ -march=armv4 -mabi=apcs-gnu -Wall -Wstrict-prototypes
-c -o environment.o environment.c
The "right" way to handle this (IMO) is to add this to your makefile:
$(VERBOSE).SILENT:
Then in your rules where you don't ever want the command printed (for example, an echo statement as in Beta's answer below) you prefix it with #. For all other commands, you don't prefix it with #.
What this does is enable "silent" mode by default (because the variable VERBOSE is not set and so this resolves to the .SILENT pseudo-target).
Then if you want to see everything, you add a VERBOSE=1 (actually you can set it to any non-empty value, so VERBOSE=true if you prefer). When you do that it turns off "silent" mode because the above line expands to 1.SILENT: (or true.SILENT: or whatever) which is meaningless to make.
You can use the option make --silent which will suppress output for all targets. If you want to suppress output for some commands, you can prefix them by #
I like something like this:
$(obj)environment.o: $(src)environment.c
#echo building $#
#$(CC) $(AFLAGS) -Wa, --no-warn \
-DENV_CRC=$(shell $(obj)../tools/envcrc) \
-c -o $# $(src)environment.c
The #echo ... gives a minimal status message, the '#' in front of the $(CC) suppresses standard output (but still allows error messages).
You can use this syntax : #$(CC) $(AFLAGS) -Wa, --no-warn \...
Related
I wrote a kernel, without using -ffreestanding option, and while looking some kernels source codes, I see they compiled its kernels with -ffreestanding option. So, I tried to see what happens if I compile with the -ffreestanding option? And I see there was no difference between compiling with the -ffreestanding, and without the -ffreestanding option:
$ xxd kernel > kernel.xxd
$ xxd kernel_freestanding > kernel_freestanding.xxd
$ diff kernel kernel_freestanding
Why use an option, and see the files are same with, and without using that option?
And the diff's command output was empty, and the files are same.
Edit
That's how I compile, and it has no effect:
$(CPP_OBJS): %.o: %.cpp
$(CC) -m32 -nostdlib -nostdinc -fno-builtin -c $< -o $# -Iinclude -Iinclude/lib/k -Iinclude/lib/kc
i thought it would be easy but i can't actually figure out nor find on internet, a solution to advertise "compilation of the objects file" (for instance) just before compiling, and avoiding relink in the same time
my makefile would be something like this :
libfrog.a: $(OBJS)
#echo "building the library"
ar -rc $# $^
%.o:%.c
gcc -i. -c -o $# $<
which produce, when prompt "make" :
gcc -I. -c -o file01.o file01.c
gcc -I. -c -o file02.o file02.c
gcc -I. -c -o file03.o file03.c
gcc -I. -c -o file04.o file04.c
gcc -I. -c -o file05.o file05.c
building library
ar -rc libfrog.a file01.o file02.o file03.o file04.o file05.o
but i would like to have :
compilation of the objects files
gcc -I. -c -o file01.o file01.c
gcc -I. -c -o file02.o file02.c
gcc -I. -c -o file03.o file03.c
gcc -I. -c -o file04.o file04.c
gcc -I. -c -o file05.o file05.c
building library
ar -rc libfrog.a file01.o file02.o file03.o file04.o file05.o
now :
1 - if i put an echo before the rule libfrog.a is called (say by creating another first rule), it will print even if i prompt "make" two times and nothing is to be done...
2 - if i put an echo in the rule %.o:%.c it will print for each file
3 - if i put an echo as a dependency of the first rule it will force to relink all the files when prompt "make" again, even when just one file has been modified libfrog.a: echo $(OBJS) (and a rule "echo" which echo the text)...
so I've tried to echo for each compilation but with changing the text to echo nothing, i failed... i tried to create an echo.txt file just to create a rule that would depend on its existence but i failed too. I have no idea if it's possible ?
It's not really simple to do. But if you're using GNU make you can do it with the help of order-only prerequisites:
%.o : %.c | announce
gcc -I. -c -o $# $<
.PHONY: announce
announce:
echo "compilation of the objects files"
Personally I don't think showing this message is needed and I wouldn't add even the above amount of complexity to support it in my makefiles.
But if you really want to do it and you don't want the message to be printed unless some object file needs to be made, you'll have to get really fancy and do something like this:
PRINTED :=
%.o : %.c
$(or $(PRINTED),$(eval PRINTED := :)echo "compilation of the objects files")
gcc -I. -c -o $# $<
Once it's working you'll want to add a # before the first recipe line.
I know the silent flag (-s) for make will hide the recipe echoing completely, however this makes it hard to see progress.
For example currently I have hundreds of lines such as (I've broken up the line to fit SO):
g++ -I. -std=c++11 -Wall -Wno-unused-local-typedefs -Wno-literal-suffix
-Wno-unused-but-set-variable `wx-config --cxxflags --unicode=no`
-MT dialog_export.o -MD -MP -MF .deps/dialog_export.Tpo
-c -o dialog_export.o dialog_export.cpp
It would be great if it could just print part of the line, say without the flags, something like:
g++ dialog_export.o dialog_export.cpp
Or just some way of seeing progress, but without spamming the console with a tonne of messages.
A number of build systems from the autotools to the kernel build system to CMake, etc. do this sort of thing.
The trick is to dynamically control whether the silencing # is present on the recipe lines or not and if it is to replace it with a manual echo of some friendlier message.
To get a message like what you want you would use something like this:
E_g++ := #echo 'g++ $(filter %.o,$^) $#'
%.o: %.cpp
$(E_g++)g++ ... -o $# $^
To make this sort of thing easier for myself in projects that don't use the autotools or anything like that I wrote Silent Make Rules.
Which you would use like this:
include silent_rules.mk
$(eval $(call vrule,G++,g++ $$(filter %.o,$$^) $$#))
%.o: %.cpp:
$(SR_V_G++)g++ ... -o $# $^
This would also (like the autotools and kernel make versions) allow you to specify V=1 on the make command line to go back to the normal make output and use V=-1 to silence the output entirely.
I like rules like this:
dialog_export.o: dialog_export.cpp
#echo $#...
#g++ -I. -std=c++11 -Wall -Wno-unused-local-typedefs -Wno-literal-suffix -Wno-unused-but-set-variable `wx-config --cxxflags --unicode=no` -MT dialog_export.o -MD -MP -MF .deps/dialog_export.Tpo -c -o $# $<
The leading '#' symbols suppress command echoing, and the first command echoes the name of the target:
dialog_export.o...
If you have a makefile with hundreds of rules, you can convert them all to that form in minutes with a good editor. Or faster with a macro or sed, if you're bold.
(If you have hundreds of lines like that, your makefile can probably be simplified quite a lot, but that's for another day.)
I always use $(Q):
ifeq ("$(V)","1")
Q :=
vecho = #echo
else
Q := #
vecho = #true
endif
somerule:
$(vecho) building $# verbosely
$(Q)do command
You can then modify your pattern rules to only output the text you care about. If you need more verbose, then you just build with make V=1. I don't think there's any shortcut in make to doing this automatically save piping your output through sed (which I wouldn't recommend).
I'm using CentOS 6.5. When I do a make, I typically see the full gcc/g++ commands that the Makefile is executing, like
...
gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I/opt/emacs/emacs-24.3/lib -I../src -I/opt/emacs/emacs-24.3/src -g3 -O2 -MT pthread_sigmask.o -MD -MP -MF .deps/pthread_sigmask.Tpo -c -o pthread_sigmask.o pthread_sigmask.c
...
But in some systems, I only see:
$ make
Building test1.o...
Building test2.o...
...
Is it possible to change the "Building ..." messages back to the full gcc/g++ command output?
The output that you see when you run make with a given makefile
depends on how the makefile is written. You will see the
output that the author of the makefile wants you to see.
If a command in a recipe in the makefile is prefixed with #,
then make will not echo the command. So if my makefile is, e.g.
foobar: foobar.o
gcc -o $# $<
foobar.o: foobar.c
gcc -c -o $# $<
then the output of make will be:
gcc -c -o foobar.o foobar.c
gcc -o foobar foobar.o
But if I change the makefile to:
foobar: foobar.o
#echo "Linking foobar"
#gcc -o $# $<
foobar.o: foobar.c
#echo "Compiling foobar"
#gcc -c -o $# $<
then the output becomes:
Compiling foobar
Linking foobar
So to see the output that you would prefer to see you will have to edit the
makefile, removing the #-prefixes from the commands you expect to see
and deleting entirely the commands that print the "Building..." messages.
At least, this is what you would need to do if the makefiles that bother
you in this way build the target using recipes that directly invoke gcc/g++. It
is possible that they build their targets using recipes that invoke some intermediate
tool that doesn't echo the compiler commands and instead emits the "Building..."
messages. Without seeing the makefile(s) I can't say.
I want to run the next line in a makefile:
g++ -O2 -g -Wall -c -fmessage-length=0 -MMD -MP -MF"$(#:%.o=%.d)" -o "$#" "$<"
I want to define a variable that will contain all the flags:
FLAGS := -O2 -g -Wall -c -fmessage-length=0 -MMD -MP -MF"$(#:%.o=%.d)"
and then use this variable instead of the hardcoded line:
g++ $(FLAGS) -o "$#" "$<"
however the last part of the above line (the quoted part) creates problems.
my question is how can I assign this line to a variable? I tried all kind of escape characters combinations but nothing seems to work.
thanks.
The issue comes from the FLAGS :=. Indeed, using the := operator to set the FLAGS variable instructs make to evaluate the value of the variable only once and now. However, at the time of the definition of FLAGS, variable # is not defined. It will only be defined within the rule that has the g++ command. That's why it results in -MF"".
You should use FLAGS= (no column). Defined with the simple =, the FLAGS variable will only be evaluated when used, i.e. in the g++ command line. At that place, the $# variable will be defined and valid.