[PATCH 1/2] Clean up: Makefile.in: Correct the prerequisites
Michael Witten
mfwitten at gmail.com
Tue Jul 11 13:08:56 AWST 2017
This commit provides 3 useful results:
* It allows parallel make (`make -j') to function correctly.
* It allows `make' to be run from within the libtom(crypt|math)
directory without having to worry about the state of
prerequisites provided by Dropbear or by the other libtom*.
* It ensures that nearly every target (including every intermediate
target) need be made only if at least one of that target's
particular prerequisites has been touched.
In other words, if you edit some header file, H, only those
object files that include H will be re-made.
Before this commit, a number of header files, $(HEADERS), were listed
explicitly in Dropbear's makefile as prerequisites for the final,
complete program targets; however, the targets that *actually* depend
on such headers are not the complete programs, but rather the intermediate
object files from which those program targets are themselves made.
Thus, $(HEADERS) should actually be listed as the prerequisites for
the various intermediate object files. However, not every such object
file actually depends on every header, meaning that some object files
would be built unnecessarily if one of the headers is touched.
Therefore, `HEADERS' has been removed entirely, and replaced with
a mechanism by which each object file's prerequisites are determined
dynamically during the build process; the initial invocation of `make'
is only given a limited knowledge of the prerequisites, but every future
invocation has automatic access to fine[r]-grained details.
This is made possible with a GCC-specific set of command-line arguments,
which instruct `gcc' to output makefile-compatible rules that define
each object file's prerequisites. While it may be useful to handle the
case in which the compiler does not support these options, it would
probably be acceptable to do so in a future commit; fortunately, even
`llvm-gcc' appears to support the options in question.
Thus, for now, the minimal knowledge of prerequisites to which `make'
has access during the initial run is basically just the one header
which potentially needs to be made before almost everything else:
default_options.h
There is only one object file that is made from source which doesn't
ultimately include that header:
curve25519-donna.o
However, there's little worth in explaining this fact to `make'; instead,
the most practical solution is just to list `default_options.h' as
a prerequisite for every object file.
This same "runtime" discovery of prerequisites could be used for the
built-in libtom{crypt,math} dependencies, but it turns out that these
projects are organized in a way that makes the results rather useless;
in particular, each *.c file includes all headers, so everything would
be re-made whenever any header is touched, which is what already happens
with the naive, manual approach that is currently employed.
Nevertheless, experimenting with this possibility has proven fruitful,
because it revealed a few dependencies that these projects share among
themselves, not only with respect to each other, but also with respect
to Dropbear's sources; for example, when Dropbear's `dbhelper.h' is
touched, both `libtomcrypt' and `libtommath' have object files that
need to be re-made, etc.
The responsiblity for managing such prerequisites has been moved
from Dropbear's makefile to the makefiles of the libtom* libraries;
because Dropbear's makefile merely run's a new instance of `make'
to construct each one of those libraries, only those libraries'
makefiles can handle the prerequisites meaningfully.
Nevertheless, there is one prerequisite of libtomcrypt that must
*also* be handled by Dropbear's makefile: `default_options.h'. This
is because both libtomcrypt's makefile and Dropbear's makefile have
recipes for creating `default_options.h' (libtomcrypt's makefile runs
Dropbear's makefile to do the dirty work), which breaks one of the
assumptions of `make', namely that a particular target is only ever
made by running one recipe for it at a time; during a parallel make,
this interplay between the makefiles would escape the notice of each
separate instance of `make', thereby creating a situation where two of
them are trying to make `default_options.h' at the same time.
The solution is simple: Don't allow this to happen.
One way to prohibit this scenario is to require `default_options.h' to
be made only by Dropbear's makefile, but this solution would preclude
the possibility of being able to run `make' directly on libtomcrypt's
makefile without having to worry about also running Dropbear's makefile,
which is a possibility that might be useful for someone who wants to
experiment with altering this library's source (in other words, it's
nice to be able to run `make' from within libtomcrypt's directory while
hacking on libtomcrypt, and yet not worry about making sure that
`default_options.h' has been made, etc.).
---
.gitignore | 1 +
Makefile.in | 67 +++++++++++++++++++++++++++++++------------------
libtomcrypt/Makefile.in | 6 +++++
libtommath/Makefile.in | 5 +++-
4 files changed, 53 insertions(+), 26 deletions(-)
diff --git a/.gitignore b/.gitignore
index b81c1ea..1ef4318 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ Makefile
config.h
config.h.in
configure
+/prerequisites/
diff --git a/Makefile.in b/Makefile.in
index e264d0d..885a4f0 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -18,9 +18,9 @@ STATIC_LTM=libtommath/libtommath.a
LIBTOM_LIBS=@LIBTOM_LIBS@
ifeq (@BUNDLED_LIBTOM@, 1)
-LIBTOM_DEPS=$(STATIC_LTC) $(STATIC_LTM)
-CFLAGS+=-I$(srcdir)/libtomcrypt/src/headers/
-LIBTOM_LIBS=$(STATIC_LTC) $(STATIC_LTM)
+LIBTOM_LIBS=$(STATIC_LTC) $(STATIC_LTM)
+LIBTOM_DEPS=$(LIBTOM_LIBS)
+CFLAGS+=-I$(srcdir)/libtomcrypt/src/headers
endif
ifneq ($(wildcard localoptions.h),)
@@ -50,22 +50,13 @@ CLISVROBJS=common-session.o packet.o common-algo.o common-kex.o \
tcp-accept.o listener.o process-packet.o dh_groups.o \
common-runopts.o circbuffer.o curve25519-donna.o list.o netio.o
-KEYOBJS=dropbearkey.o
-
-CONVERTOBJS=dropbearconvert.o keyimport.o
-
-HEADERS=options.h dbutil.h session.h packet.h algo.h ssh.h buffer.h kex.h \
- dss.h bignum.h signkey.h rsa.h dbrandom.h service.h auth.h \
- debug.h channel.h chansession.h config.h queue.h sshpty.h \
- termcodes.h gendss.h genrsa.h runopts.h includes.h \
- loginrec.h atomicio.h x11fwd.h agentfwd.h tcpfwd.h compat.h \
- listener.h fake-rfc2553.h ecc.h ecdsa.h
-
dropbearobjs=$(COMMONOBJS) $(CLISVROBJS) $(SVROBJS)
dbclientobjs=$(COMMONOBJS) $(CLISVROBJS) $(CLIOBJS)
-dropbearkeyobjs=$(COMMONOBJS) $(KEYOBJS)
+dropbearkeyobjs=$(COMMONOBJS) dropbearkey.o
-dropbearconvertobjs=$(COMMONOBJS) $(CONVERTOBJS)
+dropbearconvertobjs=$(COMMONOBJS) dropbearconvert.o keyimport.o
scpobjs=scp.o progressmeter.o atomicio.o scpmisc.o compat.o
+programobjs=$(sort $(foreach prog, $(PROGRAMS), $($(prog)objs)))
+dropbearmultiobjs=dbmulti.o $(programobjs)
VPATH=@srcdir@
srcdir=@srcdir@
@@ -114,10 +105,11 @@ ifeq ($(STATIC), 1)
endif
ifeq ($(MULTI), 1)
- dropbearmultiobjs=dbmulti.o $(sort $(foreach prog, $(PROGRAMS), $($(prog)objs)))
+ allobjs=$(dropbearmultiobjs)
CFLAGS+=$(addprefix -DDBMULTI_, $(PROGRAMS)) -DDROPBEAR_MULTI
TARGETS_NAMES=dropbearmulti
else
+ allobjs=$(programobjs)
TARGETS_NAMES=$(PROGRAMS)
endif
@@ -176,28 +168,52 @@ $(filter-out inst_dropbear,$(TARGETS_inst_)): inst_%: %$(EXEEXT)
.PHONY: inst_dropbearmulti
inst_dropbearmulti: $(PROGRAMS_insmulti)
+prerequisites_dir=prerequisites
+
+$(prerequisites_dir):
+ mkdir -p $(prerequisites_dir)
+
+include $(wildcard $(prerequisites_dir)/*.d)
+
+$(allobjs): CFLAGS+=-MMD -MF $(prerequisites_dir)/[email protected]
+$(allobjs): default_options.h | $(prerequisites_dir)
+
-dropbear$(EXEEXT): $(HEADERS) $(dropbearobjs) $(LIBTOM_DEPS)
+dropbear$(EXEEXT): $(dropbearobjs) $(LIBTOM_DEPS)
$(CC) $(LDFLAGS) -o $@ $(dropbearobjs) $(LIBTOM_LIBS) $(LIBS) @CRYPTLIB@
-dbclient$(EXEEXT): $(HEADERS) $(dbclientobjs) $(LIBTOM_DEPS)
+dbclient$(EXEEXT): $(dbclientobjs) $(LIBTOM_DEPS)
$(CC) $(LDFLAGS) -o $@ $(dbclientobjs) $(LIBTOM_LIBS) $(LIBS)
-dropbearkey$(EXEEXT): $(HEADERS) $(dropbearkeyobjs) $(LIBTOM_DEPS)
+dropbearkey$(EXEEXT): $(dropbearkeyobjs) $(LIBTOM_DEPS)
$(CC) $(LDFLAGS) -o $@ $(dropbearkeyobjs) $(LIBTOM_LIBS) $(LIBS)
-dropbearconvert$(EXEEXT): $(HEADERS) $(dropbearconvertobjs) $(LIBTOM_DEPS)
+dropbearconvert$(EXEEXT): $(dropbearconvertobjs) $(LIBTOM_DEPS)
$(CC) $(LDFLAGS) -o $@ $(dropbearconvertobjs) $(LIBTOM_LIBS)
-scp$(EXEEXT): $(HEADERS) $(scpobjs)
+scp$(EXEEXT): $(scpobjs)
$(CC) $(LDFLAGS) -o $@ $(scpobjs)
-dropbearmulti$(EXEEXT): $(HEADERS) $(dropbearmultiobjs) $(LIBTOM_DEPS)
+dropbearmulti$(EXEEXT): $(dropbearmultiobjs) $(LIBTOM_DEPS)
$(CC) $(LDFLAGS) -o $@ $(dropbearmultiobjs) $(LIBTOM_LIBS) $(LIBS) @CRYPTLIB@
+# Experimentation has revealed that `make' won't consider whether
+# a target has been updated unless a recipe for that target has
+# been run; thus, the following variable is used to help human
+# readers understand that there is a recipe which does NOTHING.
+NOTHING:=
+
-$(STATIC_LTC): options.h
- $(MAKE) -C libtomcrypt
+$(STATIC_LTC): libtomcrypt
+ $(NOTHING)
-$(STATIC_LTM): options.h
- $(MAKE) -C libtommath
+$(STATIC_LTM): libtommath
+ $(NOTHING)
+
+.PHONY: libtomcrypt
+libtomcrypt: | default_options.h
+ $(MAKE) -C libtomcrypt
+
+.PHONY: libtommath
+libtommath:
+ $(MAKE) -C libtommath
.PHONY: ltc-clean
@@ -220,6 +236,7 @@ thisclean:
-rm -f dropbear$(EXEEXT) dbclient$(EXEEXT) dropbearkey$(EXEEXT) \
dropbearconvert$(EXEEXT) scp$(EXEEXT) scp-progress$(EXEEXT) \
dropbearmulti$(EXEEXT) *.o *.da *.bb *.bbg *.prof
+ -rm -rf $(prerequisites_dir)
.PHONY: distclean
distclean: clean tidy
diff --git a/libtomcrypt/Makefile.in b/libtomcrypt/Makefile.in
index d9b3668..d8f9a6d 100644
--- a/libtomcrypt/Makefile.in
+++ b/libtomcrypt/Makefile.in
@@ -263,8 +263,14 @@ src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
#This rule makes the libtomcrypt library.
library: $(LIBNAME)
+src/misc/zeromem.o: ../dbhelpers.h
+src/math/ltm_desc.o: ../libtommath/tommath.h ../libtommath/tommath_class.h ../libtommath/tommath_superclass.h
+$(OBJECTS): ../config.h ../options.h ../default_options.h ../sysoptions.h
$(OBJECTS): $(HEADERS)
+../default_options.h: ../default_options.h.in
+ $(MAKE) -C .. default_options.h
+
testprof/$(LIBTEST):
cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE)
diff --git a/libtommath/Makefile.in b/libtommath/Makefile.in
index dbcd2a0..c06187a 100644
--- a/libtommath/Makefile.in
+++ b/libtommath/Makefile.in
@@ -17,7 +17,7 @@ endif
ifneq ($V,1)
@echo " * ${CC} $@"
endif
- ${silent} ${CC} -c ${CFLAGS} $^ -o $@
+ ${silent} ${CC} -c ${CFLAGS} $*.c -o $@
#default files to install
ifndef LIBNAME
@@ -62,6 +62,9 @@ $(LIBNAME): $(OBJECTS)
$(AR) $(ARFLAGS) $@ $(OBJECTS)
$(RANLIB) $@
+bn_mp_clear.o: ../dbhelpers.h
+$(OBJECTS): ../config.h
+
#make a profiled library (takes a while!!!)
#
# This will build the library with profile generation
--
2.10.0
More information about the Dropbear
mailing list