1#!/bin/sh -e
2#
3# Copyright (c) 2002 Ruslan Ermilov, The FreeBSD Project
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD: stable/10/tools/make_libdeps.sh 326521 2017-12-04 09:54:03Z hselasky $
28
29export PATH=/bin:/usr/bin
30
31set -e
32
33LC_ALL=C			# make sort deterministic
34FS=': '				# internal field separator
35LIBDEPENDS=./_libdeps		# intermediate output file
36LIBDIRS=./_libdirs		# intermediate output file
37USRSRC=${1:-/usr/src}		# source root
38LIBS="
39	lib
40	gnu/lib
41	kerberos5/lib
42	secure/lib
43	usr.bin/lex/lib
44	cddl/lib
45	contrib/ofed
46"				# where to scan for libraries
47
48
49# convert -lfoo to foo
50convert()
51{
52    sed -e "s/\-l//g" -e "s/pthread/thr/g" -e "s/ncurses.*/ncurses/g"
53}
54
55# find library build directory given library name
56findlibdir()
57{
58	while read NAME && read DIR
59	do
60		if [ "$NAME" = "$1" ]; then
61			echo "$DIR"
62			exit
63		fi
64	done
65
66	# Should not happen
67	echo lib_not_found/lib$1
68}
69
70# find library build directories given one or more library names
71resolvelibdirs()
72{
73	while read LIBNAME
74	do
75		cat $LIBDIRS | tr ' ' '\n' | findlibdir "$LIBNAME"
76	done
77}
78
79# Generate interdependencies between libraries.
80#
81genlibdepends()
82{
83	(
84		# Reset file
85		echo -n > $LIBDIRS
86
87		# First pass - generate list of directories
88		cd ${USRSRC}
89		find -s ${LIBS} -name Makefile |
90		xargs grep -l 'bsd\.lib\.mk' |
91		while read makefile; do
92			libdir=$(dirname ${makefile})
93			libname=$(
94				cd ${libdir}
95				make -m ${USRSRC}/share/mk WITH_OFED=YES -V LIB
96			)
97			if [ "${libname}" ]; then
98			    echo "${libname} ${libdir}" >> $LIBDIRS
99			fi
100		done
101
102		# Second pass - generate dependencies
103		find -s ${LIBS} -name Makefile |
104		xargs grep -l 'bsd\.lib\.mk' |
105		while read makefile; do
106			libdir=$(dirname ${makefile})
107			deps=$(
108				cd ${libdir}
109				make -m ${USRSRC}/share/mk WITH_OFED=YES -V LDADD
110			)
111			if [ "${deps}" ]; then
112				echo ${libdir}"${FS}"$(echo ${deps} | tr ' ' '\n' | convert | resolvelibdirs)
113			fi
114		done
115	)
116}
117
118main()
119{
120	if [ ! -f ${LIBDEPENDS} ]; then
121		genlibdepends >${LIBDEPENDS}
122	fi
123
124	prebuild_libs=$(
125		awk -F"${FS}" '{ print $2 }' ${LIBDEPENDS} |rs 0 1 |sort -u
126	)
127	echo "Libraries with dependents:"
128	echo
129	echo ${prebuild_libs} |
130	rs 0 1
131	echo
132
133	echo "List of interdependencies:"
134	echo
135	for lib in ${prebuild_libs}; do
136		grep "^${lib}${FS}" ${LIBDEPENDS} || true
137	done |
138	awk -F"${FS}" '{
139		if ($2 in dependents)
140			dependents[$2]=dependents[$2]" "$1
141		else
142			dependents[$2]=$1
143	}
144	END {
145		for (lib in dependents)
146			print dependents[lib]": " lib
147	}' |
148	sort
149
150	exit 0
151}
152
153main
154