aboutsummaryrefslogtreecommitdiff
path: root/libexec/build-make
blob: 8a4bf9c9af2c24083bb1e2b120caee1ab4221131 (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
#!/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"

	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