1#!/bin/bash 2 3# Copyright (C) 2020 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 17set -e 18shopt -s extglob 19shopt -s globstar 20 21# to use relative paths 22cd $(dirname $0) 23 24RUN_FROM_SERVER=0 25 26# when executed directly from commandline, build dependencies 27if [[ $(basename $0) == "rundiff.sh" ]]; then 28 if [ -z $ANDROID_BUILD_TOP ]; then 29 echo "You need to source and lunch before you can use this script" 30 exit 1 31 fi 32 $ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode linkerconfig conv_apex_manifest conv_linker_config 33else 34 # workaround to use host tools on build server 35 export PATH=$(dirname $0):$PATH 36 RUN_FROM_SERVER=1 37fi 38 39# $1: target libraries.txt file 40# $2: list of libs. ex) a.so:b.so:c.so 41function write_libraries_txt { 42 rm -rf $1 43 IFS=':' 44 for lib in $2; do 45 echo $lib >> $1 46 done 47 unset IFS 48} 49 50# Simulate build process 51# $1: input tree (with *.json) 52# $2: output tree (*.json files are converted into *.pb) 53function build_root { 54 cp -R $1/* $2 55 56 for json in $2/**/linker.config.json; do 57 conv_linker_config proto -s $json -o ${json%.json}.pb 58 rm $json 59 done 60 for json in $2/**/apex_manifest.json; do 61 conv_apex_manifest proto $json -o ${json%.json}.pb 62 rm $json 63 done 64} 65 66function run_linkerconfig_stage0 { 67 # prepare root 68 69 echo "Prepare root for stage 0" 70 TMP_PATH=$2/stage0 71 mkdir $TMP_PATH 72 build_root testdata/root $TMP_PATH 73 ./testdata/prepare_root.sh --root $TMP_PATH 74 75 mkdir -p $1/stage0 76 echo "Running linkerconfig for stage 0" 77 linkerconfig -v R -r $TMP_PATH -t $1/stage0 78 79 echo "Stage 0 completed" 80} 81 82function run_linkerconfig_stage1 { 83 # prepare root 84 echo "Prepare root for stage 1" 85 TMP_PATH=$2/stage1 86 mkdir $TMP_PATH 87 build_root testdata/root $TMP_PATH 88 ./testdata/prepare_root.sh --bootstrap --root $TMP_PATH 89 90 mkdir -p $1/stage1 91 echo "Running linkerconfig for stage 1" 92 linkerconfig -v R -r $TMP_PATH -t $1/stage1 93 94 echo "Stage 1 completed" 95} 96 97function run_linkerconfig_stage2 { 98 # prepare root 99 echo "Prepare root for stage 2" 100 TMP_PATH=$2/stage2 101 mkdir $TMP_PATH 102 build_root testdata/root $TMP_PATH 103 ./testdata/prepare_root.sh --all --root $TMP_PATH 104 105 mkdir -p $1/stage2 106 echo "Running linkerconfig for stage 2" 107 linkerconfig -v R -r $TMP_PATH -t $1/stage2 108 109 # skip prepare_root in order to use the same apexs 110 mkdir -p $1/product-enabled 111 echo "Running linkerconfig for product-enabled" 112 linkerconfig -v R -p R -r $TMP_PATH -t $1/product-enabled 113 114 # skip prepare_root (reuse the previous setup) 115 mkdir -p $1/gen-only-a-single-apex 116 echo "Running linkerconfig for gen-only-a-single-apex" 117 linkerconfig -v R -r $TMP_PATH --apex com.vendor.service2 -t $1/gen-only-a-single-apex 118 119 # skip prepare_root in order to use the same apexs 120 # but with system/etc/vndkcorevariant.libraries.txt 121 vndk_core_variant_libs_file=$TMP_PATH/system/etc/vndkcorevariant.libraries.txt 122 write_libraries_txt $vndk_core_variant_libs_file libevent.so:libexif.so:libfmq.so 123 mkdir -p $1/vndk-in-system 124 echo "Running linkerconfig for vndk-in-system" 125 linkerconfig -v R -p R -r $TMP_PATH -t $1/vndk-in-system 126 # clean up 127 rm -if $vndk_core_variant_libs_file 128 vndk_core_variant_libs_file= 129 130 echo "Stage 2 completed" 131} 132 133function run_linkerconfig_others { 134 # prepare root 135 echo "Prepare root for stage others" 136 TMP_PATH=$2/others 137 mkdir $TMP_PATH 138 build_root testdata/root $TMP_PATH 139 ./testdata/prepare_root.sh --all --block com.android.art:com.android.vndk.vR --root $TMP_PATH 140 141 mkdir -p $1/guest 142 echo "Running linkerconfig for guest" 143 linkerconfig -v R -p R -r $TMP_PATH -t $1/guest 144 145 # skip prepare_root in order to use the same apexes except VNDK 146 rm -iRf $TMP_PATH/apex/com.android.vndk.vR 147 mkdir -p $1/legacy 148 echo "Running linkerconfig for legacy" 149 linkerconfig -r $TMP_PATH -t $1/legacy 150 151 echo "Stage others completed" 152} 153 154# $1: target output directory 155function run_linkerconfig_to { 156 # delete old output 157 rm -rf $1 158 159 TMP_ROOT=$(mktemp -d -t linkerconfig-root-XXXXXXXX) 160 161 run_linkerconfig_stage0 $1 $TMP_ROOT & 162 163 run_linkerconfig_stage1 $1 $TMP_ROOT & 164 165 run_linkerconfig_stage2 $1 $TMP_ROOT & 166 167 run_linkerconfig_others $1 $TMP_ROOT & 168 169 for job in `jobs -p` 170 do 171 wait $job 172 done 173 174 # Remove temp root if required 175 if [[ $RUN_FROM_SERVER -ne 1 ]]; then 176 rm -rf $TMP_ROOT 177 fi 178} 179 180# update golden_output 181if [[ $1 == "--update" ]]; then 182 run_linkerconfig_to ./testdata/golden_output 183 echo "Updated" 184 exit 0 185fi 186 187echo "Running linkerconfig diff test..." 188 189run_linkerconfig_to ./testdata/output 190 191echo "Running diff from test output" 192if diff -ruN ./testdata/golden_output ./testdata/output ; then 193 echo "No changes." 194else 195 echo 196 echo "------------------------------------------------------------------------------------------" 197 echo "if change looks fine, run following:" 198 echo " \$ANDROID_BUILD_TOP/system/linkerconfig/rundiff.sh --update" 199 echo "------------------------------------------------------------------------------------------" 200 # fail 201 exit 1 202fi