stages/*: change license to Apache 2.0
[dragora.git] / bootstrap
blob7acc716c5729d05c7827c2e03bd872995f21df73
1 #! /bin/sh -
3 # Builder of custom stages (cross compilers, GNU/Linux distributions)
5 # Copyright (c) 2014-2017 Matias Fonzo, <selk@dragora.org>.
7 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at
11 # http://www.apache.org/licenses/LICENSE-2.0
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
19 # EXIT STATUS
20 # 0 = Successful completion
21 # 1 = Minor common errors (e.g: help usage, support not available)
22 # 2 = Command execution error
23 # 3 = Integrity check error for compressed files
25 PROGRAM="${0##*/}"
27 # Override locale settings
28 LC_ALL=C
29 LANGUAGE=C
30 export LC_ALL LANGUAGE
32 # Get physical working directory, absolute path name
33 CWD=$(CDPATH= cd -P -- $(dirname -- "$0") && printf "$PWD")
35 #### Functions
37 usage() {
38 printf "%s\n" \
39 "Builder of custom stages (cross compilers, GNU/Linux distributions)" \
40 "" \
41 "Usage: $PROGRAM [OPTION]... [FILE]..." \
42 "" \
43 "Defaults for the options are specified in brackets." \
44 "" \
45 "Options:" \
46 " -h display this help and exit" \
47 " -V print version information and exit" \
48 " -a target architecture [${arch}]" \
49 " -j parallel jobs for the compiler [${jobs}]" \
50 " -k keep (don't delete) source directory" \
51 " -o output directory [${output}]" \
52 " -s stage number to build [${stage}]" \
53 "" \
54 "Some influential environment variables:" \
55 " TMPDIR temporary directory for sources [${TMPDIR}]" \
56 " BTCC C compiler command [${BTCC}]" \
57 " BTCXX C++ compiler command [${BTCXX}]" \
58 " BTCFLAGS C compiler flags [${BTCFLAGS}]" \
59 " BTCXXFLAGS C++ compiler flags [${BTCXXFLAGS}]" \
60 " BTLDFLAGS linker flags [${BTLDFLAGS}]" \
61 " VENDOR vendor name to reflect on the target triplet" \
62 "" \
63 "Supported architectures (targets):"
64 for arch in "${CWD}/targets"/*
66 printf "${arch##*/} "
67 done
68 echo
71 version()
73 printf "%s\n" \
74 "$PROGRAM 3.16" \
75 "Copyright (C) 2014-2017 Matias Andres Fonzo." \
76 "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>" \
77 "This is free software: you are free to change and redistribute it." \
78 "There is NO WARRANTY, to the extent permitted by law."
81 warn()
83 echo "$@" 1>&2
86 chkstatus_or_exit()
88 status=$?
90 if test $status -ne 0
91 then
92 echo "Return status = $status" 1>&2
93 exit ${1-2}; # If not given, defaults to 2
96 unset status
99 # Function to test and extract tarball files
100 untar() {
101 tar tf "$1" > /dev/null && {
102 cd -- "$2" && tar xpf "$1"
104 chkstatus_or_exit 3
107 #### Warning for good practices
109 # Recommended practices is to set variables in front of `configure',
110 # or make(1), see also:
112 # http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Defining-Variables.html
113 # http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Setting-Output-Variables.html
114 # http://www.gnu.org/software/make/manual/make.html#Environment
116 warn_flags()
118 warn "WARNING: Environment variable '$1' is set." \
119 "This will be unset to avoid possible risks." \
123 #### Default values
125 BTCC="${BTCC:=cc}"
126 BTCXX="${BTCXX:=c++}"
127 BTCFLAGS="${BTCFLAGS:=-g0 -Os}"
128 BTCXXFLAGS="${BTCXXFLAGS:=$BTCFLAGS}"
129 BTLDFLAGS="${BTLDFLAGS:=-s}"
130 worktree="$CWD"
131 arch="$(uname -m)" || chkstatus_or_exit
132 jobs=1
133 opt_keep=opt_keep.off
134 output=${worktree}/OUTPUT.${PROGRAM}
135 TMPDIR="${TMPDIR:=${output}/sources}"
136 stage=0
138 # Compose vendor name adding "-" as suffix
139 test -n "$VENDOR" && VENDOR="${VENDOR}-"
141 #### Parse options
143 while getopts :ha:j:ko:s:V name
145 case $name in
147 usage
148 exit 0
151 arch="$OPTARG"
154 jobs="$OPTARG"
157 opt_keep=opt_keep
160 output="$OPTARG"
163 stage="$OPTARG"
166 version
167 exit 0
170 warn "Option '-${OPTARG}' requires an argument"
171 usage
172 exit 1
175 warn "Illegal option -- '-${OPTARG}'"
176 usage
177 exit 1
179 esac
180 done
181 shift $(( OPTIND - 1 ))
183 # Check for environment variables, print warning, unset in any case
184 test "${CC:+CC_defined}" = CC_defined && warn_flags CC
185 test "${CXX:+CXX_defined}" = CXX_defined && warn_flags CXX
186 test "${CFLAGS:+CFLAGS_defined}" = CFLAGS_defined && warn_flags CFLAGS
187 test "${CXXFLAGS:+CXXFLAGS_defined}" = CXXFLAGS_defined && warn_flags CXXFLAGS
188 test "${LDFLAGS:+LDFLAGS_defined}" = LDFLAGS_defined && warn_flags LDFLAGS
190 unset CC CXX CFLAGS CXXFLAGS LDFLAGS warn_flags
192 # Avoid exportation of 'libSuffix' when a target is loaded
193 libSuffix=""
195 # Load target architecture-file
197 if test -f "${worktree}/targets/$arch"
198 then
199 echo "${PROGRAM}: Loading target $arch ..."
200 . "${worktree}/targets/$arch"
201 else
202 warn \
203 "${PROGRAM}: Target name not recognized -- '${arch}'" \
204 "See '$0 -h' for more information"
205 exit 1
208 # Determine the host to use.
210 # Set up the host if a C compiler command was exported,
211 # otherwise, a local `cc' will be used instead
213 if test -n "$BTCC"
214 then
215 host="$(${BTCC} -dumpmachine)" || chkstatus_or_exit
216 else
217 host="$(cc -dumpmachine)" || chkstatus_or_exit
220 # If the host and the target are the same triplet, it won't work.
221 # We are changing the host if it is really needed
223 if test "$host" = "$target"
224 then
225 # Rename VENDOR to 'cross'. If empty, 'cross-linux' is added
226 case "${host%-*-*}" in
227 *-*)
228 host="$(echo "$host" | sed -e 's/-[^-]*/-cross/')"
231 host="$(echo "$host" | sed -e 's/-[^-]*/-cross-linux/')"
233 esac
236 # Compose variables for the physical output,
237 # print some useful information
239 crossdir=${output}/cross/${target}
240 rootdir=${output}/stage${stage}
242 printf "%s\n" \
243 "BTCC: $BTCC" \
244 "BTCXX: $BTCXX" \
245 "BTCFLAGS: $BTCFLAGS" \
246 "BTCXXFLAGS: $BTCXXFLAGS" \
247 "BTLDFLAGS: $BTLDFLAGS" \
248 "Host: $host" \
249 "Target: $target" \
250 "Output directory: $output" \
251 "Cross directory: $crossdir" \
252 "Root directory: $rootdir"
254 # Remove write permission for group and other
255 umask 022
257 # Create required directories
258 if test ! -d "$output"
259 then
260 mkdir -p -- "$output" || chkstatus_or_exit
262 if test ! -d "$TMPDIR"
263 then
264 mkdir -p -- "$TMPDIR" || chkstatus_or_exit
267 # Set default path and propagate variables
269 PATH="${crossdir}/bin:${PATH}"
270 export PATH VENDOR TMPDIR
272 # Main loop
273 for file in "${CWD}/stages/${stage}"/${@:-??-*}
275 file="${file##*/}"
277 if test ! -f "${CWD}/stages/${stage}/$file"
278 then
279 warn "${PROGRAM}: ${stage}/${file}: No such file or stage number"
280 exit 1
282 if test ! -x "${CWD}/stages/${stage}/$file"
283 then
284 warn "${PROGRAM}: ${stage}/${file}: File not executable, dodging"
285 continue;
288 #### Stage pre-settings
290 # Create sysroot directory, recreating the symlink for the stage 0
292 if test "$stage" = 0
293 then
294 mkdir -p -- "${crossdir}/$target" || chkstatus_or_exit
296 if test ! -e "${crossdir}/${target}/usr"
297 then
298 ln -sf . "${crossdir}/${target}/usr" || chkstatus_or_exit
301 # Ensure toolchain sanity for multilib purposes
302 case $arch in
303 i586 | *x32 | x86_64 )
304 if test ! -e "${crossdir}/lib" -a -n "$libSuffix"
305 then
306 ln -sf lib${libSuffix} "${crossdir}/lib" || chkstatus_or_exit
309 esac
312 # Create "tools" directory, recreating the symlink for the stage 1
313 if test "$stage" = 1
314 then
315 if test ! -d "${rootdir}/tools"
316 then
317 mkdir -p -- "${rootdir}/tools" || chkstatus_or_exit
320 # Make required symlink
321 ln -sf "${rootdir}/tools" / || chkstatus_or_exit
324 #### Load the file containing the instruction
326 echo "${PROGRAM}: Processing $file from stage $stage ..."
328 # Set trap before to run the script in order to
329 # catch the return status, exit code 2 if fails
331 trap 'chkstatus_or_exit 2' EXIT HUP INT QUIT ABRT TERM
333 # Exit immediately on any error
334 set -e
336 . "${CWD}/stages/${stage}/$file"
338 # Deactivate shell option(s)
339 set +e ; set +x
341 # Reset given signals
342 trap - EXIT HUP INT QUIT ABRT TERM
344 # Delete declared directories on the cleanup() function
345 if test "$opt_keep" != opt_keep
346 then
347 if type cleanup 1> /dev/null 2> /dev/null
348 then
349 cleanup || chkstatus_or_exit 2
350 unset cleanup
354 # Back to the current working directory
355 cd -- "$CWD" || chkstatus_or_exit
356 done