From 628603cb57d130021799f640a99a7511517b105e Mon Sep 17 00:00:00 2001 From: Eric Xiao Date: Mon, 22 Jun 2026 21:54:15 -0700 Subject: [PATCH 1/8] Setup STM32 cross compiler for motor driver firmware --- environment_setup/setup_software_mac.sh | 4 ++++ environment_setup/util.sh | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/environment_setup/setup_software_mac.sh b/environment_setup/setup_software_mac.sh index 5a759fa89f..5ed0db8ea9 100755 --- a/environment_setup/setup_software_mac.sh +++ b/environment_setup/setup_software_mac.sh @@ -76,6 +76,10 @@ print_status_msg "Setting up cross compiler for robot software" install_cross_compiler $sys print_status_msg "Done setting up cross compiler for robot software" +print_status_msg "Setting up STM32 cross-compiler for motor board firmware" +install_stm32_cross_compiler $sys +print_status_msg "Done setting up STM32 cross-compiler" + print_status_msg "Setting Up Python Development Headers" install_python_toolchain_headers print_status_msg "Done Setting Up Python Development Headers" diff --git a/environment_setup/util.sh b/environment_setup/util.sh index 75359ea10f..72a6ab2d23 100755 --- a/environment_setup/util.sh +++ b/environment_setup/util.sh @@ -127,14 +127,17 @@ install_python_dev_cross_compile_headers() { install_stm32_cross_compiler() { arch="aarch64" - if is_x86 $1; then + if is_darwin $1; then + arch="darwin-arm64" + elif is_x86 $1; then arch="x86_64" fi - download_link=https://developer.arm.com/-/media/Files/downloads/gnu/14.3.rel1/binrel/arm-gnu-toolchain-14.3.rel1-${arch}-arm-none-eabi.tar.xz + toolchain_name=arm-gnu-toolchain-14.3.rel1-${arch}-arm-none-eabi + download_link=https://developer.arm.com/-/media/Files/downloads/gnu/14.3.rel1/binrel/${toolchain_name}.tar.xz wget -N $download_link -O /tmp/tbots_download_cache/arm-gnu-toolchain.tar.xz tar -xf /tmp/tbots_download_cache/arm-gnu-toolchain.tar.xz -C /tmp/tbots_download_cache/ - sudo mv /tmp/tbots_download_cache/arm-gnu-toolchain-14.3.rel1-${arch}-arm-none-eabi /opt/tbotspython/arm-none-eabi-gcc + sudo mv /tmp/tbots_download_cache/${toolchain_name} /opt/tbotspython/arm-none-eabi-gcc rm /tmp/tbots_download_cache/arm-gnu-toolchain.tar.xz } From 49272c87d9fc7d9527b6126bab3a87496bedc4ab Mon Sep 17 00:00:00 2001 From: Eric Xiao Date: Tue, 23 Jun 2026 14:43:01 -0700 Subject: [PATCH 2/8] Add mac cross compiler for raspberry pi --- environment_setup/util.sh | 9 +-- src/MODULE.bazel | 7 +++ src/toolchains/cc/BUILD | 74 +++++++++++++++++++++++ src/toolchains/cc/wrapper/macos_robot_gcc | 7 +++ 4 files changed, 90 insertions(+), 7 deletions(-) create mode 100755 src/toolchains/cc/wrapper/macos_robot_gcc diff --git a/environment_setup/util.sh b/environment_setup/util.sh index 72a6ab2d23..26ec64a9e7 100755 --- a/environment_setup/util.sh +++ b/environment_setup/util.sh @@ -37,15 +37,10 @@ install_clang_format() { } install_cross_compiler() { - file_name=aarch64-tbots-linux-gnu-for-aarch64 if is_darwin $1; then - full_file_name=$file_name.tar.xz - curl -L "https://raw.githubusercontent.com/UBC-Thunderbots/Software-External-Dependencies/refs/heads/main/toolchain/$full_file_name" \ - -o /tmp/tbots_download_cache/$full_file_name - tar -xf /tmp/tbots_download_cache/$full_file_name -C /tmp/tbots_download_cache/ - sudo mv /tmp/tbots_download_cache/aarch64-tbots-linux-gnu /opt/tbotspython - rm /tmp/tbots_download_cache/$full_file_name + brew install messense/macos-cross-toolchains/aarch64-unknown-linux-gnu else + file_name=aarch64-tbots-linux-gnu-for-aarch64 if is_x86 $1; then file_name=aarch64-tbots-linux-gnu-for-x86 fi diff --git a/src/MODULE.bazel b/src/MODULE.bazel index 3c3c8729e8..841523f4da 100644 --- a/src/MODULE.bazel +++ b/src/MODULE.bazel @@ -250,6 +250,7 @@ register_toolchains( ) register_toolchains( + "//toolchains/cc:cc_toolchain_for_macos_robot", "//toolchains/cc:cc_toolchain_for_k8_aarch64_linux", "//toolchains/cc:cc_toolchain_for_k8", "//toolchains/cc:cc_toolchain_for_aarch64", @@ -286,6 +287,12 @@ new_local_repository( path = "/opt/tbotspython/aarch64-tbots-linux-gnu/", ) +new_local_repository( + name = "macos_robot_gcc", + build_file = "@//extlibs:macos_robot_gcc.BUILD", + path = "/opt/homebrew/Cellar/aarch64-unknown-linux-gnu/15.2.0/toolchain/", +) + new_local_repository( name = "motor_board_gcc", build_file = "@//extlibs:motor_board_gcc.BUILD", diff --git a/src/toolchains/cc/BUILD b/src/toolchains/cc/BUILD index a560ba1276..f6d6d4777a 100644 --- a/src/toolchains/cc/BUILD +++ b/src/toolchains/cc/BUILD @@ -269,6 +269,9 @@ cc_toolchain_config_k8_aarch64_linux( toolchain( name = "cc_toolchain_for_k8_aarch64_linux", + exec_compatible_with = [ + "@platforms//os:linux", + ], target_compatible_with = [ "@platforms//cpu:aarch64", "@platforms//os:linux", @@ -278,6 +281,77 @@ toolchain( toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", ) +# NOTE: the Cellar path is version-pinned; a repository rule should derive it +# (e.g. from `brew --prefix`) once this is productionized. +MACOS_ROBOT_TC = "/opt/homebrew/Cellar/aarch64-unknown-linux-gnu/15.2.0/toolchain" + +cc_toolchain_config_k8_aarch64_linux( + name = "gcc_macos_robot", + builtin_include_directories = [ + MACOS_ROBOT_TC + "/aarch64-unknown-linux-gnu/include/c++/15.2.0", + MACOS_ROBOT_TC + "/aarch64-unknown-linux-gnu/include/c++/15.2.0/aarch64-unknown-linux-gnu", + MACOS_ROBOT_TC + "/aarch64-unknown-linux-gnu/include/c++/15.2.0/backward", + MACOS_ROBOT_TC + "/lib/gcc/aarch64-unknown-linux-gnu/15.2.0/include", + MACOS_ROBOT_TC + "/lib/gcc/aarch64-unknown-linux-gnu/15.2.0/include-fixed", + MACOS_ROBOT_TC + "/aarch64-unknown-linux-gnu/include", + MACOS_ROBOT_TC + "/aarch64-unknown-linux-gnu/sysroot/usr/include", + ] + make_builtin_include_directories(), + tool_paths = { + "ar": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-ar", + "cpp": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-cpp", + # messense ships no dwp; point at gcc (unused without fission). + "dwp": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-gcc", + # wrapper forces -fuse-ld=bfd (messense has no gold linker). + "gcc": "wrapper/macos_robot_gcc", + "gcov": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-gcov", + "ld": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-ld", + "nm": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-nm", + "objcopy": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-objcopy", + "objdump": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-objdump", + "strip": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-strip", + }, + toolchain_identifier = "gcc-macos-robot", +) + +filegroup( + name = "macos_robot_everything", + srcs = [ + "wrapper/macos_robot_gcc", + "@macos_robot_gcc//:everything", + ], +) + +cc_toolchain( + name = "cc_toolchain_macos_robot", + all_files = ":macos_robot_everything", + ar_files = ":macos_robot_everything", + as_files = ":macos_robot_everything", + compiler_files = ":macos_robot_everything", + dwp_files = ":macos_robot_everything", + linker_files = ":macos_robot_everything", + objcopy_files = ":macos_robot_everything", + strip_files = ":macos_robot_everything", + supports_param_files = 0, + tags = ["no-ide"], + toolchain_config = ":gcc_macos_robot", + toolchain_identifier = "gcc-macos-robot", +) + +toolchain( + name = "cc_toolchain_for_macos_robot", + exec_compatible_with = [ + "@platforms//os:osx", + "@platforms//cpu:aarch64", + ], + target_compatible_with = [ + "@platforms//cpu:aarch64", + "@platforms//os:linux", + ":glibc_2_27", + ], + toolchain = ":cc_toolchain_macos_robot", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + toolchain( name = "cc_toolchain_for_k8", exec_compatible_with = [ diff --git a/src/toolchains/cc/wrapper/macos_robot_gcc b/src/toolchains/cc/wrapper/macos_robot_gcc new file mode 100755 index 0000000000..cc4ed4f89e --- /dev/null +++ b/src/toolchains/cc/wrapper/macos_robot_gcc @@ -0,0 +1,7 @@ +#!/bin/bash --norc + +# The prebuilt messense aarch64-unknown-linux-gnu toolchain ships only the BFD +# linker (ld/ld.bfd) — no ld.gold. The shared cc_toolchain config adds +# -fuse-ld=gold, so append -fuse-ld=bfd (last one wins) to use the linker that +# actually exists. Ignored for non-link (compile) invocations. +exec /opt/homebrew/Cellar/aarch64-unknown-linux-gnu/15.2.0/toolchain/bin/aarch64-unknown-linux-gnu-gcc "$@" -fuse-ld=bfd From 64f2cc7061f0a7f81a3d67b7f696aaa257b7cee3 Mon Sep 17 00:00:00 2001 From: Eric Xiao Date: Tue, 23 Jun 2026 17:30:02 -0700 Subject: [PATCH 3/8] Specify linux only targets --- environment_setup/setup_software_mac.sh | 2 ++ src/software/embedded/BUILD | 2 ++ src/software/embedded/gpio/BUILD | 2 ++ src/software/embedded/motor_controller/BUILD | 2 ++ src/software/embedded/services/BUILD | 2 ++ src/tbots.py | 9 ++++++++- 6 files changed, 18 insertions(+), 1 deletion(-) diff --git a/environment_setup/setup_software_mac.sh b/environment_setup/setup_software_mac.sh index 5ed0db8ea9..f11580089a 100755 --- a/environment_setup/setup_software_mac.sh +++ b/environment_setup/setup_software_mac.sh @@ -59,6 +59,8 @@ sudo pip install -r macos_requirements.txt print_status_msg "Done Setting Up Python Environment" +sudo ln -s /opt/tbotspython/bin/platformio /usr/local/bin/platformio + print_status_msg "Fetching game controller" install_gamecontroller $sys diff --git a/src/software/embedded/BUILD b/src/software/embedded/BUILD index 6a34ee0639..a92bcb7bdd 100644 --- a/src/software/embedded/BUILD +++ b/src/software/embedded/BUILD @@ -48,6 +48,8 @@ cc_library( name = "spi_utils", srcs = ["spi_utils.cpp"], hdrs = ["spi_utils.h"], + # Uses Linux kernel headers (linux/spi/spidev.h); robot-only. + target_compatible_with = ["@platforms//os:linux"], deps = [ "//software/logger", ], diff --git a/src/software/embedded/gpio/BUILD b/src/software/embedded/gpio/BUILD index a09031ccf2..b3e02951b0 100644 --- a/src/software/embedded/gpio/BUILD +++ b/src/software/embedded/gpio/BUILD @@ -10,6 +10,8 @@ cc_library( "gpio.h", "gpio_char_dev.h", ], + # Uses Linux kernel headers (linux/gpio.h); robot-only. + target_compatible_with = ["@platforms//os:linux"], deps = [ "//software/logger", "//software/logger:network_logger", diff --git a/src/software/embedded/motor_controller/BUILD b/src/software/embedded/motor_controller/BUILD index 26518edbfd..16c3f1b0ca 100644 --- a/src/software/embedded/motor_controller/BUILD +++ b/src/software/embedded/motor_controller/BUILD @@ -27,6 +27,8 @@ cc_library( "stspin_motor_controller.h", "tmc_motor_controller.h", ], + # Uses Linux kernel headers (linux/spi/spidev.h); robot-only. + target_compatible_with = ["@platforms//os:linux"], deps = [ ":motor_board", ":motor_fault_indicator", diff --git a/src/software/embedded/services/BUILD b/src/software/embedded/services/BUILD index fa9571a16c..ced15431fd 100644 --- a/src/software/embedded/services/BUILD +++ b/src/software/embedded/services/BUILD @@ -42,6 +42,8 @@ cc_library( name = "imu", srcs = ["imu.cpp"], hdrs = ["imu.h"], + # Uses Linux kernel headers (linux/i2c-dev.h); robot-only. + target_compatible_with = ["@platforms//os:linux"], deps = [ "//proto:tbots_cc_proto", "//shared:constants", diff --git a/src/tbots.py b/src/tbots.py index d31d68a8c0..acd5e920af 100755 --- a/src/tbots.py +++ b/src/tbots.py @@ -189,7 +189,7 @@ def create_command(config: BuildConfig, extra_args: list[str]) -> list[str]: if config.test_suite and config.action == ActionArgument.test: target = """-- //... \\ -//software/gameplay_tests/... \\ - -//toolchains/cc/... \\ + -//toolchains/... \\ -//software:unix_full_system_tar_gen""" else: target = fuzzy_find_target( @@ -214,6 +214,13 @@ def create_command(config: BuildConfig, extra_args: list[str]) -> list[str]: if condition: command += list(flag.value) + # `test --suite` resolves to //..., and `bazel test` would also try to BUILD + # every non-test target in that pattern — including robot firmware that only + # compiles with the cross toolchain (e.g. thunderloop pulls in linux/* headers + # that don't exist on the host). Restrict to test targets and their deps. + if config.test_suite and config.action == ActionArgument.test: + command += ["--build_tests_only"] + if config.jobs_option: command += [f"--jobs={config.jobs_option}"] From a33ea832fb8d80019583126c694c227e57d7a7eb Mon Sep 17 00:00:00 2001 From: Eric Xiao Date: Wed, 24 Jun 2026 11:07:38 -0700 Subject: [PATCH 4/8] Fix firmware flashing --- environment_setup/setup_software.sh | 2 +- environment_setup/setup_software_mac.sh | 1 + src/extlibs/macos_robot_gcc.BUILD | 9 +++++++ src/toolchains/cc/wrapper/macos_robot_gcc | 29 +++++++++++++++++++---- 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/extlibs/macos_robot_gcc.BUILD diff --git a/environment_setup/setup_software.sh b/environment_setup/setup_software.sh index fd94cce9a5..8172472d66 100755 --- a/environment_setup/setup_software.sh +++ b/environment_setup/setup_software.sh @@ -75,7 +75,7 @@ host_software_packages=( libffi-dev # needed to use _ctypes in Python3 libssl-dev # needed to build Python 3 with ssl support openssl # possibly also necessary for ssl in Python 3 - sshpass #used to remotely ssh into robots via Ansible + sshpass # used to remotely ssh into robots via Ansible unzip # installing tigers autoref xvfb # used for CI to run GUI applications ) diff --git a/environment_setup/setup_software_mac.sh b/environment_setup/setup_software_mac.sh index f11580089a..11b975e1cf 100755 --- a/environment_setup/setup_software_mac.sh +++ b/environment_setup/setup_software_mac.sh @@ -32,6 +32,7 @@ host_software_packages=( node@20 go@1.24 clang-format@20 + sshpass # used to remotely ssh into robots via Ansible ) for pkg in "${host_software_packages[@]}"; do diff --git a/src/extlibs/macos_robot_gcc.BUILD b/src/extlibs/macos_robot_gcc.BUILD new file mode 100644 index 0000000000..1b6f9567c4 --- /dev/null +++ b/src/extlibs/macos_robot_gcc.BUILD @@ -0,0 +1,9 @@ +package(default_visibility = ["//visibility:public"]) + +# The prebuilt messense aarch64-unknown-linux-gnu toolchain (Homebrew), exposed +# as Bazel inputs so its binaries (gcc, ld, as, ...) are staged into the sandbox +# when cross-compiling robot firmware on macOS. +filegroup( + name = "everything", + srcs = glob(["**"]), +) diff --git a/src/toolchains/cc/wrapper/macos_robot_gcc b/src/toolchains/cc/wrapper/macos_robot_gcc index cc4ed4f89e..21ae0d1b28 100755 --- a/src/toolchains/cc/wrapper/macos_robot_gcc +++ b/src/toolchains/cc/wrapper/macos_robot_gcc @@ -1,7 +1,26 @@ #!/bin/bash --norc -# The prebuilt messense aarch64-unknown-linux-gnu toolchain ships only the BFD -# linker (ld/ld.bfd) — no ld.gold. The shared cc_toolchain config adds -# -fuse-ld=gold, so append -fuse-ld=bfd (last one wins) to use the linker that -# actually exists. Ignored for non-link (compile) invocations. -exec /opt/homebrew/Cellar/aarch64-unknown-linux-gnu/15.2.0/toolchain/bin/aarch64-unknown-linux-gnu-gcc "$@" -fuse-ld=bfd +# Wrapper around the prebuilt messense aarch64-unknown-linux-gnu GCC 15.2.0, +# applying two robot-deployment fix-ups (both no-ops for compile-only calls): +# +# * Static C++ runtime: this toolchain is GCC 15, newer than the robot's system +# libstdc++, so a dynamic libstdc++ dependency requires GLIBCXX/CXXABI symbol +# versions the robot doesn't have. Bazel passes an explicit `-lstdc++`, which +# `-static-libstdc++` does NOT intercept, so rewrite it to the static archive +# (`-l:libstdc++.a`). `-static-libgcc` covers libgcc. +# +# * `-fuse-ld=bfd`: messense ships only the BFD linker (no ld.gold), but the +# shared cc_toolchain config adds `-fuse-ld=gold`; appending bfd wins. + +TC=/opt/homebrew/Cellar/aarch64-unknown-linux-gnu/15.2.0/toolchain + +args=() +for a in "$@"; do + if [ "$a" = "-lstdc++" ]; then + args+=("-l:libstdc++.a") + else + args+=("$a") + fi +done + +exec "$TC/bin/aarch64-unknown-linux-gnu-gcc" "${args[@]}" -fuse-ld=bfd -static-libgcc From 25da3af5f0efbad1df14e0ef1231807740ce4479 Mon Sep 17 00:00:00 2001 From: Eric Xiao Date: Thu, 25 Jun 2026 12:10:15 -0700 Subject: [PATCH 5/8] Dont hardcode cross compiler version --- src/MODULE.bazel | 2 +- src/toolchains/cc/BUILD | 29 +++++++++++++---------- src/toolchains/cc/wrapper/macos_robot_gcc | 6 +++-- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/MODULE.bazel b/src/MODULE.bazel index 841523f4da..990e1ca030 100644 --- a/src/MODULE.bazel +++ b/src/MODULE.bazel @@ -290,7 +290,7 @@ new_local_repository( new_local_repository( name = "macos_robot_gcc", build_file = "@//extlibs:macos_robot_gcc.BUILD", - path = "/opt/homebrew/Cellar/aarch64-unknown-linux-gnu/15.2.0/toolchain/", + path = "/opt/homebrew/opt/aarch64-unknown-linux-gnu/toolchain/", ) new_local_repository( diff --git a/src/toolchains/cc/BUILD b/src/toolchains/cc/BUILD index f6d6d4777a..1034be799c 100644 --- a/src/toolchains/cc/BUILD +++ b/src/toolchains/cc/BUILD @@ -281,21 +281,26 @@ toolchain( toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", ) -# NOTE: the Cellar path is version-pinned; a repository rule should derive it -# (e.g. from `brew --prefix`) once this is productionized. -MACOS_ROBOT_TC = "/opt/homebrew/Cellar/aarch64-unknown-linux-gnu/15.2.0/toolchain" +# Execution paths resolve through Homebrew's version-independent `opt` symlink +# (`brew --prefix aarch64-unknown-linux-gnu`), re-pointed on every `brew upgrade`, +# so nothing here is pinned to a Cellar version. +MACOS_ROBOT_TC = "/opt/homebrew/opt/aarch64-unknown-linux-gnu/toolchain" + +# Invoking gcc through the `opt` symlink makes it report system-header absolute +# paths two different ways: the sysroot auto-includes (e.g. stdc-predef.h) are +# realpath'd to the resolved Cellar dir, while the C++ stdlib headers are reported +# through the symlink. Whitelist both version-independent install roots so Bazel's +# absolute-path-inclusion check passes for either form and for any `brew`-installed +# version (builtin_include_directories are matched as path prefixes). +MACOS_ROBOT_TC_HEADER_ROOTS = [ + "/opt/homebrew/opt/aarch64-unknown-linux-gnu", # symlink-reported (libstdc++ headers) + "/opt/homebrew/Cellar/aarch64-unknown-linux-gnu", # realpath-reported (sysroot headers) +] cc_toolchain_config_k8_aarch64_linux( name = "gcc_macos_robot", - builtin_include_directories = [ - MACOS_ROBOT_TC + "/aarch64-unknown-linux-gnu/include/c++/15.2.0", - MACOS_ROBOT_TC + "/aarch64-unknown-linux-gnu/include/c++/15.2.0/aarch64-unknown-linux-gnu", - MACOS_ROBOT_TC + "/aarch64-unknown-linux-gnu/include/c++/15.2.0/backward", - MACOS_ROBOT_TC + "/lib/gcc/aarch64-unknown-linux-gnu/15.2.0/include", - MACOS_ROBOT_TC + "/lib/gcc/aarch64-unknown-linux-gnu/15.2.0/include-fixed", - MACOS_ROBOT_TC + "/aarch64-unknown-linux-gnu/include", - MACOS_ROBOT_TC + "/aarch64-unknown-linux-gnu/sysroot/usr/include", - ] + make_builtin_include_directories(), + builtin_include_directories = + MACOS_ROBOT_TC_HEADER_ROOTS + make_builtin_include_directories(), tool_paths = { "ar": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-ar", "cpp": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-cpp", diff --git a/src/toolchains/cc/wrapper/macos_robot_gcc b/src/toolchains/cc/wrapper/macos_robot_gcc index 21ae0d1b28..b030f6d7ab 100755 --- a/src/toolchains/cc/wrapper/macos_robot_gcc +++ b/src/toolchains/cc/wrapper/macos_robot_gcc @@ -1,6 +1,6 @@ #!/bin/bash --norc -# Wrapper around the prebuilt messense aarch64-unknown-linux-gnu GCC 15.2.0, +# Wrapper around the prebuilt messense aarch64-unknown-linux-gnu GCC 15.x, # applying two robot-deployment fix-ups (both no-ops for compile-only calls): # # * Static C++ runtime: this toolchain is GCC 15, newer than the robot's system @@ -12,7 +12,9 @@ # * `-fuse-ld=bfd`: messense ships only the BFD linker (no ld.gold), but the # shared cc_toolchain config adds `-fuse-ld=gold`; appending bfd wins. -TC=/opt/homebrew/Cellar/aarch64-unknown-linux-gnu/15.2.0/toolchain +# Homebrew's version-independent symlink (kept in sync with MACOS_ROBOT_TC in +# //toolchains/cc:BUILD), so this survives `brew upgrade` of the toolchain. +TC=/opt/homebrew/opt/aarch64-unknown-linux-gnu/toolchain args=() for a in "$@"; do From e44b5f825d6ba8b92f2e1cb5acec4b2972f6ef00 Mon Sep 17 00:00:00 2001 From: Eric Xiao Date: Thu, 25 Jun 2026 15:13:35 -0700 Subject: [PATCH 6/8] Print status message for setup --- environment_setup/setup_software_mac.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/environment_setup/setup_software_mac.sh b/environment_setup/setup_software_mac.sh index 11b975e1cf..acc3cc8cda 100755 --- a/environment_setup/setup_software_mac.sh +++ b/environment_setup/setup_software_mac.sh @@ -60,8 +60,6 @@ sudo pip install -r macos_requirements.txt print_status_msg "Done Setting Up Python Environment" -sudo ln -s /opt/tbotspython/bin/platformio /usr/local/bin/platformio - print_status_msg "Fetching game controller" install_gamecontroller $sys @@ -79,6 +77,10 @@ print_status_msg "Setting up cross compiler for robot software" install_cross_compiler $sys print_status_msg "Done setting up cross compiler for robot software" +print_status_msg "Setting Up PlatformIO" +sudo ln -s /opt/tbotspython/bin/platformio /usr/local/bin/platformio +print_status_msg "Done PlatformIO Setup" + print_status_msg "Setting up STM32 cross-compiler for motor board firmware" install_stm32_cross_compiler $sys print_status_msg "Done setting up STM32 cross-compiler" From 5d7d3f5d7d1063966caac11c5a2249499ca685dc Mon Sep 17 00:00:00 2001 From: Eric Xiao Date: Thu, 25 Jun 2026 15:22:20 -0700 Subject: [PATCH 7/8] Install cross compiler with brew dont need the util --- environment_setup/setup_software_mac.sh | 5 +---- environment_setup/util.sh | 20 ++++++++------------ 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/environment_setup/setup_software_mac.sh b/environment_setup/setup_software_mac.sh index acc3cc8cda..23658ddbfa 100755 --- a/environment_setup/setup_software_mac.sh +++ b/environment_setup/setup_software_mac.sh @@ -33,6 +33,7 @@ host_software_packages=( go@1.24 clang-format@20 sshpass # used to remotely ssh into robots via Ansible + messense/macos-cross-toolchains/aarch64-unknown-linux-gnu # raspberry pi cross compiler ) for pkg in "${host_software_packages[@]}"; do @@ -73,10 +74,6 @@ print_status_msg "Install clang-format" install_clang_format $sys print_status_msg "Done installing clang-format" -print_status_msg "Setting up cross compiler for robot software" -install_cross_compiler $sys -print_status_msg "Done setting up cross compiler for robot software" - print_status_msg "Setting Up PlatformIO" sudo ln -s /opt/tbotspython/bin/platformio /usr/local/bin/platformio print_status_msg "Done PlatformIO Setup" diff --git a/environment_setup/util.sh b/environment_setup/util.sh index 26ec64a9e7..8a006f6891 100755 --- a/environment_setup/util.sh +++ b/environment_setup/util.sh @@ -37,19 +37,15 @@ install_clang_format() { } install_cross_compiler() { - if is_darwin $1; then - brew install messense/macos-cross-toolchains/aarch64-unknown-linux-gnu - else - file_name=aarch64-tbots-linux-gnu-for-aarch64 - if is_x86 $1; then - file_name=aarch64-tbots-linux-gnu-for-x86 - fi - full_file_name=$file_name.tar.xz - wget https://raw.githubusercontent.com/UBC-Thunderbots/Software-External-Dependencies/refs/heads/main/toolchain/$full_file_name -O /tmp/tbots_download_cache/$full_file_name - tar -xf /tmp/tbots_download_cache/$full_file_name -C /tmp/tbots_download_cache/ - sudo mv /tmp/tbots_download_cache/aarch64-tbots-linux-gnu /opt/tbotspython - rm /tmp/tbots_download_cache/$full_file_name + file_name=aarch64-tbots-linux-gnu-for-aarch64 + if is_x86 $1; then + file_name=aarch64-tbots-linux-gnu-for-x86 fi + full_file_name=$file_name.tar.xz + wget https://raw.githubusercontent.com/UBC-Thunderbots/Software-External-Dependencies/refs/heads/main/toolchain/$full_file_name -O /tmp/tbots_download_cache/$full_file_name + tar -xf /tmp/tbots_download_cache/$full_file_name -C /tmp/tbots_download_cache/ + sudo mv /tmp/tbots_download_cache/aarch64-tbots-linux-gnu /opt/tbotspython + rm /tmp/tbots_download_cache/$full_file_name } install_gamecontroller () { From 3dca982dbb32698f252877a335cb3514e1905e47 Mon Sep 17 00:00:00 2001 From: Eric Xiao Date: Thu, 25 Jun 2026 15:29:42 -0700 Subject: [PATCH 8/8] Remove unnecessary comments --- src/extlibs/macos_robot_gcc.BUILD | 3 --- src/tbots.py | 4 ---- src/toolchains/cc/BUILD | 21 ++++----------------- 3 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/extlibs/macos_robot_gcc.BUILD b/src/extlibs/macos_robot_gcc.BUILD index 1b6f9567c4..3d70d0b5ea 100644 --- a/src/extlibs/macos_robot_gcc.BUILD +++ b/src/extlibs/macos_robot_gcc.BUILD @@ -1,8 +1,5 @@ package(default_visibility = ["//visibility:public"]) -# The prebuilt messense aarch64-unknown-linux-gnu toolchain (Homebrew), exposed -# as Bazel inputs so its binaries (gcc, ld, as, ...) are staged into the sandbox -# when cross-compiling robot firmware on macOS. filegroup( name = "everything", srcs = glob(["**"]), diff --git a/src/tbots.py b/src/tbots.py index abd9653f2e..b745d76482 100755 --- a/src/tbots.py +++ b/src/tbots.py @@ -221,10 +221,6 @@ def create_command(config: BuildConfig, extra_args: list[str]) -> list[str]: if condition: command += list(flag.value) - # `test --suite` resolves to //..., and `bazel test` would also try to BUILD - # every non-test target in that pattern — including robot firmware that only - # compiles with the cross toolchain (e.g. thunderloop pulls in linux/* headers - # that don't exist on the host). Restrict to test targets and their deps. if config.test_suite and config.action == ActionArgument.test: command += ["--build_tests_only"] diff --git a/src/toolchains/cc/BUILD b/src/toolchains/cc/BUILD index 1034be799c..a71dc2651e 100644 --- a/src/toolchains/cc/BUILD +++ b/src/toolchains/cc/BUILD @@ -281,32 +281,19 @@ toolchain( toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", ) -# Execution paths resolve through Homebrew's version-independent `opt` symlink -# (`brew --prefix aarch64-unknown-linux-gnu`), re-pointed on every `brew upgrade`, -# so nothing here is pinned to a Cellar version. MACOS_ROBOT_TC = "/opt/homebrew/opt/aarch64-unknown-linux-gnu/toolchain" -# Invoking gcc through the `opt` symlink makes it report system-header absolute -# paths two different ways: the sysroot auto-includes (e.g. stdc-predef.h) are -# realpath'd to the resolved Cellar dir, while the C++ stdlib headers are reported -# through the symlink. Whitelist both version-independent install roots so Bazel's -# absolute-path-inclusion check passes for either form and for any `brew`-installed -# version (builtin_include_directories are matched as path prefixes). -MACOS_ROBOT_TC_HEADER_ROOTS = [ - "/opt/homebrew/opt/aarch64-unknown-linux-gnu", # symlink-reported (libstdc++ headers) - "/opt/homebrew/Cellar/aarch64-unknown-linux-gnu", # realpath-reported (sysroot headers) -] - cc_toolchain_config_k8_aarch64_linux( name = "gcc_macos_robot", - builtin_include_directories = - MACOS_ROBOT_TC_HEADER_ROOTS + make_builtin_include_directories(), + builtin_include_directories = [ + "/opt/homebrew/opt/aarch64-unknown-linux-gnu", # symlink-reported (libstdc++ headers) + "/opt/homebrew/Cellar/aarch64-unknown-linux-gnu", # realpath-reported (sysroot headers) + ] + make_builtin_include_directories(), tool_paths = { "ar": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-ar", "cpp": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-cpp", # messense ships no dwp; point at gcc (unused without fission). "dwp": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-gcc", - # wrapper forces -fuse-ld=bfd (messense has no gold linker). "gcc": "wrapper/macos_robot_gcc", "gcov": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-gcov", "ld": MACOS_ROBOT_TC + "/bin/aarch64-unknown-linux-gnu-ld",