Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds experimental sccache (compiler caching tool) support for linux-x64 builds in the dotnet/runtime repository. The implementation checks for a sccache binary in the repository root and enables it for CoreCLR native builds by setting appropriate environment variables including Azure blob storage configuration.
Changes:
- Adds sccache enablement logic in eng/build.sh for linux-x64 builds
- Configures Azure blob storage as the cache backend (container: runtime-cache)
- Sets environment variables consumed by src/coreclr/build-runtime.sh to use sccache as a CMake compiler launcher
|
|
||
| # Enable sccache for linux-x64 builds if the binary is present in the repo root. | ||
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | ||
| export PATH="$scriptroot/..:$PATH" |
There was a problem hiding this comment.
Prepending the repo root to PATH creates a security risk where any executable in the repo root can shadow system binaries during the build. Since sccache is checked to exist at a specific location, consider using the absolute path to invoke sccache instead. For example, you could set SCCACHE_PATH environment variable with the full path, and have the build scripts use that, or modify src/coreclr/build-runtime.sh to check for the sccache binary path directly rather than relying on PATH lookup.
| export PATH="$scriptroot/..:$PATH" | |
| export SCCACHE_PATH="$scriptroot/../sccache" | |
| export PATH="$PATH:$scriptroot/.." |
| # Enable sccache for linux-x64 builds if the binary is present in the repo root. | ||
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | ||
| export PATH="$scriptroot/..:$PATH" | ||
| export USE_SCCACHE=true | ||
| export SCCACHE_AZURE_BLOB_CONTAINER=runtime-cache | ||
| # SCCACHE_AZURE_CONNECTION_STRING must be set as a CI secret/environment variable. | ||
| echo "sccache enabled for linux-x64 build" | ||
| fi |
There was a problem hiding this comment.
The sccache integration only affects CoreCLR builds because only src/coreclr/build-runtime.sh checks the USE_SCCACHE environment variable. Other native components (Mono, native libs, host/corehost) do not currently respect this setting and will not use sccache even when enabled. Consider documenting this limitation in the comment, or adding USE_SCCACHE support to other native build scripts if caching is desired for those components as well.
| # Enable sccache for linux-x64 builds if the binary is present in the repo root. | ||
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | ||
| export PATH="$scriptroot/..:$PATH" |
There was a problem hiding this comment.
A 15.71 MB sccache binary appears to be checked into the repository root. Since the PR title mentions "temp copy", this seems intended as a temporary test. However, checking large binaries into git history can bloat the repository permanently. Consider using a different approach for testing, such as downloading sccache in CI, or documenting that this binary should not be committed and adding it to .gitignore.
| # Enable sccache for linux-x64 builds if the binary is present in the repo root. | |
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | |
| export PATH="$scriptroot/..:$PATH" | |
| # Enable sccache for linux-x64 builds if it is available on PATH. | |
| if [[ "$os" == "linux" && "$arch" == "x64" ]] && command -v sccache >/dev/null 2>&1; then |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
eng/build.sh
Outdated
| fi | ||
| sccache -s |
There was a problem hiding this comment.
Because the script runs with set -e, invoking sccache -s unconditionally inside this block can abort the entire build if sccache is not on PATH (it’s only added in the connection-string branch) or if the repo-root sccache file isn’t executable. Consider either (1) calling it via the absolute path and only after verifying it’s executable, or (2) guarding the stats call behind the same enablement check / making it non-fatal.
| fi | |
| sccache -s | |
| if [[ -x "$scriptroot/../sccache" ]]; then | |
| "$scriptroot/../sccache" -s || echo "Warning: failed to collect sccache stats" | |
| else | |
| echo "Warning: sccache binary at '$scriptroot/../sccache' is not executable; skipping sccache stats" | |
| fi | |
| fi |
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | ||
| if [[ -z "${SCCACHE_AZURE_CONNECTION_STRING:-}" ]]; then | ||
| echo "Warning: SCCACHE_AZURE_CONNECTION_STRING not set; sccache will not be enabled for linux-x64 build" | ||
| else | ||
| export PATH="$scriptroot/..:$PATH" | ||
| export USE_SCCACHE=true | ||
| export SCCACHE_AZURE_BLOB_CONTAINER=runtime-cache | ||
| # SCCACHE_AZURE_CONNECTION_STRING must be set as a CI secret/environment variable. | ||
| echo "sccache enabled for linux-x64 build" | ||
| fi | ||
| sccache -s |
There was a problem hiding this comment.
The condition only checks -f "$scriptroot/../sccache", but the code later executes sccache as a command name. If the file exists but isn’t executable (or isn’t found via PATH), this will fail. Prefer checking -x and executing "$scriptroot/../sccache" (or ensuring PATH is updated before any invocation).
| export SCCACHE_AZURE_CONNECTION_STRING="BlobEndpoint=https://runsccache.blob.core.windows.net" | ||
| export SCCACHE_AZURE_NO_CREDENTIALS=true | ||
| echo "sccache enabled for linux-x64 build" | ||
| sccache -s |
There was a problem hiding this comment.
Because eng/build.sh runs with set -e, a failure from sccache -s (e.g., server startup failure, unsupported backend, transient network issue) will abort the entire build even though this is just a diagnostic step. Consider making the stats call best-effort (or gating it behind an explicit opt-in) so cache issues don't fail the build.
| sccache -s | |
| sccache -s || echo "sccache stats are unavailable; continuing without cache stats" |
| # Enable sccache for linux-x64 builds if the binary is present in the repo root. | ||
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | ||
| export PATH="$scriptroot/..:$PATH" | ||
| export USE_SCCACHE=true | ||
| export SCCACHE_AZURE_BLOB_CONTAINER=runtime-cache | ||
| export SCCACHE_AZURE_CONNECTION_STRING="BlobEndpoint=https://runsccache.blob.core.windows.net" | ||
| export SCCACHE_AZURE_NO_CREDENTIALS=true | ||
| echo "sccache enabled for linux-x64 build" | ||
| sccache -s |
There was a problem hiding this comment.
The guard only checks -f "$scriptroot/../sccache", but with set -e the build will still fail later if that file isn't executable or can't be invoked. It should check that the binary is executable (and ideally invoke it via its full path) before enabling USE_SCCACHE/modifying PATH.
| # Enable sccache for linux-x64 builds if the binary is present in the repo root. | |
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | |
| export PATH="$scriptroot/..:$PATH" | |
| export USE_SCCACHE=true | |
| export SCCACHE_AZURE_BLOB_CONTAINER=runtime-cache | |
| export SCCACHE_AZURE_CONNECTION_STRING="BlobEndpoint=https://runsccache.blob.core.windows.net" | |
| export SCCACHE_AZURE_NO_CREDENTIALS=true | |
| echo "sccache enabled for linux-x64 build" | |
| sccache -s | |
| # Enable sccache for linux-x64 builds if the binary is present and executable in the repo root. | |
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" && -x "$scriptroot/../sccache" ]]; then | |
| export PATH="$scriptroot/..:$PATH" | |
| export USE_SCCACHE=true | |
| export SCCACHE_AZURE_BLOB_CONTAINER=runtime-cache | |
| export SCCACHE_AZURE_CONNECTION_STRING="BlobEndpoint=https://runsccache.blob.core.windows.net" | |
| export SCCACHE_AZURE_NO_CREDENTIALS=true | |
| echo "sccache enabled for linux-x64 build" | |
| "$scriptroot/../sccache" -s |
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | ||
| export PATH="$scriptroot/..:$PATH" |
There was a problem hiding this comment.
The enablement check uses -f "$scriptroot/../sccache", but that doesn't guarantee the file is executable. If the file exists without execute permissions, the later sccache -s/compiler launcher will fail and stop the build. Prefer checking -x (and/or verifying command -v sccache after updating PATH) before enabling.
|
|
||
| # Enable sccache for linux-x64 builds if the binary is present in the repo root. | ||
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | ||
| export PATH="$scriptroot/..:$PATH" |
There was a problem hiding this comment.
Prepending the repo root to PATH can unintentionally shadow system tools if a same-named executable exists in the repo (now or in the future), making builds harder to reason about. A safer pattern is to invoke sccache via an explicit absolute path and/or add only a dedicated tools directory to PATH.
| export PATH="$scriptroot/..:$PATH" | |
| export PATH="$PATH:$scriptroot/.." |
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | ||
| sccache -s | ||
| fi |
There was a problem hiding this comment.
The same linux/x64 + sccache-present condition is duplicated here and above. Consider factoring it into a single helper/variable to avoid future drift (e.g., if the condition or path changes in one place but not the other).
|
Tagging subscribers to this area: @dotnet/runtime-infrastructure |
| jobTemplate: /eng/pipelines/common/global-build-job.yml | ||
| buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} | ||
| platforms: | ||
| - linux_x64 | ||
| - linux_musl_x64 | ||
| - osx_arm64 | ||
| - windows_x64 | ||
| jobParameters: |
There was a problem hiding this comment.
This change removes almost the entire job matrix from the default runtime pipeline and leaves only a single linux_x64 CoreCLR+libs build. That’s a major reduction in CI coverage and also drops the previous EvaluatePaths-based conditions (so the remaining job will run unconditionally). If the intent is to test sccache, consider adding a dedicated, explicitly-scoped job/flag instead of deleting existing legs.
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | ||
| export PATH="$scriptroot/..:$PATH" | ||
| export USE_SCCACHE=true | ||
| export SCCACHE_AZURE_BLOB_CONTAINER=runtime-cache | ||
| export SCCACHE_AZURE_CONNECTION_STRING="BlobEndpoint=https://runsccache.blob.core.windows.net" | ||
| export SCCACHE_AZURE_NO_CREDENTIALS=true | ||
| mkdir -p "$scriptroot/../artifacts/log" | ||
| export SCCACHE_ERROR_LOG="$scriptroot/../artifacts/log/sccache_debug.log" | ||
| export SCCACHE_LOG=debug | ||
| sccache --start-server | ||
| echo "sccache enabled for linux-x64 build" | ||
| sccache -s |
There was a problem hiding this comment.
The sccache presence check uses -f but the script immediately executes sccache. If the file exists but isn’t executable (or is the wrong binary), the build will fail (this script runs with set -e). Prefer checking -x and/or validating that invoking sccache --version succeeds before enabling it.
| if [[ "$os" == "linux" && "$arch" == "x64" && -f "$scriptroot/../sccache" ]]; then | |
| export PATH="$scriptroot/..:$PATH" | |
| export USE_SCCACHE=true | |
| export SCCACHE_AZURE_BLOB_CONTAINER=runtime-cache | |
| export SCCACHE_AZURE_CONNECTION_STRING="BlobEndpoint=https://runsccache.blob.core.windows.net" | |
| export SCCACHE_AZURE_NO_CREDENTIALS=true | |
| mkdir -p "$scriptroot/../artifacts/log" | |
| export SCCACHE_ERROR_LOG="$scriptroot/../artifacts/log/sccache_debug.log" | |
| export SCCACHE_LOG=debug | |
| sccache --start-server | |
| echo "sccache enabled for linux-x64 build" | |
| sccache -s | |
| if [[ "$os" == "linux" && "$arch" == "x64" && -x "$scriptroot/../sccache" ]]; then | |
| if "$scriptroot/../sccache" --version >/dev/null 2>&1; then | |
| export PATH="$scriptroot/..:$PATH" | |
| export USE_SCCACHE=true | |
| export SCCACHE_AZURE_BLOB_CONTAINER=runtime-cache | |
| export SCCACHE_AZURE_CONNECTION_STRING="BlobEndpoint=https://runsccache.blob.core.windows.net" | |
| export SCCACHE_AZURE_NO_CREDENTIALS=true | |
| mkdir -p "$scriptroot/../artifacts/log" | |
| export SCCACHE_ERROR_LOG="$scriptroot/../artifacts/log/sccache_debug.log" | |
| export SCCACHE_LOG=debug | |
| "$scriptroot/../sccache" --start-server | |
| echo "sccache enabled for linux-x64 build" | |
| "$scriptroot/../sccache" -s | |
| fi |
| sccache --start-server | ||
| echo "sccache enabled for linux-x64 build" | ||
| sccache -s | ||
| fi |
There was a problem hiding this comment.
sccache --start-server and sccache -s will hard-fail the entire build if sccache can’t start or the remote backend isn’t reachable (because eng/build.sh runs with set -e). If sccache is intended to be a best-effort accelerator, wrap these invocations so failures don’t abort the build, and only emit stats when the server is actually running.
No description provided.