Skip to content

Conversation

@johnno1962
Copy link
Contributor

Add --single-arch option.

Hi Apple, this patch is a follow up to the conversation on S/E related to the difficulty of using the utils/build-toolchain script since the introduction of Macs with Apple silicon. This adds an option --single-arch which by temporally removing the infer-cross-compile-hosts-on-darwin option from the mixin_osx_package_base preset allows users's to build a toolchain for their current architecture only.

This should probably be the default for this script but as how it goes about it is a little untidy I'll leave it as it as an option.

Cheers

Copy link
Contributor

@MaxDesiatov MaxDesiatov left a comment

Choose a reason for hiding this comment

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

This should not modify existing presets. And it doesn't allow using this option for build-script either. The patch application will also fail when build-presets.ini is changed. I'd recommend adding a new preset in build-presets.ini instead.

@johnno1962
Copy link
Contributor Author

I didn't think you'd like this approach but I avoided what you suggest as it would involve replicating a lot of text that really shouldn't be duplicated. If the script runs though it reverts the change to the presets to err on the safe-ish side.

@MaxDesiatov
Copy link
Contributor

it would involve replicating a lot of text that really shouldn't be duplicated.

There's no need for duplication, since presets support mixins. What would make sense is a base preset that builds for a single platform, and an inheriting preset that avoids duplication and adds a single option to the base that enables cross-compilation for both Intel and ARM.

@johnno1962
Copy link
Contributor Author

I would agree but I am not very familiar with what presets are and their syntax even. If you propose something detailed and concrete I can test it for you but would prefer not to touch the presets file at the repo level.

@wti
Copy link
Contributor

wti commented Jul 1, 2025

not very familiar with what presets are and their syntax even

They look like key/value properties where the section titles are the preset names, with special "mixin" value keys that are parsed to resolve and incorporate other preset section values (by presets.py, which also binds template text).

but would prefer not to touch the presets file at the repo level

fwiw, the build help (in driver_arguments.py [1] EPILOG) suggests writing a custom presets file. Instead of modifying build-presets.ini, perhaps start by defining and using custom presets file that works for your scenario. If you can't re-use existing high-level preset names, then perhaps dump the closest one [2] and make new high-level names as needed.

Custom presets, once written (perhaps per Max's design above) and validated, could be the basis for a proposal to add a new preset [3]. But just validating and publishing or documenting your working presets file would help others (like me) in a similar situation.

(caveat: I have no authority or experience. My interest stems from a back-burner itch to get toolchain docc into universal form on macOS.)


[1]

If you have your own favorite set of options, you can create your own, local,


[2] Use presets.py if you want to parse and resolve. It's easy to use from test_presets.py, which runs from build_swift/run_tests.py.


[3] A new preset would not affect any current users. Hence Max above: This should not modify existing presets Modifying old presets would be hard to test. Dumping all the fully-resolved presets now results in ~8600 lines (228 presets using 264 configuration values, averaging 35 values per preset) -- hard to think about touching that.

@johnno1962
Copy link
Contributor Author

johnno1962 commented Jul 1, 2025

Thanks for the documentation about presets. I agree it's difficult to even think of touching the existing presets file but I would oppose creating a new one which is the existing presets file differing by only removing the infer-cross-compile-hosts-on-darwin option as it would very quickly go out of sync. I suggest doing this in realtime as the build-toolchain script is run as an alternative. If you will never accept this then I'll close this PR.

@MaxDesiatov
Copy link
Contributor

You don't have to modify (the set of options in) existing presets. Adding a new base preset that existing one could mix in with a single addition of infer-cross-compile-hosts-on-darwin would keep the set of options the same, while allowing contributors to use this new base preset to avoid spending time and resources on universal builds.

That way you're keeping the existing behavior unchanged, avoid duplication, and no longer rely on fragile hacks with patch applications that are error prone.

Second iteration.
@johnno1962
Copy link
Contributor Author

I've added another commit which you could look at. It creates a new presets file with the option removed on demand and does not check it in or modify the existing presets file. As I said I would be very reluctant to "just" make changes to the existing presets as that is well beyond my pay grade. I don't think it would be easy as I'm not sure the presets used by build-toolchain and "normal" toolchain building don't overlap.

@MaxDesiatov
Copy link
Contributor

MaxDesiatov commented Jul 1, 2025

Please avoid creating new preset files, as those are not easily discoverable. As I mentioned above, there's an obvious way to do it that avoids duplication, doesn't change the set of options used for existing presets, doesn't introduce new options to existing build scripts, and is easy to review and to handle in the future. It is also discoverable and doesn't introduce branching out to existing workflows due to separate scripts or new preset files. The diff would be much smaller too: it literally amounts to a base preset declaration without infer-cross-compile-hosts-on-darwin and a mixin declaration with infer-cross-compile-hosts-on-darwin.

I don't think it would be easy as I'm not sure the presets used by build-toolchain and "normal" toolchain building don't overlap.

Would you elaborate what you mean by "normal" toolchain building?

@johnno1962
Copy link
Contributor Author

johnno1962 commented Jul 1, 2025

By normal toolchain building I mean the CI commands which use the build-script. As I have said, I'm reluctant to modify the existing presets file for fear of regression and I don't believe it would be possible if multiple presets (with qualifiers) are shared between the various ways of generating a toolchain so they cannot inherit from a common single ancestor. I may be wrong on the latter point but I do know I don't have more time to spend exploring that and validate changes which takes hours per iteration. I'm offering a tactical fix to address the issue mentioned on the forum with very low and localised risk.

@johnno1962
Copy link
Contributor Author

It's not like I don't understand what you mean it's the qualifiers that are the problem. A diff would look ike the following

diff --git a/utils/build-presets.ini b/utils/build-presets.ini index d3e88a1107f..9a2b8c813d3 100644 --- a/utils/build-presets.ini +++ b/utils/build-presets.ini @@ -1324,7 +1324,7 @@ llvm-targets-to-build=X86;ARM;AArch64;WebAssembly #===------------------------------------------------------------------------===# # OS X Package Builders #===------------------------------------------------------------------------===# -[preset: mixin_osx_package_base] +[preset: mixin_osx_package_basic] mixin-preset=mixin_buildbot_install_components_with_clang ios tvos @@ -1351,9 +1351,6 @@ swiftdocc release-debuginfo compiler-vendor=apple -# Cross compile for Apple Silicon -infer-cross-compile-hosts-on-darwin - lldb-use-system-debugserver lldb-build-type=Release build-ninja @@ -1428,6 +1425,11 @@ darwin-toolchain-version=%(darwin_toolchain_version)s darwin-toolchain-alias=%(darwin_toolchain_alias)s darwin-toolchain-require-use-os-runtime=0 +[preset: mixin_osx_package_base] +mixin-preset= + mixin_osx_package_basic + infer-cross-compile-hosts-on-darwin + [preset: mixin_osx_package_test] build-subdir=buildbot_osx @@ -1583,6 +1585,33 @@ mixin-preset= mixin_buildbot_osx_package,no_test mixin_osx_package,use_os_runtime +# Single architecture +[preset: single_arch_osx_package] +mixin-preset= + mixin_osx_package_basic + mixin_osx_package_test + mixin_lightweight_assertions,no-stdlib-asserts + +[preset: single_arch_osx_package,no_test] +mixin-preset= + single_arch_osx_package + mixin_buildbot_osx_package,no_test + +[preset: single_arch_osx_package,use_os_runtime] +mixin-preset= + single_arch_osx_package + mixin_osx_package,use_os_runtime + +[preset: single_arch_osx_package,macos_only] +mixin-preset= + single_arch_osx_package + mixin_osx_package,macos_only + +[preset: single_arch_osx_package,no_assertions] +mixin-preset= + single_arch_osx_package + mixin_osx_package_test + #===------------------------------------------------------------------------===# # LLDB build configurations # 

But that doesn't cater combinations of qualifiers like the original file. I just don't believe this is the right approach.

@MaxDesiatov
Copy link
Contributor

MaxDesiatov commented Jul 1, 2025

Just the first part of the diff you posted would be quite sufficient IMO. Maybe someone would want to bikeshed WRT preset naming, but I would approve this:

diff --git a/utils/build-presets.ini b/utils/build-presets.ini index d3e88a1107f..9a2b8c813d3 100644 --- a/utils/build-presets.ini +++ b/utils/build-presets.ini @@ -1324,7 +1324,7 @@ llvm-targets-to-build=X86;ARM;AArch64;WebAssembly #===------------------------------------------------------------------------===# # OS X Package Builders #===------------------------------------------------------------------------===# -[preset: mixin_osx_package_base] +[preset: mixin_osx_package_basic] mixin-preset=mixin_buildbot_install_components_with_clang ios tvos @@ -1351,9 +1351,6 @@ swiftdocc release-debuginfo compiler-vendor=apple -# Cross compile for Apple Silicon~ -infer-cross-compile-hosts-on-darwin - lldb-use-system-debugserver lldb-build-type=Release build-ninja @@ -1428,6 +1425,11 @@ darwin-toolchain-version=%(darwin_toolchain_version)s darwin-toolchain-alias=%(darwin_toolchain_alias)s darwin-toolchain-require-use-os-runtime=0 +[preset: mixin_osx_package_base] +mixin-preset= + mixin_osx_package_basic +# Cross compile for Apple Silicon~ +infer-cross-compile-hosts-on-darwin + 
@johnno1962
Copy link
Contributor Author

johnno1962 commented Jul 1, 2025

But that wouldn't be sufficient solve the problem would it? The "entry point" is preset buildbot_osx_package which is replicated along with various qualifiers like buildbot_osx_package,use_os_runtime and buildbot_osx_package,no_assertions that inherit from mixin_osx_package_base. That and the various variations per qualifier and combinations of qualifiers need to be replicated as well under a new "entry point" single_arch_osx_package (for example) inheriting from mixin_osx_package_basic as in my diff.

Create single architecture presets.
Use single architecture preset.
@johnno1962
Copy link
Contributor Author

johnno1962 commented Jul 1, 2025

OK, I've committed a third iteration using an edit to the presets. There is only one preset that works in combination with --single-arch modifier, buildbot_osx_package,no_test,single_arch. This wouldn't be the variation I'd choose.

Copy link
Contributor

@MaxDesiatov MaxDesiatov left a comment

Choose a reason for hiding this comment

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

Perfect, thank you!

@johnno1962
Copy link
Contributor Author

Cool. Can you kick off a CI build toolchain as a check please?

@MaxDesiatov
Copy link
Contributor

One more thing before that, would you mind adding a note about --single-arch to README.md?

@MaxDesiatov MaxDesiatov changed the title Add --single-arch option to build-toolchain Add --single-arch option to build-toolchain Jul 1, 2025
Mention --single-arch option.
@johnno1962
Copy link
Contributor Author

I've added a quick note about the new option but in the longer term I wonder if the README.md of the entire project is the right place for introducing build-toolchain. Let me know if/when you want me to squash the commits.

Co-authored-by: Max Desiatov <m_desiatov@apple.com>
@johnno1962
Copy link
Contributor Author

There is a problem with the presets file. It builds in the wrong directory, I'm looking at it.

Co-authored-by: Max Desiatov <m_desiatov@apple.com>
@MaxDesiatov
Copy link
Contributor

@swift-ci build toolchain

Set build-subdir
@johnno1962
Copy link
Contributor Author

Think I've resolved the presets issue. Pease review what I have done carefully. You could also mention disk space in the --single-arch message in the README.md

@johnno1962
Copy link
Contributor Author

johnno1962 commented Jul 1, 2025

Still working to get a toolchain with the presets approach out. It always fails with this error:

-- Symbols (liblldb): exporting all symbols from the lldb namespace -- LLDB.framework: build path is '/Volumes/Data3/PreviousContent/swift-source/build/buildbot_osx/lldb-macosx-arm64/bin' -- LLDB.framework: install path is '/Library/Developer/Toolchains/swift-LOCAL-2025-07-01-a.xctoolchain/usr/../System/Library/PrivateFrameworks' -- LLDB.framework: resources subdirectory is 'Versions/A/Resources' -- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) CMake Error at test/CMakeLists.txt:188 (message): Couldn't find libcxx build in '/Volumes/Data3/PreviousContent/swift-source/build/buildbot_osx/libcxx-macosx-arm64'. To run the test-suite for a standalone LLDB build please build libcxx and point LLDB_TEST_LIBCXX_ROOT_DIR to it. -- LLDB tests use out-of-tree debugserver: /Applications/Xcode.app/Contents/Developer/../SharedFrameworks/LLDB.framework/Resources/debugserver -- Configuring incomplete, errors occurred! See also "/Volumes/Data3/PreviousContent/swift-source/build/buildbot_osx/lldb-macosx-arm64/CMakeFiles/CMakeOutput.log". See also "/Volumes/Data3/PreviousContent/swift-source/build/buildbot_osx/lldb-macosx-arm64/CMakeFiles/CMakeError.log". real	21m9.456s user	211m58.443s sys	11m24.906s 

There is something up with the new preset. It's simply not as simple as you think.
"My" approach (using the new or old presets file) with the originally proposed build-toolchain script always works.

@johnno1962 johnno1962 changed the title Add --single-arch option to build-toolchain [DNM] Add --single-arch option to build-toolchain Jul 1, 2025
Revert script to second iteration.
@johnno1962
Copy link
Contributor Author

johnno1962 commented Jul 1, 2025

I've added commits to progressively roll back to the second iteration. I'm afraid I don't have the time to try to get a presets based solution which seems unduly complicated and risky and I consider inferior anyway (as it doesn't cater for the supported modifier combinations) to work.

@johnno1962 johnno1962 changed the title [DNM] Add --single-arch option to build-toolchain Add --single-arch option to build-toolchain Jul 1, 2025
Copy link
Contributor

@MaxDesiatov MaxDesiatov left a comment

Choose a reason for hiding this comment

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

I don't think that a separate preset file in the current set up is worth it.

@johnno1962
Copy link
Contributor Author

johnno1962 commented Jul 1, 2025

The separate presets file is never checked in, it is always regenerated when you use the --single-arch option then deleted. Given the limitations of presets/mixins it is the easiest way to remove the option infer-cross-compile-hosts-on-darwin.

@johnno1962
Copy link
Contributor Author

@airspeedswift, Any chance you could find a way to un-block this PR for me. I think it's fair to say Max and I have agreed to disagree about how to go about solving this problem building toolchains locally that came up in the forums. Hint: the solution is not to delete the build-toolchain script!

@wti
Copy link
Contributor

wti commented Jul 7, 2025

Sorry, but doesn't a personal custom presets file enable you to build without this PR?

fwiw, the build help (in driver_arguments.py [1] EPILOG) suggests writing a custom presets file

That sounds like it doesn't require a PR; you'd just pass the path to your own preset file as an argument to the script.

Proving that there's some preset configuration-set that builds what you want the way you want would be a first step for updating build-presets.ini, and would unblock you or anyone with such a file, even if the PR is not adopted. Conversely, proving it's not possible would motivate making flag or logic changes (seemingly proposed above).

To work through your own settings or to evaluate build-presets.ini changes, you can dump the presets after resolving mixin's by writing a pseudo-test in utils/build_swift/tests/build_swift/test_presets.py (invoked via utils/build_swift/run_tests.py). (Indeed, I wonder if there should be some integration test based on dumped resolved-configuration diffing, since it's a kind of API change.)

[edit: corrected preset file name]

@johnno1962
Copy link
Contributor Author

I was thinking about this impasse and I was wondering if it wasn't time to remove the infer-cross-compile-hosts-on-darwin option from the mixin_osx_package_base preset and create a new preset mixing it in for the preset the overnight toolchain build jobs use which is about the only thing that benefits from building multi-architecture now. If it is buildbot_osx_package, perhaps it would be worth creating a new preset buildbot_osx_package,multi-arch and switch the job to use that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

3 participants