From 0f577749aaa24307ac69d4b586a9b673455ed157 Mon Sep 17 00:00:00 2001 From: Zuhaitz Méndez Fernández de Aránguiz Date: Sun, 25 Jan 2026 18:30:22 +0000 Subject: Generating binary (APE) as a release. --- .github/workflows/build-ape.yml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-ape.yml b/.github/workflows/build-ape.yml index 3fe5c17..f5e9c85 100644 --- a/.github/workflows/build-ape.yml +++ b/.github/workflows/build-ape.yml @@ -3,6 +3,7 @@ name: APE Portable Build on: push: branches: [ "main" ] + tags: [ "v*" ] pull_request: branches: [ "main" ] workflow_dispatch: @@ -10,6 +11,8 @@ on: jobs: build-ape: runs-on: ubuntu-latest + permissions: + contents: write steps: - uses: actions/checkout@v4 @@ -32,14 +35,25 @@ jobs: make clean make ape - - name: Upload zc.com + - name: Upload zc.com Artifact uses: actions/upload-artifact@v4 with: name: zc-portable path: out/bin/zc.com - - name: Upload zc-boot.com + - name: Upload zc-boot.com Artifact uses: actions/upload-artifact@v4 with: name: zc-boot-portable path: out/bin/zc-boot.com + + - name: Create Release + if: startsWith(github.ref, 'refs/tags/v') + uses: softprops/action-gh-release@v2 + with: + files: | + out/bin/zc.com + out/bin/zc-boot.com + draft: false + prerelease: false + generate_release_notes: true -- cgit v1.2.3 From d5ad18ff3b97515c12a35f00d940e62bb34b7401 Mon Sep 17 00:00:00 2001 From: Zuhaitz Méndez Fernández de Aránguiz Date: Sun, 25 Jan 2026 19:00:17 +0000 Subject: Improving Windows support and update LICENSE --- LICENSE | 26 ++++++++++++++++++++++++++ Makefile | 2 +- README.md | 2 +- examples/graphics/mandelbrot.zc | 1 + src/main.c | 4 ++-- 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/LICENSE b/LICENSE index c5bb75b..ec6dc3b 100644 --- a/LICENSE +++ b/LICENSE @@ -19,3 +19,29 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +### zc-ape License + +MIT License + +Copyright (c) 2026 Eugene Olonov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile index 977542c..eaec55a 100644 --- a/Makefile +++ b/Makefile @@ -182,7 +182,7 @@ uninstall-ape: # Clean clean: - $(RM) $(OBJ_DIR) obj-ape $(TARGET) out.c plugins/*.so out + $(RM) $(OBJ_DIR) obj-ape $(TARGET) out.c plugins/*.so a.out* @echo "=> Clean complete!" # Test diff --git a/README.md b/README.md index 91634a3..4f4a5d7 100644 --- a/README.md +++ b/README.md @@ -1249,5 +1249,5 @@ This project uses the following third-party libraries: * **[cJSON](https://github.com/DaveGamble/cJSON)** (MIT License): Used for JSON parsing and generation in the Language Server. * Copyright (c) 2009-2017 Dave Gamble and cJSON contributors -* **[zc-ape](https://github.com/OEvgeny/zc-ape)** (MIT License): The original Actually Portable Executable port of Zen-C. The APE integration in this repository is based on this work by [OEvgeny](https://github.com/OEvgeny). +* **[zc-ape](https://github.com/OEvgeny/zc-ape)** (MIT License): The original Actually Portable Executable port of Zen-C by [Eugene Olonov](https://github.com/OEvgeny). * **[Cosmopolitan Libc](https://github.com/jart/cosmopolitan)** (ISC License): The foundational library that makes APE possible. diff --git a/examples/graphics/mandelbrot.zc b/examples/graphics/mandelbrot.zc index aca94ba..04f61b9 100644 --- a/examples/graphics/mandelbrot.zc +++ b/examples/graphics/mandelbrot.zc @@ -1,4 +1,5 @@ +@derive(Copy) struct Complex { re: float, im: float, diff --git a/src/main.c b/src/main.c index 62bb98d..3bf4832 100644 --- a/src/main.c +++ b/src/main.c @@ -56,8 +56,8 @@ void print_usage() int main(int argc, char **argv) { memset(&g_config, 0, sizeof(g_config)); -#ifdef __COSMOPOLITAN__ - strcpy(g_config.cc, "cosmocc"); +#ifdef _WIN32 + strcpy(g_config.cc, "gcc.exe"); #else strcpy(g_config.cc, "gcc"); #endif -- cgit v1.2.3 From 555141e35166c7f7d98c16f6f95fde8e57a651c2 Mon Sep 17 00:00:00 2001 From: Zuhaitz Méndez Fernández de Aránguiz Date: Sun, 25 Jan 2026 19:24:58 +0000 Subject: Implement runtime OS detection and automatic versioning --- .github/workflows/build-ape.yml | 2 +- Makefile | 6 ++++-- src/main.c | 39 +++++++++++++++++++++++---------------- src/parser/parser_stmt.c | 26 ++++++++++++++++---------- src/repl/repl.c | 22 ++++++++++++++++------ src/utils/utils.c | 30 +++++++++++++++++------------- src/zprep.h | 14 ++++++++++++++ 7 files changed, 91 insertions(+), 48 deletions(-) diff --git a/.github/workflows/build-ape.yml b/.github/workflows/build-ape.yml index f5e9c85..ded68fe 100644 --- a/.github/workflows/build-ape.yml +++ b/.github/workflows/build-ape.yml @@ -30,7 +30,7 @@ jobs: - name: Build APE run: | - # Ensure PATH is updated in this step + # Ensure PATH is updated and build with tag-aware versioning export PATH="$HOME/cosmocc/bin:$PATH" make clean make ape diff --git a/Makefile b/Makefile index eaec55a..34b9a43 100644 --- a/Makefile +++ b/Makefile @@ -19,8 +19,9 @@ endif # Default: gcc # To build with clang: make CC=clang # To build with zig: make CC="zig cc" -CC = gcc -CFLAGS = -Wall -Wextra -g -I./src -I./src/ast -I./src/parser -I./src/codegen -I./plugins -I./src/zen -I./src/utils -I./src/lexer -I./src/analysis -I./src/lsp +# Version synchronization +GIT_VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "0.1.0") +CFLAGS = -Wall -Wextra -g -I./src -I./src/ast -I./src/parser -I./src/codegen -I./plugins -I./src/zen -I./src/utils -I./src/lexer -I./src/analysis -I./src/lsp -DZEN_VERSION=\"$(GIT_VERSION)\" TARGET = zc$(EXE) LIBS = -lm -lpthread -ldl @@ -106,6 +107,7 @@ $(ZC_COM_BIN): $(ZC_ENTRY_O) $(SRCS) PLUGINS= \ CC=$(COSMOCC) \ OBJ_DIR=obj-ape \ + ZEN_VERSION="$(GIT_VERSION)" \ LIBS="$(abspath $(ZC_ENTRY_O)) -Wl,--wrap=main" \ TARGET="$(abspath $@)"; diff --git a/src/main.c b/src/main.c index 3bf4832..e2b3cde 100644 --- a/src/main.c +++ b/src/main.c @@ -56,11 +56,14 @@ void print_usage() int main(int argc, char **argv) { memset(&g_config, 0, sizeof(g_config)); -#ifdef _WIN32 - strcpy(g_config.cc, "gcc.exe"); -#else - strcpy(g_config.cc, "gcc"); -#endif + if (z_is_windows()) + { + strcpy(g_config.cc, "gcc.exe"); + } + else + { + strcpy(g_config.cc, "gcc"); + } if (argc < 2) { @@ -346,14 +349,15 @@ int main(int argc, char **argv) const char *thread_flag = g_parser_ctx->has_async ? "-lpthread" : ""; const char *math_flag = "-lm"; -#ifdef _WIN32 - // Windows might use different flags or none for math/threads - math_flag = ""; - if (g_parser_ctx->has_async) + if (z_is_windows()) { - thread_flag = ""; + // Windows might use different flags or none for math/threads + math_flag = ""; + if (g_parser_ctx->has_async) + { + thread_flag = ""; + } } -#endif // If using cosmocc, it handles these usually, but keeping them is okay for Linux targets @@ -386,11 +390,14 @@ int main(int argc, char **argv) if (g_config.mode_run) { char run_cmd[2048]; -#ifdef _WIN32 - sprintf(run_cmd, "%s", outfile); -#else - sprintf(run_cmd, "./%s", outfile); -#endif + if (z_is_windows()) + { + sprintf(run_cmd, "%s", outfile); + } + else + { + sprintf(run_cmd, "./%s", outfile); + } ret = system(run_cmd); remove(outfile); zptr_plugin_mgr_cleanup(); diff --git a/src/parser/parser_stmt.c b/src/parser/parser_stmt.c index aba6f5e..303f6ac 100644 --- a/src/parser/parser_stmt.c +++ b/src/parser/parser_stmt.c @@ -3179,11 +3179,14 @@ char *run_comptime_block(ParserContext *ctx, Lexer *l) char cmd[4096]; char bin[1024]; -#ifdef _WIN32 - sprintf(bin, "%s.exe", filename); -#else - sprintf(bin, "%s.bin", filename); -#endif + if (z_is_windows()) + { + sprintf(bin, "%s.exe", filename); + } + else + { + sprintf(bin, "%s.bin", filename); + } sprintf(cmd, "%s %s -o %s", g_config.cc, filename, bin); if (!g_config.verbose) { @@ -3199,11 +3202,14 @@ char *run_comptime_block(ParserContext *ctx, Lexer *l) sprintf(out_file, "%s.out", filename); // Platform-neutral execution -#ifdef _WIN32 - sprintf(cmd, "%s > %s", bin, out_file); -#else - sprintf(cmd, "./%s > %s", bin, out_file); -#endif + if (z_is_windows()) + { + sprintf(cmd, "%s > %s", bin, out_file); + } + else + { + sprintf(cmd, "./%s > %s", bin, out_file); + } if (system(cmd) != 0) { diff --git a/src/repl/repl.c b/src/repl/repl.c index 274c14c..cb63293 100644 --- a/src/repl/repl.c +++ b/src/repl/repl.c @@ -28,12 +28,10 @@ void run_repl(const char *self_path) char history_path[512]; const char *home = getenv("HOME"); -#ifdef _WIN32 - if (!home) + if (z_is_windows() && !home) { home = getenv("USERPROFILE"); } -#endif if (home) { snprintf(history_path, sizeof(history_path), "%s/.zprep_history", home); @@ -273,10 +271,14 @@ void run_repl(const char *self_path) { tmpdir = getenv("TMP"); } - if (!tmpdir) + if (!tmpdir && !z_is_windows()) { tmpdir = "/tmp"; } + if (!tmpdir) + { + tmpdir = "."; + } snprintf(edit_path, sizeof(edit_path), "%s/zprep_edit_%d.zc", tmpdir, rand()); FILE *f = fopen(edit_path, "w"); if (f) @@ -658,10 +660,14 @@ void run_repl(const char *self_path) { tmpdir = getenv("TMP"); } - if (!tmpdir) + if (!tmpdir && !z_is_windows()) { tmpdir = "/tmp"; } + if (!tmpdir) + { + tmpdir = "."; + } snprintf(tmp_path, sizeof(tmp_path), "%s/zprep_repl_type_%d.zc", tmpdir, rand()); FILE *f = fopen(tmp_path, "w"); @@ -752,10 +758,14 @@ void run_repl(const char *self_path) { tmpdir = getenv("TMP"); } - if (!tmpdir) + if (!tmpdir && !z_is_windows()) { tmpdir = "/tmp"; } + if (!tmpdir) + { + tmpdir = "."; + } snprintf(tmp_path, sizeof(tmp_path), "%s/zprep_repl_time_%d.zc", tmpdir, rand()); FILE *f = fopen(tmp_path, "w"); diff --git a/src/utils/utils.c b/src/utils/utils.c index 159326e..56a7690 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -671,14 +671,17 @@ void scan_build_directives(ParserContext *ctx, const char *src) { printf("[zprep] Downloading %s...\n", filename); char cmd[8192]; -#ifdef _WIN32 - // On Windows, try curl which is often built-in now - sprintf(cmd, "curl -s -L \"%s\" -o \"%s\"", url, filename); -#else - // Try wget, then curl. - sprintf(cmd, "wget -q \"%s\" -O \"%s\" || curl -s -L \"%s\" -o \"%s\"", url, - filename, url, filename); -#endif + if (z_is_windows()) + { + // On Windows, try curl which is often built-in now + sprintf(cmd, "curl -s -L \"%s\" -o \"%s\"", url, filename); + } + else + { + // Try wget, then curl. + sprintf(cmd, "wget -q \"%s\" -O \"%s\" || curl -s -L \"%s\" -o \"%s\"", url, + filename, url, filename); + } if (system(cmd) != 0) { zwarn("Failed to download %s", url); @@ -693,11 +696,12 @@ void scan_build_directives(ParserContext *ctx, const char *src) libs++; } -#ifdef _WIN32 - zwarn("pkg-config is usually not available on Windows. Build directive " - "'pkg-config:%s' might fail.", - libs); -#endif + if (z_is_windows()) + { + zwarn("pkg-config is usually not available on Windows. Build directive " + "'pkg-config:%s' might fail.", + libs); + } char cmd[4096]; sprintf(cmd, "pkg-config --cflags %s", libs); diff --git a/src/zprep.h b/src/zprep.h index ea38927..e7004ee 100644 --- a/src/zprep.h +++ b/src/zprep.h @@ -7,9 +7,23 @@ #include #include #include +#include + +#ifdef __COSMOPOLITAN__ +#include "libc/dce.h" +#define z_is_windows() IsWindows() +#else +#ifdef _WIN32 +#define z_is_windows() 1 +#else +#define z_is_windows() 0 +#endif +#endif // **ZEN VERSION** +#ifndef ZEN_VERSION #define ZEN_VERSION "0.1.0" +#endif // ** ANSI COLORS ** #define COLOR_RESET "\033[0m" -- cgit v1.2.3