Skip to content

Default to ninja for faster builds (mac & linux) - #124041

Merged
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build
Feb 8, 2026
Merged

Default to ninja for faster builds (mac & linux)#124041
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build

Conversation

@steveisok

@steveisoksteveisok commented Feb 5, 2026

Copy link
Copy Markdown
Member

Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg 654s vs 718s per build). This change defaults to using ninja for both MacOS and Linux.

Changes:

  • eng/build.sh: default to using ninja
  • eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out

Users can opt out with --ninja false (or -ninja false for native builds).

Contributes to #54022 (#54022)

Benchmarking showed ninja provides ~8.8% faster builds on macOS
(avg 654s vs 718s per build). This change defaults to using ninja
when the host OS is macOS.
Changes:
- eng/build.sh: Default --ninja true on macOS, track explicit user override
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out
Users can opt out with --ninja false (or -ninja false for native builds).
@steveisok
steveisok requested review from a team and CopilotFebruary 5, 2026 13:01
@github-actionsgithub-actionsBot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves macOS build performance by defaulting to the Ninja build system instead of Make, achieving approximately 8.8% faster build times (654s vs 718s average). The change is opt-out via --ninja false to maintain flexibility.

Changes:

  • Default ninja build system on macOS for improved performance
  • Add explicit flag tracking to prevent overriding user preferences
  • Update help text to document the new default and opt-out mechanism

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

FileDescription
eng/build.shAdds macOS-specific ninja default with tracking to avoid overriding explicit user settings
eng/native/build-commons.shSets ninja as default on macOS and enhances -ninja flag to accept true/false values

Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
@jkotas

Copy link
Copy Markdown
Member

docs\workflow\requirements\macos-requirements.md needs to be updated - ninja is no longer optional by default after this change.

@jkotasjkotas added area-Infrastructure and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Feb 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

@am11

am11 commented Feb 5, 2026

Copy link
Copy Markdown
Member

Windows also defaults to ninja. Maybe we should flip the switch: --skipninja and cherry-pick installation script change a2b49ec. It's a tiny script dependency considering everything else required by the build.

@jkotas

Copy link
Copy Markdown
Member

--skipninja

Nit: Avoiding negations in names is a generally better UX design. I like -ninja false better than -skipninja.

- Use single useNinja variable in eng/build.sh instead of tracking explicit-ness
- Initialize __UseNinja=0 in build-commons.sh, then override to 1 on macOS
- Remove __UseNinja=0 initialization from build-runtime.sh and tests/build.sh
so the macOS default takes effect
- Update macOS requirements docs to reflect ninja is now default
@jkoritzinsky

Copy link
Copy Markdown
Member

I was just talking with @agocke about requiring Ninja on macOS to make it easier to maintain our Swift usage (as CMake only supports Swift with Ninja and XCode) so we don't need to manually invoke the Swift compiler and do our own object file handling.

I think this is a great first step in that direction!

Comment threadeng/build.sh Outdated
Based on PR feedback, default to using Ninja for native builds on any
Unix platform where ninja is installed, rather than only on macOS.
This aligns with the Mono subtree behavior and provides faster builds
when ninja is available.
CopilotAI review requested due to automatic review settings February 5, 2026 22:48
@steveisoksteveisok changed the title Default to ninja on macOS for faster buildsDefault to ninja if installed for faster builds (mac & linux)Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/build.sh Outdated
Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
Comment threadeng/build.sh Outdated
@am11

am11 commented Feb 7, 2026

Copy link
Copy Markdown
Member

It was implemented that way when you first asked, but later reverted due to concerns about build determinism (see #124041 (comment)). I believe build determinism is a separate issue, and Ninja by itself cannot meaningfully affect it: even small differences in toolchain versions or machine environments prevent bit-for-bit identical outputs. Docker largely addresses this on Linux by fixing the environment, but on other platforms there are more fundamental sources of nondeterminism to address, well beyond what Ninja alone can affect.

@steveisok

Copy link
Copy Markdown
MemberAuthor

Ok, @am11 votes for use if installed. @jkoritzinsky you appear to be as well.

@jkotas?

I don't have a strong opinion, but if I had to pick, I'd choose ninja by default and only opt out explicitly.

@jkotas

Copy link
Copy Markdown
Member

numbers for the build time improvement on Linux

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

I'd choose ninja by default

Yes, I think we should have it on by default for macOS and Linux at least, so that folks do not accidentally forget to install it and get worse build times.

other platforms

I am fine with off by default (or automatic light up) for other platforms if it helps.

Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
@jkoritzinsky

Copy link
Copy Markdown
Member

I'm okay with on-by-default as well. I just figured that use-if-available is an easier change to accept if we weren't sure if we wanted to switch.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
CopilotAI review requested due to automatic review settings February 7, 2026 19:16

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/native/build-commons.sh
Comment threadeng/build.sh
Comment threadeng/build.sh
Comment threadeng/native/build-commons.sh
When -ninja was followed by another flag (e.g. --ninja --subset clr),
the parser would consume the next argument as a ninja value and break
argument parsing. Now check if $2 starts with '-' before treating it
as a true/false value.
@steveisok

Copy link
Copy Markdown
MemberAuthor

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

Ran on WSL for a 4 hour loop. 12% better there on average.

Comment threaddocs/workflow/requirements/macos-requirements.md
CopilotAI review requested due to automatic review settings February 8, 2026 04:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@jkotasjkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@wfurt

wfurt commented Feb 9, 2026

Copy link
Copy Markdown
Member

This broke runtime-libraries enterprise-linux (that was skipped on the PR). #124187
It would be nice if it falls back automatically if Ninja is not present.

iremyux pushed a commit to iremyux/dotnet-runtime that referenced this pull request Mar 2, 2026
Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg
654s vs 718s per build). This change defaults to using ninja for both
MacOS and Linux.
Changes:
- eng/build.sh: default to using ninja
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false
opt-out
Users can opt out with --ninja false (or -ninja false for native
builds).
Contributes to dotnet#54022
(dotnet#54022)
---------
Co-authored-by: Steve Pfister <steve.pfister@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Mar 12, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants

@steveisok@jkotas@am11@jkoritzinsky@wfurt@janvorli
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Default to ninja for faster builds (mac & linux) by steveisok · Pull Request #124041 · dotnet/runtime · GitHub
Skip to content

Default to ninja for faster builds (mac & linux) - #124041

Merged
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build
Feb 8, 2026
Merged

Default to ninja for faster builds (mac & linux)#124041
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build

Conversation

@steveisok

@steveisoksteveisok commented Feb 5, 2026

Copy link
Copy Markdown
Member

Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg 654s vs 718s per build). This change defaults to using ninja for both MacOS and Linux.

Changes:

  • eng/build.sh: default to using ninja
  • eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out

Users can opt out with --ninja false (or -ninja false for native builds).

Contributes to #54022 (#54022)

Benchmarking showed ninja provides ~8.8% faster builds on macOS
(avg 654s vs 718s per build). This change defaults to using ninja
when the host OS is macOS.
Changes:
- eng/build.sh: Default --ninja true on macOS, track explicit user override
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out
Users can opt out with --ninja false (or -ninja false for native builds).
@steveisok
steveisok requested review from a team and CopilotFebruary 5, 2026 13:01
@github-actionsgithub-actionsBot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves macOS build performance by defaulting to the Ninja build system instead of Make, achieving approximately 8.8% faster build times (654s vs 718s average). The change is opt-out via --ninja false to maintain flexibility.

Changes:

  • Default ninja build system on macOS for improved performance
  • Add explicit flag tracking to prevent overriding user preferences
  • Update help text to document the new default and opt-out mechanism

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

FileDescription
eng/build.shAdds macOS-specific ninja default with tracking to avoid overriding explicit user settings
eng/native/build-commons.shSets ninja as default on macOS and enhances -ninja flag to accept true/false values

Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
@jkotas

Copy link
Copy Markdown
Member

docs\workflow\requirements\macos-requirements.md needs to be updated - ninja is no longer optional by default after this change.

@jkotasjkotas added area-Infrastructure and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Feb 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

@am11

am11 commented Feb 5, 2026

Copy link
Copy Markdown
Member

Windows also defaults to ninja. Maybe we should flip the switch: --skipninja and cherry-pick installation script change a2b49ec. It's a tiny script dependency considering everything else required by the build.

@jkotas

Copy link
Copy Markdown
Member

--skipninja

Nit: Avoiding negations in names is a generally better UX design. I like -ninja false better than -skipninja.

- Use single useNinja variable in eng/build.sh instead of tracking explicit-ness
- Initialize __UseNinja=0 in build-commons.sh, then override to 1 on macOS
- Remove __UseNinja=0 initialization from build-runtime.sh and tests/build.sh
so the macOS default takes effect
- Update macOS requirements docs to reflect ninja is now default
@jkoritzinsky

Copy link
Copy Markdown
Member

I was just talking with @agocke about requiring Ninja on macOS to make it easier to maintain our Swift usage (as CMake only supports Swift with Ninja and XCode) so we don't need to manually invoke the Swift compiler and do our own object file handling.

I think this is a great first step in that direction!

Comment threadeng/build.sh Outdated
Based on PR feedback, default to using Ninja for native builds on any
Unix platform where ninja is installed, rather than only on macOS.
This aligns with the Mono subtree behavior and provides faster builds
when ninja is available.
CopilotAI review requested due to automatic review settings February 5, 2026 22:48
@steveisoksteveisok changed the title Default to ninja on macOS for faster buildsDefault to ninja if installed for faster builds (mac & linux)Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/build.sh Outdated
Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
Comment threadeng/build.sh Outdated
@am11

am11 commented Feb 7, 2026

Copy link
Copy Markdown
Member

It was implemented that way when you first asked, but later reverted due to concerns about build determinism (see #124041 (comment)). I believe build determinism is a separate issue, and Ninja by itself cannot meaningfully affect it: even small differences in toolchain versions or machine environments prevent bit-for-bit identical outputs. Docker largely addresses this on Linux by fixing the environment, but on other platforms there are more fundamental sources of nondeterminism to address, well beyond what Ninja alone can affect.

@steveisok

Copy link
Copy Markdown
MemberAuthor

Ok, @am11 votes for use if installed. @jkoritzinsky you appear to be as well.

@jkotas?

I don't have a strong opinion, but if I had to pick, I'd choose ninja by default and only opt out explicitly.

@jkotas

Copy link
Copy Markdown
Member

numbers for the build time improvement on Linux

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

I'd choose ninja by default

Yes, I think we should have it on by default for macOS and Linux at least, so that folks do not accidentally forget to install it and get worse build times.

other platforms

I am fine with off by default (or automatic light up) for other platforms if it helps.

Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
@jkoritzinsky

Copy link
Copy Markdown
Member

I'm okay with on-by-default as well. I just figured that use-if-available is an easier change to accept if we weren't sure if we wanted to switch.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
CopilotAI review requested due to automatic review settings February 7, 2026 19:16

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/native/build-commons.sh
Comment threadeng/build.sh
Comment threadeng/build.sh
Comment threadeng/native/build-commons.sh
When -ninja was followed by another flag (e.g. --ninja --subset clr),
the parser would consume the next argument as a ninja value and break
argument parsing. Now check if $2 starts with '-' before treating it
as a true/false value.
@steveisok

Copy link
Copy Markdown
MemberAuthor

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

Ran on WSL for a 4 hour loop. 12% better there on average.

Comment threaddocs/workflow/requirements/macos-requirements.md
CopilotAI review requested due to automatic review settings February 8, 2026 04:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@jkotasjkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@wfurt

wfurt commented Feb 9, 2026

Copy link
Copy Markdown
Member

This broke runtime-libraries enterprise-linux (that was skipped on the PR). #124187
It would be nice if it falls back automatically if Ninja is not present.

iremyux pushed a commit to iremyux/dotnet-runtime that referenced this pull request Mar 2, 2026
Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg
654s vs 718s per build). This change defaults to using ninja for both
MacOS and Linux.
Changes:
- eng/build.sh: default to using ninja
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false
opt-out
Users can opt out with --ninja false (or -ninja false for native
builds).
Contributes to dotnet#54022
(dotnet#54022)
---------
Co-authored-by: Steve Pfister <steve.pfister@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Mar 12, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants

@steveisok@jkotas@am11@jkoritzinsky@wfurt@janvorli
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Default to ninja for faster builds (mac & linux) by steveisok · Pull Request #124041 · dotnet/runtime · GitHub
Skip to content

Default to ninja for faster builds (mac & linux) - #124041

Merged
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build
Feb 8, 2026
Merged

Default to ninja for faster builds (mac & linux)#124041
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build

Conversation

@steveisok

@steveisoksteveisok commented Feb 5, 2026

Copy link
Copy Markdown
Member

Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg 654s vs 718s per build). This change defaults to using ninja for both MacOS and Linux.

Changes:

  • eng/build.sh: default to using ninja
  • eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out

Users can opt out with --ninja false (or -ninja false for native builds).

Contributes to #54022 (#54022)

Benchmarking showed ninja provides ~8.8% faster builds on macOS
(avg 654s vs 718s per build). This change defaults to using ninja
when the host OS is macOS.
Changes:
- eng/build.sh: Default --ninja true on macOS, track explicit user override
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out
Users can opt out with --ninja false (or -ninja false for native builds).
@steveisok
steveisok requested review from a team and CopilotFebruary 5, 2026 13:01
@github-actionsgithub-actionsBot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves macOS build performance by defaulting to the Ninja build system instead of Make, achieving approximately 8.8% faster build times (654s vs 718s average). The change is opt-out via --ninja false to maintain flexibility.

Changes:

  • Default ninja build system on macOS for improved performance
  • Add explicit flag tracking to prevent overriding user preferences
  • Update help text to document the new default and opt-out mechanism

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

FileDescription
eng/build.shAdds macOS-specific ninja default with tracking to avoid overriding explicit user settings
eng/native/build-commons.shSets ninja as default on macOS and enhances -ninja flag to accept true/false values

Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
@jkotas

Copy link
Copy Markdown
Member

docs\workflow\requirements\macos-requirements.md needs to be updated - ninja is no longer optional by default after this change.

@jkotasjkotas added area-Infrastructure and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Feb 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

@am11

am11 commented Feb 5, 2026

Copy link
Copy Markdown
Member

Windows also defaults to ninja. Maybe we should flip the switch: --skipninja and cherry-pick installation script change a2b49ec. It's a tiny script dependency considering everything else required by the build.

@jkotas

Copy link
Copy Markdown
Member

--skipninja

Nit: Avoiding negations in names is a generally better UX design. I like -ninja false better than -skipninja.

- Use single useNinja variable in eng/build.sh instead of tracking explicit-ness
- Initialize __UseNinja=0 in build-commons.sh, then override to 1 on macOS
- Remove __UseNinja=0 initialization from build-runtime.sh and tests/build.sh
so the macOS default takes effect
- Update macOS requirements docs to reflect ninja is now default
@jkoritzinsky

Copy link
Copy Markdown
Member

I was just talking with @agocke about requiring Ninja on macOS to make it easier to maintain our Swift usage (as CMake only supports Swift with Ninja and XCode) so we don't need to manually invoke the Swift compiler and do our own object file handling.

I think this is a great first step in that direction!

Comment threadeng/build.sh Outdated
Based on PR feedback, default to using Ninja for native builds on any
Unix platform where ninja is installed, rather than only on macOS.
This aligns with the Mono subtree behavior and provides faster builds
when ninja is available.
CopilotAI review requested due to automatic review settings February 5, 2026 22:48
@steveisoksteveisok changed the title Default to ninja on macOS for faster buildsDefault to ninja if installed for faster builds (mac & linux)Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/build.sh Outdated
Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
Comment threadeng/build.sh Outdated
@am11

am11 commented Feb 7, 2026

Copy link
Copy Markdown
Member

It was implemented that way when you first asked, but later reverted due to concerns about build determinism (see #124041 (comment)). I believe build determinism is a separate issue, and Ninja by itself cannot meaningfully affect it: even small differences in toolchain versions or machine environments prevent bit-for-bit identical outputs. Docker largely addresses this on Linux by fixing the environment, but on other platforms there are more fundamental sources of nondeterminism to address, well beyond what Ninja alone can affect.

@steveisok

Copy link
Copy Markdown
MemberAuthor

Ok, @am11 votes for use if installed. @jkoritzinsky you appear to be as well.

@jkotas?

I don't have a strong opinion, but if I had to pick, I'd choose ninja by default and only opt out explicitly.

@jkotas

Copy link
Copy Markdown
Member

numbers for the build time improvement on Linux

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

I'd choose ninja by default

Yes, I think we should have it on by default for macOS and Linux at least, so that folks do not accidentally forget to install it and get worse build times.

other platforms

I am fine with off by default (or automatic light up) for other platforms if it helps.

Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
@jkoritzinsky

Copy link
Copy Markdown
Member

I'm okay with on-by-default as well. I just figured that use-if-available is an easier change to accept if we weren't sure if we wanted to switch.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
CopilotAI review requested due to automatic review settings February 7, 2026 19:16

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/native/build-commons.sh
Comment threadeng/build.sh
Comment threadeng/build.sh
Comment threadeng/native/build-commons.sh
When -ninja was followed by another flag (e.g. --ninja --subset clr),
the parser would consume the next argument as a ninja value and break
argument parsing. Now check if $2 starts with '-' before treating it
as a true/false value.
@steveisok

Copy link
Copy Markdown
MemberAuthor

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

Ran on WSL for a 4 hour loop. 12% better there on average.

Comment threaddocs/workflow/requirements/macos-requirements.md
CopilotAI review requested due to automatic review settings February 8, 2026 04:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@jkotasjkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@wfurt

wfurt commented Feb 9, 2026

Copy link
Copy Markdown
Member

This broke runtime-libraries enterprise-linux (that was skipped on the PR). #124187
It would be nice if it falls back automatically if Ninja is not present.

iremyux pushed a commit to iremyux/dotnet-runtime that referenced this pull request Mar 2, 2026
Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg
654s vs 718s per build). This change defaults to using ninja for both
MacOS and Linux.
Changes:
- eng/build.sh: default to using ninja
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false
opt-out
Users can opt out with --ninja false (or -ninja false for native
builds).
Contributes to dotnet#54022
(dotnet#54022)
---------
Co-authored-by: Steve Pfister <steve.pfister@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Mar 12, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants

@steveisok@jkotas@am11@jkoritzinsky@wfurt@janvorli
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Default to ninja for faster builds (mac & linux) by steveisok · Pull Request #124041 · dotnet/runtime · GitHub
Skip to content

Default to ninja for faster builds (mac & linux) - #124041

Merged
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build
Feb 8, 2026
Merged

Default to ninja for faster builds (mac & linux)#124041
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build

Conversation

@steveisok

@steveisoksteveisok commented Feb 5, 2026

Copy link
Copy Markdown
Member

Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg 654s vs 718s per build). This change defaults to using ninja for both MacOS and Linux.

Changes:

  • eng/build.sh: default to using ninja
  • eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out

Users can opt out with --ninja false (or -ninja false for native builds).

Contributes to #54022 (#54022)

Benchmarking showed ninja provides ~8.8% faster builds on macOS
(avg 654s vs 718s per build). This change defaults to using ninja
when the host OS is macOS.
Changes:
- eng/build.sh: Default --ninja true on macOS, track explicit user override
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out
Users can opt out with --ninja false (or -ninja false for native builds).
@steveisok
steveisok requested review from a team and CopilotFebruary 5, 2026 13:01
@github-actionsgithub-actionsBot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves macOS build performance by defaulting to the Ninja build system instead of Make, achieving approximately 8.8% faster build times (654s vs 718s average). The change is opt-out via --ninja false to maintain flexibility.

Changes:

  • Default ninja build system on macOS for improved performance
  • Add explicit flag tracking to prevent overriding user preferences
  • Update help text to document the new default and opt-out mechanism

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

FileDescription
eng/build.shAdds macOS-specific ninja default with tracking to avoid overriding explicit user settings
eng/native/build-commons.shSets ninja as default on macOS and enhances -ninja flag to accept true/false values

Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
@jkotas

Copy link
Copy Markdown
Member

docs\workflow\requirements\macos-requirements.md needs to be updated - ninja is no longer optional by default after this change.

@jkotasjkotas added area-Infrastructure and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Feb 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

@am11

am11 commented Feb 5, 2026

Copy link
Copy Markdown
Member

Windows also defaults to ninja. Maybe we should flip the switch: --skipninja and cherry-pick installation script change a2b49ec. It's a tiny script dependency considering everything else required by the build.

@jkotas

Copy link
Copy Markdown
Member

--skipninja

Nit: Avoiding negations in names is a generally better UX design. I like -ninja false better than -skipninja.

- Use single useNinja variable in eng/build.sh instead of tracking explicit-ness
- Initialize __UseNinja=0 in build-commons.sh, then override to 1 on macOS
- Remove __UseNinja=0 initialization from build-runtime.sh and tests/build.sh
so the macOS default takes effect
- Update macOS requirements docs to reflect ninja is now default
@jkoritzinsky

Copy link
Copy Markdown
Member

I was just talking with @agocke about requiring Ninja on macOS to make it easier to maintain our Swift usage (as CMake only supports Swift with Ninja and XCode) so we don't need to manually invoke the Swift compiler and do our own object file handling.

I think this is a great first step in that direction!

Comment threadeng/build.sh Outdated
Based on PR feedback, default to using Ninja for native builds on any
Unix platform where ninja is installed, rather than only on macOS.
This aligns with the Mono subtree behavior and provides faster builds
when ninja is available.
CopilotAI review requested due to automatic review settings February 5, 2026 22:48
@steveisoksteveisok changed the title Default to ninja on macOS for faster buildsDefault to ninja if installed for faster builds (mac & linux)Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/build.sh Outdated
Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
Comment threadeng/build.sh Outdated
@am11

am11 commented Feb 7, 2026

Copy link
Copy Markdown
Member

It was implemented that way when you first asked, but later reverted due to concerns about build determinism (see #124041 (comment)). I believe build determinism is a separate issue, and Ninja by itself cannot meaningfully affect it: even small differences in toolchain versions or machine environments prevent bit-for-bit identical outputs. Docker largely addresses this on Linux by fixing the environment, but on other platforms there are more fundamental sources of nondeterminism to address, well beyond what Ninja alone can affect.

@steveisok

Copy link
Copy Markdown
MemberAuthor

Ok, @am11 votes for use if installed. @jkoritzinsky you appear to be as well.

@jkotas?

I don't have a strong opinion, but if I had to pick, I'd choose ninja by default and only opt out explicitly.

@jkotas

Copy link
Copy Markdown
Member

numbers for the build time improvement on Linux

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

I'd choose ninja by default

Yes, I think we should have it on by default for macOS and Linux at least, so that folks do not accidentally forget to install it and get worse build times.

other platforms

I am fine with off by default (or automatic light up) for other platforms if it helps.

Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
@jkoritzinsky

Copy link
Copy Markdown
Member

I'm okay with on-by-default as well. I just figured that use-if-available is an easier change to accept if we weren't sure if we wanted to switch.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
CopilotAI review requested due to automatic review settings February 7, 2026 19:16

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/native/build-commons.sh
Comment threadeng/build.sh
Comment threadeng/build.sh
Comment threadeng/native/build-commons.sh
When -ninja was followed by another flag (e.g. --ninja --subset clr),
the parser would consume the next argument as a ninja value and break
argument parsing. Now check if $2 starts with '-' before treating it
as a true/false value.
@steveisok

Copy link
Copy Markdown
MemberAuthor

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

Ran on WSL for a 4 hour loop. 12% better there on average.

Comment threaddocs/workflow/requirements/macos-requirements.md
CopilotAI review requested due to automatic review settings February 8, 2026 04:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@jkotasjkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@wfurt

wfurt commented Feb 9, 2026

Copy link
Copy Markdown
Member

This broke runtime-libraries enterprise-linux (that was skipped on the PR). #124187
It would be nice if it falls back automatically if Ninja is not present.

iremyux pushed a commit to iremyux/dotnet-runtime that referenced this pull request Mar 2, 2026
Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg
654s vs 718s per build). This change defaults to using ninja for both
MacOS and Linux.
Changes:
- eng/build.sh: default to using ninja
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false
opt-out
Users can opt out with --ninja false (or -ninja false for native
builds).
Contributes to dotnet#54022
(dotnet#54022)
---------
Co-authored-by: Steve Pfister <steve.pfister@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Mar 12, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants

@steveisok@jkotas@am11@jkoritzinsky@wfurt@janvorli
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Default to ninja for faster builds (mac & linux) by steveisok · Pull Request #124041 · dotnet/runtime · GitHub
Skip to content

Default to ninja for faster builds (mac & linux) - #124041

Merged
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build
Feb 8, 2026
Merged

Default to ninja for faster builds (mac & linux)#124041
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build

Conversation

@steveisok

@steveisoksteveisok commented Feb 5, 2026

Copy link
Copy Markdown
Member

Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg 654s vs 718s per build). This change defaults to using ninja for both MacOS and Linux.

Changes:

  • eng/build.sh: default to using ninja
  • eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out

Users can opt out with --ninja false (or -ninja false for native builds).

Contributes to #54022 (#54022)

Benchmarking showed ninja provides ~8.8% faster builds on macOS
(avg 654s vs 718s per build). This change defaults to using ninja
when the host OS is macOS.
Changes:
- eng/build.sh: Default --ninja true on macOS, track explicit user override
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out
Users can opt out with --ninja false (or -ninja false for native builds).
@steveisok
steveisok requested review from a team and CopilotFebruary 5, 2026 13:01
@github-actionsgithub-actionsBot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves macOS build performance by defaulting to the Ninja build system instead of Make, achieving approximately 8.8% faster build times (654s vs 718s average). The change is opt-out via --ninja false to maintain flexibility.

Changes:

  • Default ninja build system on macOS for improved performance
  • Add explicit flag tracking to prevent overriding user preferences
  • Update help text to document the new default and opt-out mechanism

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

FileDescription
eng/build.shAdds macOS-specific ninja default with tracking to avoid overriding explicit user settings
eng/native/build-commons.shSets ninja as default on macOS and enhances -ninja flag to accept true/false values

Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
@jkotas

Copy link
Copy Markdown
Member

docs\workflow\requirements\macos-requirements.md needs to be updated - ninja is no longer optional by default after this change.

@jkotasjkotas added area-Infrastructure and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Feb 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

@am11

am11 commented Feb 5, 2026

Copy link
Copy Markdown
Member

Windows also defaults to ninja. Maybe we should flip the switch: --skipninja and cherry-pick installation script change a2b49ec. It's a tiny script dependency considering everything else required by the build.

@jkotas

Copy link
Copy Markdown
Member

--skipninja

Nit: Avoiding negations in names is a generally better UX design. I like -ninja false better than -skipninja.

- Use single useNinja variable in eng/build.sh instead of tracking explicit-ness
- Initialize __UseNinja=0 in build-commons.sh, then override to 1 on macOS
- Remove __UseNinja=0 initialization from build-runtime.sh and tests/build.sh
so the macOS default takes effect
- Update macOS requirements docs to reflect ninja is now default
@jkoritzinsky

Copy link
Copy Markdown
Member

I was just talking with @agocke about requiring Ninja on macOS to make it easier to maintain our Swift usage (as CMake only supports Swift with Ninja and XCode) so we don't need to manually invoke the Swift compiler and do our own object file handling.

I think this is a great first step in that direction!

Comment threadeng/build.sh Outdated
Based on PR feedback, default to using Ninja for native builds on any
Unix platform where ninja is installed, rather than only on macOS.
This aligns with the Mono subtree behavior and provides faster builds
when ninja is available.
CopilotAI review requested due to automatic review settings February 5, 2026 22:48
@steveisoksteveisok changed the title Default to ninja on macOS for faster buildsDefault to ninja if installed for faster builds (mac & linux)Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/build.sh Outdated
Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
Comment threadeng/build.sh Outdated
@am11

am11 commented Feb 7, 2026

Copy link
Copy Markdown
Member

It was implemented that way when you first asked, but later reverted due to concerns about build determinism (see #124041 (comment)). I believe build determinism is a separate issue, and Ninja by itself cannot meaningfully affect it: even small differences in toolchain versions or machine environments prevent bit-for-bit identical outputs. Docker largely addresses this on Linux by fixing the environment, but on other platforms there are more fundamental sources of nondeterminism to address, well beyond what Ninja alone can affect.

@steveisok

Copy link
Copy Markdown
MemberAuthor

Ok, @am11 votes for use if installed. @jkoritzinsky you appear to be as well.

@jkotas?

I don't have a strong opinion, but if I had to pick, I'd choose ninja by default and only opt out explicitly.

@jkotas

Copy link
Copy Markdown
Member

numbers for the build time improvement on Linux

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

I'd choose ninja by default

Yes, I think we should have it on by default for macOS and Linux at least, so that folks do not accidentally forget to install it and get worse build times.

other platforms

I am fine with off by default (or automatic light up) for other platforms if it helps.

Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
@jkoritzinsky

Copy link
Copy Markdown
Member

I'm okay with on-by-default as well. I just figured that use-if-available is an easier change to accept if we weren't sure if we wanted to switch.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
CopilotAI review requested due to automatic review settings February 7, 2026 19:16

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/native/build-commons.sh
Comment threadeng/build.sh
Comment threadeng/build.sh
Comment threadeng/native/build-commons.sh
When -ninja was followed by another flag (e.g. --ninja --subset clr),
the parser would consume the next argument as a ninja value and break
argument parsing. Now check if $2 starts with '-' before treating it
as a true/false value.
@steveisok

Copy link
Copy Markdown
MemberAuthor

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

Ran on WSL for a 4 hour loop. 12% better there on average.

Comment threaddocs/workflow/requirements/macos-requirements.md
CopilotAI review requested due to automatic review settings February 8, 2026 04:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@jkotasjkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@wfurt

wfurt commented Feb 9, 2026

Copy link
Copy Markdown
Member

This broke runtime-libraries enterprise-linux (that was skipped on the PR). #124187
It would be nice if it falls back automatically if Ninja is not present.

iremyux pushed a commit to iremyux/dotnet-runtime that referenced this pull request Mar 2, 2026
Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg
654s vs 718s per build). This change defaults to using ninja for both
MacOS and Linux.
Changes:
- eng/build.sh: default to using ninja
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false
opt-out
Users can opt out with --ninja false (or -ninja false for native
builds).
Contributes to dotnet#54022
(dotnet#54022)
---------
Co-authored-by: Steve Pfister <steve.pfister@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Mar 12, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants

@steveisok@jkotas@am11@jkoritzinsky@wfurt@janvorli
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Default to ninja for faster builds (mac & linux) by steveisok · Pull Request #124041 · dotnet/runtime · GitHub
Skip to content

Default to ninja for faster builds (mac & linux) - #124041

Merged
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build
Feb 8, 2026
Merged

Default to ninja for faster builds (mac & linux)#124041
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build

Conversation

@steveisok

@steveisoksteveisok commented Feb 5, 2026

Copy link
Copy Markdown
Member

Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg 654s vs 718s per build). This change defaults to using ninja for both MacOS and Linux.

Changes:

  • eng/build.sh: default to using ninja
  • eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out

Users can opt out with --ninja false (or -ninja false for native builds).

Contributes to #54022 (#54022)

Benchmarking showed ninja provides ~8.8% faster builds on macOS
(avg 654s vs 718s per build). This change defaults to using ninja
when the host OS is macOS.
Changes:
- eng/build.sh: Default --ninja true on macOS, track explicit user override
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out
Users can opt out with --ninja false (or -ninja false for native builds).
@steveisok
steveisok requested review from a team and CopilotFebruary 5, 2026 13:01
@github-actionsgithub-actionsBot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves macOS build performance by defaulting to the Ninja build system instead of Make, achieving approximately 8.8% faster build times (654s vs 718s average). The change is opt-out via --ninja false to maintain flexibility.

Changes:

  • Default ninja build system on macOS for improved performance
  • Add explicit flag tracking to prevent overriding user preferences
  • Update help text to document the new default and opt-out mechanism

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

FileDescription
eng/build.shAdds macOS-specific ninja default with tracking to avoid overriding explicit user settings
eng/native/build-commons.shSets ninja as default on macOS and enhances -ninja flag to accept true/false values

Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
@jkotas

Copy link
Copy Markdown
Member

docs\workflow\requirements\macos-requirements.md needs to be updated - ninja is no longer optional by default after this change.

@jkotasjkotas added area-Infrastructure and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Feb 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

@am11

am11 commented Feb 5, 2026

Copy link
Copy Markdown
Member

Windows also defaults to ninja. Maybe we should flip the switch: --skipninja and cherry-pick installation script change a2b49ec. It's a tiny script dependency considering everything else required by the build.

@jkotas

Copy link
Copy Markdown
Member

--skipninja

Nit: Avoiding negations in names is a generally better UX design. I like -ninja false better than -skipninja.

- Use single useNinja variable in eng/build.sh instead of tracking explicit-ness
- Initialize __UseNinja=0 in build-commons.sh, then override to 1 on macOS
- Remove __UseNinja=0 initialization from build-runtime.sh and tests/build.sh
so the macOS default takes effect
- Update macOS requirements docs to reflect ninja is now default
@jkoritzinsky

Copy link
Copy Markdown
Member

I was just talking with @agocke about requiring Ninja on macOS to make it easier to maintain our Swift usage (as CMake only supports Swift with Ninja and XCode) so we don't need to manually invoke the Swift compiler and do our own object file handling.

I think this is a great first step in that direction!

Comment threadeng/build.sh Outdated
Based on PR feedback, default to using Ninja for native builds on any
Unix platform where ninja is installed, rather than only on macOS.
This aligns with the Mono subtree behavior and provides faster builds
when ninja is available.
CopilotAI review requested due to automatic review settings February 5, 2026 22:48
@steveisoksteveisok changed the title Default to ninja on macOS for faster buildsDefault to ninja if installed for faster builds (mac & linux)Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/build.sh Outdated
Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
Comment threadeng/build.sh Outdated
@am11

am11 commented Feb 7, 2026

Copy link
Copy Markdown
Member

It was implemented that way when you first asked, but later reverted due to concerns about build determinism (see #124041 (comment)). I believe build determinism is a separate issue, and Ninja by itself cannot meaningfully affect it: even small differences in toolchain versions or machine environments prevent bit-for-bit identical outputs. Docker largely addresses this on Linux by fixing the environment, but on other platforms there are more fundamental sources of nondeterminism to address, well beyond what Ninja alone can affect.

@steveisok

Copy link
Copy Markdown
MemberAuthor

Ok, @am11 votes for use if installed. @jkoritzinsky you appear to be as well.

@jkotas?

I don't have a strong opinion, but if I had to pick, I'd choose ninja by default and only opt out explicitly.

@jkotas

Copy link
Copy Markdown
Member

numbers for the build time improvement on Linux

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

I'd choose ninja by default

Yes, I think we should have it on by default for macOS and Linux at least, so that folks do not accidentally forget to install it and get worse build times.

other platforms

I am fine with off by default (or automatic light up) for other platforms if it helps.

Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
@jkoritzinsky

Copy link
Copy Markdown
Member

I'm okay with on-by-default as well. I just figured that use-if-available is an easier change to accept if we weren't sure if we wanted to switch.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
CopilotAI review requested due to automatic review settings February 7, 2026 19:16

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/native/build-commons.sh
Comment threadeng/build.sh
Comment threadeng/build.sh
Comment threadeng/native/build-commons.sh
When -ninja was followed by another flag (e.g. --ninja --subset clr),
the parser would consume the next argument as a ninja value and break
argument parsing. Now check if $2 starts with '-' before treating it
as a true/false value.
@steveisok

Copy link
Copy Markdown
MemberAuthor

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

Ran on WSL for a 4 hour loop. 12% better there on average.

Comment threaddocs/workflow/requirements/macos-requirements.md
CopilotAI review requested due to automatic review settings February 8, 2026 04:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@jkotasjkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@wfurt

wfurt commented Feb 9, 2026

Copy link
Copy Markdown
Member

This broke runtime-libraries enterprise-linux (that was skipped on the PR). #124187
It would be nice if it falls back automatically if Ninja is not present.

iremyux pushed a commit to iremyux/dotnet-runtime that referenced this pull request Mar 2, 2026
Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg
654s vs 718s per build). This change defaults to using ninja for both
MacOS and Linux.
Changes:
- eng/build.sh: default to using ninja
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false
opt-out
Users can opt out with --ninja false (or -ninja false for native
builds).
Contributes to dotnet#54022
(dotnet#54022)
---------
Co-authored-by: Steve Pfister <steve.pfister@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Mar 12, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants

@steveisok@jkotas@am11@jkoritzinsky@wfurt@janvorli
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Default to ninja for faster builds (mac & linux) by steveisok · Pull Request #124041 · dotnet/runtime · GitHub
Skip to content

Default to ninja for faster builds (mac & linux) - #124041

Merged
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build
Feb 8, 2026
Merged

Default to ninja for faster builds (mac & linux)#124041
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build

Conversation

@steveisok

@steveisoksteveisok commented Feb 5, 2026

Copy link
Copy Markdown
Member

Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg 654s vs 718s per build). This change defaults to using ninja for both MacOS and Linux.

Changes:

  • eng/build.sh: default to using ninja
  • eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out

Users can opt out with --ninja false (or -ninja false for native builds).

Contributes to #54022 (#54022)

Benchmarking showed ninja provides ~8.8% faster builds on macOS
(avg 654s vs 718s per build). This change defaults to using ninja
when the host OS is macOS.
Changes:
- eng/build.sh: Default --ninja true on macOS, track explicit user override
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out
Users can opt out with --ninja false (or -ninja false for native builds).
@steveisok
steveisok requested review from a team and CopilotFebruary 5, 2026 13:01
@github-actionsgithub-actionsBot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves macOS build performance by defaulting to the Ninja build system instead of Make, achieving approximately 8.8% faster build times (654s vs 718s average). The change is opt-out via --ninja false to maintain flexibility.

Changes:

  • Default ninja build system on macOS for improved performance
  • Add explicit flag tracking to prevent overriding user preferences
  • Update help text to document the new default and opt-out mechanism

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

FileDescription
eng/build.shAdds macOS-specific ninja default with tracking to avoid overriding explicit user settings
eng/native/build-commons.shSets ninja as default on macOS and enhances -ninja flag to accept true/false values

Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
@jkotas

Copy link
Copy Markdown
Member

docs\workflow\requirements\macos-requirements.md needs to be updated - ninja is no longer optional by default after this change.

@jkotasjkotas added area-Infrastructure and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Feb 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

@am11

am11 commented Feb 5, 2026

Copy link
Copy Markdown
Member

Windows also defaults to ninja. Maybe we should flip the switch: --skipninja and cherry-pick installation script change a2b49ec. It's a tiny script dependency considering everything else required by the build.

@jkotas

Copy link
Copy Markdown
Member

--skipninja

Nit: Avoiding negations in names is a generally better UX design. I like -ninja false better than -skipninja.

- Use single useNinja variable in eng/build.sh instead of tracking explicit-ness
- Initialize __UseNinja=0 in build-commons.sh, then override to 1 on macOS
- Remove __UseNinja=0 initialization from build-runtime.sh and tests/build.sh
so the macOS default takes effect
- Update macOS requirements docs to reflect ninja is now default
@jkoritzinsky

Copy link
Copy Markdown
Member

I was just talking with @agocke about requiring Ninja on macOS to make it easier to maintain our Swift usage (as CMake only supports Swift with Ninja and XCode) so we don't need to manually invoke the Swift compiler and do our own object file handling.

I think this is a great first step in that direction!

Comment threadeng/build.sh Outdated
Based on PR feedback, default to using Ninja for native builds on any
Unix platform where ninja is installed, rather than only on macOS.
This aligns with the Mono subtree behavior and provides faster builds
when ninja is available.
CopilotAI review requested due to automatic review settings February 5, 2026 22:48
@steveisoksteveisok changed the title Default to ninja on macOS for faster buildsDefault to ninja if installed for faster builds (mac & linux)Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/build.sh Outdated
Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
Comment threadeng/build.sh Outdated
@am11

am11 commented Feb 7, 2026

Copy link
Copy Markdown
Member

It was implemented that way when you first asked, but later reverted due to concerns about build determinism (see #124041 (comment)). I believe build determinism is a separate issue, and Ninja by itself cannot meaningfully affect it: even small differences in toolchain versions or machine environments prevent bit-for-bit identical outputs. Docker largely addresses this on Linux by fixing the environment, but on other platforms there are more fundamental sources of nondeterminism to address, well beyond what Ninja alone can affect.

@steveisok

Copy link
Copy Markdown
MemberAuthor

Ok, @am11 votes for use if installed. @jkoritzinsky you appear to be as well.

@jkotas?

I don't have a strong opinion, but if I had to pick, I'd choose ninja by default and only opt out explicitly.

@jkotas

Copy link
Copy Markdown
Member

numbers for the build time improvement on Linux

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

I'd choose ninja by default

Yes, I think we should have it on by default for macOS and Linux at least, so that folks do not accidentally forget to install it and get worse build times.

other platforms

I am fine with off by default (or automatic light up) for other platforms if it helps.

Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
@jkoritzinsky

Copy link
Copy Markdown
Member

I'm okay with on-by-default as well. I just figured that use-if-available is an easier change to accept if we weren't sure if we wanted to switch.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
CopilotAI review requested due to automatic review settings February 7, 2026 19:16

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/native/build-commons.sh
Comment threadeng/build.sh
Comment threadeng/build.sh
Comment threadeng/native/build-commons.sh
When -ninja was followed by another flag (e.g. --ninja --subset clr),
the parser would consume the next argument as a ninja value and break
argument parsing. Now check if $2 starts with '-' before treating it
as a true/false value.
@steveisok

Copy link
Copy Markdown
MemberAuthor

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

Ran on WSL for a 4 hour loop. 12% better there on average.

Comment threaddocs/workflow/requirements/macos-requirements.md
CopilotAI review requested due to automatic review settings February 8, 2026 04:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@jkotasjkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@wfurt

wfurt commented Feb 9, 2026

Copy link
Copy Markdown
Member

This broke runtime-libraries enterprise-linux (that was skipped on the PR). #124187
It would be nice if it falls back automatically if Ninja is not present.

iremyux pushed a commit to iremyux/dotnet-runtime that referenced this pull request Mar 2, 2026
Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg
654s vs 718s per build). This change defaults to using ninja for both
MacOS and Linux.
Changes:
- eng/build.sh: default to using ninja
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false
opt-out
Users can opt out with --ninja false (or -ninja false for native
builds).
Contributes to dotnet#54022
(dotnet#54022)
---------
Co-authored-by: Steve Pfister <steve.pfister@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Mar 12, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants

@steveisok@jkotas@am11@jkoritzinsky@wfurt@janvorli
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Default to ninja for faster builds (mac & linux) by steveisok · Pull Request #124041 · dotnet/runtime · GitHub
Skip to content

Default to ninja for faster builds (mac & linux) - #124041

Merged
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build
Feb 8, 2026
Merged

Default to ninja for faster builds (mac & linux)#124041
steveisok merged 9 commits into
dotnet:mainfrom
steveisok:test-ninja-build

Conversation

@steveisok

@steveisoksteveisok commented Feb 5, 2026

Copy link
Copy Markdown
Member

Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg 654s vs 718s per build). This change defaults to using ninja for both MacOS and Linux.

Changes:

  • eng/build.sh: default to using ninja
  • eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out

Users can opt out with --ninja false (or -ninja false for native builds).

Contributes to #54022 (#54022)

Benchmarking showed ninja provides ~8.8% faster builds on macOS
(avg 654s vs 718s per build). This change defaults to using ninja
when the host OS is macOS.
Changes:
- eng/build.sh: Default --ninja true on macOS, track explicit user override
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false opt-out
Users can opt out with --ninja false (or -ninja false for native builds).
@steveisok
steveisok requested review from a team and CopilotFebruary 5, 2026 13:01
@github-actionsgithub-actionsBot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves macOS build performance by defaulting to the Ninja build system instead of Make, achieving approximately 8.8% faster build times (654s vs 718s average). The change is opt-out via --ninja false to maintain flexibility.

Changes:

  • Default ninja build system on macOS for improved performance
  • Add explicit flag tracking to prevent overriding user preferences
  • Update help text to document the new default and opt-out mechanism

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

FileDescription
eng/build.shAdds macOS-specific ninja default with tracking to avoid overriding explicit user settings
eng/native/build-commons.shSets ninja as default on macOS and enhances -ninja flag to accept true/false values

Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
@jkotas

Copy link
Copy Markdown
Member

docs\workflow\requirements\macos-requirements.md needs to be updated - ninja is no longer optional by default after this change.

@jkotasjkotas added area-Infrastructure and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Feb 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

@am11

am11 commented Feb 5, 2026

Copy link
Copy Markdown
Member

Windows also defaults to ninja. Maybe we should flip the switch: --skipninja and cherry-pick installation script change a2b49ec. It's a tiny script dependency considering everything else required by the build.

@jkotas

Copy link
Copy Markdown
Member

--skipninja

Nit: Avoiding negations in names is a generally better UX design. I like -ninja false better than -skipninja.

- Use single useNinja variable in eng/build.sh instead of tracking explicit-ness
- Initialize __UseNinja=0 in build-commons.sh, then override to 1 on macOS
- Remove __UseNinja=0 initialization from build-runtime.sh and tests/build.sh
so the macOS default takes effect
- Update macOS requirements docs to reflect ninja is now default
@jkoritzinsky

Copy link
Copy Markdown
Member

I was just talking with @agocke about requiring Ninja on macOS to make it easier to maintain our Swift usage (as CMake only supports Swift with Ninja and XCode) so we don't need to manually invoke the Swift compiler and do our own object file handling.

I think this is a great first step in that direction!

Comment threadeng/build.sh Outdated
Based on PR feedback, default to using Ninja for native builds on any
Unix platform where ninja is installed, rather than only on macOS.
This aligns with the Mono subtree behavior and provides faster builds
when ninja is available.
CopilotAI review requested due to automatic review settings February 5, 2026 22:48
@steveisoksteveisok changed the title Default to ninja on macOS for faster buildsDefault to ninja if installed for faster builds (mac & linux)Feb 5, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/build.sh Outdated
Comment threadeng/native/build-commons.sh Outdated
Comment threadeng/build.sh Outdated
Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
Comment threadeng/build.sh Outdated
@am11

am11 commented Feb 7, 2026

Copy link
Copy Markdown
Member

It was implemented that way when you first asked, but later reverted due to concerns about build determinism (see #124041 (comment)). I believe build determinism is a separate issue, and Ninja by itself cannot meaningfully affect it: even small differences in toolchain versions or machine environments prevent bit-for-bit identical outputs. Docker largely addresses this on Linux by fixing the environment, but on other platforms there are more fundamental sources of nondeterminism to address, well beyond what Ninja alone can affect.

@steveisok

Copy link
Copy Markdown
MemberAuthor

Ok, @am11 votes for use if installed. @jkoritzinsky you appear to be as well.

@jkotas?

I don't have a strong opinion, but if I had to pick, I'd choose ninja by default and only opt out explicitly.

@jkotas

Copy link
Copy Markdown
Member

numbers for the build time improvement on Linux

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

I'd choose ninja by default

Yes, I think we should have it on by default for macOS and Linux at least, so that folks do not accidentally forget to install it and get worse build times.

other platforms

I am fine with off by default (or automatic light up) for other platforms if it helps.

Comment threaddocs/workflow/requirements/macos-requirements.md Outdated
@jkoritzinsky

Copy link
Copy Markdown
Member

I'm okay with on-by-default as well. I just figured that use-if-available is an easier change to accept if we weren't sure if we wanted to switch.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
CopilotAI review requested due to automatic review settings February 7, 2026 19:16

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment threadeng/native/build-commons.sh
Comment threadeng/build.sh
Comment threadeng/build.sh
Comment threadeng/native/build-commons.sh
When -ninja was followed by another flag (e.g. --ninja --subset clr),
the parser would consume the next argument as a ninja value and break
argument parsing. Now check if $2 starts with '-' before treating it
as a true/false value.
@steveisok

Copy link
Copy Markdown
MemberAuthor

I see 5% improvement for ./build.sh -s clr -c release in mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net11.0-cross-amd64 container on standard issue devbox. (~610seconds without ninja, 580seconds with ninja, average of 10+ builds)

Ran on WSL for a 4 hour loop. 12% better there on average.

Comment threaddocs/workflow/requirements/macos-requirements.md
CopilotAI review requested due to automatic review settings February 8, 2026 04:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@jkotasjkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@wfurt

wfurt commented Feb 9, 2026

Copy link
Copy Markdown
Member

This broke runtime-libraries enterprise-linux (that was skipped on the PR). #124187
It would be nice if it falls back automatically if Ninja is not present.

iremyux pushed a commit to iremyux/dotnet-runtime that referenced this pull request Mar 2, 2026
Benchmarking showed ninja provides ~8.8% faster builds on macOS (avg
654s vs 718s per build). This change defaults to using ninja for both
MacOS and Linux.
Changes:
- eng/build.sh: default to using ninja
- eng/native/build-commons.sh: Default -ninja on macOS, add -ninja false
opt-out
Users can opt out with --ninja false (or -ninja false for native
builds).
Contributes to dotnet#54022
(dotnet#54022)
---------
Co-authored-by: Steve Pfister <steve.pfister@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Mar 12, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants

@steveisok@jkotas@am11@jkoritzinsky@wfurt@janvorli