| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 1 | #!/bin/bash -eu | 
 | 2 |  | 
| Rupert Shuttleworth | 2a4fc3e | 2021-04-21 07:10:09 -0400 | [diff] [blame] | 3 | set -o pipefail | 
 | 4 |  | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 5 | # This test exercises the bootstrapping process of the build system | 
 | 6 | # in a source tree that only contains enough files for Bazel and Soong to work. | 
 | 7 |  | 
| Lukacs T. Berki | 3b730c4 | 2021-04-08 13:21:13 +0200 | [diff] [blame] | 8 | source "$(dirname "$0")/lib.sh" | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 9 |  | 
| Rupert Shuttleworth | 413a7a9 | 2021-05-18 07:47:15 -0400 | [diff] [blame] | 10 | readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel" | 
 | 11 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 12 | readonly target_product="${TARGET_PRODUCT:-aosp_arm}" | 
 | 13 |  | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 14 | function test_smoke { | 
 | 15 |   setup | 
 | 16 |   run_soong | 
 | 17 | } | 
 | 18 |  | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 19 | function test_null_build() { | 
 | 20 |   setup | 
 | 21 |   run_soong | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 22 |   local -r bootstrap_mtime1=$(stat -c "%y" out/soong/bootstrap.ninja) | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 23 |   local -r output_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 24 |   run_soong | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 25 |   local -r bootstrap_mtime2=$(stat -c "%y" out/soong/bootstrap.ninja) | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 26 |   local -r output_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 27 |  | 
 | 28 |   if [[ "$bootstrap_mtime1" == "$bootstrap_mtime2" ]]; then | 
 | 29 |     # Bootstrapping is always done. It doesn't take a measurable amount of time. | 
 | 30 |     fail "Bootstrap Ninja file did not change on null build" | 
 | 31 |   fi | 
 | 32 |  | 
 | 33 |   if [[ "$output_mtime1" != "$output_mtime2" ]]; then | 
 | 34 |     fail "Output Ninja file changed on null build" | 
 | 35 |   fi | 
 | 36 | } | 
 | 37 |  | 
 | 38 | function test_soong_build_rebuilt_if_blueprint_changes() { | 
 | 39 |   setup | 
 | 40 |   run_soong | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 41 |   local -r mtime1=$(stat -c "%y" out/soong/bootstrap.ninja) | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 42 |  | 
 | 43 |   sed -i 's/pluginGenSrcCmd/pluginGenSrcCmd2/g' build/blueprint/bootstrap/bootstrap.go | 
 | 44 |  | 
 | 45 |   run_soong | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 46 |   local -r mtime2=$(stat -c "%y" out/soong/bootstrap.ninja) | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 47 |  | 
 | 48 |   if [[ "$mtime1" == "$mtime2" ]]; then | 
 | 49 |     fail "Bootstrap Ninja file did not change" | 
 | 50 |   fi | 
 | 51 | } | 
 | 52 |  | 
 | 53 | function test_change_android_bp() { | 
 | 54 |   setup | 
 | 55 |   mkdir -p a | 
 | 56 |   cat > a/Android.bp <<'EOF' | 
 | 57 | python_binary_host { | 
 | 58 |   name: "my_little_binary_host", | 
 | 59 |   srcs: ["my_little_binary_host.py"] | 
 | 60 | } | 
 | 61 | EOF | 
 | 62 |   touch a/my_little_binary_host.py | 
 | 63 |   run_soong | 
 | 64 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 65 |   grep -q "^# Module:.*my_little_binary_host" out/soong/build."${target_product}".ninja || fail "module not found" | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 66 |  | 
 | 67 |   cat > a/Android.bp <<'EOF' | 
 | 68 | python_binary_host { | 
 | 69 |   name: "my_great_binary_host", | 
 | 70 |   srcs: ["my_great_binary_host.py"] | 
 | 71 | } | 
 | 72 | EOF | 
 | 73 |   touch a/my_great_binary_host.py | 
 | 74 |   run_soong | 
 | 75 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 76 |   grep -q "^# Module:.*my_little_binary_host" out/soong/build."${target_product}".ninja && fail "old module found" | 
 | 77 |   grep -q "^# Module:.*my_great_binary_host" out/soong/build."${target_product}".ninja || fail "new module not found" | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 78 | } | 
 | 79 |  | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 80 | function test_add_android_bp() { | 
 | 81 |   setup | 
 | 82 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 83 |   local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 84 |  | 
 | 85 |   mkdir -p a | 
 | 86 |   cat > a/Android.bp <<'EOF' | 
 | 87 | python_binary_host { | 
 | 88 |   name: "my_little_binary_host", | 
 | 89 |   srcs: ["my_little_binary_host.py"] | 
 | 90 | } | 
 | 91 | EOF | 
 | 92 |   touch a/my_little_binary_host.py | 
 | 93 |   run_soong | 
 | 94 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 95 |   local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 96 |   if [[ "$mtime1" == "$mtime2" ]]; then | 
 | 97 |     fail "Output Ninja file did not change" | 
 | 98 |   fi | 
 | 99 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 100 |   grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".ninja || fail "New module not in output" | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 101 |  | 
 | 102 |   run_soong | 
 | 103 | } | 
 | 104 |  | 
 | 105 | function test_delete_android_bp() { | 
 | 106 |   setup | 
 | 107 |   mkdir -p a | 
 | 108 |   cat > a/Android.bp <<'EOF' | 
 | 109 | python_binary_host { | 
 | 110 |   name: "my_little_binary_host", | 
 | 111 |   srcs: ["my_little_binary_host.py"] | 
 | 112 | } | 
 | 113 | EOF | 
 | 114 |   touch a/my_little_binary_host.py | 
 | 115 |   run_soong | 
 | 116 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 117 |   grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".ninja || fail "Module not in output" | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 118 |  | 
 | 119 |   rm a/Android.bp | 
 | 120 |   run_soong | 
 | 121 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 122 |   if grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".ninja; then | 
| Lukacs T. Berki | f8e2428 | 2021-04-14 10:31:00 +0200 | [diff] [blame] | 123 |     fail "Old module in output" | 
 | 124 |   fi | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 125 | } | 
 | 126 |  | 
| Colin Cross | 1042595 | 2021-04-12 18:59:18 -0700 | [diff] [blame] | 127 | # Test that an incremental build with a glob doesn't rerun soong_build, and | 
 | 128 | # only regenerates the globs on the first but not the second incremental build. | 
 | 129 | function test_glob_noop_incremental() { | 
 | 130 |   setup | 
 | 131 |  | 
| Colin Cross | b72877f | 2021-04-16 10:09:54 -0700 | [diff] [blame] | 132 |   # This test needs to start from a clean build, but setup creates an | 
 | 133 |   # initialized tree that has already been built once.  Clear the out | 
| Lukacs T. Berki | 731bb91 | 2021-04-16 09:16:19 +0200 | [diff] [blame] | 134 |   # directory to start from scratch (see b/185591972) | 
| Colin Cross | b72877f | 2021-04-16 10:09:54 -0700 | [diff] [blame] | 135 |   rm -rf out | 
 | 136 |  | 
| Colin Cross | 1042595 | 2021-04-12 18:59:18 -0700 | [diff] [blame] | 137 |   mkdir -p a | 
 | 138 |   cat > a/Android.bp <<'EOF' | 
 | 139 | python_binary_host { | 
 | 140 |   name: "my_little_binary_host", | 
 | 141 |   srcs: ["*.py"], | 
 | 142 | } | 
 | 143 | EOF | 
 | 144 |   touch a/my_little_binary_host.py | 
 | 145 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 146 |   local -r ninja_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Colin Cross | 1042595 | 2021-04-12 18:59:18 -0700 | [diff] [blame] | 147 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 148 |   local glob_deps_file=out/soong/globs/"${target_product}"/0.d | 
| Colin Cross | 1042595 | 2021-04-12 18:59:18 -0700 | [diff] [blame] | 149 |  | 
 | 150 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 151 |   local -r ninja_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Colin Cross | 1042595 | 2021-04-12 18:59:18 -0700 | [diff] [blame] | 152 |  | 
 | 153 |   # There is an ineffiencency in glob that requires bpglob to rerun once for each glob to update | 
 | 154 |   # the entry in the .ninja_log.  It doesn't update the output file, but we can detect the rerun | 
 | 155 |   # by checking if the deps file was created. | 
 | 156 |   if [ ! -e "$glob_deps_file" ]; then | 
 | 157 |     fail "Glob deps file missing after second build" | 
 | 158 |   fi | 
 | 159 |  | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 160 |   local -r glob_deps_mtime2=$(stat -c "%y" "$glob_deps_file") | 
| Colin Cross | 1042595 | 2021-04-12 18:59:18 -0700 | [diff] [blame] | 161 |  | 
 | 162 |   if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then | 
 | 163 |     fail "Ninja file rewritten on null incremental build" | 
 | 164 |   fi | 
 | 165 |  | 
 | 166 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 167 |   local -r ninja_mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 168 |   local -r glob_deps_mtime3=$(stat -c "%y" "$glob_deps_file") | 
| Colin Cross | 1042595 | 2021-04-12 18:59:18 -0700 | [diff] [blame] | 169 |  | 
 | 170 |   if [[ "$ninja_mtime2" != "$ninja_mtime3" ]]; then | 
 | 171 |     fail "Ninja file rewritten on null incremental build" | 
 | 172 |   fi | 
 | 173 |  | 
 | 174 |   # The bpglob commands should not rerun after the first incremental build. | 
 | 175 |   if [[ "$glob_deps_mtime2" != "$glob_deps_mtime3" ]]; then | 
 | 176 |     fail "Glob deps file rewritten on second null incremental build" | 
 | 177 |   fi | 
 | 178 | } | 
 | 179 |  | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 180 | function test_add_file_to_glob() { | 
 | 181 |   setup | 
 | 182 |  | 
 | 183 |   mkdir -p a | 
 | 184 |   cat > a/Android.bp <<'EOF' | 
 | 185 | python_binary_host { | 
 | 186 |   name: "my_little_binary_host", | 
 | 187 |   srcs: ["*.py"], | 
 | 188 | } | 
 | 189 | EOF | 
 | 190 |   touch a/my_little_binary_host.py | 
 | 191 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 192 |   local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 193 |  | 
 | 194 |   touch a/my_little_library.py | 
 | 195 |   run_soong | 
 | 196 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 197 |   local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 198 |   if [[ "$mtime1" == "$mtime2" ]]; then | 
 | 199 |     fail "Output Ninja file did not change" | 
 | 200 |   fi | 
 | 201 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 202 |   grep -q my_little_library.py out/soong/build."${target_product}".ninja || fail "new file is not in output" | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 203 | } | 
 | 204 |  | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 205 | function test_soong_build_rerun_iff_environment_changes() { | 
 | 206 |   setup | 
 | 207 |  | 
| Liz Kammer | 33cc80e | 2023-05-18 18:20:28 +0000 | [diff] [blame] | 208 |   mkdir -p build/soong/cherry | 
 | 209 |   cat > build/soong/cherry/Android.bp <<'EOF' | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 210 | bootstrap_go_package { | 
 | 211 |   name: "cherry", | 
 | 212 |   pkgPath: "android/soong/cherry", | 
 | 213 |   deps: [ | 
 | 214 |     "blueprint", | 
 | 215 |     "soong", | 
 | 216 |     "soong-android", | 
 | 217 |   ], | 
 | 218 |   srcs: [ | 
 | 219 |     "cherry.go", | 
 | 220 |   ], | 
 | 221 |   pluginFor: ["soong_build"], | 
 | 222 | } | 
 | 223 | EOF | 
 | 224 |  | 
| Liz Kammer | 33cc80e | 2023-05-18 18:20:28 +0000 | [diff] [blame] | 225 |   cat > build/soong/cherry/cherry.go <<'EOF' | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 226 | package cherry | 
 | 227 |  | 
 | 228 | import ( | 
 | 229 |   "android/soong/android" | 
 | 230 |   "github.com/google/blueprint" | 
 | 231 | ) | 
 | 232 |  | 
 | 233 | var ( | 
 | 234 |   pctx = android.NewPackageContext("cherry") | 
 | 235 | ) | 
 | 236 |  | 
 | 237 | func init() { | 
 | 238 |   android.RegisterSingletonType("cherry", CherrySingleton) | 
 | 239 | } | 
 | 240 |  | 
 | 241 | func CherrySingleton() android.Singleton { | 
 | 242 |   return &cherrySingleton{} | 
 | 243 | } | 
 | 244 |  | 
 | 245 | type cherrySingleton struct{} | 
 | 246 |  | 
 | 247 | func (p *cherrySingleton) GenerateBuildActions(ctx android.SingletonContext) { | 
 | 248 |   cherryRule := ctx.Rule(pctx, "cherry", | 
 | 249 |     blueprint.RuleParams{ | 
 | 250 |       Command: "echo CHERRY IS " + ctx.Config().Getenv("CHERRY") + " > ${out}", | 
 | 251 |       CommandDeps: []string{}, | 
 | 252 |       Description: "Cherry", | 
 | 253 |     }) | 
 | 254 |  | 
 | 255 |   outputFile := android.PathForOutput(ctx, "cherry", "cherry.txt") | 
 | 256 |   var deps android.Paths | 
 | 257 |  | 
 | 258 |   ctx.Build(pctx, android.BuildParams{ | 
 | 259 |     Rule: cherryRule, | 
 | 260 |     Output: outputFile, | 
 | 261 |     Inputs: deps, | 
 | 262 |   }) | 
 | 263 | } | 
 | 264 | EOF | 
 | 265 |  | 
 | 266 |   export CHERRY=TASTY | 
 | 267 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 268 |   grep -q "CHERRY IS TASTY" out/soong/build."${target_product}".ninja \ | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 269 |     || fail "first value of environment variable is not used" | 
 | 270 |  | 
 | 271 |   export CHERRY=RED | 
 | 272 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 273 |   grep -q "CHERRY IS RED" out/soong/build."${target_product}".ninja \ | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 274 |     || fail "second value of environment variable not used" | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 275 |   local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 276 |  | 
 | 277 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 278 |   local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 279 |   if [[ "$mtime1" != "$mtime2" ]]; then | 
 | 280 |     fail "Output Ninja file changed when environment variable did not" | 
 | 281 |   fi | 
 | 282 |  | 
 | 283 | } | 
 | 284 |  | 
| Colin Cross | 662d614 | 2022-11-03 20:38:01 -0700 | [diff] [blame] | 285 | function test_create_global_include_directory() { | 
 | 286 |   setup | 
 | 287 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 288 |   local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Colin Cross | 662d614 | 2022-11-03 20:38:01 -0700 | [diff] [blame] | 289 |  | 
 | 290 |   # Soong needs to know if top level directories like hardware/ exist for use | 
 | 291 |   # as global include directories.  Make sure that doesn't cause regens for | 
 | 292 |   # unrelated changes to the top level directory. | 
 | 293 |   mkdir -p system/core | 
 | 294 |  | 
 | 295 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 296 |   local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Colin Cross | 662d614 | 2022-11-03 20:38:01 -0700 | [diff] [blame] | 297 |   if [[ "$mtime1" != "$mtime2" ]]; then | 
 | 298 |     fail "Output Ninja file changed when top level directory changed" | 
 | 299 |   fi | 
 | 300 |  | 
 | 301 |   # Make sure it does regen if a missing directory in the path of a global | 
 | 302 |   # include directory is added. | 
 | 303 |   mkdir -p system/core/include | 
 | 304 |  | 
 | 305 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 306 |   local -r mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Colin Cross | 662d614 | 2022-11-03 20:38:01 -0700 | [diff] [blame] | 307 |   if [[ "$mtime2" = "$mtime3" ]]; then | 
 | 308 |     fail "Output Ninja file did not change when global include directory created" | 
 | 309 |   fi | 
 | 310 |  | 
 | 311 | } | 
 | 312 |  | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 313 | function test_add_file_to_soong_build() { | 
 | 314 |   setup | 
 | 315 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 316 |   local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 317 |  | 
| Liz Kammer | 33cc80e | 2023-05-18 18:20:28 +0000 | [diff] [blame] | 318 |   mkdir -p vendor/foo/picard | 
 | 319 |   cat > vendor/foo/picard/Android.bp <<'EOF' | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 320 | bootstrap_go_package { | 
 | 321 |   name: "picard-soong-rules", | 
 | 322 |   pkgPath: "android/soong/picard", | 
 | 323 |   deps: [ | 
 | 324 |     "blueprint", | 
 | 325 |     "soong", | 
 | 326 |     "soong-android", | 
 | 327 |   ], | 
 | 328 |   srcs: [ | 
 | 329 |     "picard.go", | 
 | 330 |   ], | 
 | 331 |   pluginFor: ["soong_build"], | 
 | 332 | } | 
 | 333 | EOF | 
 | 334 |  | 
| Liz Kammer | 33cc80e | 2023-05-18 18:20:28 +0000 | [diff] [blame] | 335 |   cat > vendor/foo/picard/picard.go <<'EOF' | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 336 | package picard | 
 | 337 |  | 
 | 338 | import ( | 
 | 339 |   "android/soong/android" | 
 | 340 |   "github.com/google/blueprint" | 
 | 341 | ) | 
 | 342 |  | 
 | 343 | var ( | 
 | 344 |   pctx = android.NewPackageContext("picard") | 
 | 345 | ) | 
 | 346 |  | 
 | 347 | func init() { | 
 | 348 |   android.RegisterSingletonType("picard", PicardSingleton) | 
 | 349 | } | 
 | 350 |  | 
 | 351 | func PicardSingleton() android.Singleton { | 
 | 352 |   return &picardSingleton{} | 
 | 353 | } | 
 | 354 |  | 
 | 355 | type picardSingleton struct{} | 
 | 356 |  | 
 | 357 | func (p *picardSingleton) GenerateBuildActions(ctx android.SingletonContext) { | 
 | 358 |   picardRule := ctx.Rule(pctx, "picard", | 
 | 359 |     blueprint.RuleParams{ | 
 | 360 |       Command: "echo Make it so. > ${out}", | 
 | 361 |       CommandDeps: []string{}, | 
 | 362 |       Description: "Something quotable", | 
 | 363 |     }) | 
 | 364 |  | 
 | 365 |   outputFile := android.PathForOutput(ctx, "picard", "picard.txt") | 
 | 366 |   var deps android.Paths | 
 | 367 |  | 
 | 368 |   ctx.Build(pctx, android.BuildParams{ | 
 | 369 |     Rule: picardRule, | 
 | 370 |     Output: outputFile, | 
 | 371 |     Inputs: deps, | 
 | 372 |   }) | 
 | 373 | } | 
 | 374 |  | 
 | 375 | EOF | 
 | 376 |  | 
 | 377 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 378 |   local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 379 |   if [[ "$mtime1" == "$mtime2" ]]; then | 
 | 380 |     fail "Output Ninja file did not change" | 
 | 381 |   fi | 
 | 382 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 383 |   grep -q "Make it so" out/soong/build."${target_product}".ninja || fail "New action not present" | 
| Lukacs T. Berki | d1e3f1f | 2021-03-16 08:55:23 +0100 | [diff] [blame] | 384 | } | 
 | 385 |  | 
| Colin Cross | c02504e | 2021-04-08 10:34:16 -0700 | [diff] [blame] | 386 | # Tests a glob in a build= statement in an Android.bp file, which is interpreted | 
 | 387 | # during bootstrapping. | 
 | 388 | function test_glob_during_bootstrapping() { | 
 | 389 |   setup | 
 | 390 |  | 
| Liz Kammer | 33cc80e | 2023-05-18 18:20:28 +0000 | [diff] [blame] | 391 |   mkdir -p build/soong/picard | 
 | 392 |   cat > build/soong/picard/Android.bp <<'EOF' | 
| Colin Cross | c02504e | 2021-04-08 10:34:16 -0700 | [diff] [blame] | 393 | build=["foo*.bp"] | 
 | 394 | EOF | 
| Liz Kammer | 33cc80e | 2023-05-18 18:20:28 +0000 | [diff] [blame] | 395 |   cat > build/soong/picard/fooa.bp <<'EOF' | 
| Colin Cross | c02504e | 2021-04-08 10:34:16 -0700 | [diff] [blame] | 396 | bootstrap_go_package { | 
 | 397 |   name: "picard-soong-rules", | 
 | 398 |   pkgPath: "android/soong/picard", | 
 | 399 |   deps: [ | 
 | 400 |     "blueprint", | 
 | 401 |     "soong", | 
 | 402 |     "soong-android", | 
 | 403 |   ], | 
 | 404 |   srcs: [ | 
 | 405 |     "picard.go", | 
 | 406 |   ], | 
 | 407 |   pluginFor: ["soong_build"], | 
 | 408 | } | 
 | 409 | EOF | 
 | 410 |  | 
| Liz Kammer | 33cc80e | 2023-05-18 18:20:28 +0000 | [diff] [blame] | 411 |   cat > build/soong/picard/picard.go <<'EOF' | 
| Colin Cross | c02504e | 2021-04-08 10:34:16 -0700 | [diff] [blame] | 412 | package picard | 
 | 413 |  | 
 | 414 | import ( | 
 | 415 |   "android/soong/android" | 
 | 416 |   "github.com/google/blueprint" | 
 | 417 | ) | 
 | 418 |  | 
 | 419 | var ( | 
 | 420 |   pctx = android.NewPackageContext("picard") | 
 | 421 | ) | 
 | 422 |  | 
 | 423 | func init() { | 
 | 424 |   android.RegisterSingletonType("picard", PicardSingleton) | 
 | 425 | } | 
 | 426 |  | 
 | 427 | func PicardSingleton() android.Singleton { | 
 | 428 |   return &picardSingleton{} | 
 | 429 | } | 
 | 430 |  | 
 | 431 | type picardSingleton struct{} | 
 | 432 |  | 
 | 433 | var Message = "Make it so." | 
 | 434 |  | 
 | 435 | func (p *picardSingleton) GenerateBuildActions(ctx android.SingletonContext) { | 
 | 436 |   picardRule := ctx.Rule(pctx, "picard", | 
 | 437 |     blueprint.RuleParams{ | 
 | 438 |       Command: "echo " + Message + " > ${out}", | 
 | 439 |       CommandDeps: []string{}, | 
 | 440 |       Description: "Something quotable", | 
 | 441 |     }) | 
 | 442 |  | 
 | 443 |   outputFile := android.PathForOutput(ctx, "picard", "picard.txt") | 
 | 444 |   var deps android.Paths | 
 | 445 |  | 
 | 446 |   ctx.Build(pctx, android.BuildParams{ | 
 | 447 |     Rule: picardRule, | 
 | 448 |     Output: outputFile, | 
 | 449 |     Inputs: deps, | 
 | 450 |   }) | 
 | 451 | } | 
 | 452 |  | 
 | 453 | EOF | 
 | 454 |  | 
 | 455 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 456 |   local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Colin Cross | c02504e | 2021-04-08 10:34:16 -0700 | [diff] [blame] | 457 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 458 |   grep -q "Make it so" out/soong/build."${target_product}".ninja || fail "Original action not present" | 
| Colin Cross | c02504e | 2021-04-08 10:34:16 -0700 | [diff] [blame] | 459 |  | 
| Liz Kammer | 33cc80e | 2023-05-18 18:20:28 +0000 | [diff] [blame] | 460 |   cat > build/soong/picard/foob.bp <<'EOF' | 
| Colin Cross | c02504e | 2021-04-08 10:34:16 -0700 | [diff] [blame] | 461 | bootstrap_go_package { | 
 | 462 |   name: "worf-soong-rules", | 
 | 463 |   pkgPath: "android/soong/worf", | 
 | 464 |   deps: [ | 
 | 465 |     "blueprint", | 
 | 466 |     "soong", | 
 | 467 |     "soong-android", | 
 | 468 |     "picard-soong-rules", | 
 | 469 |   ], | 
 | 470 |   srcs: [ | 
 | 471 |     "worf.go", | 
 | 472 |   ], | 
 | 473 |   pluginFor: ["soong_build"], | 
 | 474 | } | 
 | 475 | EOF | 
 | 476 |  | 
| Liz Kammer | 33cc80e | 2023-05-18 18:20:28 +0000 | [diff] [blame] | 477 |   cat > build/soong/picard/worf.go <<'EOF' | 
| Colin Cross | c02504e | 2021-04-08 10:34:16 -0700 | [diff] [blame] | 478 | package worf | 
 | 479 |  | 
 | 480 | import "android/soong/picard" | 
 | 481 |  | 
 | 482 | func init() { | 
 | 483 |    picard.Message = "Engage." | 
 | 484 | } | 
 | 485 | EOF | 
 | 486 |  | 
 | 487 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 488 |   local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Colin Cross | c02504e | 2021-04-08 10:34:16 -0700 | [diff] [blame] | 489 |   if [[ "$mtime1" == "$mtime2" ]]; then | 
 | 490 |     fail "Output Ninja file did not change" | 
 | 491 |   fi | 
 | 492 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 493 |   grep -q "Engage" out/soong/build."${target_product}".ninja || fail "New action not present" | 
| Colin Cross | c02504e | 2021-04-08 10:34:16 -0700 | [diff] [blame] | 494 |  | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 495 |   if grep -q "Make it so" out/soong/build."${target_product}".ninja; then | 
| Lukacs T. Berki | f8e2428 | 2021-04-14 10:31:00 +0200 | [diff] [blame] | 496 |     fail "Original action still present" | 
 | 497 |   fi | 
| Colin Cross | c02504e | 2021-04-08 10:34:16 -0700 | [diff] [blame] | 498 | } | 
 | 499 |  | 
| Lukacs T. Berki | c6012f3 | 2021-09-06 18:31:46 +0200 | [diff] [blame] | 500 | function test_soong_docs_smoke() { | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 501 |   setup | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 502 |  | 
| Lukacs T. Berki | c6012f3 | 2021-09-06 18:31:46 +0200 | [diff] [blame] | 503 |   run_soong soong_docs | 
 | 504 |  | 
 | 505 |   [[ -e "out/soong/docs/soong_build.html" ]] || fail "Documentation for main page not created" | 
 | 506 |   [[ -e "out/soong/docs/cc.html" ]] || fail "Documentation for C++ modules not created" | 
 | 507 | } | 
 | 508 |  | 
 | 509 | function test_null_build_after_soong_docs() { | 
 | 510 |   setup | 
| Lukacs T. Berki | 1a86bd2 | 2021-08-19 16:24:30 +0200 | [diff] [blame] | 511 |  | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 512 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 513 |   local -r ninja_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 514 |  | 
| Lukacs T. Berki | c6012f3 | 2021-09-06 18:31:46 +0200 | [diff] [blame] | 515 |   run_soong soong_docs | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 516 |   local -r docs_mtime1=$(stat -c "%y" out/soong/docs/soong_build.html) | 
| Lukacs T. Berki | c6012f3 | 2021-09-06 18:31:46 +0200 | [diff] [blame] | 517 |  | 
 | 518 |   run_soong soong_docs | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 519 |   local -r docs_mtime2=$(stat -c "%y" out/soong/docs/soong_build.html) | 
| Lukacs T. Berki | c6012f3 | 2021-09-06 18:31:46 +0200 | [diff] [blame] | 520 |  | 
 | 521 |   if [[ "$docs_mtime1" != "$docs_mtime2" ]]; then | 
 | 522 |     fail "Output Ninja file changed on null build" | 
 | 523 |   fi | 
 | 524 |  | 
 | 525 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 526 |   local -r ninja_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | c6012f3 | 2021-09-06 18:31:46 +0200 | [diff] [blame] | 527 |  | 
 | 528 |   if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then | 
| Lukacs T. Berki | f0b3b94 | 2021-03-23 11:46:47 +0100 | [diff] [blame] | 529 |     fail "Output Ninja file changed on null build" | 
 | 530 |   fi | 
 | 531 | } | 
 | 532 |  | 
| Spandan Das | 0506361 | 2021-06-25 01:39:04 +0000 | [diff] [blame] | 533 | function test_write_to_source_tree { | 
 | 534 |   setup | 
 | 535 |   mkdir -p a | 
 | 536 |   cat > a/Android.bp <<EOF | 
 | 537 | genrule { | 
 | 538 |   name: "write_to_source_tree", | 
 | 539 |   out: ["write_to_source_tree"], | 
 | 540 |   cmd: "touch file_in_source_tree && touch \$(out)", | 
 | 541 | } | 
 | 542 | EOF | 
 | 543 |   readonly EXPECTED_OUT=out/soong/.intermediates/a/write_to_source_tree/gen/write_to_source_tree | 
 | 544 |   readonly ERROR_LOG=${MOCK_TOP}/out/error.log | 
 | 545 |   readonly ERROR_MSG="Read-only file system" | 
 | 546 |   readonly ERROR_HINT_PATTERN="BUILD_BROKEN_SRC_DIR" | 
 | 547 |   # Test in ReadOnly source tree | 
 | 548 |   run_ninja BUILD_BROKEN_SRC_DIR_IS_WRITABLE=false ${EXPECTED_OUT} &> /dev/null && \ | 
 | 549 |     fail "Write to source tree should not work in a ReadOnly source tree" | 
 | 550 |  | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 551 |   if grep -q "${ERROR_MSG}" "${ERROR_LOG}" && grep -q "${ERROR_HINT_PATTERN}" "${ERROR_LOG}" ; then | 
| Spandan Das | 0506361 | 2021-06-25 01:39:04 +0000 | [diff] [blame] | 552 |     echo Error message and error hint found in logs >/dev/null | 
 | 553 |   else | 
 | 554 |     fail "Did not find Read-only error AND error hint in error.log" | 
 | 555 |   fi | 
 | 556 |  | 
 | 557 |   # Test in ReadWrite source tree | 
 | 558 |   run_ninja BUILD_BROKEN_SRC_DIR_IS_WRITABLE=true ${EXPECTED_OUT} &> /dev/null || \ | 
 | 559 |     fail "Write to source tree did not succeed in a ReadWrite source tree" | 
 | 560 |  | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 561 |   if  grep -q "${ERROR_MSG}\|${ERROR_HINT_PATTERN}" "${ERROR_LOG}" ; then | 
| Spandan Das | 0506361 | 2021-06-25 01:39:04 +0000 | [diff] [blame] | 562 |     fail "Found read-only error OR error hint in error.log" | 
 | 563 |   fi | 
 | 564 | } | 
 | 565 |  | 
| Lukacs T. Berki | 97bb9f1 | 2021-04-01 18:28:45 +0200 | [diff] [blame] | 566 | function test_dump_json_module_graph() { | 
 | 567 |   setup | 
| Lukacs T. Berki | a1b9372 | 2021-09-02 17:23:06 +0200 | [diff] [blame] | 568 |   run_soong json-module-graph | 
 | 569 |   if [[ ! -r "out/soong/module-graph.json" ]]; then | 
| Lukacs T. Berki | 97bb9f1 | 2021-04-01 18:28:45 +0200 | [diff] [blame] | 570 |     fail "JSON file was not created" | 
 | 571 |   fi | 
 | 572 | } | 
 | 573 |  | 
| Lukacs T. Berki | e571dc3 | 2021-08-25 14:14:13 +0200 | [diff] [blame] | 574 | function test_json_module_graph_back_and_forth_null_build() { | 
 | 575 |   setup | 
 | 576 |  | 
 | 577 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 578 |   local -r ninja_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | e571dc3 | 2021-08-25 14:14:13 +0200 | [diff] [blame] | 579 |  | 
| Lukacs T. Berki | a1b9372 | 2021-09-02 17:23:06 +0200 | [diff] [blame] | 580 |   run_soong json-module-graph | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 581 |   local -r json_mtime1=$(stat -c "%y" out/soong/module-graph.json) | 
| Lukacs T. Berki | e571dc3 | 2021-08-25 14:14:13 +0200 | [diff] [blame] | 582 |  | 
 | 583 |   run_soong | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 584 |   local -r ninja_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Lukacs T. Berki | e571dc3 | 2021-08-25 14:14:13 +0200 | [diff] [blame] | 585 |   if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then | 
 | 586 |     fail "Output Ninja file changed after writing JSON module graph" | 
 | 587 |   fi | 
 | 588 |  | 
| Lukacs T. Berki | a1b9372 | 2021-09-02 17:23:06 +0200 | [diff] [blame] | 589 |   run_soong json-module-graph | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 590 |   local -r json_mtime2=$(stat -c "%y" out/soong/module-graph.json) | 
| Lukacs T. Berki | e571dc3 | 2021-08-25 14:14:13 +0200 | [diff] [blame] | 591 |   if [[ "$json_mtime1" != "$json_mtime2" ]]; then | 
 | 592 |     fail "JSON module graph file changed after writing Ninja file" | 
 | 593 |   fi | 
 | 594 |  | 
 | 595 | } | 
 | 596 |  | 
| Lukacs T. Berki | 3a82169 | 2021-09-06 17:08:02 +0200 | [diff] [blame] | 597 | function test_queryview_null_build() { | 
 | 598 |   setup | 
 | 599 |  | 
 | 600 |   run_soong queryview | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 601 |   local -r output_mtime1=$(stat -c "%y" out/soong/queryview.marker) | 
| Lukacs T. Berki | 3a82169 | 2021-09-06 17:08:02 +0200 | [diff] [blame] | 602 |  | 
 | 603 |   run_soong queryview | 
| Usta Shrestha | 4e17a2e | 2022-12-08 01:18:44 -0500 | [diff] [blame] | 604 |   local -r output_mtime2=$(stat -c "%y" out/soong/queryview.marker) | 
| Lukacs T. Berki | 3a82169 | 2021-09-06 17:08:02 +0200 | [diff] [blame] | 605 |  | 
 | 606 |   if [[ "$output_mtime1" != "$output_mtime2" ]]; then | 
 | 607 |     fail "Queryview marker file changed on null build" | 
 | 608 |   fi | 
 | 609 | } | 
 | 610 |  | 
| Chris Parsons | a3ae007 | 2023-05-10 21:10:08 +0000 | [diff] [blame] | 611 | # This test verifies that adding a new glob to a blueprint file only | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 612 | # causes build."${target_product}".ninja to be regenerated on the *next* build, and *not* | 
| Chris Parsons | a3ae007 | 2023-05-10 21:10:08 +0000 | [diff] [blame] | 613 | # the build after. (This is a regression test for a bug where globs | 
 | 614 | # resulted in two successive regenerations.) | 
 | 615 | function test_new_glob_incrementality { | 
 | 616 |   setup | 
 | 617 |  | 
 | 618 |   run_soong nothing | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 619 |   local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Chris Parsons | a3ae007 | 2023-05-10 21:10:08 +0000 | [diff] [blame] | 620 |  | 
 | 621 |   mkdir -p globdefpkg/ | 
 | 622 |   cat > globdefpkg/Android.bp <<'EOF' | 
 | 623 | filegroup { | 
 | 624 |   name: "fg_with_glob", | 
 | 625 |   srcs: ["*.txt"], | 
 | 626 | } | 
 | 627 | EOF | 
 | 628 |  | 
 | 629 |   run_soong nothing | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 630 |   local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Chris Parsons | a3ae007 | 2023-05-10 21:10:08 +0000 | [diff] [blame] | 631 |  | 
 | 632 |   if [[ "$mtime1" == "$mtime2" ]]; then | 
 | 633 |     fail "Ninja file was not regenerated, despite a new bp file" | 
 | 634 |   fi | 
 | 635 |  | 
 | 636 |   run_soong nothing | 
| Spandan Das | 08e90c2 | 2024-03-29 19:00:20 +0000 | [diff] [blame] | 637 |   local -r mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja) | 
| Chris Parsons | a3ae007 | 2023-05-10 21:10:08 +0000 | [diff] [blame] | 638 |  | 
 | 639 |   if [[ "$mtime2" != "$mtime3" ]]; then | 
 | 640 |     fail "Ninja file was regenerated despite no previous bp changes" | 
 | 641 |   fi | 
 | 642 | } | 
 | 643 |  | 
| Usta Shrestha | 572ecec | 2022-12-08 01:29:21 -0500 | [diff] [blame] | 644 | scan_and_run_tests |