Crafter.Build/implementations/main.cpp

24 lines
1,008 B
C++
Raw Normal View History

2026-07-23 01:24:42 +02:00
// SPDX-License-Identifier: LGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
2026-04-27 07:04:42 +02:00
fix: line-buffer stdout when redirected so progress/readiness lines flush When crafter-build's stdout is not a TTY (redirected to a file or pipe) the C runtime defaults to full (block) buffering. The progress path is TTY-aware and the in-place redraw flushes explicitly, but the non-TTY append path (`[N/M]` lines), Finalize()'s `Built N steps` line and the `-r` server's `listening on port :N` line all go through block-buffered stdout with no flush. They accumulate in the buffer and only spill at ~4KB boundaries. On a normal build this is hidden because the C runtime flushes stdout at exit. Under `-r` the process never exits — it blocks in its serve loop — so the trailing buffer is never flushed: a redirected log freezes mid-build (or sits at 0 bytes) even though the build finished and the server is already answering. Any tooling that polls the log for `Built …` / `listening …` / `[N/N]` hangs forever. This is the real cause of the frozen log misdiagnosed as a build deadlock in #16. Fix: switch stdout to line buffering at the very top of main(), before any output, only when stdout is not a terminal. Every `\n` then flushes, so the markers reach a redirected log immediately. No behaviour change on a TTY. Kept self-contained in main.cpp using system headers (isatty + setvbuf) rather than a new Crafter::Progress export: the self-hosting exe build compiles main.cpp against the installed/cached Crafter.Build module BMIs, which shadow the freshly built local ones, so a new interface symbol would not be visible without reinstalling crafter-build first. Resolves #18 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 14:42:33 +00:00
#include <cstdio>
refactor: drop Windows host support crafter-build is moving to a single Flatpak distribution, and there is no Windows host in that picture: no build.cmd, no MSVC or mingw host build, no DLL plus launcher. Delete every host-Windows path instead of leaving it to rot unverified: the cmd.exe command runner and quoting, the LOCALAPPDATA cache, the MSVC and mingw-host LoadProject variants with their LIBCXX_DIR and CRAFTER_MINGW_DIR plumbing, the winsock port probe, the LoadLibrary libclang loader, the console-width and isatty shims, and the preprocessor guards around the Linux bodies. The x86_64-w64-mingw32 cross-compile target stays. It is target logic (output names, -femulated-tls, the libstdc++ link extras, copying a dependency DLL next to a mingw exe, wine as the runner) and did not depend on any of the removed code. The msvc target goes with the host that was the only thing able to use it. Three target-path warts fixed on the way: ExpectedOutput named a mingw static library <name>.lib while the archive step wrote lib<name>.a, so those libraries relinked on every run; the import lib is no longer copied next to a mingw exe, since the dependency's own bin dir is already on the link line; and llvm-ar now writes every archive, not only the LTO ones, so Debug and Release archives are made the same way. CRAFTER_API and Crafter.Build-Api.h existed only for the DLL boundary. Nothing downstream used them, so they are removed rather than kept as an empty macro nobody can verify. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 21:56:38 +02:00
#include <unistd.h>
fix: line-buffer stdout when redirected so progress/readiness lines flush When crafter-build's stdout is not a TTY (redirected to a file or pipe) the C runtime defaults to full (block) buffering. The progress path is TTY-aware and the in-place redraw flushes explicitly, but the non-TTY append path (`[N/M]` lines), Finalize()'s `Built N steps` line and the `-r` server's `listening on port :N` line all go through block-buffered stdout with no flush. They accumulate in the buffer and only spill at ~4KB boundaries. On a normal build this is hidden because the C runtime flushes stdout at exit. Under `-r` the process never exits — it blocks in its serve loop — so the trailing buffer is never flushed: a redirected log freezes mid-build (or sits at 0 bytes) even though the build finished and the server is already answering. Any tooling that polls the log for `Built …` / `listening …` / `[N/N]` hangs forever. This is the real cause of the frozen log misdiagnosed as a build deadlock in #16. Fix: switch stdout to line buffering at the very top of main(), before any output, only when stdout is not a terminal. Every `\n` then flushes, so the markers reach a redirected log immediately. No behaviour change on a TTY. Kept self-contained in main.cpp using system headers (isatty + setvbuf) rather than a new Crafter::Progress export: the self-hosting exe build compiles main.cpp against the installed/cached Crafter.Build module BMIs, which shadow the freshly built local ones, so a new interface symbol would not be visible without reinstalling crafter-build first. Resolves #18 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 14:42:33 +00:00
2026-04-27 07:04:42 +02:00
import std;
import Crafter.Build;
int main(int argc, char** argv) {
fix: line-buffer stdout when redirected so progress/readiness lines flush When crafter-build's stdout is not a TTY (redirected to a file or pipe) the C runtime defaults to full (block) buffering. The progress path is TTY-aware and the in-place redraw flushes explicitly, but the non-TTY append path (`[N/M]` lines), Finalize()'s `Built N steps` line and the `-r` server's `listening on port :N` line all go through block-buffered stdout with no flush. They accumulate in the buffer and only spill at ~4KB boundaries. On a normal build this is hidden because the C runtime flushes stdout at exit. Under `-r` the process never exits — it blocks in its serve loop — so the trailing buffer is never flushed: a redirected log freezes mid-build (or sits at 0 bytes) even though the build finished and the server is already answering. Any tooling that polls the log for `Built …` / `listening …` / `[N/N]` hangs forever. This is the real cause of the frozen log misdiagnosed as a build deadlock in #16. Fix: switch stdout to line buffering at the very top of main(), before any output, only when stdout is not a terminal. Every `\n` then flushes, so the markers reach a redirected log immediately. No behaviour change on a TTY. Kept self-contained in main.cpp using system headers (isatty + setvbuf) rather than a new Crafter::Progress export: the self-hosting exe build compiles main.cpp against the installed/cached Crafter.Build module BMIs, which shadow the freshly built local ones, so a new interface symbol would not be visible without reinstalling crafter-build first. Resolves #18 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 14:42:33 +00:00
// Line-buffer stdout when it is not a terminal. Must run before any stdout
// write. When stdout is a regular file or pipe the C runtime defaults to
// full (block) buffering, so the append-only progress lines ("[N/M]") and
// the trailing "Built … steps" / "listening on port …" lines would sit in
// the buffer and never reach a redirected log — fatal for tooling that
// polls the log for a readiness marker, and worst under -r where the
// process blocks in its serve loop and never returns to flush. A TTY is
// already line-buffered and its in-place redraw path flushes explicitly, so
// only adjust when redirected.
refactor: drop Windows host support crafter-build is moving to a single Flatpak distribution, and there is no Windows host in that picture: no build.cmd, no MSVC or mingw host build, no DLL plus launcher. Delete every host-Windows path instead of leaving it to rot unverified: the cmd.exe command runner and quoting, the LOCALAPPDATA cache, the MSVC and mingw-host LoadProject variants with their LIBCXX_DIR and CRAFTER_MINGW_DIR plumbing, the winsock port probe, the LoadLibrary libclang loader, the console-width and isatty shims, and the preprocessor guards around the Linux bodies. The x86_64-w64-mingw32 cross-compile target stays. It is target logic (output names, -femulated-tls, the libstdc++ link extras, copying a dependency DLL next to a mingw exe, wine as the runner) and did not depend on any of the removed code. The msvc target goes with the host that was the only thing able to use it. Three target-path warts fixed on the way: ExpectedOutput named a mingw static library <name>.lib while the archive step wrote lib<name>.a, so those libraries relinked on every run; the import lib is no longer copied next to a mingw exe, since the dependency's own bin dir is already on the link line; and llvm-ar now writes every archive, not only the LTO ones, so Debug and Release archives are made the same way. CRAFTER_API and Crafter.Build-Api.h existed only for the DLL boundary. Nothing downstream used them, so they are removed rather than kept as an empty macro nobody can verify. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 21:56:38 +02:00
if (isatty(STDOUT_FILENO) == 0) {
fix: line-buffer stdout when redirected so progress/readiness lines flush When crafter-build's stdout is not a TTY (redirected to a file or pipe) the C runtime defaults to full (block) buffering. The progress path is TTY-aware and the in-place redraw flushes explicitly, but the non-TTY append path (`[N/M]` lines), Finalize()'s `Built N steps` line and the `-r` server's `listening on port :N` line all go through block-buffered stdout with no flush. They accumulate in the buffer and only spill at ~4KB boundaries. On a normal build this is hidden because the C runtime flushes stdout at exit. Under `-r` the process never exits — it blocks in its serve loop — so the trailing buffer is never flushed: a redirected log freezes mid-build (or sits at 0 bytes) even though the build finished and the server is already answering. Any tooling that polls the log for `Built …` / `listening …` / `[N/N]` hangs forever. This is the real cause of the frozen log misdiagnosed as a build deadlock in #16. Fix: switch stdout to line buffering at the very top of main(), before any output, only when stdout is not a terminal. Every `\n` then flushes, so the markers reach a redirected log immediately. No behaviour change on a TTY. Kept self-contained in main.cpp using system headers (isatty + setvbuf) rather than a new Crafter::Progress export: the self-hosting exe build compiles main.cpp against the installed/cached Crafter.Build module BMIs, which shadow the freshly built local ones, so a new interface symbol would not be visible without reinstalling crafter-build first. Resolves #18 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 14:42:33 +00:00
std::setvbuf(stdout, nullptr, _IOLBF, 0);
}
2026-04-27 07:04:42 +02:00
return Crafter::Run(argc, argv);
}