Imagine the following target and command generated by autoconf:
.c.lo:
$(LTCOMPILE) -MT $# -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $# $<
$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
I'm looking for a way in Makefile.am to manipulate that command, knowing that the command is generated by autoconf and I don't know what it is. In theory, something like this:
if BUILD_QUIETLY
Q=#
endif
.c.lo:
$(Q)$(autoconf-command-for-c-lo)
Or something like this (this is similar to Linux kernel's build output):
quiet_cmd_cc = CC $#
cmd_cc = $(autoconf-command-for-c-o)
.c.o:
$(call cmd,cc)
Where cmd is a function that executes cmd_$1 and either prints quiet_cmd_$1 or cmd_$1 based on a variable.
I looked for this on the internet, but most of the websites talk about the basics of autoconf. There doesn't seem to be any questions related to this here either.
Is this even possible?
Per chirlu's comment, automake has an option to generate quiet output builds.
This page has the necessary instructions. In short, put the following in configure.ac:
AM_SILENT_RULES([yes])
To then disable it, either do:
make V=0
after configuration, or:
./configure --enable-silent-rules
on configuration.
You can always pipe the output to /dev/null:
./configure 2>&1 >/dev/null
make 2>&1 >/dev/null
Related
Several modules each are tested independently with their own test_$(MODULE).c.
A shared library has been generated $(LIBRARY) containing modules without coverage. $(basename $<).o should override the one in $(LIBRARY). For some reason, I get results as if they are not overridden. Can someone review this and make suggestions on fixes? Currently I have non-generic gcov rules for each of the five objects. These gcovs work correctly. Below I show the generic rule and one specific use of the rule.
SHARED_OPTS=-O0 -Wall -Wextra -fPIC
GOPTS=$(SHARED_OPTS) -g -coverage -pg
%.gcov : %
#echo "\t$# generic (needs work)"
#-gcc $(GOPTS) -c -o test_$(basename $<).o test_$<
#-gcc $(GOPTS) -c -o $(basename $<).o $<
#-gcc $(GOPTS) -o gcov_test_$(basename $<) \
test_$(basename $<).o \
$(basename $<).o \
-L . -l $(LIBRARY)
#-./gcov_test_$(basename $<)
#-gcov $< >$#.out 2>&1
#echo "no Mac gprof: -gprof gcov_test_$(basename $<) gmon.out > $<.prof"
#$(call timestamp,$#)
Unicode.c.gcov: Unicode.c
If anyone is interested in collaborating on high efficiency high quality Unicode lexing/parsing support by developing a shared library, I would love to have reviewers or contributors.
The Makefile fragment shown above is in a github repository:
https://github.com/jlettvin/Unicode Specifically down the c subdirectory.
While you're trying to find problems in your makefile you should avoid using #, as it hides the command line and so you can't see issues. Also you should avoid - here: if any of those commands fail you certainly don't want to continue to run the rest of the recipe, I wouldn't expect.
I don't know if it's a cut/paste problem but I have to assume that these lines, at least, are wrong:
#-gcc $(GOPTS) -c -o test_$(basename $<).o test_$<
#-gcc $(GOPTS) -c -o $(basename $<).o $<
As far as I can tell from your makefile, the last words on these lines should be test_$<.c and $<.c respectively.
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 have a master Makefile that calls submakefiles inside directories.
Those submakefiles are generated by autotools starting from Makefile.am and configure.ac files.
The first target of the entire project is a shared library, while the others are executables that link against it (so there is a dependency in the main Makefile).
The problem is that I can only see the compilation output of the shared library, while the other projects are just printing warnings and errors (just stderr text, I believe).
I can't understand what is causing this behaviour since all the projects are called from the very same rule in the master Makefile and all the submakefiles are autogenerated from very seemed configuration files.
The snippet of master Makefile that compiles all the targets looks like this:
SUBDIRS = libMylib app1 app2 app3
$(SUBDIRS):
$(ECHO) "-> Building $#"
$(MAKE) -C $#
$(ECHO) "-> Build of $# finished."
The output of "libMylib" is like:
-> Building libMylib
libtool: compile: ppc-linux-gcc -DHAVE_CONFIG_H -I. -I/opt/ELDK/ppc_8xx/usr/include/ -I/opt/ELDK/ppc_8xx/include/ -Wall -std=gnu99 -O2 -MT libMylibF1.lo -MD -MP -MF .deps/libMylibF1.Tpo -c libMylibF1.c -fPIC -DPIC -o .libs/libMylibF1.o
...
libtool: link: ppc-linux-gcc -shared -fPIC -DPIC .libs/libMylibF1.o .libs/libMylibF2.o .libs/libMylibF3.o -Wl,-rpath -Wl,/opt/ELDK/ppc_8xx/lib -Wl,-rpath -Wl,/opt/ELDK/ppc_8xx/lib -lz -lpthread -O2 -Wl,-soname -Wl,libMylib.so.0 -o .libs/libMylib.so.0.0.0
libtool: link: (cd ".libs" && rm -f "libMylib.so.0" && ln -s "libMylib.so.0.0.0" "libawmg.so.0")
libtool: link: (cd ".libs" && rm -f "libMylib.so" && ln -s "libMylib.so.0.0.0" "libMylib.so")
libtool: link: ( cd ".libs" && rm -f "libMylib.la" && ln -s "../libMylib.la" "libMylib.la" )
-> Build of libAwmg finished.
While the output of any "appN" is:
-> Building app1
app1F1.c: In function `app1F1Func1':
app1F1.c:161: warning: unused variable `varA'
app1F2.c:85: warning: `app1F2FuncX' defined but not used
-> Build of app1 finished.
Could anyone please help me?
EDIT:
I found out that I was able to see the compile stuff in "libMylib" because it is "libtoolized".
If I "libtoolize" another project, I can see the linker part of the output (libtool: link:...).
So, considering that make calls a shell (sh) for each line in the rule, that $(MAKE) equals to just "make" and, by default, make is verbose, why do the submake is not printing its output to stdout?
Which flags may be passed to it so that this happens?
It depends on the Makefiles in the sub directories. If, for example, you have a # in front of the compile commands in the app Makefiles, then they will not output the commands that were being run (also look for $(Q), which is used quite commonly when you want to enable/disable verboseness in makefiles). Alternatively, your make commands in the apps directories may be pushing stdout to some files (which would still allow you to see the warnings).
By the same token your library makefile may be incorrectly redirecting stderr elsewhere, which would explain why you don't see any error outputs on that (or it just doens't have any errors...)
Please post the build rules in the other directories (and all associated variable definitions) if you want more help.
Well, my master makefile includes another file that puts a .SILENT rule in.
I haven't noticed that until today.
Removing this rule makes everithing work as expected.
Oh my...
How I stop make from saying make: Nothing to be done for 'all'. or make: 'file' is up to date? I'd like my build to be silent when it's not doing anything - there are other places where echo is called to track build progress, so this message is just cluttering things up. I am currently silencing it like this:
all: dependency1 dependency2
#:
Something tells me there must be a better way. Any ideas?
Edit:
I would like to keep command echo working when it does need to build something, however. A good example of what I'm hoping for is along the lines of --no-print-directory, but I can't find any other flags to shut up selected messages.
Maybe make -s?
So after a couple days of reading around the web, it looks like there isn't any better way than what I'm doing. Some people recommended something along the lines of:
all: dependency1 dependency2 | silent
silent:
#:
That is, just depending on the silent target would be enough to quiet things down. Since I didn't come up with any other workable solutions, I'm going with what I have.
You might try...
$ make -q || make
The advantage of doing it this way is that nothing is printed when there is nothing to do but make produces the normal output when it does need to proceed...
To quote (from memory) from the old make(1) man page, BUGS section: There are some things you can't get make to shut up about. Meanwhile, the -s or --silent option may help.
You can set the -s commandline argument to make in the makefile itself, by setting MAKEFLAGS. Nothing is printed unless you explicitely print it, so I use the following makefile to echo invoked commands.
MAKEFLAGS += -s
PROJECT = progname
CC = g++
SDIR = src
ODIR = obj
BDIR = bin
IDIR = include
OBJS = $(patsubst $(SDIR)/%.cc,$(ODIR)/%.o,$(wildcard $(SDIR)/*.cc))
.PHONY: all debug clean
all: $(BDIR)/$(PROJECT)
debug: CFLAGS += -g -Wall -Wextra
debug: all
$(BDIR)/$(PROJECT): $(OBJS)
#mkdir -p $(BDIR)
#echo LINKING $<
#$(CC) -o $# $(OBJS) -I$(IDIR)
$(ODIR)/%.o: $(SDIR)/%.cc
#mkdir -p $(ODIR)
#echo "COMPILING $<"
#$(CC) -o $# -c $< $(CFLAGS)
clean:
#echo "CLEAN"
#rm -rf $(BDIR) $(ODIR)
Removing the MAKEFLAGS variable will print all invoked commands. The Makefile compiles any c++ project where source files (with .cc extension) are put into the src directory and header files are put into the include directory.
make 2>&1 | egrep -v 'Nothing to be done|up to date'