xref: /freebsd/contrib/bmake/mk/stage-install.sh (revision c59c3bf34db360695f07735bebc76a768cac5afc)
1#!/bin/sh
2
3# NAME:
4#	stage-install.sh - wrapper around install
5#
6# SYNOPSIS:
7#	stage-install.sh [variable="value"] "args" "dest"
8#
9# DESCRIPTION:
10#	This script is a wrapper around the normal install(1).
11#	Its role is to add '.dirdep' files to the destination.
12#	The variables we might use are:
13#
14#	INSTALL
15#		Path to actual install(1), default is
16#		$REAL_INSTALL
17#
18#	OBJDIR
19#		Path to the dir where '.dirdep' was generated,
20#		default is '.'
21#
22#	_DIRDEP
23#		Path to actual '.dirdep' file, default is
24#		$OBJDIR/.dirdep
25#
26#	The "args" and "dest" are passed as is to install(1), and if a
27#	'.dirdep' file exists it will be linked or copied to each
28#	"file".dirdep placed in "dest" or "dest".dirdep if it happed
29#	to be a file rather than a directory.
30#
31#	Before we run install(1), we check if "dest" needs to be a
32#	directory (more than one file in "args") and create it
33#	if necessary.
34#
35# SEE ALSO:
36#	meta.stage.mk
37#
38
39# RCSid:
40#	$Id: stage-install.sh,v 1.11 2024/02/17 17:26:57 sjg Exp $
41#
42#	SPDX-License-Identifier: BSD-2-Clause
43#
44#	@(#) Copyright (c) 2013-2020, Simon J. Gerraty
45#
46#	This file is provided in the hope that it will
47#	be of use.  There is absolutely NO WARRANTY.
48#	Permission to copy, redistribute or otherwise
49#	use this file is hereby granted provided that
50#	the above copyright notice and this notice are
51#	left intact.
52#
53#	Please send copies of changes and bug-fixes to:
54#	sjg@crufty.net
55#
56
57INSTALL=${REAL_INSTALL:-install}
58OBJDIR=.
59
60while :
61do
62    case "$1" in
63    *=*) eval "$1"; shift;;
64    *) break;;
65    esac
66done
67
68# get last entry from "$@" without side effects
69last_entry() {
70    while [ $# -gt 8 ]
71    do
72        shift 8
73    done
74    eval last=\$$#
75    echo $last
76}
77
78# mkdir $dest if needed (more than one file)
79mkdir_if_needed() {
80    (
81        lf=
82        while [ $# -gt 8 ]
83        do
84            shift 4
85        done
86        for f in "$@"
87        do
88            [ -f $f ] || continue
89            [ $f = $dest ] && continue
90            if [ -n "$lf" ]; then
91                # dest must be a directory
92                mkdir -p $dest
93                break
94            fi
95            lf=$f
96        done
97    )
98}
99
100args="$@"
101dest=`last_entry "$@"`
102case " $args " in
103*" -d "*) ;;
104*) [ -e $dest ] || mkdir_if_needed "$@";;
105esac
106
107# if .dirdep doesn't exist, just run install and be done
108_DIRDEP=${_DIRDEP:-$OBJDIR/.dirdep}
109[ -s $_DIRDEP ] && EXEC= || EXEC=exec
110$EXEC $INSTALL "$@" || exit 1
111
112# from meta.stage.mk
113LnCp() {
114    rm -f $2 2> /dev/null
115    ln $1 $2 2> /dev/null || cp -p $1 $2
116}
117
118StageDirdep() {
119  t=$1
120  if [ -s $t.dirdep ]; then
121      cmp -s $_DIRDEP $t.dirdep && return
122      case "${STAGE_CONFLICT:-error}" in
123      [Ee]*) STAGE_CONFLICT=ERROR action=exit;;
124      *) STAGE_CONFLICT=WARNING action=: ;;
125      esac
126      echo "$STAGE_CONFLICT: $t installed by `cat $t.dirdep` not `cat $_DIRDEP`" >&2
127      $action 1
128  fi
129  LnCp $_DIRDEP $t.dirdep || exit 1
130}
131
132if [ -f $dest ]; then
133    # a file, there can be only one .dirdep needed
134    StageDirdep $dest
135elif [ -d $dest ]; then
136    for f in $args
137    do
138        test -f $f || continue
139        StageDirdep $dest/${f##*/}
140    done
141fi
142