xref: /aosp_15_r20/external/executorch/.ci/scripts/setup-macos.sh (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1#!/bin/bash
2# Copyright (c) Meta Platforms, Inc. and affiliates.
3# All rights reserved.
4#
5# This source code is licensed under the BSD-style license found in the
6# LICENSE file in the root directory of this source tree.
7
8set -exu
9
10# shellcheck source=/dev/null
11source "$(dirname "${BASH_SOURCE[0]}")/utils.sh"
12
13BUILD_TOOL=$1
14if [[ -z "${BUILD_TOOL:-}" ]]; then
15  echo "Missing build tool (require buck2 or cmake), exiting..."
16  exit 1
17else
18  echo "Setup MacOS for ${BUILD_TOOL} ..."
19fi
20
21install_buck() {
22  if ! command -v zstd &> /dev/null; then
23    brew install zstd
24  fi
25
26  if ! command -v curl &> /dev/null; then
27    brew install curl
28  fi
29
30  pushd .ci/docker
31  # TODO(huydo): This is a one-off copy of buck2 2024-05-15 to unblock Jon and
32  # re-enable ShipIt. It’s not ideal that upgrading buck2 will require a manual
33  # update the cached binary on S3 bucket too. Let me figure out if there is a
34  # way to correctly implement the previous setup of installing a new version of
35  # buck2 only when it’s needed. AFAIK, the complicated part was that buck2
36  # --version doesn't say anything w.r.t its release version, i.e. 2024-05-15.
37  # See D53878006 for more details.
38  #
39  # If you need to upgrade buck2 version on S3, please reach out to Dev Infra
40  # team for help.
41  BUCK2_VERSION=$(cat ci_commit_pins/buck2.txt)
42  BUCK2=buck2-aarch64-apple-darwin-${BUCK2_VERSION}.zst
43  curl -s "https://ossci-macos.s3.amazonaws.com/${BUCK2}" -o "${BUCK2}"
44
45  zstd -d "${BUCK2}" -o buck2
46
47  chmod +x buck2
48  mv buck2 /opt/homebrew/bin
49
50  rm "${BUCK2}"
51  popd
52}
53
54function write_sccache_stub() {
55  OUTPUT=$1
56  BINARY=$(basename "${OUTPUT}")
57
58  printf "#!/bin/sh\nif [ \$(ps auxc \$(ps auxc -o ppid \$\$ | grep \$\$ | rev | cut -d' ' -f1 | rev) | tr '\\\\n' ' ' | rev | cut -d' ' -f2 | rev) != sccache ]; then\n  exec sccache %s \"\$@\"\nelse\n  exec %s \"\$@\"\nfi" "$(which "${BINARY}")" "$(which "${BINARY}")" > "${OUTPUT}"
59  chmod a+x "${OUTPUT}"
60}
61
62install_sccache() {
63  # Use existing S3 cache bucket for self-hosted MacOS runner
64  export SCCACHE_BUCKET=ossci-compiler-cache-circleci-v2
65  export SCCACHE_S3_KEY_PREFIX=executorch
66  export SCCACHE_IDLE_TIMEOUT=0
67  export SCCACHE_ERROR_LOG=/tmp/sccache_error.log
68  export RUST_LOG=sccache::server=error
69
70  SCCACHE_PATH="/usr/local/bin"
71  # NB: The function is adopted from PyTorch MacOS build workflow
72  # https://github.com/pytorch/pytorch/blob/main/.github/workflows/_mac-build.yml
73  if ! command -v sccache &> /dev/null; then
74    sudo curl --retry 3 "https://s3.amazonaws.com/ossci-macos/sccache/sccache-v0.4.1-${RUNNER_ARCH}" --output "${SCCACHE_PATH}/sccache"
75    sudo chmod +x "${SCCACHE_PATH}/sccache"
76  fi
77
78  export PATH="${SCCACHE_PATH}:${PATH}"
79
80  # Create temp directory for sccache shims if TMP_DIR doesn't exist
81  if [ -z "${TMP_DIR:-}" ]; then
82    TMP_DIR=$(mktemp -d)
83    trap 'rm -rfv ${TMP_DIR}' EXIT
84    export PATH="${TMP_DIR}:$PATH"
85  fi
86
87  write_sccache_stub "${TMP_DIR}/c++"
88  write_sccache_stub "${TMP_DIR}/cc"
89  write_sccache_stub "${TMP_DIR}/clang++"
90  write_sccache_stub "${TMP_DIR}/clang"
91
92  sccache --zero-stats || true
93}
94
95# This is the same rpath fix copied from PyTorch macos setup script
96# https://github.com/pytorch/pytorch/blob/main/.ci/pytorch/macos-common.sh
97print_cmake_info() {
98  CMAKE_EXEC=$(which cmake)
99  echo "$CMAKE_EXEC"
100
101  export CMAKE_EXEC
102  # Explicitly add conda env lib folder to cmake rpath to address the flaky issue
103  # where cmake dependencies couldn't be found. This seems to point to how conda
104  # links $CMAKE_EXEC to its package cache when cloning a new environment
105  install_name_tool -add_rpath @executable_path/../lib "${CMAKE_EXEC}" || true
106  # Adding the rpath will invalidate cmake signature, so signing it again here
107  # to trust the executable. EXC_BAD_ACCESS (SIGKILL (Code Signature Invalid))
108  # with an exit code 137 otherwise
109  codesign -f -s - "${CMAKE_EXEC}" || true
110}
111
112setup_macos_env_variables() {
113  CMAKE_PREFIX_PATH=$(python -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())')
114  export CMAKE_PREFIX_PATH
115}
116
117setup_macos_env_variables
118# NB: we need buck2 in all cases because cmake build also depends on calling
119# buck2 atm
120install_buck
121install_pip_dependencies
122
123# TODO(huydhn): Unlike our self-hosted runner, GitHub runner doesn't have access
124# to our infra, so compiler caching needs to be setup differently using GitHub
125# cache. However, I need to figure out how to set that up for Nova MacOS job
126if [[ -z "${GITHUB_RUNNER:-}" ]]; then
127  install_sccache
128fi
129
130print_cmake_info
131install_executorch
132build_executorch_runner "${BUILD_TOOL}"
133