279 lines · 10.8 KB · Text
RawDownload
#!/usr/bin/env bash set -euo pipefailsource script/lib/blob-store.sh export ZED_BUNDLE=trueexport MACOSX_DEPLOYMENT_TARGET=10.15.7# Deal with versions of macOS that don't include libstdc++ headersexport CXXFLAGS="-stdlib=libc++"# Version of Git to Bundle with Zed from github.com/desktop/dugite-nativeGIT_VERSION="v2.43.3"GIT_VERSION_SHA="fa29823" function help_info() {    echo "Usage: ${0##*/} [options] [bundle_name]"    echo "Build the application bundle for macOS."    echo "Options:"    echo "  -d    Compile in debug mode"    echo "  -l    Compile for local architecture only."    echo "  -o    Open dir with the resulting DMG or launch the app itself in local mode."    echo "  -i    Install the resulting DMG into /Applications in local mode. Noop without -l."    echo "  -h    Display this help and exit."} function handle_args {    build_flag="--release"    target_dir="release"    # This gets exported because we need to handle local/full differently in notarize-mac script    export local_only=false     while getopts 'dloih' flag    do        case "${flag}" in            o) open_result=true;;            d)                export CARGO_INCREMENTAL=true                export CARGO_BUNDLE_SKIP_BUILD=true                build_flag="";                target_dir="debug"                ;;            l)                export CARGO_INCREMENTAL=true                export CARGO_BUNDLE_SKIP_BUILD=true                export local_only=true                ;;            i) local_install=true;;            h)                help_info                exit 0                ;;            *)                help_info                exit 1                ;;        esac    done    shift $((OPTIND-1))     bundle_name=${1:-}    # If bundle_name doesn't end in .app, append it    if [[ "$bundle_name" != *.app ]]; then        bundle_name="$bundle_name.app"    fi     if [ "$local_only" = false ] && ! command -v parallel &> /dev/null; then        echo "GNU Parallel is not installed. Please install it to continue."        exit 1    fi} function setup_cargo_bundle() {    cargo_bundle_version=$(cargo -q bundle --help 2>&1 | head -n 1 || echo "")    if [ "$cargo_bundle_version" != "cargo-bundle v0.6.0-zed" ]; then        cargo install cargo-bundle --git https://github.com/zed-industries/cargo-bundle.git --branch zed-deploy    fi} function build() {    if [ "$local_only" = true ]; then        echo "Building for local target only."        cargo build ${build_flag} --package zed --package cli --package remote_server    else        echo "Compiling zed binaries"        cargo build ${build_flag} --package zed --package cli --target aarch64-apple-darwin --target x86_64-apple-darwin        # Build remote_server in separate invocation to prevent feature unification from other crates        # from influencing dynamic libraries required by it.        cargo build ${build_flag} --package remote_server     --target aarch64-apple-darwin --target x86_64-apple-darwin    fi     echo "Creating application bundle"    pushd crates/zed     channel=$(<RELEASE_CHANNEL)    cp Cargo.toml Cargo.toml.backup    sed -i.backup \        "s/package.metadata.bundle-${channel}/package.metadata.bundle/" \        Cargo.toml    if [ "$local_only" = true ]; then        app_path=$(cargo bundle ${build_flag} --select-workspace-root | xargs)    else        app_path_x64=$(cargo bundle ${build_flag} --target x86_64-apple-darwin --select-workspace-root | xargs)        app_path_aarch64=$(cargo bundle ${build_flag} --target aarch64-apple-darwin --select-workspace-root | xargs)        app_path=$app_path_x64    fi     # If bundle_name is not set or empty, use the basename of $app_path    if [ -z "$bundle_name" ]; then        bundle_name=$(basename "$app_path")    fi     mv Cargo.toml.backup Cargo.toml    popd    echo "Bundled ${app_path}"} # Download and unpack a specific git versionfunction download_and_unpack() {    local url=$1    local path_to_unpack=$2    local target_path=$3     temp_dir=$(mktemp -d)     if ! command -v curl &> /dev/null; then        echo "curl is not installed. Please install curl to continue."        exit 1    fi     curl --silent --fail --location "$url" | tar -xvz -C "$temp_dir" -f - "$path_to_unpack"     mv "$temp_dir/$path_to_unpack" "$target_path"     rm -rf "$temp_dir"} # Downloadfunction download_git() {    local architecture=$1    local target_binary=$2     tmp_dir=$(mktemp -d)    pushd "$tmp_dir"     case "$architecture" in        aarch64-apple-darwin)            download_and_unpack "https://github.com/desktop/dugite-native/releases/download/${GIT_VERSION}/dugite-native-${GIT_VERSION}-${GIT_VERSION_SHA}-macOS-arm64.tar.gz" bin/git ./git            ;;        x86_64-apple-darwin)            download_and_unpack "https://github.com/desktop/dugite-native/releases/download/${GIT_VERSION}/dugite-native-${GIT_VERSION}-${GIT_VERSION_SHA}-macOS-x64.tar.gz" bin/git ./git            ;;        universal)            download_and_unpack "https://github.com/desktop/dugite-native/releases/download/${GIT_VERSION}/dugite-native-${GIT_VERSION}-${GIT_VERSION_SHA}-macOS-arm64.tar.gz" bin/git ./git_arm64            download_and_unpack "https://github.com/desktop/dugite-native/releases/download/${GIT_VERSION}/dugite-native-${GIT_VERSION}-${GIT_VERSION_SHA}-macOS-x64.tar.gz" bin/git ./git_x64            lipo -create ./git_arm64 ./git_x64 -output ./git            ;;        *)            echo "Unsupported architecture: $architecture"            exit 1            ;;    esac     popd     mv "${tmp_dir}/git" "${target_binary}"    rm -rf "$tmp_dir"} # Prepare binaries for a specific architecturefunction prepare_binaries() {    local architecture=$1    local this_app_path=$2     echo "Unpacking dSYMs for $architecture"    if ! dsymutil --flat "target/${architecture}/${target_dir}/Zed" 2> target/dsymutil.log; then        echo "dsymutil failed"        cat target/dsymutil.log        exit 1    fi    version="$(cargo metadata --no-deps --manifest-path crates/zed/Cargo.toml --offline --format-version=1 | jq -r '.packages | map(select(.name == "zed"))[0].version')"    if [ "$channel" == "nightly" ]; then        version="$version-$(git rev-parse --short HEAD)"    fi     echo "Removing existing gzipped dSYMs for $architecture"    rm -f "target/${architecture}/${target_dir}/Zed.dwarf.gz"     echo "Gzipping dSYMs for $architecture"    gzip "target/${architecture}/${target_dir}/Zed.dwarf"     echo "Uploading dSYMs for $architecture"    # FIXME: Uncomment this back.    # upload_to_blob_store_public \    #     "zed-debug-symbols" \    #     "target/${architecture}/${target_dir}/Zed.dwarf.gz" \    #     "$channel/Zed-$version-${architecture}.dwarf.gz"     cp "target/${architecture}/${target_dir}/zed" "${this_app_path}/Contents/MacOS/zed"    cp "target/${architecture}/${target_dir}/cli" "${this_app_path}/Contents/MacOS/cli"} function local_run() {    version_info=$(rustc --version --verbose)    host_line=$(echo "$version_info" | grep host)    local_target_triple=${host_line#*: }    # script/notarize-mac sign_app_binaries <bundle_name> <target_dir> <channel> <app_path> <architecture> <architecture_dir>    ./script/notarize-mac sign_app_binaries "$bundle_name" "$target_dir" "$channel" "$app_path" "$local_target_triple" "$local_target_triple"    ./script/notarize-mac sign_binary "target/release/remote_server"    if [ "$local_install" = true ]; then        rm -rf "/Applications/$bundle_name"        mv "$app_path" "/Applications/$bundle_name"        echo "Installed application bundle: /Applications/$bundle_name"    fi    if [ "$open_result" = true ]; then        open "$app_path"    fi} function full_run() {    echo "Creating aarch64 app bundle..."    prepare_binaries "aarch64-apple-darwin" "$app_path_aarch64"    download_git aarch64-apple-darwin "${app_path_aarch64}/Contents/MacOS/git"     echo "Creating aarch64 x86_64 bundle..."    prepare_binaries "x86_64-apple-darwin" "$app_path_x64"    download_git x86_64-apple-darwin "${app_path_x64}/Contents/MacOS/git"     echo "Creating universal app bundle..."    cp -R "$app_path_x64" target/release/    app_path=target/release/$(basename "$app_path_x64")    lipo -create \        "target/x86_64-apple-darwin/${target_dir}/zed" \        "target/aarch64-apple-darwin/${target_dir}/zed" \        -output "${app_path}/Contents/MacOS/zed"    lipo -create \        "target/x86_64-apple-darwin/${target_dir}/cli" \        "target/aarch64-apple-darwin/${target_dir}/cli" \        -output "${app_path}/Contents/MacOS/cli"    download_git universal "${app_path}/Contents/MacOS/git"     echo "Beginning parallel work..."     # Piping output through these will add a prefix and colorize the line    prefix1="sed 's/^/\x1b[35m[Bundle aarch64] \x1b[0m/'" # magenta    prefix2="sed 's/^/\x1b[34m[Bundle x86_x64] \x1b[0m/'" # blue    prefix3="sed 's/^/\x1b[36m[Bundle Combine] \x1b[0m/'" # cyan    prefix4="sed 's/^/\x1b[33m[Remote aarch64] \x1b[0m/'" # yellow    prefix5="sed 's/^/\x1b[32m[Remote x86_x64] \x1b[0m/'" # green      # These each take approximately 4minutes. Use GNU Parallel to submit them simultaneously.    # Output is interlaced between all tasks, so add unique prefixes (sed) and line numbers (nl)    # to preserve de-interlacing if necessary e.g. Copy output to clipboard and then: pbpaste | sort | pbcopy    # Parallel inherits PATH, SHELL, HOME, LANG, LC_* environment variables by default.    export PARALLEL_CITATION_SILENT=1    parallel --jobs 8 --halt soon,fail=1 --line-buffer \        --env local_only \        --env MACOS_CERTIFICATE \        --env MACOS_CERTIFICATE_PASSWORD \        --env APPLE_NOTARIZATION_USERNAME \        --env APPLE_NOTARIZATION_PASSWORD \        ::: \        "./script/notarize-mac sign_app_binaries \"$bundle_name\" \"$target_dir\" \"$channel\" \"$app_path_aarch64\" aarch64-apple-darwin  aarch64-apple-darwin | nl | $prefix1" \        "./script/notarize-mac sign_app_binaries \"$bundle_name\" \"$target_dir\" \"$channel\" \"$app_path_x64\"     x86_64-apple-darwin   x86_64-apple-darwin  | nl | $prefix2" \        "./script/notarize-mac sign_app_binaries \"$bundle_name\" \"$target_dir\" \"$channel\" \"$app_path\"         universal             .                    | nl | $prefix3" \        "./script/notarize-mac sign_binary target/aarch64-apple-darwin/release/remote_server | nl | $prefix4"        "./script/notarize-mac sign_binary target/x86_64-apple-darwin/release/remote_server | nl | $prefix5" \     gzip --stdout --best target/x86_64-apple-darwin/release/remote_server > target/zed-remote-server-macos-x86_64.gz    gzip --stdout --best target/aarch64-apple-darwin/release/remote_server > target/zed-remote-server-macos-aarch64.gz} handle_args "$@"setup_cargo_bundlebuildif [ "$local_only" = true ]; then  local_runelse  full_runfi