From d74e6f5278e67f42e9a020f81c9eb0272f624618 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Fri, 16 Oct 2026 08:06:09 +0000 Subject: feat(driver)!: select LLVM IR output with -S Save native executables by default and LLVM IR with -S, using source-adjacent .out and .ll names. Keep -r independent of output selection and update the manuals and three-platform nightly smoke checks. BREAKING CHANGE: plain compilation and -o now save native executables. Use -S to save textual LLVM IR. Co-Authored-By: Claude Fable 5.1 --- doc/build.md | 14 ++++++++------ doc/cpsc.1.md | 52 +++++++++++++++++++++++++++++++++------------------- doc/install.md | 2 +- 3 files changed, 42 insertions(+), 26 deletions(-) (limited to 'doc') diff --git a/doc/build.md b/doc/build.md index 08b4f24..d9f94c6 100644 --- a/doc/build.md +++ b/doc/build.md @@ -56,7 +56,7 @@ mkdir -p build/deps/packages cd build/deps/packages apt-get download \ llvm-23-dev llvm-23 llvm-23-runtime llvm-23-tools llvm-23-linker-tools \ - libllvm23 libclang-cpp23 libclang-23-dev liblld-23-dev libpolly-23-dev libz3-dev libz3-4 \ + libllvm23 libclang-cpp23 libclang-23-dev liblld-23-dev liblld-23 libpolly-23-dev libz3-dev libz3-4 \ libffi-dev libffi8 libxml2-dev libxml2 \ zlib1g-dev zlib1g libzstd-dev libzstd1 libncurses-dev libtinfo6 ) @@ -64,7 +64,8 @@ mkdir -p build/deps/packages `apt-get download` also downloads explicitly named packages that are already installed. The LLVM companion packages satisfy its CMake imports, while the -development support packages supply the static archives used by `EMBEDDED`. +development support packages supply required static archives. Clang, LLD and Polly +archives are needed for embedded native linking in every execution mode. ### Windows (MSYS2 MINGW64) @@ -92,8 +93,7 @@ and [LLVM package](https://packages.msys2.org/packages/mingw-w64-x86_64-llvm) currently provide 23.1.3. MSYS2 keeps these package names unversioned; its compiler executables are `clang.exe` and `clang++.exe`, not `clang-23.exe` or `clang++-23.exe`. CMake rejects another major version even when the package -name is unchanged. MINGW64 Clang uses the GNU linker and C++ library supplied -by its package dependencies; cpsc itself is compiled with Clang 23. +name is unchanged. MINGW64 Clang defaults to the GNU linker and C++ library supplied by its package dependencies. cpsc is compiled with Clang 23 and linked with LLD, retaining the GNU C++ runtime. Before downloading LLVM, confirm that these repository packages' `Version` fields all start with `23.`: @@ -132,7 +132,7 @@ relocation tools with `xcode-select --install` if needed. The LLVM bottle below provides Clang 23. Install CMake with Homebrew: ```bash -brew install cmake python lld +brew install cmake python ``` Recommended binary-bottle downloads to the build directory: @@ -159,7 +159,7 @@ initial configuration; there is no default. The choice is saved in CMake's cache |---|---| | `PATH` | Run external `lli` from LLVM 23 in PATH; reject `-r` before compilation if it is missing or its version cannot be validated. | | `EMBEDDED` | Run with the statically linked LLVM engine inside `cpsc`; no PATH lookup. | -| `NONE` | Reject `-r`; compiling to IR still works. | +| `NONE` | Reject `-r`; native and IR compilation still work. | Linux: @@ -209,6 +209,8 @@ required archive is a configure error. Linux also links the C++ runtime statical and MinGW uses static linking. The tested Debian/LLVM 23 executable needs only the system libc, libm and dynamic loader. Build for the intended OS and CPU. +All execution modes embed the Clang driver, LLD and the startup objects, runtime archives and system-library link inputs needed for native output. Python prepares these compressed resources during configuration; it is not needed by users. Native output requires no installed compiler, linker or development SDK. On Linux, generated programs statically link the C++ runtime and dynamically link glibc and its system libraries, so they require a compatible system glibc. Do not use global `-static` on Linux. macOS embeds SDK library stubs and uses operating-system runtime libraries; Windows embeds MinGW link inputs and statically links non-system runtimes. + For `PATH` mode, add the extracted LLVM 23 `lli` directory to your shell's PATH after configuration. Only `-r` checks the selected `lli --version`, with a five-second timeout. Missing, wrong or unrecognized versions fail before source diff --git a/doc/cpsc.1.md b/doc/cpsc.1.md index c58f1ad..92f73b5 100644 --- a/doc/cpsc.1.md +++ b/doc/cpsc.1.md @@ -6,15 +6,15 @@ cpsc - compile and run CIE pseudocode # SYNOPSIS -**cpsc** [**-r**] [**-o** *output*] *source* +**cpsc** [**-r**] [**-S**] [**-o** *output*] *source* **cpsc** **-h** # DESCRIPTION -Compile one pseudocode source file to LLVM IR. Options may appear before or after the source path. Source input from stdin is not supported. +Compile one pseudocode source file to a native executable, or to textual LLVM IR with **-S**. Options may appear before or after the source path. Source input from stdin is not supported. -Without **-o** or **-r**, replace the source filename's extension with `.ir` and save the output beside the source file. +Without **-o**, save beside the source file, replacing its extension with `.out` for an executable or `.ll` for IR. This naming also applies on Windows. With **-r** alone, run without saving a file. # OPTIONS @@ -22,39 +22,54 @@ Without **-o** or **-r**, replace the source filename's extension with `.ir` and : Print only the documentation entry point: `man 1 cpsc` on Unix/macOS, or Start Menu > cpsc > cpsc Help on Windows. Return successfully without compiling, even when other arguments are present. **-o** *output* -: Save IR to the specified path. May be specified only once. With **-r**, keep this file even if execution fails. +: Save to the specified path. Without **-S**, save a native executable; with **-S**, save LLVM IR. Use the path exactly as given; its extension does not select the output format. May be specified only once. With **-r**, keep this file even if execution fails. + +**-S** +: Save textual LLVM IR instead of a native executable. Without **-o**, use the source filename with a `.ll` extension beside the source file. May be combined with **-r** to save IR and run the program. **-r** -: Run the compiled program with the runner selected at build time (see EXECUTION MODES). Without **-o**, do not save permanent IR. The program inherits stdin, stdout and stderr; `INPUT` can read terminal or piped input. +: Run the compiled program with the runner selected at build time (see EXECUTION MODES). Save output first when **-S** or **-o** is also present; otherwise do not save a file. The program inherits stdin, stdout and stderr; `INPUT` can read terminal or piped input. + +# NATIVE COMPILATION + +Native compilation uses LLVM, the Clang driver and LLD embedded in `cpsc`. Required startup objects, runtime archives and system-library link inputs are embedded too and unpacked temporarily when linking. No external compiler, linker or development SDK is needed. Generate programs for the compiler's own operating system and CPU architecture; cross-compilation is not supported. + +On Linux, both `cpsc` and generated executables statically link the C++ runtime and retain dynamic dependencies on glibc and its system libraries. They require a compatible system glibc; static linking does not remove that requirement. Windows links non-system runtimes statically and uses Windows system DLLs. macOS uses operating-system libraries, including the system C++ runtime. # EXECUTION MODES -The executable has one of the following execution modes, selected when it was built. All modes can compile to LLVM IR; the mode determines whether and how **-r** runs the program. +The executable has one of the following execution modes, selected when it was built. All modes can generate native executables and LLVM IR; the mode determines whether and how **-r** runs the program. Running uses the selected runner even when a native executable is also saved. **PATH** -: Run `lli` from LLVM 23 in PATH. With **-r**, check the selected executable's version before compilation or output writing; a missing executable, a different major version or a failed or unrecognized version check is a fatal error. Version detection has a five-second timeout. Without **-r**, no external tools are checked. This mode does not invoke or check `clang` or `clang++`. Without **-o**, write temporary IR and delete it afterward, including on execution failure. +: Run `lli` from LLVM 23 in PATH. With **-r**, check the selected executable's version before compilation or output writing; a missing executable, a different major version or a failed or unrecognized version check is a fatal error. Version detection has a five-second timeout. Without **-r**, no external tools are checked. Execution uses temporary `.ll` IR unless **-S** saves IR; temporary IR is deleted afterward, including on execution failure. **EMBEDDED** -: Run the statically linked LLVM engine inside `cpsc`, without looking for `lli` in PATH. Without **-o**, execute the module in memory. Users do not need LLVM or `lli` installed; the executable may still depend on the operating system's C runtime libraries. +: Run the statically linked LLVM engine inside `cpsc`, without looking for `lli` in PATH. Execute the module in memory. Users do not need LLVM or `lli` installed; the executable may still depend on the operating system's runtime libraries. **NONE** -: Reject **-r** with an error before compilation or output writing. Compilation to IR remains available. +: Reject **-r** with an error before compilation or output writing. Native compilation and IR output remain available. # EXAMPLES -Compile and save `test.ir` beside `test.cps`: +Compile and save `test.out` beside `test.cps`: ```sh cpsc test.cps ``` -Choose the output path: +Choose the executable's output path: + +```sh +cpsc test.cps -o result +``` + +Save LLVM IR as `test.ll` beside `test.cps`: ```sh -cpsc test.cps -o result.ir +cpsc test.cps -S ``` -Run without saving permanent IR: +Run without saving output: ```sh cpsc test.cps -r @@ -63,15 +78,14 @@ cpsc test.cps -r Save IR and run it: ```sh -cpsc test.cps -r -o result.ir +cpsc test.cps -r -S -o result.ll ``` -Build a native program with Clang 23's C++ driver so the exception runtime is linked. Use `clang++` from the LLVM 23 installation; Debian/Ubuntu also provides the versioned name `clang++-23`. MSYS2 MINGW64 and Homebrew use the unversioned name. +Save a native program and run it on Unix: ```sh -cpsc test.cps -o test.ll -clang++ test.ll -o test -./test +cpsc test.cps -o test.out +./test.out ``` # EXIT STATUS @@ -88,7 +102,7 @@ An uncaught program exception returns 1 after printing `Unhandled exception. Pro # NOTES -Compiler diagnostics go to stderr. Failed compilation does not write IR. Successful compilation overwrites an existing output file, but an output path that refers to the source file (including a symbolic or hard link) is rejected. +Compiler diagnostics go to stderr. Failed source compilation does not write output; failed native linking does not replace an existing output file. Successful compilation overwrites an existing output file, but an output path that refers to the source file (including a symbolic or hard link) is rejected. Missing input, including invoking `cpsc` without arguments, reports `cpsc: fatal error: no input files`. Ordinary lexical, syntax and semantic errors use `error:`; failures that prevent compilation, such as file I/O errors, use `fatal error:`. Compilation and argument failures end with one `compilation terminated.` line. Execution-stage failures do not print that line. diff --git a/doc/install.md b/doc/install.md index a8e8a2e..9b59ee1 100644 --- a/doc/install.md +++ b/doc/install.md @@ -82,7 +82,7 @@ time in UTC followed by its short ID: `yyyymmdd-hhmmss-commit`. The version is read each time packaging runs. The package uses the current build's execution mode and contains `cpsc`, `doc/cpsc.1`, `doc/language/**/*.7`, `install.sh` and `LICENSE`. Packaging builds the compiler and manual automatically; it requires Git and Pandoc. -Use `EMBEDDED` when recipients should not need LLVM or `lli` at run time. +All modes generate executables without an installed compiler, linker or development SDK. Use `EMBEDDED` when recipients should also be able to use `-r` without LLVM or `lli` installed. Extract the archive with `tar -xJf`, enter the extracted directory, then run `sudo ./install.sh`, or `./install.sh --prefix "$HOME/.local"` for a local installation. -- cgit v1.3.1-4-g156e