fix xpi extraction
[dports.git] / Mk / bsd.destdir.mk
1 #-*- tab-width: 4; -*-
2 # ex:ts=4
3 #
4 # bsd.destdir.mk - Support for chrooted installation
5 #
6 # Created by: Gabor Kovesdan <gabor@FreeBSD.org>
7 #
8 # $FreeBSD$
9 #
10 # Please make sure all changes to this file are passed through the maintainer.
11
12 DESTDIR_Include_MAINTAINER=             portmgr@FreeBSD.org
13
14 #
15 # The target order is always: pre-chroot do-chroot post-chroot
16 #
17 # pre-chroot
18 #                       - You can use this for special preparation work, that
19 #                         want to do before chrooting into the destination
20 #                         environment and doing the real build.  At default
21 #                         this target is empty.
22 #
23 # do-chroot
24 #                       - This is the main target for doing the chrooted
25 #                         operations.  It mounts the ports tree and devfs into
26 #                         the destination environment and starts make(1)
27 #                         by calling chroot(1).
28 #
29 # post-chroot
30 #                       - This target runs chrooted just after chroot(1) was
31 #                         called.  You can use this for special preparation
32 #                         work for the chrooted build if necessary.  At
33 #                         default, this target is empty.
34 #
35 # DESTDIR_ENV_LIST
36 #                       - Contains names of the variables in host environ(7),
37 #                         which should be imported into the chrooted environ
38 #                         along with their values.
39 #                         Default: empty.
40 #
41 # DESTDIR_MOUNT_LIST
42 #                       - Contains the directories to mount into the
43 #                         destination.  This is to make PORTSDIR, DISTDIR, etc.
44 #                         available in the destination environment.  Three
45 #                         forms of entries are allowed:
46 #                         VAR
47 #                               - Mounts the path contained by VAR into
48 #                                 a temporary directory and sets VAR to that
49 #                                 directory in the destination environ(7).
50 #                         VAR:HOST_PATH
51 #                               - Mounts HOST_PATH to a a temporary directory
52 #                                 and sets VAR to that directory in the
53 #                                 destination environ(7).
54 #                         VAR:HOST_PATH:DEST_PATH
55 #                               - Mounts HOST_PATH to DEST_PATH and sets VAR
56 #                                 to DEST_PATH in the destination environ(7).
57 #                         Default: PORTSDIR DISTDIR
58 #
59 # You can use something like this in host /etc/make.conf to
60 # customize per-chroot environment:
61 #       .if ${DESTDIR}=/foo/bar
62 #       PREFIX=/opt
63 #       CFLAGS=-O3 -pipe
64 #       DESTDIR_ENV_LIST=PREFIX CFLAGS
65 #       .endif
66 #
67
68 .if !defined(_DESTDIRMKINCLUDED)
69
70 _DESTDIRMKINCLUDED=     yes
71
72 .if defined(WITH_DESTDIR_DEBUG)
73 DEBUG_MSG=      ${ECHO_MSG} "DEBUG:"
74 .else
75 DEBUG_MSG=      ${TRUE}
76 .endif
77
78 DESTDIR_ENV_LIST?=
79 DESTDIR_ENV=    CHROOTED=yes PATH=${PATH} TERM=${TERM}
80 .for _var in ${DESTDIR_ENV_LIST:NDESTDIR:NCHROOTED:NPORTSDIR}
81 DESTDIR_ENV+=   ${_var}="${${_var}}"
82 .endfor
83
84 # Processing DESTDIR_MOUNT_LIST into something more machine-readable
85 # VAR:HOST_PATH:DEST_PATH
86 # VAR -> VAR:${VAR}:TMP
87 # VAR:HOST_PATH -> VAR:HOST_PATH:TMP
88 DESTDIR_MOUNT_LIST?=    PORTSDIR DISTDIR
89 _DESTDIR_MOUNT_LIST=
90 .for _entry in ${DESTDIR_MOUNT_LIST}
91 __entry=${_entry}
92 .if ${__entry:M*\:*\:*}
93 _DESTDIR_MOUNT_LIST+=   ${_entry}
94 .elif ${__entry:M*\:*}
95 _DESTDIR_MOUNT_LIST+=   ${_entry}:___temp___
96 .else
97 .if defined(${_entry}) && !empty(${_entry})
98 _DESTDIR_MOUNT_LIST+=   ${_entry}:${${_entry}}:___temp___
99 .endif
100 .endif
101 .endfor
102
103 .MAIN:  all
104 .for _target in ${.TARGETS}
105 ${_target}: pre-chroot do-chroot
106         @${TRUE}
107 .endfor
108
109 .if !target(pre-chroot)
110 pre-chroot:
111         @${TRUE}
112 .endif
113
114 .if !target(do-chroot)
115 do-chroot:
116         @if [ ! -d ${DESTDIR} ]; then \
117                 ${ECHO_MSG} "===>  Directory ${DESTDIR} does not exist"; \
118                 ${ECHO_MSG} "===>  Please set DESTDIR to a valid jail environment."; \
119                 exit 1; \
120         fi; \
121         _destdir=`${REALPATH} ${DESTDIR}`; \
122         _mounted_entries_list=""; \
123         _created_mountpoints_list=""; \
124         _var_path_list=""; \
125         ${ECHO_MSG} "===>  Creating some important subdirectories"; \
126         for _dir in tmp dev; do \
127                 [ -d $${_destdir}/$${_dir} ] || \
128                         if ${MKDIR} $${_destdir}/$${_dir}; then \
129                                 ${ECHO_MSG} "===> /$${_dir} subdirectory has been successfully created"; \
130                                 _created_mountpoints_list="$${_destdir}/$${_dir} $${_created_mountpoints_list}"; \
131                         else \
132                                 ${ECHO_MSG} "===> /$${_dir} subdirectory could not be created"; \
133                                 exit 2; \
134                         fi; \
135         done; \
136         ${DEBUG_MSG} "_DESTDIR_MOUNT_LIST=${_DESTDIR_MOUNT_LIST}"; \
137         for _entry in ${_DESTDIR_MOUNT_LIST}; do \
138                 ${DEBUG_MSG} "Processing $${_entry}"; \
139                 _mount_var=$${_entry%%:*}; \
140                 _tp=$${_entry#*:}; \
141                 _host_path=`${REALPATH} $${_tp%:*}`; \
142                 _dest_path=$${_entry##*:}; \
143                 _full_dest_path=`${REALPATH} $${_destdir}/$${_dest_path}`; \
144                 _entry_was_created=0; \
145                 _entry_should_mount=0; \
146                 ${DEBUG_MSG} "$${_mount_var}:$${_host_path}:$${_full_dest_path}"; \
147                 if [ "$${_dest_path}" = "___temp___" ]; then \
148                         ${DEBUG_MSG} "Creating temporary mount point"; \
149                         if _full_dest_path=`${MKTEMP} -d $${_destdir}/tmp/mountpoint.XXXXXX`; then \
150                                 ${DEBUG_MSG} "Temporary mount point $${_full_dest_path} created successfully"; \
151                                 _entry_was_created=1; \
152                                 _entry_should_mount=1; \
153                                 _dest_path=$${_full_dest_path#$${_destdir}}; \
154                                 _created_mountpoints_list="$${_full_dest_path} $${_created_mountpoints_list}"; \
155                         else \
156                                 ${ECHO_MSG} "===> Failed to create temporary mount point"; \
157                                 exit 9; \
158                         fi; \
159                 else \
160                         ${DEBUG_MSG} "Checking if already mounted"; \
161                         if ${MOUNT}|${GREP} -qs "^$${_host_path} on $${_full_dest_path} ("; then \
162                                 ${DEBUG_MSG} "$${_host_path} is already mounted on $${_full_dest_path}"; \
163                                 _var_path_list="$${_var_path_list} $${_mount_var}=$${_dest_path}"; \
164                         else \
165                                 ${DEBUG_MSG} "$${_host_path} is not mounted on $${_full_dest_path}"; \
166                                 _entry_should_mount=1; \
167                         fi; \
168                 fi; \
169                 [ -d $${_full_dest_path} ] || \
170                         if ${MKDIR} $${_full_dest_path}; then \
171                                 ${DEBUG_MSG} "Mount point $${_full_dest_path} created"; \
172                                 _entry_was_created=1; \
173                                 _created_mountpoints_list="$${_created_mountpoints_list} ${_full_dest_path}"; \
174                         else \
175                                 ${ECHO_MSG} "===> Mount point $${_full_dest_path} could not be created"; \
176                                 exit 7; \
177                         fi; \
178                 [ "$${_entry_should_mount}" = "0" ] || \
179                         if ${MOUNT_NULLFS} $${_host_path} $${_full_dest_path}; then \
180                                 ${DEBUG_MSG} "Directory $${_host_path} mounted"; \
181                                 _mounted_entries_list="$${_full_dest_path} $${_mounted_entries_list}"; \
182                                 _var_path_list="$${_var_path_list} $${_mount_var}=$${_dest_path}"; \
183                         else \
184                                 ${ECHO_MSG} "===> Dir $${_host_path} could not be mounted"; \
185                                 [ "$${_entry_was_created}" = "0" ] || \
186                                         ${RMDIR} $${_full_dest_path} || ${TRUE}; \
187                                 exit 8; \
188                         fi; \
189         done; \
190         ${DEBUG_MSG} "Handling devfs separately"; \
191         _full_dest_path=$${_destdir}/dev; \
192         ${MOUNT}|${GREP} -qs "^devfs on $${_full_dest_path} (" || \
193                 if ${MOUNT_DEVFS} $${_full_dest_path}; then \
194                         ${DEBUG_MSG} "devfs mounted"; \
195                         _mounted_entries_list="$${_full_dest_path} $${_mounted_entries_list}"; \
196                 else \
197                         ${ECHO_MSG} "===> devfs could not be mounted"; \
198                         [ -n "$${_created_mountpoints_list%%* $${_destdir}/dev *}" ] || \
199                                 ${RMDIR} $${_destdir}/dev || ${TRUE}; \
200                         exit 9; \
201                 fi; \
202         _var_path_list="$${_var_path_list} DEVFS=/dev"; \
203         ${DEBUG_MSG} "Things we mounted: $${_mounted_entries_list}"; \
204         ${DEBUG_MSG} "Things we created: $${_created_mountpoints_list}"; \
205         ${DEBUG_MSG} "_var_path_list: $${_var_path_list}"; \
206         ${ECHO_MSG} "===>  Starting chrooted make in ${DESTDIR}..."; \
207         export $${_var_path_list}; \
208         ${CHROOT} $${_destdir} ${SH} -c "\
209                 cd $${PORTSDIR}${.CURDIR:S|^${PORTSDIR}||}; \
210                 ${SETENV} -i ${DESTDIR_ENV} $${_var_path_list} ${MAKE} ${.TARGETS}" && \
211                 { status=$$?; ${ECHO_MSG} "===>  Chrooted make in ${DESTDIR} succeeded"; } || \
212                 { status=$$?; ${ECHO_MSG} "===>  Chrooted make in ${DESTDIR} failed"; }; \
213                 ${ECHO_MSG} "===>  Cleaning up..."; \
214         for _entry in $${_mounted_entries_list}; do \
215                 ${UMOUNT} -f $${_entry} || ${TRUE}; \
216         done; \
217         for _entry in $${_created_mountpoints_list}; do \
218                 ${RMDIR} $${_entry} || ${TRUE}; \
219         done; \
220         exit $$status
221 .endif  # !target(do-chroot)
222 .endif  # !defined(_DESTDIRMKINCLUDED)