From 6fa37b57c1070517ad6b060103046fda6328ffc8 Mon Sep 17 00:00:00 2001
From: Luke Shumaker <lukeshu@parabola.nu>
Date: Wed, 13 Dec 2017 13:49:07 -0500
Subject: [PATCH] contrib: recursive dependency tracking

Let's say we're building gnutls (since the system version is too new).
gnutls depends on nettle.
Let's say we're using the system nettle (naturally in FOUND_PKGS).
nettle depends on gmp.

With the old (non-recursive) dependency tracking, we would end up building
gmp just for nettle, even though we aren't even building nettle!

Change-Id: I24e6f59416839ea202e0aceafe101432fe9c2646
Reviewed-by: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
---
 contrib/src/README              | 18 ++++++------------
 contrib/src/ffmpeg/rules.mak    |  2 +-
 contrib/src/flac/rules.mak      |  2 +-
 contrib/src/gnutls/rules.mak    |  2 +-
 contrib/src/main.mak            |  5 ++++-
 contrib/src/nettle/rules.mak    |  2 +-
 contrib/src/opendht/rules.mak   |  2 +-
 contrib/src/secp256k1/rules.mak |  2 +-
 contrib/src/vorbis/rules.mak    |  4 ++--
 9 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/contrib/src/README b/contrib/src/README
index 581a392195..a17d82e47f 100644
--- a/contrib/src/README
+++ b/contrib/src/README
@@ -92,18 +92,12 @@ Dependencies
 If package bar depends on package foo, the special DEPS_bar variable
 should be defined as follow:
 
-	DEPS_bar = foo $(DEPS_foo)
-
-Note that dependency resolution is unfortunately _not_ recursive.
-Therefore $(DEPS_foo) really should be specified explicitly as shown
-above. (In practice, this will not make any difference insofar as there
-are no pure second-level nested dependencies. For instance, libass
-depends on FontConfig, which depends on FreeType, but libass depends
-directly on FreeType anyway.)
-
-Also note that DEPS_bar is set "recursively" with =, rather than
-"immediately" with :=. This is so that $(DEPS_foo) is expanded
-correctly, even if DEPS_foo it is defined after DEPS_bar.
+	DEPS_bar = foo
+
+Dependency resolution is recursive (unlike in previous versions); the
+above will cause bar to also depend on the dependencies of foo.  It is
+illegal to have a dependency cycle, and an error will be emitted if
+one is created.
 
 Implementation note:
 
diff --git a/contrib/src/ffmpeg/rules.mak b/contrib/src/ffmpeg/rules.mak
index b1db5d1311..e86403e256 100644
--- a/contrib/src/ffmpeg/rules.mak
+++ b/contrib/src/ffmpeg/rules.mak
@@ -11,7 +11,7 @@ ifeq ($(call need_pkg,"libavutil >= 55.75.100 libavcodec >= 57.106.101 libavform
 PKGS_FOUND += ffmpeg
 endif
 
-DEPS_ffmpeg = iconv zlib x264 vpx opus speex $(DEPS_vpx)
+DEPS_ffmpeg = iconv zlib x264 vpx opus speex
 
 FFMPEGCONF = \
 	--cc="$(CC)" \
diff --git a/contrib/src/flac/rules.mak b/contrib/src/flac/rules.mak
index 7abc69938c..857593aad7 100644
--- a/contrib/src/flac/rules.mak
+++ b/contrib/src/flac/rules.mak
@@ -47,7 +47,7 @@ FLACCONF += --disable-asm-optimizations
 endif
 endif
 
-DEPS_flac = ogg $(DEPS_ogg)
+DEPS_flac = ogg
 
 .flac: flac
 	cd $< && $(HOSTVARS) ./configure $(FLACCONF)
diff --git a/contrib/src/gnutls/rules.mak b/contrib/src/gnutls/rules.mak
index 843135814f..4441fcf910 100644
--- a/contrib/src/gnutls/rules.mak
+++ b/contrib/src/gnutls/rules.mak
@@ -60,7 +60,7 @@ ifdef HAVE_IOS
 	GNUTLS_CONF += --disable-hardware-acceleration
 endif
 
-DEPS_gnutls = nettle $(DEPS_nettle) iconv $(DEPS_iconv)
+DEPS_gnutls = nettle iconv
 
 
 #Workaround for localtime_r function
diff --git a/contrib/src/main.mak b/contrib/src/main.mak
index 51cbbfbcdd..2cc639a464 100644
--- a/contrib/src/main.mak
+++ b/contrib/src/main.mak
@@ -391,7 +391,10 @@ PKGS_AUTOMATIC := $(filter-out $(PKGS_FOUND),$(PKGS))
 # Apply manual selection (from bootstrap):
 PKGS_MANUAL := $(sort $(PKGS_ENABLE) $(filter-out $(PKGS_DISABLE),$(PKGS_AUTOMATIC)))
 # Resolve dependencies:
-PKGS_DEPS := $(filter-out $(PKGS_FOUND) $(PKGS_MANUAL),$(sort $(foreach p,$(PKGS_MANUAL),$(DEPS_$(p)))))
+dep_on = $(if $(filter $1,$2),\
+  $(error Dependency cycle detected: $(patsubst %,% ->,$2) $(filter $1,$2)),\
+  $(sort $(foreach p,$(filter-out $(PKGS_FOUND),$(1)),$(p) $(call dep_on,$(DEPS_$(p)),$2 $(p)))))
+PKGS_DEPS := $(call dep_on,$(PKGS_MANUAL))
 PKGS := $(sort $(PKGS_MANUAL) $(PKGS_DEPS))
 
 convert-static:
diff --git a/contrib/src/nettle/rules.mak b/contrib/src/nettle/rules.mak
index f811297a66..b924c7f87b 100644
--- a/contrib/src/nettle/rules.mak
+++ b/contrib/src/nettle/rules.mak
@@ -19,7 +19,7 @@ nettle: nettle-$(NETTLE_VERSION).tar.gz .sum-nettle
 	$(UPDATE_AUTOCONFIG)
 	$(MOVE)
 
-DEPS_nettle = gmp $(DEPS_gmp)
+DEPS_nettle = gmp
 
 .nettle: nettle
 ifdef HAVE_IOS
diff --git a/contrib/src/opendht/rules.mak b/contrib/src/opendht/rules.mak
index 4443a6fc03..b7fbe8ec83 100644
--- a/contrib/src/opendht/rules.mak
+++ b/contrib/src/opendht/rules.mak
@@ -15,7 +15,7 @@ ifneq ($(call need_pkg,"libargon2"),)
 DEPS_opendht += argon2
 endif
 ifneq ($(call need_pkg,"gnutls >= 3.3.0"),)
-DEPS_opendht += gnutls $(DEPS_gnutls)
+DEPS_opendht += gnutls
 endif
 
 $(TARBALLS)/opendht-$(OPENDHT_VERSION).tar.gz:
diff --git a/contrib/src/secp256k1/rules.mak b/contrib/src/secp256k1/rules.mak
index 7f20f103aa..b28f2f4123 100644
--- a/contrib/src/secp256k1/rules.mak
+++ b/contrib/src/secp256k1/rules.mak
@@ -7,7 +7,7 @@ PKGS += secp256k1
 ifeq ($(call need_pkg,"libsecp256k1"),)
 PKGS_FOUND += secp256k1
 endif
-DEPS_secp256k1 = gmp $(DEPS_gmp)
+DEPS_secp256k1 = gmp
 
 $(TARBALLS)/secp256k1-$(SECP256K1_VERSION).tar.gz:
 	$(call download,$(SECP256K1_URL))
diff --git a/contrib/src/vorbis/rules.mak b/contrib/src/vorbis/rules.mak
index 1fb2685145..e20cc74939 100644
--- a/contrib/src/vorbis/rules.mak
+++ b/contrib/src/vorbis/rules.mak
@@ -36,7 +36,7 @@ endif
 	$(UPDATE_AUTOCONFIG)
 	$(MOVE)
 
-DEPS_vorbis = ogg $(DEPS_ogg)
+DEPS_vorbis = ogg
 
 .vorbis: vorbis
 	$(RECONF) -Im4
@@ -47,7 +47,7 @@ DEPS_vorbis = ogg $(DEPS_ogg)
 .sum-vorbisenc: .sum-vorbis
 	touch $@
 
-DEPS_vorbisenc = vorbis $(DEPS_vorbis)
+DEPS_vorbisenc = vorbis
 
 .vorbisenc:
 	touch $@
-- 
GitLab