blob: 0aa51680547335f4568e2c1a01773bef880cd419 [file] [log] [blame]
Kenny Root5fd6d312013-06-11 16:36:54 -07001#!/bin/bash
2#
3# Copyright (C) 2009 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18#
19# This script imports new versions of scrypt (http://www.tarsnap.com/scrypt/) into the
20# Android source tree. To run, (1) fetch the appropriate tarball from the scrypt repository,
21# (2) check the gpg/pgp signature, and then (3) run:
22# ./import_scrypt.sh import scrypt-*.tar.gz
23#
24# IMPORTANT: See README.android for additional details.
25
26# turn on exit on error as well as a warning when it happens
27set -e
28set -x
29trap "echo WARNING: Exiting on non-zero subprocess exit code" ERR;
30
31# Ensure consistent sorting order / tool output.
32export LANG=C
33export LC_ALL=C
34
35export DIRNAME=$(dirname $0)
36
37function die() {
38 declare -r message=$1
39
40 echo $message
41 exit 1
42}
43
44function usage() {
45 declare -r message=$1
46
47 if [ ! "$message" = "" ]; then
48 echo $message
49 fi
50 echo "Usage:"
51 echo " ./import_scrypt.sh import </path/to/scrypt-*.tar.gz>"
52 echo " ./import_scrypt.sh regenerate <patch/*.patch>"
53 echo " ./import_scrypt.sh generate <patch/*.patch> </path/to/scrypt-*.tar.gz>"
54 exit 1
55}
56
57function main() {
58 if [ ! -d patches ]; then
59 die "scrypt patch directory patches/ not found"
60 fi
61
62 if [ ! -f scrypt.version ]; then
63 die "scrypt.version not found"
64 fi
65
66 source $DIRNAME/scrypt.version
67 if [ "$SCRYPT_VERSION" == "" ]; then
68 die "Invalid scrypt.version; see README.android for more information"
69 fi
70
71 SCRYPT_DIR=scrypt-$SCRYPT_VERSION
72 SCRYPT_DIR_ORIG=$SCRYPT_DIR.orig
73
74 if [ ! -f scrypt.config ]; then
75 die "scrypt.config not found"
76 fi
77
78 source $DIRNAME/scrypt.config
79 if [ "$CONFIGURE_ARGS" == "" -o "$UNNEEDED_SOURCES" == "" -o "$NEEDED_SOURCES" == "" ]; then
80 die "Invalid scrypt.config; see README.android for more information"
81 fi
82
83 declare -r command=$1
84 shift || usage "No command specified. Try import, regenerate, or generate."
85 if [ "$command" = "import" ]; then
86 declare -r tar=$1
87 shift || usage "No tar file specified."
88 import $tar
89 elif [ "$command" = "regenerate" ]; then
90 declare -r patch=$1
91 shift || usage "No patch file specified."
92 [ -d $SCRYPT_DIR ] || usage "$SCRYPT_DIR not found, did you mean to use generate?"
Logan Chien629ed232017-08-31 19:15:50 +080093 [ -d $SCRYPT_DIR_ORIG ] || usage "$SCRYPT_DIR_ORIG not found, did you mean to use generate?"
Kenny Root5fd6d312013-06-11 16:36:54 -070094 regenerate $patch
95 elif [ "$command" = "generate" ]; then
96 declare -r patch=$1
97 shift || usage "No patch file specified."
98 declare -r tar=$1
99 shift || usage "No tar file specified."
100 generate $patch $tar
101 else
102 usage "Unknown command specified $command. Try import, regenerate, or generate."
103 fi
104}
105
106# Compute the name of an assembly source file generated by one of the
107# gen_asm_xxxx() functions below. The logic is the following:
108# - if "$2" is not empty, output it directly
109# - otherwise, change the file extension of $1 from .pl to .S and output
110# it.
111# Usage: default_asm_file "$1" "$2"
112# or default_asm_file "$@"
113#
114# $1: generator path (perl script)
115# $2: optional output file name.
116function default_asm_file () {
117 if [ "$2" ]; then
118 echo "$2"
119 else
120 echo "${1%%.pl}.S"
121 fi
122}
123
124# Generate an ARM assembly file.
125# $1: generator (perl script)
126# $2: [optional] output file name
127function gen_asm_arm () {
128 local OUT
129 OUT=$(default_asm_file "$@")
130 perl "$1" > "$OUT"
131}
132
133function gen_asm_mips () {
134 local OUT
135 OUT=$(default_asm_file "$@")
136 # The perl scripts expect to run the target compiler as $CC to determine
137 # the endianess of the target. Setting CC to true is a hack that forces the scripts
138 # to generate little endian output
139 CC=true perl "$1" o32 > "$OUT"
140}
141
142function gen_asm_x86 () {
143 local OUT
144 OUT=$(default_asm_file "$@")
145 perl "$1" elf -fPIC > "$OUT"
146}
147
148function gen_asm_x86_64 () {
149 local OUT
150 OUT=$(default_asm_file "$@")
151 perl "$1" elf "$OUT" > "$OUT"
152}
153
154
155# Filter all items in a list that match a given pattern.
156# $1: space-separated list
157# $2: egrep pattern.
158# Out: items in $1 that match $2
159function filter_by_egrep() {
160 declare -r pattern=$1
161 shift
162 echo "$@" | tr ' ' '\n' | grep -e "$pattern" | tr '\n' ' '
163}
164
165# Sort and remove duplicates in a space-separated list
166# $1: space-separated list
167# Out: new space-separated list
168function uniq_sort () {
Logan Chienee1d0142017-08-31 15:38:01 +0800169 echo "$@" | tr ' ' '\n' | sort -u | tr '\n' ' ' | \
170 sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
Kenny Root5fd6d312013-06-11 16:36:54 -0700171}
172
173function print_autogenerated_header() {
Logan Chienee1d0142017-08-31 15:38:01 +0800174 echo "// Auto-generated - DO NOT EDIT!"
175 echo "// To regenerate, edit scrypt.config, then run:"
176 echo "// ./import_scrypt.sh import /path/to/scrypt-$SCRYPT_VERSION.tar.gz"
177 echo "//"
Kenny Root5fd6d312013-06-11 16:36:54 -0700178}
179
180# Return the value of a computed variable name.
181# E.g.:
182# FOO=foo
183# BAR=bar
184# echo $(var_value FOO_$BAR) -> prints the value of ${FOO_bar}
185# $1: Variable name
186# Out: variable value
187var_value() {
188 # Note: don't use 'echo' here, because it's sensitive to values
189 # that begin with an underscore (e.g. "-n")
190 eval printf \"%s\\n\" \$$1
191}
192
193# Same as var_value, but returns sorted output without duplicates.
194# $1: Variable name
195# Out: variable value (if space-separated list, sorted with no duplicates)
196var_sorted_value() {
197 uniq_sort $(var_value $1)
198}
199
Logan Chienee1d0142017-08-31 15:38:01 +0800200# $1: Property name
201# $2: Indent
202# $3: Values
203print_list_in_bp() {
204 declare -r indent="$1"
Kenny Root5fd6d312013-06-11 16:36:54 -0700205 shift
Logan Chienee1d0142017-08-31 15:38:01 +0800206 declare -r name="$1"
207 shift
208
209 if [ -n "$*" ]; then
210 echo "${indent}${name}: ["
211 for value in "$@"; do
212 echo "${indent} \"${value}\","
Kenny Root5fd6d312013-06-11 16:36:54 -0700213 done
Logan Chienee1d0142017-08-31 15:38:01 +0800214 echo "${indent}],"
Kenny Root5fd6d312013-06-11 16:36:54 -0700215 fi
Kenny Root5fd6d312013-06-11 16:36:54 -0700216}
217
Logan Chienee1d0142017-08-31 15:38:01 +0800218# Print an architecture-specific section
219# $1: Arch
220# $2: Arch variant
221print_arch_section_in_bp() {
222 declare -r arch="$1"
223 declare -r variant="$2"
224
225 declare -r srcs="$(var_sorted_value SCRYPT_SOURCES_${arch})"
226 declare -r exclude_srcs="$(var_sorted_value SCRYPT_SOURCES_EXCLUDES_${arch})"
227
228 declare -r srcs_variant="$(var_sorted_value SCRYPT_SOURCES_${arch}_${variant})"
229 declare -r exclude_srcs_variant="$(var_sorted_value SCRYPT_SOURCES_EXCLUDES_${arch}_${variant})"
230
231 if [ -n "${srcs}${exclude_srcs}${srcs_variant}${exclude_srcs_variant}" ]; then
232 echo " ${arch}: {"
233
234 print_list_in_bp " " "srcs" ${srcs}
235 print_list_in_bp " " "exclude_srcs" ${exclude_srcs}
236
237 if [ -n "${src_variant}${exclude_srcs_variant}" ]; then
238 echo " ${variant}: {"
239 print_list_in_bp " " "srcs" ${srcs_variant}
240 print_list_in_bp " " "exclude_srcs" ${exclude_srcs_variant}
241 echo " },"
242 fi
243
244 echo " },"
Kenny Root5fd6d312013-06-11 16:36:54 -0700245 fi
Kenny Root5fd6d312013-06-11 16:36:54 -0700246}
247
Logan Chienee1d0142017-08-31 15:38:01 +0800248# Generate sources.bp from scrypt.config
Kenny Root5fd6d312013-06-11 16:36:54 -0700249#
Logan Chienee1d0142017-08-31 15:38:01 +0800250# $1: Target file name. (e.g. sources.bp)
251function generate_android_bp() {
Kenny Root5fd6d312013-06-11 16:36:54 -0700252 declare -r output="$1"
Kenny Root5fd6d312013-06-11 16:36:54 -0700253
Logan Chienee1d0142017-08-31 15:38:01 +0800254 # Extract cflags from upstream `./configure` script
255 cd $SCRYPT_DIR
256
257 ./configure $CONFIGURE_ARGS
258
259 declare -r tmpfile=$(mktemp)
260 (grep -e -D Makefile | grep -v CONFIGURE_ARGS= | grep -v OPTIONS=) > $tmpfile
261
262 declare -r ac_cflags=$(filter_by_egrep "^-D" $(grep -e "^CFLAG=" $tmpfile))
263 declare -r ac_depflags=$(filter_by_egrep "^-D" $(grep -e "^DEPFLAG=" $tmpfile))
264 rm -f $tmpfile
265
266 cd ..
267
268 # Generate sources.bp
Kenny Root5fd6d312013-06-11 16:36:54 -0700269 echo "Generating $(basename $output)"
270 (
271 print_autogenerated_header
Kenny Root5fd6d312013-06-11 16:36:54 -0700272
Logan Chienee1d0142017-08-31 15:38:01 +0800273 cat <<__EOF__
Kenny Root5fd6d312013-06-11 16:36:54 -0700274
Logan Chienee1d0142017-08-31 15:38:01 +0800275//
276// Copyright (C) 2017 The Android Open Source Project
277//
278// Licensed under the Apache License, Version 2.0 (the "License");
279// you may not use this file except in compliance with the License.
280// You may obtain a copy of the License at
281//
282// http://www.apache.org/licenses/LICENSE-2.0
283//
284// Unless required by applicable law or agreed to in writing, software
285// distributed under the License is distributed on an "AS IS" BASIS,
286// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
287// See the License for the specific language governing permissions and
288// limitations under the License.
289//
Kenny Root5fd6d312013-06-11 16:36:54 -0700290
Logan Chienee1d0142017-08-31 15:38:01 +0800291cc_defaults {
292 name: "libscrypt_sources",
Kenny Root5fd6d312013-06-11 16:36:54 -0700293
Logan Chienee1d0142017-08-31 15:38:01 +0800294__EOF__
Kenny Root5fd6d312013-06-11 16:36:54 -0700295
Logan Chienee1d0142017-08-31 15:38:01 +0800296 print_list_in_bp " " "cflags" \
297 $(var_sorted_value SCRYPT_CFLAGS) ${ac_cflags} ${ac_depflags}
298 echo
Kenny Root5fd6d312013-06-11 16:36:54 -0700299
Logan Chienee1d0142017-08-31 15:38:01 +0800300 print_list_in_bp " " "export_include_dirs" \
301 $(var_sorted_value SCRYPT_EXPORT_C_INCLUDE_DIRS)
302 echo
Kenny Root5fd6d312013-06-11 16:36:54 -0700303
Logan Chienee1d0142017-08-31 15:38:01 +0800304 print_list_in_bp " " "local_include_dirs" \
305 $(var_sorted_value SCRYPT_INCLUDES)
306 echo
Kenny Root5fd6d312013-06-11 16:36:54 -0700307
Logan Chienee1d0142017-08-31 15:38:01 +0800308 print_list_in_bp " " "srcs" $(var_sorted_value SCRYPT_SOURCES)
309 echo
Kenny Root5fd6d312013-06-11 16:36:54 -0700310
Logan Chienee1d0142017-08-31 15:38:01 +0800311 echo " arch: {"
Kenny Root5fd6d312013-06-11 16:36:54 -0700312
Logan Chienee1d0142017-08-31 15:38:01 +0800313 print_arch_section_in_bp "arm" "neon"
314 print_arch_section_in_bp "arm64"
315 print_arch_section_in_bp "x86"
316 print_arch_section_in_bp "x86_64"
317 print_arch_section_in_bp "mips"
318 print_arch_section_in_bp "mips64"
Kenny Root5fd6d312013-06-11 16:36:54 -0700319
Logan Chienee1d0142017-08-31 15:38:01 +0800320 cat <<__EOF__
321 },
322}
323__EOF__
Kenny Root5fd6d312013-06-11 16:36:54 -0700324 ) > "$output"
325}
326
327function import() {
328 declare -r SCRYPT_SOURCE=$1
329
330 untar $SCRYPT_SOURCE readonly
331 applypatches $SCRYPT_DIR
332
Logan Chienee1d0142017-08-31 15:38:01 +0800333 cd $SCRYPT_DIR/..
Kenny Root5fd6d312013-06-11 16:36:54 -0700334
Logan Chienee1d0142017-08-31 15:38:01 +0800335 touch MODULE_LICENSE_BSD_LIKE
Kenny Root5fd6d312013-06-11 16:36:54 -0700336
Logan Chienee1d0142017-08-31 15:38:01 +0800337 generate_android_bp "sources.bp"
Kenny Root5fd6d312013-06-11 16:36:54 -0700338
339 # Prune unnecessary sources
340 prune
341
342 NEEDED_SOURCES="$NEEDED_SOURCES"
343 for i in $NEEDED_SOURCES; do
344 echo "Updating $i"
345 rm -r $i
346 mv $SCRYPT_DIR/$i .
347 done
348
349 cleantar
350}
351
352function regenerate() {
353 declare -r patch=$1
354
355 generatepatch $patch
356}
357
358function generate() {
359 declare -r patch=$1
360 declare -r SCRYPT_SOURCE=$2
361
362 untar $SCRYPT_SOURCE
363 applypatches $SCRYPT_DIR_ORIG $patch
364 prune
365
366 for i in $NEEDED_SOURCES; do
367 echo "Restoring $i"
Logan Chien629ed232017-08-31 19:15:50 +0800368 rm -rf $SCRYPT_DIR/$i
Kenny Root5fd6d312013-06-11 16:36:54 -0700369 cp -rf $i $SCRYPT_DIR/$i
370 done
371
372 generatepatch $patch
373 cleantar
374}
375
376# Find all files in a sub-directory that are encoded in ISO-8859
377# $1: Directory.
378# Out: list of files in $1 that are encoded as ISO-8859.
379function find_iso8859_files() {
380 find $1 -type f -print0 | xargs -0 file | fgrep "ISO-8859" | cut -d: -f1
381}
382
383# Convert all ISO-8859 files in a given subdirectory to UTF-8
384# $1: Directory name
385function convert_iso8859_to_utf8() {
386 declare -r iso_files=$(find_iso8859_files "$1")
387 for iso_file in $iso_files; do
388 iconv --from-code iso-8859-1 --to-code utf-8 $iso_file > $iso_file.tmp
389 rm -f $iso_file
390 mv $iso_file.tmp $iso_file
391 done
392}
393
394function untar() {
395 declare -r SCRYPT_SOURCE=$1
396 declare -r readonly=$2
397
398 # Remove old source
399 cleantar
400
401 # Process new source
402 tar -zxf $SCRYPT_SOURCE
403 convert_iso8859_to_utf8 $SCRYPT_DIR
404 cp -rfP $SCRYPT_DIR $SCRYPT_DIR_ORIG
405 if [ ! -z $readonly ]; then
406 find $SCRYPT_DIR_ORIG -type f -print0 | xargs -0 chmod a-w
407 fi
408}
409
410function prune() {
411 echo "Removing $UNNEEDED_SOURCES"
412 (cd $SCRYPT_DIR_ORIG && rm -rf $UNNEEDED_SOURCES)
413 (cd $SCRYPT_DIR && rm -r $UNNEEDED_SOURCES)
414}
415
416function cleantar() {
417 rm -rf $SCRYPT_DIR_ORIG
418 rm -rf $SCRYPT_DIR
419}
420
421function applypatches () {
422 declare -r dir=$1
423 declare -r skip_patch=$2
424
425 cd $dir
426
427 # Apply appropriate patches
428 for i in $SCRYPT_PATCHES; do
429 if [ ! "$skip_patch" = "patches/$i" ]; then
430 echo "Applying patch $i"
431 patch -p1 --merge < ../patches/$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate patches/$i"
432 else
433 echo "Skiping patch $i"
434 fi
435
436 done
437
438 # Cleanup patch output
439 find . \( -type f -o -type l \) -name "*.orig" -print0 | xargs -0 rm -f
440
441 cd ..
442}
443
444function generatepatch() {
445 declare -r patch=$1
446
447 # Cleanup stray files before generating patch
448 find $SCRYPT_DIR -type f -name "*.orig" -print0 | xargs -0 rm -f
449 find $SCRYPT_DIR -type f -name "*~" -print0 | xargs -0 rm -f
450
451 declare -r variable_name=SCRYPT_PATCHES_`basename $patch .patch | sed s/-/_/`_SOURCES
452 # http://tldp.org/LDP/abs/html/ivr.html
453 eval declare -r sources=\$$variable_name
454 rm -f $patch
455 touch $patch
456 for i in $sources; do
Logan Chien629ed232017-08-31 19:15:50 +0800457 LC_ALL=C TZ=UTC0 diff -aupN $SCRYPT_DIR_ORIG/$i $SCRYPT_DIR/$i >> $patch && die "ERROR: No diff for patch $path in file $i"
Kenny Root5fd6d312013-06-11 16:36:54 -0700458 done
459 echo "Generated patch $patch"
460 echo "NOTE To make sure there are not unwanted changes from conflicting patches, be sure to review the generated patch."
461}
462
463main $@