- @image under txt and ansi is a picture in characters, in five styles (Image_txt_style: halfblock the default, shade, ascii, quadrant, braille), sized to the terminal's width less a margin when ktext runs in one, every cell in its own colours under ansi; a figure's caption is centred under it and no txt caption is ruled off any more. - The build compiles as many files at once as the machine has cores (JOBS; make -C com JOBS=1 for a small machine): the sub-makes' bare -j meant unlimited parallelism and exhausted 8 GB machines. The three install pages say "make -C com". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
148 lines
7.4 KiB
Bash
148 lines
7.4 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)')")
|
|
# The interpreter "python" resolves to must be python.org's, which has an
|
|
# import library under libs/. MSYS2's own python (installed as a dependency
|
|
# of poppler, through glib2) sits in /ucrt64/bin ahead of it and has none:
|
|
# a build against it compiles nothing (no Include/Python.h) or embeds an
|
|
# interpreter without the user's pip packages. env/runtime.env puts
|
|
# python.org's directory first; refuse rather than build the wrong thing.
|
|
# (Asked of the interpreter, not $(wildcard): the prefix "C:/Program Files"
|
|
# has a space, on which wildcard splits.)
|
|
ifeq (,$(NOPYTHON))
|
|
ifneq (yes,$(shell $(PYTHON) -c 'import os, sys; print("yes" if os.path.isdir(os.path.join(sys.base_prefix, "libs")) else "no")'))
|
|
$(error "python" is $(PYTHON_PREFIX)/python, not python.org's interpreter (no libs/ there); source env/runtime.env, which puts python.org's Python first on PATH)
|
|
endif
|
|
endif
|
|
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
|
|
|
|
# How many compiles run at once. Every sub-make below passes -j$(JOBS): a
|
|
# bare "-j" means UNLIMITED to GNU make, and from 2026-02 until 2026-09-30
|
|
# that is what the sub-makes carried -- all ~47 optimising compiles at once,
|
|
# which no one noticed on the development machines' memory and which put an
|
|
# 8 GB Raspberry Pi 5 into an out-of-memory livelock three times in a day
|
|
# (and was the Windows Sandbox's "parallel OOM"). The outer command never
|
|
# governed it: "make -C com" without -j was not serial. Override for a
|
|
# small machine: make -C com JOBS=1.
|
|
JOBS ?= $(shell nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)
|
|
|
|
# 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
|
|
EXE :=
|
|
DSO := .so
|
|
KLAMMERTEXT_LIBFILE := libklammertext.so
|
|
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.
|
|
GCC := g++
|
|
CLANG := clang++
|
|
LDFLAGS =
|
|
LDLIBS = -l:libdl.a $(if $(NOPYTHON),,$(PYTHON_LIB))
|
|
SHARED = -shared
|
|
SONAME =
|
|
ORIGIN := $$ORIGIN
|
|
EXPORT_DYNAMIC = -Wl,--export-all-symbols
|
|
EXE := .exe
|
|
DSO := .dll
|
|
KLAMMERTEXT_LIBFILE := klammertext.dll
|
|
# 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: klammertext.dll 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 ----------
|
|
EXE :=
|
|
DSO := .so
|
|
KLAMMERTEXT_LIBFILE := libklammertext.so
|
|
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
|
|
# Product names (decided 2026-09-25: Windows users get Windows names). The
|
|
# three variables above are set per platform: EXE is the executable suffix
|
|
# (".exe" on Windows, none elsewhere), DSO the suffix of a shared object
|
|
# loaded at run time (".dll" / ".so": document$(DSO), reflect$(DSO)), and
|
|
# KLAMMERTEXT_LIBFILE the library's file name (klammertext.dll /
|
|
# libklammertext.so). A make target carries the suffix so that the file the
|
|
# compiler writes IS the target: bin/ktext never existed on Windows -- gcc
|
|
# wrote ktext.exe -- and every make relinked the three commands. The engine's
|
|
# own copy of the DSO suffix is shared_library_suffix in mac/file.h.
|
|
#
|
|
# One link form everywhere: GNU ld's -l search list on PE ends with
|
|
# "<name>.dll", so -lklammertext finds klammertext.dll as it finds
|
|
# libklammertext.so on Linux (it did NOT find a DLL called libklammertext.so,
|
|
# which needed the exact-name -l: form).
|
|
KLAMMERTEXT_LIB = -lklammertext
|
|
|
|
# Resolve the compiler choice (gcc by default; clang with COMPILER=clang).
|
|
CXX := $(if $(filter clang,$(COMPILER)),$(CLANG),$(GCC))
|