blob: 324eae64b9364cc247d4bbc021043aa4ee9598c3 [file] [log] [blame]
Dees Troy4dff2e62013-11-10 04:11:43 +00001#!/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?"
93 [ -d $SCRYPT_DIR_ORIG_ORIG ] || usage "$SCRYPT_DIR_ORIG not found, did you mean to use generate?"
94 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 () {
169 echo "$@" | tr ' ' '\n' | sort -u | tr '\n' ' '
170}
171
172function print_autogenerated_header() {
173 echo "# Auto-generated - DO NOT EDIT!"
174 echo "# To regenerate, edit scrypt.config, then run:"
175 echo "# ./import_scrypt.sh import /path/to/scrypt-$SCRYPT_VERSION.tar.gz"
176 echo "#"
177}
178
179function generate_build_config_mk() {
180 ./configure $CONFIGURE_ARGS
181 #rm -f apps/CA.pl.bak crypto/scryptconf.h.bak
182
183 declare -r tmpfile=$(mktemp)
184 (grep -e -D Makefile | grep -v CONFIGURE_ARGS= | grep -v OPTIONS=) > $tmpfile
185
186 declare -r cflags=$(filter_by_egrep "^-D" $(grep -e "^CFLAG=" $tmpfile))
187 declare -r depflags=$(filter_by_egrep "^-D" $(grep -e "^DEPFLAG=" $tmpfile))
188 rm -f $tmpfile
189
190 echo "Generating $(basename $1)"
191 (
192 print_autogenerated_header
193
194 echo "scrypt_cflags := \\"
195 for cflag in $cflags $depflags; do
196 echo " $cflag \\"
197 done
198 echo ""
199 ) > $1
200}
201
202# Return the value of a computed variable name.
203# E.g.:
204# FOO=foo
205# BAR=bar
206# echo $(var_value FOO_$BAR) -> prints the value of ${FOO_bar}
207# $1: Variable name
208# Out: variable value
209var_value() {
210 # Note: don't use 'echo' here, because it's sensitive to values
211 # that begin with an underscore (e.g. "-n")
212 eval printf \"%s\\n\" \$$1
213}
214
215# Same as var_value, but returns sorted output without duplicates.
216# $1: Variable name
217# Out: variable value (if space-separated list, sorted with no duplicates)
218var_sorted_value() {
219 uniq_sort $(var_value $1)
220}
221
222# Print the definition of a given variable in a GNU Make build file.
223# $1: Variable name (e.g. common_src_files)
224# $2+: Variable value (e.g. list of sources)
225print_vardef_in_mk() {
226 declare -r varname=$1
227 shift
228 if [ -z "$1" ]; then
229 echo "$varname :="
230 else
231 echo "$varname := \\"
232 for src; do
233 echo " $src \\"
234 done
235 fi
236 echo ""
237}
238
239# Same as print_vardef_in_mk, but print a CFLAGS definition from
240# a list of compiler defines.
241# $1: Variable name (e.g. common_c_flags)
242# $2: List of defines (e.g. SCRYPT_NO_DONKEYS ...)
243print_defines_in_mk() {
244 declare -r varname=$1
245 shift
246 if [ -z "$1" ]; then
247 echo "$varname :="
248 else
249 echo "$varname := \\"
250 for def; do
251 echo " -D$def \\"
252 done
253 fi
254 echo ""
255}
256
257# Generate a configuration file like Scrypt-config.mk
258# This uses variable definitions from scrypt.config to build a config
259# file that can compute the list of target- and host-specific sources /
260# compiler flags for a given component.
261#
262# $1: Target file name. (e.g. Scrypt-config.mk)
263function generate_config_mk() {
264 declare -r output="$1"
265 declare -r all_archs="arm arm_neon x86 x86_64 mips"
266
267 echo "Generating $(basename $output)"
268 (
269 print_autogenerated_header
270 echo \
271"# Before including this file, the local Android.mk must define the following
272# variables:
273#
274# local_c_flags
275# local_c_includes
276# local_additional_dependencies
277#
278# This script will define the following variables:
279#
280# target_c_flags
281# target_c_includes
282# target_src_files
283#
284# host_c_flags
285# host_c_includes
286# host_src_files
287#
288
289# Ensure these are empty.
290unknown_arch_c_flags :=
291unknown_arch_src_files :=
292unknown_arch_exclude_files :=
293
294"
295 common_defines=$(var_sorted_value SCRYPT_DEFINES)
296 print_defines_in_mk common_c_flags $common_defines
297
298 common_sources=$(var_sorted_value SCRYPT_SOURCES)
299 print_vardef_in_mk common_src_files $common_sources
300
301 common_includes=$(var_sorted_value SCRYPT_INCLUDES)
302 print_vardef_in_mk common_c_includes $common_includes
303
304 for arch in $all_archs; do
305 arch_defines=$(var_sorted_value SCRYPT_DEFINES_${arch})
306 print_defines_in_mk ${arch}_c_flags $arch_defines
307
308 arch_sources=$(var_sorted_value SCRYPT_SOURCES_${arch})
309 print_vardef_in_mk ${arch}_src_files $arch_sources
310
311 arch_exclude_sources=$(var_sorted_value SCRYPT_SOURCES_EXCLUDES_${arch})
312 print_vardef_in_mk ${arch}_exclude_files $arch_exclude_sources
313
314 done
315
316 echo "\
317target_arch := \$(TARGET_ARCH)
318ifeq (\$(target_arch)-\$(TARGET_HAS_BIGENDIAN),mips-true)
319target_arch := unknown_arch
320endif
321
322target_c_flags := \$(common_c_flags) \$(\$(target_arch)_c_flags) \$(local_c_flags)
323target_c_includes := \$(addprefix external/scrypt/,\$(common_c_includes)) \$(local_c_includes)
324target_src_files := \$(common_src_files) \$(\$(target_arch)_src_files)
325target_src_files := \$(filter-out \$(\$(target_arch)_exclude_files), \$(target_src_files))
326
327# Hacks for ARM NEON support
328ifeq (\$(target_arch),arm)
329ifeq (\$(ARCH_ARM_HAVE_NEON),true)
330target_c_flags += \$(arm_neon_c_flags)
331target_src_files += \$(arm_neon_src_files)
332target_src_files := \$(filter-out \$(arm_neon_exclude_files), \$(target_src_files))
333endif
334endif
335
336ifeq (\$(HOST_OS)-\$(HOST_ARCH),linux-x86)
337host_arch := x86
338else
339host_arch := unknown_arch
340endif
341
342host_c_flags := \$(common_c_flags) \$(\$(host_arch)_c_flags) \$(local_c_flags)
343host_c_includes := \$(addprefix external/scrypt/,\$(common_c_includes)) \$(local_c_includes)
344host_src_files := \$(common_src_files) \$(\$(host_arch)_src_files)
345host_src_files := \$(filter-out \$(\$(host_arch)_exclude_files), \$(host_src_files))
346
347local_additional_dependencies += \$(LOCAL_PATH)/$(basename $output)
348"
349
350 ) > "$output"
351}
352
353function import() {
354 declare -r SCRYPT_SOURCE=$1
355
356 untar $SCRYPT_SOURCE readonly
357 applypatches $SCRYPT_DIR
358
359 cd $SCRYPT_DIR
360
361 generate_build_config_mk ../build-config.mk
362
363 touch ../MODULE_LICENSE_BSD_LIKE
364
365 cd ..
366
367 generate_config_mk Scrypt-config.mk
368
369 # Prune unnecessary sources
370 prune
371
372 NEEDED_SOURCES="$NEEDED_SOURCES"
373 for i in $NEEDED_SOURCES; do
374 echo "Updating $i"
375 rm -r $i
376 mv $SCRYPT_DIR/$i .
377 done
378
379 cleantar
380}
381
382function regenerate() {
383 declare -r patch=$1
384
385 generatepatch $patch
386}
387
388function generate() {
389 declare -r patch=$1
390 declare -r SCRYPT_SOURCE=$2
391
392 untar $SCRYPT_SOURCE
393 applypatches $SCRYPT_DIR_ORIG $patch
394 prune
395
396 for i in $NEEDED_SOURCES; do
397 echo "Restoring $i"
398 rm -r $SCRYPT_DIR/$i
399 cp -rf $i $SCRYPT_DIR/$i
400 done
401
402 generatepatch $patch
403 cleantar
404}
405
406# Find all files in a sub-directory that are encoded in ISO-8859
407# $1: Directory.
408# Out: list of files in $1 that are encoded as ISO-8859.
409function find_iso8859_files() {
410 find $1 -type f -print0 | xargs -0 file | fgrep "ISO-8859" | cut -d: -f1
411}
412
413# Convert all ISO-8859 files in a given subdirectory to UTF-8
414# $1: Directory name
415function convert_iso8859_to_utf8() {
416 declare -r iso_files=$(find_iso8859_files "$1")
417 for iso_file in $iso_files; do
418 iconv --from-code iso-8859-1 --to-code utf-8 $iso_file > $iso_file.tmp
419 rm -f $iso_file
420 mv $iso_file.tmp $iso_file
421 done
422}
423
424function untar() {
425 declare -r SCRYPT_SOURCE=$1
426 declare -r readonly=$2
427
428 # Remove old source
429 cleantar
430
431 # Process new source
432 tar -zxf $SCRYPT_SOURCE
433 convert_iso8859_to_utf8 $SCRYPT_DIR
434 cp -rfP $SCRYPT_DIR $SCRYPT_DIR_ORIG
435 if [ ! -z $readonly ]; then
436 find $SCRYPT_DIR_ORIG -type f -print0 | xargs -0 chmod a-w
437 fi
438}
439
440function prune() {
441 echo "Removing $UNNEEDED_SOURCES"
442 (cd $SCRYPT_DIR_ORIG && rm -rf $UNNEEDED_SOURCES)
443 (cd $SCRYPT_DIR && rm -r $UNNEEDED_SOURCES)
444}
445
446function cleantar() {
447 rm -rf $SCRYPT_DIR_ORIG
448 rm -rf $SCRYPT_DIR
449}
450
451function applypatches () {
452 declare -r dir=$1
453 declare -r skip_patch=$2
454
455 cd $dir
456
457 # Apply appropriate patches
458 for i in $SCRYPT_PATCHES; do
459 if [ ! "$skip_patch" = "patches/$i" ]; then
460 echo "Applying patch $i"
461 patch -p1 --merge < ../patches/$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate patches/$i"
462 else
463 echo "Skiping patch $i"
464 fi
465
466 done
467
468 # Cleanup patch output
469 find . \( -type f -o -type l \) -name "*.orig" -print0 | xargs -0 rm -f
470
471 cd ..
472}
473
474function generatepatch() {
475 declare -r patch=$1
476
477 # Cleanup stray files before generating patch
478 find $SCRYPT_DIR -type f -name "*.orig" -print0 | xargs -0 rm -f
479 find $SCRYPT_DIR -type f -name "*~" -print0 | xargs -0 rm -f
480
481 declare -r variable_name=SCRYPT_PATCHES_`basename $patch .patch | sed s/-/_/`_SOURCES
482 # http://tldp.org/LDP/abs/html/ivr.html
483 eval declare -r sources=\$$variable_name
484 rm -f $patch
485 touch $patch
486 for i in $sources; do
487 LC_ALL=C TZ=UTC0 diff -aup $SCRYPT_DIR_ORIG/$i $SCRYPT_DIR/$i >> $patch && die "ERROR: No diff for patch $path in file $i"
488 done
489 echo "Generated patch $patch"
490 echo "NOTE To make sure there are not unwanted changes from conflicting patches, be sure to review the generated patch."
491}
492
493main $@