aboutsummaryrefslogtreecommitdiff
path: root/libexec/build-make
blob: 8da60c91cb3bcde86fc8a40bc136ebf08863f859 (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
#!/usr/bin/env build

## build_make_cleanup
# deal with temporary junk when we exit
# FIXME we need a way to universally deal w/ cleanup of junk created by
# imported commands.
build_make_cleanup()
{
	test -p "${BUILDER_PIPE}" && rm -f "${BUILDER_PIPE}"
	test "${BUILDER_DEBUG:-0}" -ne '0' && return
	test -f "${BUILDER_MAKEFILE}" && rm -f "${BUILDER_MAKEFILE}"
}

build_make()
{
	if test "$#" -eq '0'; then
		error 'no make action specified'
		echo "try 'build help make'" >&2
		exit 1
	fi

	BUILDER_MAKE_ACTION="${1}"
	shift

	# This allows 'build <command> --help' to work.
	for arg; do
		case "${arg}" in
		(-h|-help|--help) exec build make-"${BUILDER_MAKE_ACTION}" --help;;
		esac
	done

	# If no target is given, then base our target on the current working
	# directory, falling back to ${TARGET} (or all/all)
	if test "$#" -eq '0'; then
		case "${BUILDER_MAKE_ACTION}" in
		(*clean) NAME='all/all';;
		(*)	 NAME="${TARGET}";;
		esac

		# Are we somewhere within the pkg structure.  If this test
		# succeeds then we are at least in a category directory within
		# the pkgdir.  Just being in pkgdir is not enough to change our
		# default argument list handling.
		if [ "${PWD##${BUILDER_PKGDIR}/}" != "${PWD}" ]; then
			category="${PWD##${BUILDER_PKGDIR}/}"
			if [ "${category%%/*}" != "${category}" ]; then
				name="${category#*/}"
				category="${category%%/*}"
				NAME="${category}/${name%%/*}"
			else
				NAME="${category}/all"
			fi
			unset category
			unset name
		fi
		set -- "${NAME}"
	fi

	# FIXME move this to a sub-command to be used by other tools.
	for package in "$@"; do
		# If all is specified anywhere in the argument list than just
		# discard everything else.
		case "${package}" in
		(-*|*/all|all) continue;;
		esac

		CATEGORY="${package%%/*}"
		if [ "${CATEGORY}" != 'all' ]; then
			if [ ! -d "${BUILDER_PKGDIR}/${CATEGORY}" ]; then
				die "invalid package category '${CATEGORY}'"
			fi
			if ! build-query --exists "${package}"; then
				exit 1
			fi
		fi
	done

	# sort/uniq the argument list
	# FIXME need a way to "resolve" the package list instead of possibly
	# clobbering it.
	set -- $(for package in "$@"; do echo "${package}" ; done | sort | uniq)

	trap build_make_cleanup 0

	# build the Makefile
	test -d "${BUILDER_TMPDIR}" || mkdir -p "${BUILDER_TMPDIR}"
	BUILDER_MAKEFILE="$(mktemp "${BUILDER_TMPDIR}/builder_makefile.XXXXXXXX")"
	if [ ! -f "${BUILDER_MAKEFILE}" ]; then
		die "failed to generate build dependencies"
	fi
	export BUILDER_MAKEFILE
	"${BUILDER_LIBDIR}/build-makedeps" || die "failed generate build dependencies"

	for package in $(cd "${SYSROOT}/var/db/binpkgs" 2> /dev/null &&
			echo */*); do
		test -e "${SYSROOT}/var/db/binpkgs/${package}" || continue
		name="${package##*/}"
		category="${package%%/*}"
		if ! build-query --exists "${category}/${name}"; then
			echo "${category}/${name}: removing bad package"
			(cd "${SYSROOT}" &&
			 cat "var/db/binpkgs/${category}/${name}" | xargs -0 rm  -f
			 rm "var/db/binpkgs/${category}/${name}")
		fi
	done
	unset category
	unset name


	packages=
	for package in "$@"; do
		case "${package}" in
		(all|*/all);;
		(*) package="$(build-query --pkgname "${package}")";;
		esac
		package="$(echo "${package}"|tr '/-' '__')"
		packages="${packages} ${package}_${BUILDER_MAKE_ACTION}"
	done
	set -- ${packages}
	unset packages

	# The 'tee' command will discard the exit status from 'make', so we
	# have to jump through a few hoops to capture the exit status in a
	# portable fashion.
	BUILDER_PIPE="`mktemp "${BUILDER_TMPDIR}/builder_pipe.XXXXXXXX"`"
	test -f "${BUILDER_PIPE}" || die 'failed to generate log-pipe placeholder'
	rm -f "${BUILDER_PIPE}" && mkfifo "${BUILDER_PIPE}" || die 'failed to create log-pipe'
	tee "${BUILDER_TMPDIR}/builder.log" < "${BUILDER_PIPE}" &
	BUILDER_LOGGER="$!"
	make -r -f "${BUILDER_MAKEFILE}" "${@}" > "${BUILDER_PIPE}" 2>&1
	exit $?
}

if test "${BUILDER_CALL_STACK}" = '__main__'; then
	simple_usage 'make' '<action> [all|[<category>/]<package|all>]' "$@"
	build_make "${@}"
fi



# vim: filetype=sh