How to make automake less ugly? - makefile

I recently learned how to use automake, and I'm somewhat annoyed that my compile commands went from a bunch of:
g++ -O2 -Wall -c fileName.cpp
To a bunch of:
depbase=`echo src/Unit.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
g++ -DHAVE_CONFIG_H -I. -I./src -g -O2 -MT src/Unit.o -MD -MP -MF $depbase.Tpo -c -o src/Unit.o src/Unit.cpp &&\
mv -f $depbase.Tpo $depbase.Po
Is there any way to clean this up? I can usually easily pick out warning messages, but now the wall of text to read though is 3x bigger and much weirder.
I know what my flags are, so making it just says "Compiling xxx.cpp" for each file would be perfect.

As of automake 1.11, you can greatly clean up the output using the silent-rules option. For example:
$ # First, make without silent rules
$ make
make all-am
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT foo.o -MD -MP -MF .deps/foo.Tpo -c -o foo.o foo.c
mv -f .deps/foo.Tpo .deps/foo.Po
/bin/sh ./libtool --tag=CC --mode=link gcc -g -O2 -o foo foo.o
libtool: link: gcc -g -O2 -o foo foo.o
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT bar.o -MD -MP -MF .deps/bar.Tpo -c -o bar.o bar.c
mv -f .deps/bar.Tpo .deps/bar.Po
/bin/sh ./libtool --tag=CC --mode=link gcc -g -O2 -o bar bar.o
libtool: link: gcc -g -O2 -o bar bar.o
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT baz.o -MD -MP -MF .deps/baz.Tpo -c -o baz.o baz.c
mv -f .deps/baz.Tpo .deps/baz.Po
/bin/sh ./libtool --tag=CC --mode=link gcc -g -O2 -o baz baz.o
libtool: link: gcc -g -O2 -o baz baz.o
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT qux.o -MD -MP -MF .deps/qux.Tpo -c -o qux.o qux.c
mv -f .deps/qux.Tpo .deps/qux.Po
/bin/sh ./libtool --tag=CC --mode=link gcc -g -O2 -o qux qux.o
libtool: link: gcc -g -O2 -o qux qux.o
$ # Now, use the silent rules
$ ./configure --enable-silent-rules > /dev/null
$ make clean all
rm -f foo bar baz qux
rm -rf .libs _libs
rm -f *.o
rm -f *.lo
make all-am
CC foo.o
CCLD foo
CC bar.o
CCLD bar
CC baz.o
CCLD baz
CC qux.o
CCLD qux
All that is needed is to add "silent-rules" to the invocation
of AM_INIT_AUTOMAKE in configure.ac, and add the option
--enable-silent-rules when you invoke configure. (There
was much debate about requiring the option to be added
at configure time when this feature was added, and there
is an easy workaround to make it unnecessary.) Note that
with silent-rules enabled, you can still get verbose
output by running 'make V=1'

I did a bit of googling around as I am in the same boat, the autoconf tools do a nice job but it kind of wrecks your eyes when the text whizzes by and no way of knowing what was that about... here is a link to a blog that mentions a tool to do this and make it look like neater just like how you see a kernel build does the magic i.e.
Compiling foo.so
Linking foo.so
Here is another link to a tool that is called prettify automake.

Related

Manually link two targets

I am trying to convert a (sloppy) Makefile into a CMakeLists.txt to better work with my IDE (CLion).
My Makefile is as follows:
all:
gcc -MD -fno-builtin -nostdinc -fno-stack-protector -Os -g -m32 -I. -c -o bin/boot0.o boot/boot0/boot0.S
ld -nostdlib -m elf_i386 -N -e start -Ttext 0x7c00 -o bin/boot0.elf bin/boot0.o
objcopy -S -O binary bin/boot0.elf bin/boot0
gcc -MD -fno-builtin -nostdinc -fno-stack-protector -Os -g -m32 -I. -c -o bin/boot1.o boot/boot1/boot1.S
gcc -MD -fno-builtin -nostdinc -fno-stack-protector -Os -g -m32 -I. -c -o bin/boot1main.o boot/boot1/boot1main.c
gcc -MD -fno-builtin -nostdinc -fno-stack-protector -Os -g -m32 -I. -c -o bin/boot1lib.o boot/boot1/boot1lib.c
gcc -MD -fno-builtin -nostdinc -fno-stack-protector -Os -g -m32 -I. -c -o bin/exec_kernel.o boot/boot1/exec_kernel.S
ld -nostdlib -m elf_i386 -N -e start -Ttext 0xd7000 -o bin/boot1.elf bin/boot1.o bin/boot1main.o bin/boot1lib.o bin/exec_kernel.o
objcopy -S -O binary bin/boot1.elf bin/boot1
gcc -MD -fno-builtin -nostdinc -fno-stack-protector -D_KERN_ -Ikern -Ikern/kern -I. -m32 -O0 -c -o bin/entry.o kern/init/entry.S
ld -o kernel -nostdlib -e start -m elf_i386 -Ttext=0x00100000 bin/entry.o -b binary
dd if=/dev/zero of=project0.img bs=512 count=256
parted -s project0.img "mktable msdos mkpart primary 63s -1s set 1 boot on"
dd if=bin/boot0 of=project0.img bs=446 count=1 conv=notrunc
dd if=bin/boo1 of=project0.img bs=512 count=62 seek=1 conv=notrunc
dd if=kern/init/kernel of=project0.img bs=512 seek=63 conv=notrunc
Mostly I am using make just to run the commands.
I am running into trouble with the fact that I have three different sets of linker flags (one each for boot0, boot1, and kern.)
Should I create separate CMakeLists.txt in each subdirectory (boot0, boot1, and kern) and then have a main one that runs each in turn and then handles the dd and parted usage, is there a better way to do this, or is CMake not an appropriate tool here?
Please have short-cuts for the compiler commands first. Then write the rule to create the first target on which the second target is dependent. Then since the first target is created; now use it to create the second target.

Make one specific target in Makefile tree

I'm building Syslinux and there is one specific directory that I would like a different CC for. Instead of patching the Makefile, I can't I just invoke make with special arguments for that file? I haven't figured out how to do this.
When I just run make normally, this last lines are:
make -r -C lzo SRC="/syslinux-6.03/lzo" OBJ="/syslinux-6.03/bios/lzo" \
-f /syslinux-6.03/lzo/Makefile all
make[3]: Entering directory '/syslinux-6.03/bios/lzo'
gcc -o prepcore prepcore.o lzo.a
But if I cd into bios/lzo and run make prepcore, it doesn't work, probably because it needs some environment from the parent directory Makefiles. The error message is:
make: Entering directory '/syslinux-6.03/lzo'
/syslinux-6.03/lzo/Makefile:14: /build.mk: No such file or directory
make: *** No rule to make target '/build.mk'. Stop.
make: Leaving directory '/syslinux-6.03/lzo'
So my question is, what is the correct way of telling make "for the current directory tree, find a target for <file> and make it"?
Here is how to do this with remake. You run "remake" and set a breakpoint on the target you want to change. Then use the remake's "write" command to write the commands it would run to a shell script. Then you can edit that shell script to adjust the commands it runs for changes you want. The shell script will have a change directory command in it that you probably want to comment out.
Here is an example:
$ rm job.o
$ remake -X job.o
GNU Make 4.1+dbg0.91
Built for x86_64-unknown-linux-gnu
...
-> (/src/external-vcs/github/remake/Makefile:621)
Makefile: Makefile.in config.status
remake<0> s
... # Step until job.o
remake<9> s
Must remake target 'job.o'.
Makefile:781: update target 'job.o' due to: job.c /usr/include/stdc-predef.h ...
##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
depbase=`echo job.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -DMAKE_MAINTAINER_MODE -pthread -I/usr/include/guile/2.0 -Wall -Wextra -Wdeclaration-after-statement -Wshadow -Wpointer-arith -Wbad-function-cast -g -O2 -MT job.o -MD -MP -MF $depbase.Tpo -c -o job.o job.c &&\
mv -f $depbase.Tpo $depbase.Po
##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
++ (/src/external-vcs/github/remake/.deps/job.Po:1)
job.o
remake<10> w
File "/tmp/job.o.sh" written.
remake<11>
Now look at the file it wrote:
#!/bin/bash
#/tmp/github/remake/.deps/job.Po:1
#cd /tmp/remake
depbase=`echo job.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -DMAKE_MAINTAINER_MODE -pthread -I/usr/include/guile/2.0 -Wall -Wextra -Wdeclaration-after-statement -Wshadow -Wpointer-arith -Wbad-function-cast -g -O2 -MT job.o -MD -MP -MF $depbase.Tpo -c -o job.o job.c &&\
mv -f $depbase.Tpo $depbase.Po

How to create makefile for compiling multiple programs

I have some problems with creating makefile. I have tried to compile some files from terminal and found right options for gcc to do this.
But I have some troubles with creating one makefile to do all this tasks.
Here are my commands that work.
gcc -c pstree.c -DHAVE_CONFIG_H -I.
gcc -o hello pstree.o -L/usr/lib/ -ltinfo
gcc -c fuser.c -DHAVE_CONFIG_H -I.
gcc -c -o libsignals.a signals.c
gcc -o hello fuser.o -L/usr/lib/ -L. -lsignals
gcc -c -o libsignals.a signals.c
gcc -o hello killall.o -L/usr/lib/ -L. -lsignals
gcc -c killall.c -DHAVE_CONFIG_H -I.
How can I make a Makefile for executing these commands?
killall: hello\ fuser.o
gcc -c -o libsignals.a signals.c
gcc -o hello killall.o -L/usr/lib/ -L. -lsignals
gcc -c killall.c -DHAVE_CONFIG_H -I.
fuser: hello\ pstree.o
gcc -c fuser.c -DHAVE_CONFIG_H -I.
gcc -c -o libsignals.a signals.c
gcc -o hello\ fuser.o -L/usr/lib/ -L. -lsignals
pstree:
gcc -c pstree.c -DHAVE_CONFIG_H -I.
gcc -o hello\ pstree.o -L/usr/lib/ -ltinfo
clean:
rm -rf *.o
I wrote very very dirty you can define cc variable such as:
CC = gcc
CFLAGS = -g -Wall -I.
LIBS = -L/usr/lib/ -lsignals
and so on.....
Mine is very dirty ....
NOTE: Before each line of intending you have to use TAB, not space.
usage :
make clean
make killall

generic makefile to create multiple executable using different flags

I would like to create a generic Makefile that builds several executables using different compiler flags for each executable without using shell commands. The executable file name should be composed from the source file and a unique post fixed name. It should also produce an assembly or preprocessor file per source file if needed.
For the target BIN_BDG_FILES, the "$<" (exercise-1.1.0.c ) is always the first item from the list (exercise-1.1.0.c exercise-1.1.1.c exercise-1.2.0.c exercise-1.2.1.c) as expected. I tried without success to modify the SRC_FILES using the filter-out function. My intent was to remove the first item from the list for each Target, so that the first item corresponds to the correct target. I am not sure this is the correct approach. Your comments are welcome.
i.e.
This is my attempt at using built in make constructs.
$(BIN_DBG_FILES): $(SRC_FILES)
$(CC) $(DBG_CFLAGS) $(IFLAGS) $< -o $#
echo SRC_FILES := $(filter-out $<, $(SRC_FILES))
Makefile
SHELL = bash
SRC_FILES = $(wildcard *.c)
BIN_FILES = $(patsubst %.c,%,$(SRC_FILES))
BIN_DBG_FILES = $(patsubst %.c,%-dbg,$(SRC_FILES))
SRC_PRE = $(patsubst %.c,%-pre,$(SRC_FILES))
CC = gcc
WARNINGS := -Wall
CFLAGS = -O2 -std=c99 $(WARNINGS)
DBG_CFLAGS = -g -O -std=c99 $(WARNINGS)
PRE_FLAG = -E
IFLAGS = -I.
all: $(BIN_FILES) $(BIN_DBG_FILES) MK-BASH
$(BIN_DBG_FILES): $(SRC_FILES)
$(CC) $(DBG_CFLAGS) $(IFLAGS) $< -o $#
MK-BASH::
for src in $(SRC_FILES); do \
echo $(CC) $(DBG_CFLAGS) $(IFLAGS) $$src -o $${src%.c}-dbg; \
$(CC) $(DBG_CFLAGS) $(IFLAGS) $$src -o $${src%.c}-dbg; \
$(CC) $(DBG_CFLAGS) $(IFLAGS) $$src -o $${src%.c}-dbg; \
$(CC) $(PRE_FLAG) $$src > $${src%.c}-pre; \
done
clean:
rm -f $(BIN_FILES) *-dbg *-pre
This is the output from executing make command.
This is the output from the target BIN_FILES.
gcc -O2 -std=c99 -Wall exercise-1.1.0.c -o exercise-1.1.0
gcc -O2 -std=c99 -Wall exercise-1.1.1.c -o exercise-1.1.1
gcc -O2 -std=c99 -Wall exercise-1.2.0.c -o exercise-1.2.0
gcc -O2 -std=c99 -Wall exercise-1.2.1.c -o exercise-1.2.1
This is the output from target BIN_DBG_FILES which uses the first source file on the list to build all targets. It should use the appropriate file (exercise-1.1.1.c) to build each target file (exercise-1.1.1-dbg).
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.1.0-dbg
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.1.1-dbg
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.2.0-dbg
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.2.1-dbg
This is the output from the target MK-BASH using shell commands.
for src in exercise-1.1.0.c exercise-1.1.1.c exercise-1.2.0.c exercise-1.2.1.c; do \
echo gcc -g -O -std=c99 -Wall -I. $src -o ${src%.c}-dbg; \
gcc -g -O -std=c99 -Wall -I. $src -o ${src%.c}-dbg; \
gcc -g -O -std=c99 -Wall -I. $src -o ${src%.c}-dbg; \
gcc -E $src > ${src%.c}-pre; \
done
output:
gcc -g -O -std=c99 -Wall -I. exercise-1.1.0.c -o exercise-1.1.0-dbg
gcc -g -O -std=c99 -Wall -I. exercise-1.1.1.c -o exercise-1.1.1-dbg
gcc -g -O -std=c99 -Wall -I. exercise-1.2.0.c -o exercise-1.2.0-dbg
gcc -g -O -std=c99 -Wall -I. exercise-1.2.1.c -o exercise-1.2.1-dbg
Use a pattern rule:
DBG: $(BIN_DBG_FILES)
%-dbg: %.c
#echo $(CC) $(DBG_CFLAGS) $(IFLAGS) $< -o $#

Why does make delete my temporary files?

I have a simple Makefile,
.PHONY: clean
PROGRAMS=$(patsubst main%.cpp,example%,$(wildcard main*.cpp))
all: ${PROGRAMS}
GCCVERSION=$(shell gcc -dumpversion)
GLCFLAGS=$(shell pkg-config --cflags gl)
CPPFLAGS=-Wall -O2 ${GLCFLAGS}
ifeq "${GCCVERSION}" "4.5.2"
CXXFLAGS=-std=c++0x
else
CXXFLAGS=-std=c++11
endif
GLLIBS=$(shell pkg-config --libs gl)
LIBS=${GLLIBS} -lglut
example%: main%.o shaders.o fileutils.o
${CXX} $^ ${LIBS} -o $#
clean:
rm -f *.o ${PROGRAMS}
But when I executed it, it delete the *.o files as last command. I don't know why:
$ make
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o main01.o main01.cpp
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o shaders.o shaders.cpp
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o fileutils.o fileutils.cpp
g++ main01.o shaders.o fileutils.o -lGL -lglut -o example01
rm main01.o fileutils.o shaders.o
Is there anything wrong with my Makefile?
Intermediate files are deleted by design: see Chained Rules in GNU make manual.
Use .SECONDARY or .PRECIOUS targets to keep your precioussss temp files.
Just to clarify the previous response, you need to add a special rule like
.PRECIOUS: myfile.o

Resources