Files
klammertext/env/makefile.env
T

137 lines
6.7 KiB
Bash
Raw Normal View History

# 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
# 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))