SOURCELIST.txt: Bump to qi 2.0 (RC 16) here
[dragora.git] / bootstrap
blob23dd307d5b7b83444d2b5a431d691cd08f6a2611
1 #! /bin/sh -
3 # Builder of custom stages (cross compilers, GNU/Linux distributions)
5 # Copyright (c) 2014-2020 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)
33 CWD="$(CDPATH='' cd -P -- "$(dirname -- "$0")" && pwd -P)" || exit $?
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 " -a Target architecture [${arch}]" \
47 " -j Parallel jobs for the compiler [${jobs}]" \
48 " -k Keep (don't delete) source directory" \
49 " -o Output directory [${output}]" \
50 " -s Stage number to build [${stage}]" \
51 " -h Display this help and exit" \
52 " -V Print version information and exit" \
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 "Targets from ${CWD}/targets/ ..."
64 for name in "${CWD}/targets"/*
66 sed -e '2q;d' "$name"
67 done
68 unset name
69 echo ""
72 version()
74 printf '%s\n' \
75 "$PROGRAM 3.23" \
76 "Copyright (C) 2014-2020 Matias Andres Fonzo." \
77 "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>" \
78 "This is free software: you are free to change and redistribute it." \
79 "There is NO WARRANTY, to the extent permitted by law."
82 warn()
84 printf '%s\n' "$@" 1>&2
87 chkstatus_or_exit()
89 status=$?
91 if test $status -ne 0
92 then
93 echo "Return status = $status" 1>&2
94 exit "${1-2}"; # If not given, defaults to 2
97 unset status
100 # Function to test and extract compressed files
101 unpack()
103 for file in "$@"
105 case $file in
106 *.tar)
107 tar tf "$file" > /dev/null && \
108 tar xpf "$file"
109 chkstatus_or_exit 3
111 *.tar.gz | *.tgz | *.tar.Z )
112 gzip -cd "$file" | tar tf - > /dev/null && \
113 gzip -cd "$file" | tar xpf -
114 chkstatus_or_exit 3
116 *.tar.bz2 | *.tbz2 | *.tbz )
117 bzip2 -cd "$file" | tar tf - > /dev/null && \
118 bzip2 -cd "$file" | tar xpf -
119 chkstatus_or_exit 3
121 *.tar.lz | *.tlz )
122 lzip -cd "$file" | tar tf - > /dev/null && \
123 lzip -cd "$file" | tar xpf -
124 chkstatus_or_exit 3
126 *.tar.xz | *.txz )
127 xz -cd "$file" | tar tf - > /dev/null && \
128 xz -cd "$file" | tar xpf -
129 chkstatus_or_exit 3
131 *.zip | *.ZIP )
132 unzip -t "$file" > /dev/null && \
133 unzip "$file" > /dev/null
134 chkstatus_or_exit 3
136 *.gz)
137 gzip -t "$file" && \
138 gzip -cd "$file" > "$(basename -- "$file" .gz)"
139 chkstatus_or_exit 3
141 *.Z)
142 gzip -t "$file" && \
143 gzip -cd "$file" > "$(basename -- "$file" .Z)"
144 chkstatus_or_exit 3
146 *.bz2)
147 bzip2 -t "$file" && \
148 bzip2 -cd "$file" > "$(basename -- "$file" .bz2)"
149 chkstatus_or_exit 3
151 *.lz)
152 lzip -t "$file" && \
153 lzip -cd "$file" > "$(basename -- "$file" .lz)"
154 chkstatus_or_exit 3
156 *.xz)
157 xz -t "$file" && \
158 xz -cd "$file" > "$(basename -- "$file" .xz)"
159 chkstatus_or_exit 3
162 warn "${PROGRAM}: cannot unpack ${file}: Unsupported extension"
163 exit 1
164 esac
165 done
166 unset file
169 # Print a warning for good practices.
171 # Recommended practices is to set variables
172 # in front of `configure' or make(1), see:
174 # http://www.gnu.org/software/make/manual/html_node/Environment.html
175 # http://gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Defining-Variables.html
176 # http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Setting-Output-Variables.html
178 warn_flags()
180 warn "" \
181 "WARNING: Environment variable '$1' is set." \
182 "This will be unset to avoid possible risks." \
186 ### Default values
188 BTCC="${BTCC:=cc}"
189 BTCXX="${BTCXX:=c++}"
190 BTCFLAGS="${BTCFLAGS:=-g0 -Os -pipe}"
191 BTCXXFLAGS="${BTCXXFLAGS:=-g0 -Os -pipe}"
192 BTLDFLAGS="${BTLDFLAGS:=-s}"
193 opt_keep=opt_keep.off
194 stage=0
195 libSuffix=""
196 arch="$(uname -m)" || chkstatus_or_exit
197 jobs=1
198 worktree="$CWD"
199 output=${worktree}/OUTPUT.${PROGRAM}
200 TMPDIR="${TMPDIR:=${output}/sources}"
202 # Compose vendor name adding "-" as suffix
203 test -n "$VENDOR" && VENDOR="${VENDOR}-"
205 ### Parse options
207 while getopts :ha:j:ko:s:V name
209 case $name in
211 usage
212 exit 0
215 arch="$OPTARG"
218 jobs="$OPTARG"
221 opt_keep=opt_keep
224 output="$OPTARG"
227 stage="$OPTARG"
230 version
231 exit 0
234 warn "Option '-${OPTARG}' requires an argument"
235 usage
236 exit 1
239 warn "Illegal option -- '-${OPTARG}'"
240 usage
241 exit 1
243 esac
244 done
245 shift $(( OPTIND - 1 ))
247 # Check for environment variables, print warning, unset in any case
249 test -n "$CC" && warn_flags CC
250 test -n "$CXX" && warn_flags CXX
251 test -n "$CFLAGS" && warn_flags CFLAGS
252 test -n "$CXXFLAGS" && warn_flags CXXFLAGS
253 test -n "$LDFLAGS" && warn_flags LDFLAGS
254 unset CC CXX CFLAGS CXXFLAGS LDFLAGS warn_flags
256 # Load target architecture-file
258 if test -f "${worktree}/targets/$arch"
259 then
260 echo "${PROGRAM}: Loading target $arch ..."
261 . "${worktree}/targets/$arch"
262 else
263 warn \
264 "${PROGRAM}: Target name not recognized -- '${arch}'" \
265 "See '$0 -h' for more information"
266 exit 1
269 # Determine the host to use.
271 # Set up the host if a C compiler command was exported,
272 # otherwise, a local `cc' will be used instead
274 if test -n "$BTCC"
275 then
276 host="$(${BTCC} -dumpmachine)" || chkstatus_or_exit
277 else
278 host="$(cc -dumpmachine)" || chkstatus_or_exit
281 # If the host and the target are the same triplet, it won't work.
282 # We are changing the host if it is really needed
284 if test "$host" = "$target"
285 then
286 # Rename VENDOR to 'cross'. If empty, 'cross-linux' is added
287 case "${host%-*-*}" in
288 *-*)
289 host="$(echo "$host" | sed -e 's/-[^-]*/-cross/')"
292 host="$(echo "$host" | sed -e 's/-[^-]*/-cross-linux/')"
294 esac
297 # Compose variables for the physical output,
298 # printing some useful information
300 crossdir=${output}/cross/${target}
301 rootdir=${output}/stage${stage}
303 printf '%s\n' \
304 "BTCC: $BTCC" \
305 "BTCXX: $BTCXX" \
306 "BTCFLAGS: $BTCFLAGS" \
307 "BTCXXFLAGS: $BTCXXFLAGS" \
308 "BTLDFLAGS: $BTLDFLAGS" \
309 "Host: $host" \
310 "Target: $target" \
311 "Output directory: $output" \
312 "Cross directory: $crossdir" \
313 "Root directory: $rootdir"
315 # Remove write permission for group and other
316 umask 022
318 # Create required directories
319 mkdir -p -- "$output" "$TMPDIR"
320 chkstatus_or_exit
322 # Set default PATH, propagate variables
323 PATH="${crossdir}/bin:${PATH}"
325 export PATH VENDOR TMPDIR
327 # Main loop
328 for file in ${CWD}/stages/${stage}/${@:-??-*}
330 file="${file##*/}"
332 if test ! -f "${CWD}/stages/${stage}/$file"
333 then
334 warn "${PROGRAM}: ${stage}/${file}: No such file or stage number"
335 exit 1
337 if test ! -x "${CWD}/stages/${stage}/$file"
338 then
339 warn "${PROGRAM}: ${stage}/${file}: File not executable, dodging"
340 continue;
343 ### Stage pre-settings
345 # Create sysroot directory, recreating the symlink for the stage 0
347 if test "$stage" = 0
348 then
349 mkdir -p -- "${crossdir}/$target" || chkstatus_or_exit
351 if test ! -e "${crossdir}/${target}/usr"
352 then
353 ln -sf . "${crossdir}/${target}/usr" || chkstatus_or_exit
356 # Ensure toolchain sanity for multilib purposes
357 case $arch in
358 aarch64* | arm* | i586 | *x32 | x86_64 | riscv* )
359 if test ! -e "${crossdir}/lib" && test -n "$libSuffix"
360 then
361 ln -sf lib${libSuffix} "${crossdir}/lib" || chkstatus_or_exit
364 esac
367 # Create "tools" directory, recreating the symlink for the stage 1
368 if test "$stage" = 1
369 then
370 if test ! -d "${rootdir}/tools"
371 then
372 mkdir -p -- "${rootdir}/tools" || chkstatus_or_exit
375 # Make required symlink
376 ln -sf "${rootdir}/tools" / || chkstatus_or_exit
379 echo "${PROGRAM}: Processing $file from stage $stage ..."
381 # Set trap before to run the script in order to
382 # catch the return status, exit code 2 if fails
384 trap 'chkstatus_or_exit 2' EXIT HUP INT QUIT ABRT TERM
386 # Exit immediately on any error
387 set -e
389 . "${CWD}/stages/${stage}/$file"
391 # Deactivate shell option(s)
392 set +e
394 # Reset given signals
395 trap - EXIT HUP INT QUIT ABRT TERM
397 # Delete declared directories on the cleanup() function
398 if test "$opt_keep" != opt_keep
399 then
400 if type cleanup 1> /dev/null 2> /dev/null
401 then
402 cleanup
403 chkstatus_or_exit 2
404 unset cleanup
408 # Back to the current working directory
409 cd -- "$CWD" || chkstatus_or_exit
410 done