Enable AOT binaries and end-to-end publishing of binaries#110
Merged
Conversation
Closes #109. - Makefile at repo root wraps local restore/build/test/publish loops. RID is auto-detected from uname; override with `make publish RID=...`. publish-all targets osx-arm64, linux-x64, win-x64. - New release job in release.yml downloads the build matrix artifacts, packages tar.gz (osx/linux) and zip (win) under dist/, and creates a GitHub Release tagged v<version> with --generate-notes. Versions containing '-' (alpha/develop) are flagged --prerelease. Re-runs upload assets with --clobber rather than failing on an existing release. - notify-failure now waits on `release` so a packaging failure files the standard incident issue. - CLAUDE.md gains the smoke-test command and a Makefile reference table. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A Windows checkout failed `make publish` with the cryptic MSB3073 / "vswhere.exe is not recognized" error. The fix isn't to guess — it's that AOT compilation requires a platform-native linker that the .NET SDK does not bundle. Codify this so the next maintainer doesn't have to rediscover it. - scripts/doctor.sh: per-platform check of .NET SDK plus the native toolchain (Xcode CLT on macOS, clang+zlib on Linux, vswhere + VC.Tools.x86.x64 on Windows). Prints a remediation step per missing item; exits non-zero if anything is missing. - Makefile: new `make doctor` target that runs the script. `make help` points users at it when publish fails. - CONTRIBUTING.md: new "Prerequisites" section with a per-platform install matrix (apt, dnf, xcode-select, VS Build Tools). - CLAUDE.md: notes the AOT toolchain requirement and points at CONTRIBUTING and `make doctor`. - .gitattributes: forces LF on Makefile and *.sh so a Windows checkout doesn't silently corrupt them via autocrlf. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Windows users running PowerShell don't have `make` and may not have bash on PATH, so the bash-only doctor was effectively unreachable from the default Windows shell. Mirror it in PowerShell and document both entrypoints. - scripts/doctor.ps1: same checks as doctor.sh — .NET SDK, vswhere, VC.Tools.x86.x64 — using native PowerShell + vswhere. - CONTRIBUTING.md: spells out three ways to run the check (`make doctor`, `bash scripts/doctor.sh`, `pwsh -File scripts/doctor.ps1`) so no one has to guess based on platform. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous Prerequisites section implied installing the VS C++ workload was sufficient on Windows. It fixes AOT publishing (MSVC linker), but does not install GNU make — VS ships MSBuild and nmake, neither of which understands our Makefile. Split the Windows row's concerns: AOT prereq is one column, `make` itself is its own column. Document the three common ways to get GNU make on Windows (choco, winget, scoop) and call out WSL/Git Bash as alternatives. Make is optional — every target maps to a plain dotnet command — so this is positioning, not adding a hard dependency. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous doctor queried vswhere with -requires VC.Tools.x86.x64. That component ID matches Build Tools / Community / Enterprise but missed VS 18 Insiders even when link.exe was present at exactly the path the AOT MSBuild target uses. False negative, exactly the kind of "setup must be wrong" guessing this script was supposed to prevent. Now both doctor scripts check for the linker directly: - if link.exe is on PATH → ok (Developer Command Prompt) - else `vswhere -find VC\Tools\MSVC\**\Hostx64\x64\link.exe` (with -prerelease so Insiders/preview installs are discovered) - else miss Verified locally: doctor now correctly identifies the linker in a VS 18 Insiders install at .../14.51.36231/.../link.exe and reports ok. Also document a separate Windows AOT failure mode in CONTRIBUTING: even with the linker installed, the AOT target shells out via cmd.exe where vswhere.exe is not on PATH, producing the same MSB3073. Fix: launch from a Developer Command Prompt, or prepend the VS Installer dir to PATH for the session. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
These were showing as untracked on every clean checkout: - .vs/ — Visual Studio's IDE cache - publish/ — local AOT output from `make publish` - dist/ — release archive output (also produced locally if anyone exercises the release packaging steps) - **/Properties/launchSettings.json — VS auto-generates this with local debug profiles; not shared Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Used as the non-AOT side-by-side output dir when working around the upstream Terminal.Gui AOT trimming bug. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`dotnet publish` (AOT or non-AOT) was dropping TextMateSharp.dll from the output directory while keeping TextMateSharp.Grammars.dll. At runtime any markdown render via the syntax highlighter threw FileNotFoundException — `clet help select --cat` reproduced it reliably. This blocked PR #110's bar of having a published binary that actually runs. Add a direct PackageReference (pin matches what Grammars already brings in transitively, so no new version surface) and document as D-034. Verified locally on win-x64 non-AOT: --version, list, and help --cat all work end-to-end. AOT publish on win-x64 still crashes at module init due to upstream TG bug gui-cs/Terminal.Gui#5239 (separate issue, not blocked on this workaround). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`src/Clet.SourceGen/` was kept around as a parking spot for a future auto-discovery source generator. v2 third-party-clets isn't on the roadmap anymore, so the project is dead weight that has to be carried through every solution-wide build, restore, and pack step. - src/Clet.SourceGen/ removed (csproj + Placeholder.cs). - Clet.slnx no longer references it. - specs/clet-spec.md project-layout trees updated; the prose lines that called the source generator out as a separate project / placeholder are gone. §11 still describes the v2 hypothetical auto-discovery design (that's an exploration section, not a current-code claim, so left intact). - CLAUDE.md project list updated to drop the SourceGen bullet. Build, unit, integration, and smoke tests all green after removal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The AOT crash chain (#5239 → #5240 partial → #5242 residual → #5243
horked-merge → TG#5249 restoring the fix) is fully resolved in TG
2.1.0-rc.2. Verified locally on win-x64:
dotnet publish src/Clet -c Release -r win-x64 --self-contained
-p:PublishAot=true -o publish/win-x64
./publish/win-x64/clet.exe --version
→ 1.0.0-alpha (Terminal.Gui 2.1.0-rc.2), exit 0
→ 21.17 MB binary
Move clet's TerminalGuiVersion default off the `2.0.2-develop.*`
float and onto a stable RC tag, satisfying spec §7's v0.5 milestone
"TG dep on a release tag, not develop".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A solution-wide `dotnet publish` (no project arg) walks every project. The test projects ProjectReference Clet, which becomes self-contained under AOT publish — and a non-self-contained project cannot reference a self-contained one. The build fails with NETSDK1151: error NETSDK1151: The referenced project '../../src/Clet/Clet.csproj' is a self-contained executable. A self-contained executable cannot be referenced by a non self-contained executable. Surfaced on win-arm64 by @tig running bare `dotnet publish` against the freshly pinned 2.1.0-rc.2. Add tests/Directory.Build.props with `<IsPublishable>false</IsPublishable>`, which propagates to all four test csprojs (UnitTests, IntegrationTests, SmokeTests, UITests). Bare `dotnet publish` now skips them and only publishes Clet itself. Tests still build and run normally. Verified locally: `dotnet publish -c Release` succeeds (only Clet publishes); `dotnet build -c Release` 0 errors; `dotnet run --project tests/Clet.UnitTests --no-build -c Release` 431/431 pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #109.
Summary
This is NOT about publishing to winget or brew; just about verifying that the binaries build and run correctly on supported platforms.
Makefileat the repo root for local restore/build/test/AOT-publish loops. RID auto-detected fromuname; override withmake publish RID=linux-x64.publish-allcoversosx-arm64,linux-x64,win-x64.releasejob in.github/workflows/release.ymlbetweentagandpublish-nuget. Downloads the build matrix artifacts, packages.tar.gz(osx/linux) and.zip(win) underdist/, creates a GitHub Releasev<version>viagh release create --generate-notes. Versions containing-(alpha/develop) get--prerelease. Re-runs upload assets with--clobber.notify-failure.needsnow includesreleaseso packaging failures still file the incident issue.make doctor(andscripts/doctor.{sh,ps1}) — checks the .NET SDK and the platform-native linker that AOT publishing needs. Prints precise remediation per missing item.CONTRIBUTING.mdPrerequisites section: per-platform install matrix for build/test, AOT, andmake(Windows separately — VS C++ workload does not include GNU make)..gitattributesforces LF onMakefileand*.shso a Windows checkout doesn't silently corrupt them..gitignorecovers.vs/,publish/,publish-nonaot/,dist/,**/Properties/launchSettings.json.D-034added: explicit<PackageReference Include="TextMateSharp">workaround, since publish was dropping the runtime DLL.Acceptance bar (per @tig)
This PR is not done until both AOT and non-AOT x64 binaries run on the maintainer's Windows box, and the branch can be pulled and runs cleanly on:
--version,list,help --catall work2.1.0-rc.2(21.17 MB binary, exit 0)IsPublishable=falsefix at 0cd826c — baredotnet publishwas failing NETSDK1151 because test projects ProjectReference self-contained Clet)2.1.0-rc.2; please re-pull2.1.0-rc.2; please re-pullVerification recipe per platform
If
make publishfails on Windows withvswhere.exe is not recognized, prepend the VS Installer dir to PATH or run from a Developer Command Prompt — see CONTRIBUTING.md → Common Windows AOT failure.Doc-update gate
Linked upstream issues
2.1.0-rc.2). clet now pins to that tag.DeepCloner.cs+ConfigurationManager.cs); an AOT regression test in TG CI was suggested in #5249's body but is not in the merge — worth a separate TG follow-up to prevent another silent re-introduction.🤖 Generated with Claude Code