summaryrefslogtreecommitdiff
path: root/mk/pkgformat/pkg/depends.mk
blob: 01fe3f30fcd220a54efcd06d0c0c58008274881a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# $NetBSD: depends.mk,v 1.15 2022/03/28 10:49:12 tnn Exp $

# This command prints out the dependency patterns for all full (run-time)
# dependencies of the package.
#
# This is used in install.mk and metadata.mk.
#

# ${_DEPENDS_FILE} contains all the dependency information
# for the package.  The format of each line of the file is:
#
#	<depends_type>	<pattern>	<directory>
#
# Valid dependency types are "bootstrap", "tool", "build", "test" and "full".
#
# ${_RDEPENDS_FILE} contains the resolved dependency information
# for the package.  For each line in ${_DEPENDS_FILE}
# a corresponding line of the following form exists:
#
#	<depends_type>	<pattern>	<pkg>
#
# "pkg" is the match for "pattern" used to fulfill the dependency.
#
# ${_RRDEPENDS_FILE} is like ${_RDEPENDS_FILE}, but all build dependencies
# are dropped, if they are dependencies of one of the full dependencies.
#
_DEPENDS_FILE=	${WRKDIR}/.depends
_RDEPENDS_FILE=	${WRKDIR}/.rdepends

_RRDEPENDS_FILE=${WRKDIR}/.rrdepends

_FULL_DEPENDS_CMD=	\
	${AWK} '$$1 == "full" { print $$3; }' < ${_RDEPENDS_FILE}

_REDUCE_DEPENDS_CMD=	${PKGSRC_SETENV} CAT=${CAT:Q}				\
				PKG_ADMIN=${PKG_ADMIN:Q}		\
				PWD_CMD=${PWD_CMD:Q} TEST=${TEST:Q}	\
			${AWK} -f ${PKGSRCDIR}/mk/pkgformat/pkg/reduce-depends.awk

_HOST_REDUCE_DEPENDS_CMD=						\
			${PKGSRC_SETENV} CAT=${CAT:Q}			\
				PKG_ADMIN=${HOST_PKG_ADMIN:Q}		\
				PWD_CMD=${PWD_CMD:Q} TEST=${TEST:Q}	\
			${AWK} -f ${PKGSRCDIR}/mk/pkgformat/pkg/reduce-depends.awk

_REDUCE_RESOLVED_DEPENDS_CMD=${PKGSRC_SETENV} CAT=${CAT:Q}		\
				PKG_INFO=${PKG_INFO:Q}			\
				HOST_PKG_INFO=${HOST_PKG_INFO:Q}	\
			${AWK} -f ${PKGSRCDIR}/mk/pkgformat/pkg/reduce-resolved-depends.awk \
				< ${_RDEPENDS_FILE}

_pkgformat-show-depends: .PHONY
	@case ${VARNAME:Q}"" in						\
	BUILD_DEPENDS)	${_REDUCE_DEPENDS_CMD} ${BUILD_DEPENDS:Q} ;;	\
	TEST_DEPENDS)	${_HOST_REDUCE_DEPENDS_CMD} ${TEST_DEPENDS:Q} ;;\
	TOOL_DEPENDS)	${_HOST_REDUCE_DEPENDS_CMD} ${TOOL_DEPENDS:Q} ;;\
	DEPENDS|*)	${_REDUCE_DEPENDS_CMD} ${DEPENDS:Q} ;;		\
	esac

_LIST_DEPENDS_CMD=	\
	${PKGSRC_SETENV} AWK=${AWK:Q} PKG_ADMIN=${PKG_ADMIN:Q} \
		PKGSRCDIR=${PKGSRCDIR:Q} PWD_CMD=${PWD_CMD:Q} SED=${SED:Q} \
		${SH} ${PKGSRCDIR}/mk/pkgformat/pkg/list-dependencies \
			" "${BOOTSTRAP_DEPENDS:Q} \
			" " \
			" "${TOOL_DEPENDS:Q} \
			" "${BUILD_DEPENDS:Q} \
			" "${DEPENDS:Q}

_LIST_DEPENDS_CMD.bootstrap=	\
	${PKGSRC_SETENV} AWK=${AWK:Q} PKG_ADMIN=${PKG_ADMIN:Q} \
		PKGSRCDIR=${PKGSRCDIR:Q} PWD_CMD=${PWD_CMD:Q} SED=${SED:Q} \
		${SH} ${PKGSRCDIR}/mk/pkgformat/pkg/list-dependencies \
			" "${BOOTSTRAP_DEPENDS:Q} " " " " " " " "

_LIST_DEPENDS_CMD.test=	\
	${PKGSRC_SETENV} AWK=${AWK:Q} PKG_ADMIN=${PKG_ADMIN:Q} \
		PKGSRCDIR=${PKGSRCDIR:Q} PWD_CMD=${PWD_CMD:Q} SED=${SED:Q} \
		${SH} ${PKGSRCDIR}/mk/pkgformat/pkg/list-dependencies \
			" " " "${TEST_DEPENDS:Q} " " " " " "

_RESOLVE_DEPENDS_CMD=	\
	${PKGSRC_SETENV} _PKG_DBDIR=${_PKG_DBDIR:Q} PKG_INFO=${PKG_INFO:Q} \
		HOST_PKG_INFO=${HOST_PKG_INFO:Q} \
		_DEPENDS_FILE=${_DEPENDS_FILE:Q} \
		${SH} ${PKGSRCDIR}/mk/pkgformat/pkg/resolve-dependencies \
			" "${BOOTSTRAP_DEPENDS:Q} \
			" " \
			" "${TOOL_DEPENDS:Q} \
			" "${BUILD_DEPENDS:Q} \
			" "${DEPENDS:Q}

# _DEPENDS_INSTALL_CMD checks whether the package $pattern is installed,
#	and installs it if necessary.
#
#	@param $pattern The pattern of the package to be installed.
#	@param $dir The pkgsrc directory from which the package can be
#		built.
#	@param $type The dependency type. Can be one of bootstrap, tool,
#		build, test, full.
#
_DEPENDS_INSTALL_CMD=							\
	case $$type in							\
	bootstrap)	Type=Bootstrap;;				\
	tool)		Type=Tool;;					\
	build)		Type=Build;;					\
	test)		Type=Test;;					\
	full)		Type=Full;;					\
	esac;								\
	case $$type in							\
	bootstrap|tool)							\
		if expr "${USE_CROSS_COMPILE:Uno}" : '[yY][eE][sS]' >/dev/null; then \
			extradep="";					\
		else							\
			extradep=" ${PKGNAME}";				\
		fi;							\
		cross=no;						\
		archopt=TARGET_ARCH=${MACHINE_ARCH};			\
		pkg=`${_HOST_PKG_BEST_EXISTS} "$$pattern" || ${TRUE}`;	\
		;;							\
	build|test|full)							\
		extradep=" ${PKGNAME}";					\
		cross=${USE_CROSS_COMPILE:Uno};				\
		archopt=;						\
		pkg=`${_PKG_BEST_EXISTS} "$$pattern" || ${TRUE}`;	\
		;;							\
	esac;								\
	case "$$pkg" in							\
	"")								\
		${STEP_MSG} "$$Type dependency $$pattern: NOT found";	\
		target=${DEPENDS_TARGET:Q};				\
		${STEP_MSG} "Verifying $$target for $$dir";		\
		[ -d "$$dir" ] || ${FAIL_MSG} "[depends.mk] The directory \`\`$$dir'' does not exist."; \
		cd $$dir;						\
		${PKGSRC_SETENV} ${PKGSRC_MAKE_ENV}			\
			_PKGSRC_DEPS="$$extradep${_PKGSRC_DEPS}"	\
			PKGNAME_REQD="$$pattern"			\
			USE_CROSS_COMPILE=$$cross			\
			$$archopt					\
		    ${MAKE} ${MAKEFLAGS} _AUTOMATIC=yes $$target;	\
		case $$type in						\
		bootstrap|tool)						\
			pkg=`${_HOST_PKG_BEST_EXISTS} "$$pattern" || ${TRUE}`;; \
		build|test|full)					\
			pkg=`${_PKG_BEST_EXISTS} "$$pattern" || ${TRUE}`;; \
		esac;							\
		case "$$pkg" in						\
		"")	${ERROR_MSG} "[depends.mk] A package matching \`\`$$pattern'' should"; \
			${ERROR_MSG} "    be installed, but one cannot be found.  Perhaps there is a"; \
			${ERROR_MSG} "    stale work directory for $$dir?"; \
			exit 1;						\
		esac;							\
		${STEP_MSG} "Returning to build of ${PKGNAME}";		\
		;;							\
	*)								\
		case $$type in						\
		bootstrap|tool)						\
			objfmt=`${HOST_PKG_INFO} -Q OBJECT_FMT "$$pkg"`;; \
		build|test|full)					\
			objfmt=`${PKG_INFO} -Q OBJECT_FMT "$$pkg"`;;	\
		esac;							\
		case "$$objfmt" in					\
		"")	${WARNING_MSG} "[depends.mk] Unknown object format for installed package $$pkg" ;; \
		${OBJECT_FMT})	;;					\
		*)	${ERROR_MSG} "[depends.mk] Installed package $$pkg has an"; \
			${ERROR_MSG} "    object format \`\`$$objfmt'' which differs from \`\`${OBJECT_FMT}''.  Please"; \
			${ERROR_MSG} "    update the $$pkg package to ${OBJECT_FMT}."; \
			exit 1;						\
			;;						\
		esac;							\
		silent=${_BOOTSTRAP_VERBOSE:Dyes};			\
		if ${TEST} -z "$${silent}"; then			\
			${STEP_MSG} "$$Type dependency $$pattern: found $$pkg"; \
		fi;							\
		;;							\
	esac

${_DEPENDS_FILE}:
	${RUN} ${MKDIR} ${.TARGET:H}
	${RUN} ${_LIST_DEPENDS_CMD} > ${.TARGET} || (${RM} -f ${.TARGET} && ${FALSE})

${_RDEPENDS_FILE}: ${_DEPENDS_FILE}
	${RUN} ${_RESOLVE_DEPENDS_CMD} > ${.TARGET} || (${RM} -f ${.TARGET} && ${FALSE})

${_RRDEPENDS_FILE}: ${_RDEPENDS_FILE}
	${RUN} ${_REDUCE_RESOLVED_DEPENDS_CMD} > ${.TARGET} || (${RM} -f ${.TARGET} && ${FALSE})

# _pkgformat-install-dependencies:
#	Installs any missing dependencies.
#
# The ${TEST} at the beginning is for the default change for the
# database directory from /var/db/pkg to ${PREFIX}/pkgdb in December 2020.
#
_pkgformat-install-dependencies: .PHONY ${_DEPENDS_FILE}
	${RUN}								\
	${TEST} -n "${PKG_DBDIR_ERROR}" && ${ERROR_MSG} ${PKG_DBDIR_ERROR:Q} && exit 1; \
	exec 3<&0;							\
	${CAT} ${_DEPENDS_FILE} | 					\
	while read type pattern dir; do					\
		${TEST} "$$type" != "bootstrap" || continue;		\
		${_DEPENDS_INSTALL_CMD} 0<&3;				\
	done

# _pkgformat-post-install-dependencies:
#	Targets after installing all dependencies.
#
_pkgformat-post-install-dependencies: .PHONY ${_RDEPENDS_FILE} ${_RRDEPENDS_FILE}

######################################################################
### pkg_install-depends (PUBLIC, pkgsrc/mk/depends/depends.mk)
######################################################################
### pkg_install-depends is a public target to install or update
### pkg_install itself.
###
.PHONY: pkg_install-depends
pkg_install-depends:
	${RUN}if [ `${PKG_INFO_CMD} -V 2>/dev/null || echo 20010302` -lt ${PKGTOOLS_REQD} ]; then \
	${PHASE_MSG} "Trying to handle out-dated pkg_install..."; \
	cd ../../pkgtools/pkg_install && ${PKGSRC_SETENV} ${PKGSRC_MAKE_ENV} \
	    _PKGSRC_DEPS=" ${PKGNAME}${_PKGSRC_DEPS}" \
	    ${MAKE} ${MAKEFLAGS} _AUTOMATIC=yes clean && \
	cd ../../pkgtools/pkg_install && ${PKGSRC_SETENV} ${PKGSRC_MAKE_ENV} \
	    _PKGSRC_DEPS=" ${PKGNAME}${_PKGSRC_DEPS}" \
	    ${MAKE} ${MAKEFLAGS} _AUTOMATIC=yes ${DEPENDS_TARGET:Q}; \
	fi

######################################################################
### bootstrap-depends (PUBLIC, pkgsrc/mk/depends/depends.mk)
######################################################################
### bootstrap-depends is a public target to install any missing
### dependencies needed during stages before the normal "depends"
### stage.  These dependencies are listed in BOOTSTRAP_DEPENDS.
###
.PHONY: bootstrap-depends
_BOOTSTRAP_DEPENDS_TARGETS+=	acquire-bootstrap-depends-lock
_BOOTSTRAP_DEPENDS_TARGETS+=	_pkgformat-bootstrap-depends
_BOOTSTRAP_DEPENDS_TARGETS+=	release-bootstrap-depends-lock

bootstrap-depends: ${_BOOTSTRAP_DEPENDS_TARGETS}

.PHONY: _pkgformat-bootstrap-depends
.if empty(PKG_FAIL_REASON)
_pkgformat-bootstrap-depends:
	${RUN}exec 3<&0;						\
	${_LIST_DEPENDS_CMD.bootstrap} | 				\
	while read type pattern dir; do					\
		${TEST} "$$type" = "bootstrap" || continue;		\
		${_DEPENDS_INSTALL_CMD} 0<&3;				\
	done
.else
_pkgformat-bootstrap-depends:
	${RUN}${DO_NADA}
.endif

.PHONY:
acquire-bootstrap-depends-lock: acquire-lock
release-bootstrap-depends-lock: release-lock

######################################################################
### test-depends (PUBLIC, pkgsrc/mk/depends/depends.mk)
######################################################################
### test-depends is a public target to install any missing
### dependencies needed for the "test" stage.
### These dependencies are listed in TEST_DEPENDS.
###
.PHONY: test-depends
_TEST_DEPENDS_TARGETS+=	acquire-test-depends-lock
_TEST_DEPENDS_TARGETS+=	_pkgformat-test-depends
_TEST_DEPENDS_TARGETS+=	release-test-depends-lock

test-depends: ${_TEST_DEPENDS_TARGETS}

_pkgformat-test-depends:
	${RUN}exec 3<&0;						\
	${_LIST_DEPENDS_CMD.test} | 					\
	while read type pattern dir; do					\
		${TEST} "$$type" = "test" || continue;			\
		${_DEPENDS_INSTALL_CMD} 0<&3;				\
	done

.PHONY:
acquire-test-depends-lock: acquire-lock
release-test-depends-lock: release-lock

_VARGROUPS+=		depends
_PKG_VARS.depends=	TOOL_DEPENDS BUILD_DEPENDS TEST_DEPENDS DEPENDS
_SORTED_VARS.depends=	TOOL_DEPENDS BUILD_DEPENDS TEST_DEPENDS DEPENDS
_DEF_VARS.depends=	_DEPENDS_FILE _RDEPENDS_FILE