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# Simulate build process
40# $1: input tree (with *.json)
41# $2: output tree (*.json files are converted into *.pb)
42function build_root {
43  cp -R $1/* $2
44
45  for json in $2/**/linker.config.json; do
46    conv_linker_config proto -s $json -o ${json%.json}.pb
47    rm $json
48  done
49  for json in $2/**/apex_manifest.json; do
50    conv_apex_manifest proto $json -o ${json%.json}.pb
51    rm $json
52  done
53}
54
55function run_linkerconfig_stage1 {
56  # prepare root
57  echo "Prepare root for stage 1"
58  TMP_PATH=$2/stage1
59  mkdir $TMP_PATH
60  build_root testdata/root $TMP_PATH
61  ./testdata/prepare_root.sh --bootstrap --root $TMP_PATH
62
63  mkdir -p $1/stage1
64  echo "Running linkerconfig for stage 1"
65  linkerconfig -z -r $TMP_PATH -t $1/stage1
66
67  echo "Stage 1 completed"
68}
69
70function run_linkerconfig_stage2 {
71  # prepare root
72  echo "Prepare root for stage 2"
73  TMP_PATH=$2/stage2
74  mkdir $TMP_PATH
75  build_root testdata/root $TMP_PATH
76  ./testdata/prepare_root.sh --all --root $TMP_PATH
77
78  mkdir -p $1/stage2
79  echo "Running linkerconfig for stage 2"
80  linkerconfig -z -r $TMP_PATH -t $1/stage2
81
82  # skip prepare_root (reuse the previous setup)
83  mkdir -p $1/vendor_with_vndk
84  echo "Running linkerconfig with VNDK available on the vendor partition"
85  linkerconfig -v R -z -r $TMP_PATH -t $1/vendor_with_vndk
86
87  # skip prepare_root (reuse the previous setup)
88  mkdir -p $1/gen-only-a-single-apex
89  echo "Running linkerconfig for gen-only-a-single-apex"
90  linkerconfig -v R -z -r $TMP_PATH --apex com.vendor.service2 -t $1/gen-only-a-single-apex
91
92  echo "Stage 2 completed"
93}
94
95function run_linkerconfig_others {
96  # prepare root
97  echo "Prepare root for stage others"
98  TMP_PATH=$2/others
99  mkdir $TMP_PATH
100  build_root testdata/root $TMP_PATH
101  ./testdata/prepare_root.sh --all --block com.android.art:com.android.vndk.vR --root $TMP_PATH
102
103  mkdir -p $1/guest
104  echo "Running linkerconfig for guest"
105  linkerconfig -v R -p R -z -r $TMP_PATH -t $1/guest
106
107  echo "Stage others completed"
108}
109
110# $1: target output directory
111function run_linkerconfig_to {
112  # delete old output
113  rm -rf $1
114
115  TMP_ROOT=$(mktemp -d -t linkerconfig-root-XXXXXXXX)
116
117  # stage 0 is no longer tested because linkerconfig do not generate ld.config.txt for stage 0
118
119  run_linkerconfig_stage1 $1 $TMP_ROOT &
120
121  run_linkerconfig_stage2 $1 $TMP_ROOT &
122
123  run_linkerconfig_others $1 $TMP_ROOT &
124
125  for job in `jobs -p`
126  do
127    wait $job
128  done
129
130  # Remove temp root if required
131  if [[ $RUN_FROM_SERVER -ne 1 ]]; then
132    rm -rf $TMP_ROOT
133  fi
134}
135
136# update golden_output
137if [[ $1 == "--update" ]]; then
138  run_linkerconfig_to ./testdata/golden_output
139  echo "Updated"
140  exit 0
141fi
142
143echo "Running linkerconfig diff test..."
144
145run_linkerconfig_to ./testdata/output
146
147echo "Running diff from test output"
148if diff -ruN ./testdata/golden_output ./testdata/output ; then
149  echo "No changes."
150else
151  echo
152  echo "------------------------------------------------------------------------------------------"
153  echo "if change looks fine, run following:"
154  echo "  \$ANDROID_BUILD_TOP/system/linkerconfig/rundiff.sh --update"
155  echo "------------------------------------------------------------------------------------------"
156  # fail
157  exit 1
158fi