[sw] Add Custom Target Dependencies

Many of our meson custom_targets depend on scripts inside the repo, but we
give them absolute paths when invoking them (usually via
`meson.source_root() / 'util/script.py'`), because meson does not cope
with relative paths including `..`. This broadly works fine,
until one of those scripts is changed, at which point meson doesn't
always realise the script will have to be re-run.

This change adds `depend_files:` configuration for each custom target
that uses an in-tree script. Where we have abstracted the definition of
the custom target, this defines a `_depend_files` variable, to go with
the `_command` variable.

One other major change is that `cargo` is now a disabler, so if meson
does not find `cargo`, you will not get any targets that depend on
cargo -- we also now ensure that we use the `cargo` that meson found,
rather than any other one that might be on the user's path.

Signed-off-by: Sam Elliott <selliott@lowrisc.org>
diff --git a/sw/device/benchmarks/coremark/meson.build b/sw/device/benchmarks/coremark/meson.build
index 6aa8b23..ad0ce48 100644
--- a/sw/device/benchmarks/coremark/meson.build
+++ b/sw/device/benchmarks/coremark/meson.build
@@ -38,7 +38,8 @@
 
   coremark_top_earlgrey_embedded = custom_target(
     'coremark_top_earlgrey_' + device_name,
-    command: make_embedded_target,
+    command: make_embedded_target_command,
+    depend_files: [make_embedded_target_depend_files,],
     input: coremark_top_earlgrey_elf,
     output: make_embedded_target_outputs,
     build_by_default: true,
@@ -51,6 +52,7 @@
       coremark_top_earlgrey_elf,
       coremark_top_earlgrey_embedded,
     ],
+    depend_files: [export_target_depend_files,],
     output: 'coremark_top_earlgrey_export_' + device_name,
     build_always_stale: true,
     build_by_default: true,
diff --git a/sw/device/boot_rom/meson.build b/sw/device/boot_rom/meson.build
index d5e4119..095a297 100644
--- a/sw/device/boot_rom/meson.build
+++ b/sw/device/boot_rom/meson.build
@@ -9,10 +9,13 @@
     output: 'chip_info.h',
     command: [
       prog_python,
-      '@SOURCE_DIR@/util/rom_chip_info.py',
+      meson.source_root() / 'util/rom_chip_info.py',
       '--outdir', '@OUTDIR@',
       '--ot_version', ot_version,
-    ]
+    ],
+    depend_files: [
+      meson.source_root() / 'util/rom_chip_info.py',
+    ],
   )],
 )
 
@@ -60,7 +63,8 @@
 
   boot_rom_embedded = custom_target(
     'boot_rom_' + device_name,
-    command: make_embedded_target,
+    command: make_embedded_target_command,
+    depend_files: [make_embedded_target_depend_files,],
     input: boot_rom_elf,
     output: make_embedded_target_outputs,
     build_by_default: true,
@@ -69,6 +73,7 @@
   custom_target(
     'boot_rom_export_' + device_name,
     command: export_target_command,
+    depend_files: [export_target_depend_files,],
     input: [boot_rom_elf, boot_rom_embedded],
     output: 'boot_rom_export_' + device_name,
     build_always_stale: true,
diff --git a/sw/device/examples/hello_usbdev/meson.build b/sw/device/examples/hello_usbdev/meson.build
index d1bb89d..7b09ef6 100644
--- a/sw/device/examples/hello_usbdev/meson.build
+++ b/sw/device/examples/hello_usbdev/meson.build
@@ -29,7 +29,8 @@
 
   hello_usbdev_embedded = custom_target(
     'hello_usbdev_' + device_name,
-    command: make_embedded_target,
+    command: make_embedded_target_command,
+    depend_files: [make_embedded_target_depend_files,],
     input: hello_usbdev_elf,
     output: make_embedded_target_outputs,
     build_by_default: true,
@@ -38,6 +39,7 @@
   custom_target(
     'hello_usbdev_export_' + device_name,
     command: export_target_command,
+    depend_files: [export_target_depend_files,],
     input: [hello_usbdev_elf, hello_usbdev_embedded],
     output: 'hello_usbdev_export_' + device_name,
     build_always_stale: true,
diff --git a/sw/device/examples/hello_world/meson.build b/sw/device/examples/hello_world/meson.build
index 60e44cb..fcb0d9b 100644
--- a/sw/device/examples/hello_world/meson.build
+++ b/sw/device/examples/hello_world/meson.build
@@ -26,7 +26,8 @@
 
   hello_world_embedded = custom_target(
     'hello_world_' + device_name,
-    command: make_embedded_target,
+    command: make_embedded_target_command,
+    depend_files: [make_embedded_target_depend_files,],
     input: hello_world_elf,
     output: make_embedded_target_outputs,
     build_by_default: true,
@@ -35,6 +36,7 @@
   custom_target(
     'hello_world_export_' + device_name,
     command: export_target_command,
+    depend_files: [export_target_depend_files,],
     input: [hello_world_elf, hello_world_embedded],
     output: 'hello_world_export_' + device_name,
     build_always_stale: true,
diff --git a/sw/device/mask_rom/meson.build b/sw/device/mask_rom/meson.build
index b987b9b..da93739 100644
--- a/sw/device/mask_rom/meson.build
+++ b/sw/device/mask_rom/meson.build
@@ -33,7 +33,8 @@
 
   mask_rom_embedded = custom_target(
     'mask_rom_' + device_name,
-    command: make_embedded_target,
+    command: make_embedded_target_command,
+    depend_files: [make_embedded_target_depend_files,],
     input: mask_rom_elf,
     output: make_embedded_target_outputs,
     build_by_default: true,
@@ -42,6 +43,7 @@
   custom_target(
     'mask_rom_export_' + device_name,
     command: export_target_command,
+    depend_files: [export_target_depend_files,],
     input: [mask_rom_elf, mask_rom_embedded],
     output: 'mask_rom_export_' + device_name,
     build_always_stale: true,
diff --git a/sw/device/meson.build b/sw/device/meson.build
index 34045b8..4ed2baf 100644
--- a/sw/device/meson.build
+++ b/sw/device/meson.build
@@ -10,8 +10,9 @@
 #
 # These definitions should only be available to directories which define executables.
 make_embedded_target_outputs = ['@BASENAME@.bin', '@BASENAME@.dis', '@BASENAME@.32.vmem', '@BASENAME@.64.vmem']
-make_embedded_target = [
-  prog_python, meson.source_root() / 'util/embedded_target.py',
+make_embedded_target_command = [
+  prog_python,
+  meson.source_root() / 'util/embedded_target.py',
   '--objcopy', prog_objcopy,
   '--srec_cat', prog_srec_cat,
   '--objdump', prog_objdump,
@@ -19,6 +20,9 @@
   '--basename', '@BASENAME@',
   '--outdir', '@OUTDIR@',
 ]
+make_embedded_target_depend_files = [
+  meson.source_root() / 'util/embedded_target.py',
+]
 
 embedded_target_extra_link_args = [
   '-Wl,--build-id=none',
diff --git a/sw/device/riscv_compliance_support/meson.build b/sw/device/riscv_compliance_support/meson.build
index d8d6fae..1e236ba 100644
--- a/sw/device/riscv_compliance_support/meson.build
+++ b/sw/device/riscv_compliance_support/meson.build
@@ -29,6 +29,7 @@
   custom_target(
     'riscv_compliance_support_export_' + device_name,
     command: export_target_command,
+    depend_files: [export_target_depend_files,],
     input: [riscv_compliance_support],
     output: 'riscv_compliance_support_export_' + device_name,
     build_always_stale: true,
diff --git a/sw/device/rom_exts/meson.build b/sw/device/rom_exts/meson.build
index d4f34be..8bd4d6b 100644
--- a/sw/device/rom_exts/meson.build
+++ b/sw/device/rom_exts/meson.build
@@ -46,6 +46,7 @@
   depend_files: [
     'manifest.h.tpl',
     'manifest.hjson',
+    meson.source_root() / 'util/rom-ext-manifest-generator.py',
   ],
   command: [
     prog_python,
@@ -94,7 +95,8 @@
 
     rom_ext_embedded = custom_target(
       slot + '_' + device_name,
-      command: make_embedded_target,
+      command: make_embedded_target_command,
+      depend_files: [make_embedded_target_depend_files,],
       input: rom_ext_elf,
       output: make_embedded_target_outputs,
       build_by_default: true,
@@ -103,6 +105,7 @@
     custom_target(
       slot + '_export_' + device_name,
       command: export_target_command,
+      depend_files: [export_target_depend_files,],
       input: [rom_ext_elf, rom_ext_embedded],
       output: slot + '_export_' + device_name,
       build_always_stale: true,
diff --git a/sw/device/sca/aes_serial/meson.build b/sw/device/sca/aes_serial/meson.build
index bf0bebd..1908428 100644
--- a/sw/device/sca/aes_serial/meson.build
+++ b/sw/device/sca/aes_serial/meson.build
@@ -25,7 +25,8 @@
 
   aes_serial_embedded = custom_target(
     'aes_serial_' + device_name,
-    command: make_embedded_target,
+    command: make_embedded_target_command,
+    depend_files: [make_embedded_target_depend_files,],
     input: aes_serial_elf,
     output: make_embedded_target_outputs,
     build_by_default: true,
@@ -34,6 +35,7 @@
   custom_target(
     'aes_serial_export_' + device_name,
     command: export_target_command,
+    depend_files: [export_target_depend_files,],
     input: [aes_serial_elf, aes_serial_embedded],
     output: 'aes_serial_export_' + device_name,
     build_always_stale: true,
diff --git a/sw/device/tests/meson.build b/sw/device/tests/meson.build
index 6d5b57f..8fa15c4 100644
--- a/sw/device/tests/meson.build
+++ b/sw/device/tests/meson.build
@@ -154,7 +154,8 @@
 
     sw_test_embedded = custom_target(
       sw_test_name + '_' + device_name,
-      command: make_embedded_target,
+      command: make_embedded_target_command,
+      depend_files: [make_embedded_target_depend_files,],
       input: sw_test_elf,
       output: make_embedded_target_outputs,
       build_by_default: true,
@@ -179,6 +180,7 @@
     custom_target(
       sw_test_name + '_export_' + device_name,
       command: export_target_command,
+      depend_files: [export_target_depend_files,],
       input: [sw_test_elf, sw_test_embedded, sw_test_dv_frames],
       output: sw_test_name + '_export_' + device_name,
       build_always_stale: true,
@@ -209,7 +211,8 @@
 
   crt_test_embedded = custom_target(
     'crt_test_' + device_name,
-    command: make_embedded_target,
+    command: make_embedded_target_command,
+    depend_files: [make_embedded_target_depend_files,],
     input: crt_test_elf,
     output: make_embedded_target_outputs,
     build_by_default: true,
@@ -218,6 +221,7 @@
   custom_target(
     'crt_test_export_' + device_name,
     command: export_target_command,
+    depend_files: [export_target_depend_files,],
     input: [crt_test_elf, crt_test_embedded],
     output: 'crt_test_export_' + device_name,
     build_always_stale: true,
diff --git a/sw/device/tock/meson.build b/sw/device/tock/meson.build
index 0624bb7..2abc25f 100644
--- a/sw/device/tock/meson.build
+++ b/sw/device/tock/meson.build
@@ -2,7 +2,7 @@
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
 
-cargo = find_program('cargo', required: false)
+cargo = find_program('cargo', required: false, disabler: true)
 
 target = 'riscv32imc-unknown-none-elf'
 build_type = 'release'
@@ -33,6 +33,7 @@
   'tock_raw',
   command: [
     build_tock_cmd,
+    cargo,
     target,
     build_type,
     manifest_path,
@@ -42,6 +43,11 @@
     meson.build_root(),
     rust_flags,
   ],
+  depend_files: [
+    build_tock_cmd,
+    manifest_path,
+    toolchain_file,
+  ],
   output: target,
   console: true,
   build_always_stale: true,
@@ -68,7 +74,6 @@
     '@INPUT@',
     '@OUTPUT@'
   ],
-  depends: tock_elf,
   input: tock_elf,
   output: 'opentitan.bin',
   build_always_stale: true,
@@ -78,8 +83,8 @@
 custom_target(
   'tock_export',
   command: export_target_command,
+  depend_files: [export_target_depend_files,],
   input: [tock_elf, tock_bin],
-  depends: [tock_elf, tock_bin],
   output: 'tock',
   build_always_stale: true,
   build_by_default: false,
diff --git a/sw/host/spiflash/meson.build b/sw/host/spiflash/meson.build
index a9e53e6..68b95ec 100644
--- a/sw/host/spiflash/meson.build
+++ b/sw/host/spiflash/meson.build
@@ -22,6 +22,7 @@
   'spiflash_export',
   output: 'spiflash_export',
   command: export_target_command,
+  depend_files: [export_target_depend_files,],
   input: spiflash_bin,
   build_always_stale: true,
   build_by_default: true,
diff --git a/sw/meson.build b/sw/meson.build
index c097217..18109d0 100644
--- a/sw/meson.build
+++ b/sw/meson.build
@@ -10,6 +10,9 @@
   '@OUTDIR@',
   '@INPUT@',
 ]
+export_target_depend_files = [
+  meson.source_root() / 'util/export_target.sh',
+]
 
 subdir('vendor')
 subdir('otbn')
diff --git a/sw/otbn/meson.build b/sw/otbn/meson.build
index 5d2075e..8e84375 100644
--- a/sw/otbn/meson.build
+++ b/sw/otbn/meson.build
@@ -59,6 +59,14 @@
   '@OUTDIR@',
   '@INPUT@',
 ]
+otbn_build_depend_files = [
+  prog_otbn_as,
+  prog_otbn_ld,
+  prog_objcopy.path(),
+  prog_as.path(),
+  prog_ld.path(),
+  prog_otbn_build,
+]
 
 # Note on variable naming below: Variables in meson are global, we hence prefix
 # all variables with sw_otbn as "our namespace". Variables which are meant to be
@@ -78,6 +86,7 @@
     input: sw_otbn__app_sources,
     output: sw_otbn__app_output_files,
     command: otbn_build_command,
+    depend_files: [otbn_build_depend_files,],
   )
 
   # A library containing the OTBN application in a form embeddable into device
@@ -104,6 +113,7 @@
   custom_target(
     'sw_otbn_app_export_' + sw_otbn__app_name,
     command: export_target_command,
+    depend_files: [export_target_depend_files,],
     input: [sw_otbn__target[1]],
     output: 'sw_otbn_app_export_' + sw_otbn__app_name,
     build_always_stale: true,
diff --git a/util/build_tock.sh b/util/build_tock.sh
index 71908de..d564b0b 100755
--- a/util/build_tock.sh
+++ b/util/build_tock.sh
@@ -9,22 +9,23 @@
 # solution to read the rust-toolchain file from the Tock repository and set the
 # RUSTFLAGS environment variable.
 
-TARGET="${1}"
-MODE="${2}"
-MANIFEST_PATH="${3}"
-TARGET_DIR="${4}"
-TOOLCHAIN_FILE="${5}"
-export MESON_SOURCE_ROOT="${6}"
-export MESON_BUILD_ROOT="${7}"
-export RUSTFLAGS="${8}"
+CARGO="${1}"
+TARGET="${2}"
+MODE="${3}"
+MANIFEST_PATH="${4}"
+TARGET_DIR="${5}"
+TOOLCHAIN_FILE="${6}"
+export MESON_SOURCE_ROOT="${7}"
+export MESON_BUILD_ROOT="${8}"
+export RUSTFLAGS="${9}"
 
 if [[ "${MODE}" == "release" ]]; then
-	RELEASE_FLAG="--release"
+  RELEASE_FLAG="--release"
 fi
 
-cargo +"$(cat ${TOOLCHAIN_FILE})" build \
-	--target "${TARGET}" \
-	--manifest-path "${MANIFEST_PATH}" \
-	--target-dir "${TARGET_DIR}" \
-	--features="${TOCK_FEATURES}" \
-	${RELEASE_FLAG}
+"${CARGO}" +"$(cat ${TOOLCHAIN_FILE})" build \
+  --target "${TARGET}" \
+  --manifest-path "${MANIFEST_PATH}" \
+  --target-dir "${TARGET_DIR}" \
+  --features="${TOCK_FEATURES}" \
+  ${RELEASE_FLAG}