Files
klammertext/env/makefile.env
T
ack fe475e774a Klammertext runs natively on Windows; a Windows source-install guide; the bundled sh for @eval :shell
Assembled from klammertext-dev f344a37d0f6e. The commands, the library,
the Standard Klammer Set, the reflection klammerset and the Python
binding build and run natively on Windows (MSYS2 UCRT64 gcc, python.org
Python), and both test tiers pass there. doc/install/windows_source_install.md
is the fifth install guide: a source install parallel to the Linux and
macOS ones, verified by following it on a pristine Windows 11.

Behaviour on every system: paths Klammertext prints use forward slashes;
output is LF; the command line is UTF-8 on Windows; @eval :shell is a
POSIX shell command everywhere -- on Windows it runs the sh Klammertext
ships, BusyBox for Windows (win/busybox/, GPLv2, with its licence and the
source pointer). KLAMMERTEXT_FONTS and KLAMMERTEXT_KLAMMERSETS are lists in
the system's PATH convention (';' on Windows). On Linux and macOS nothing
observable changes.
2026-09-25 00:32:55 +02:00

105 lines
4.9 KiB
Bash

# env/makefile.env — single cross-platform build environment for Klammertext.
#
# Included identically by every component Makefile:
# include $(KLAMMERTEXT_HOME)/env/makefile.env
#
# The platform is auto-detected with uname; the compiler is chosen with
# make COMPILER=gcc (default)
# make COMPILER=clang
# There is no per-host/per-OS file and no DESKTOP_SESSION/HOST/SITE selector.
ifndef KLAMMERTEXT_HOME
$(error KLAMMERTEXT_HOME is not set -- source env/runtime.env first)
endif
include $(KLAMMERTEXT_HOME)/env/optimize.env
UNAME_S := $(shell uname -s)
CPP_VERSION := c++20
# Default compiler: clang on macOS, gcc elsewhere. gcc-built Klammertext
# binaries crash at runtime on macOS (a documented gcc/macOS codegen issue), so
# gcc there is only a compile-time conformance check (via `./dev/rebuild.sh
# gcc`, which compiles under g++ then rebuilds with clang). Override with
# `make COMPILER=...`.
ifeq ($(UNAME_S),Darwin)
COMPILER ?= clang # gcc | clang
else
COMPILER ?= gcc # gcc | clang
endif
# Python: version- and platform-agnostic, no hardcoded paths. On Windows the
# interpreter is python.org's (the one PyPI wheels -- OpenImageIO -- are built
# for); it ships no python3-config, so its prefix is asked of the interpreter
# itself and its import library named by version (libs/python312.lib).
ifneq (,$(filter MINGW% MSYS%,$(UNAME_S)))
PYTHON := python
PYTHON_PREFIX := $(shell cygpath -m "$$($(PYTHON) -c 'import sys; print(sys.base_prefix)')")
PYTHON_INC := -I"$(PYTHON_PREFIX)/Include"
PYTHON_LIB := -L"$(PYTHON_PREFIX)/libs" -l$(shell $(PYTHON) -c 'import sys; print("python%d%d" % sys.version_info[:2])')
else
PYTHON := python3
PYTHON_INC := $(shell python3-config --includes)
PYTHON_LIB := $(shell python3-config --ldflags --embed)
endif
# Flags common to all platforms.
CPPFLAGS = -I$(KLAMMERTEXT_HOME)/mac $(PYTHON_INC)
CXXFLAGS = -Wall -Wextra -Weffc++ -Wshadow -std=$(CPP_VERSION) -fPIC $(OPTIMIZE) $(SANITIZE)
ifeq ($(UNAME_S),Darwin)
# ---------- macOS (Apple Silicon) ----------
# Package-manager prefix, auto-detected: Homebrew (/opt/homebrew) or MacPorts
# (/opt/local). Override with `make MACOS_PREFIX=...`. Only the prefix differs
# between the two: the compiler is Apple Clang either way, and all Python flags
# come from python3-config (prefix-agnostic), so nothing else is PM-specific.
MACOS_PREFIX ?= $(shell test -d /opt/homebrew && echo /opt/homebrew || (test -d /opt/local && echo /opt/local || echo /opt/homebrew))
# Newest optional gcc (conformance check only): Homebrew g++-NN or MacPorts g++-mp-NN.
GCC := $(shell g=$$(ls $(MACOS_PREFIX)/bin/g++-[0-9]* $(MACOS_PREFIX)/bin/g++-mp-[0-9]* 2>/dev/null | sort -V | tail -1); echo $${g:-g++})
CLANG := clang++ # Apple clang (or brew/port llvm)
CPPFLAGS += -I$(MACOS_PREFIX)/include
LDFLAGS = -L$(MACOS_PREFIX)/lib
LDLIBS = $(if $(NOPYTHON),,$(PYTHON_LIB))
SHARED = -dynamiclib
SONAME = -install_name @rpath/$(notdir $@)
ORIGIN := @loader_path
EXPORT_DYNAMIC = -Wl,-export_dynamic
else ifneq (,$(filter MINGW% MSYS%,$(UNAME_S)))
# ---------- Windows (MSYS2, UCRT64 environment; native PE binaries) ----------
# uname says MINGW64_NT-... under UCRT64 too. The compilers come from the
# environment's PATH (/ucrt64/bin). libdl.a is the mingw-w64-dlfcn shim over
# LoadLibrary, linked statically so no libdl.dll travels with the products.
# PE has no soname and no rpath; a DLL is found through PATH or
# the executable's own directory, and GNU ld's -l search list on PE does not
# include ".so", hence the exact-name form below.
GCC := g++
CLANG := clang++
LDFLAGS =
LDLIBS = -l:libdl.a $(if $(NOPYTHON),,$(PYTHON_LIB))
SHARED = -shared
SONAME =
ORIGIN := $$ORIGIN
EXPORT_DYNAMIC = -Wl,--export-all-symbols
KLAMMERTEXT_LIB = -l:libklammertext.so
# A Windows program finds a DLL through PATH or its own directory, never an
# rpath. So every directory that holds a program or a Python extension also
# holds the DLLs it needs: libklammertext.so and the three gcc runtime DLLs
# the toolchain links (from the compiler's own bin/). com/ and kpy/ copy them.
GCC_BIN := $(dir $(shell cygpath -m "$$(command -v g++)"))
GCC_RUNTIME_DLLS := libstdc++-6.dll libgcc_s_seh-1.dll libwinpthread-1.dll
else
# ---------- Linux ----------
GCC := /usr/bin/g++
CLANG := $(shell command -v clang++-18 2>/dev/null || command -v clang++ 2>/dev/null)
LDFLAGS = -L/usr/lib/x86_64-linux-gnu
LDLIBS = -ldl $(if $(NOPYTHON),,$(PYTHON_LIB))
SHARED = -shared
SONAME = -Wl,-soname,$(notdir $@)
ORIGIN := $$ORIGIN
EXPORT_DYNAMIC = -rdynamic
endif
# How a link line names libklammertext (set above for Windows).
KLAMMERTEXT_LIB ?= -lklammertext
# Resolve the compiler choice (gcc by default; clang with COMPILER=clang).
CXX := $(if $(filter clang,$(COMPILER)),$(CLANG),$(GCC))