# SPDX-License-Identifier: 0BSD CXX ?= c++ CC ?= cc CPP ?= cpp MANDOC ?= mandoc AWK ?= awk SED ?= sed SYMLINK ?= n LTO ?= y VOREUTILS_VERSION ?= $(shell git describe --always) VOREUTILS_DATE ?= $(shell date $(shell date --version > /dev/null 2>&1 && echo "--date @" || echo "-r ")$(shell git log -1 --no-show-signature --format=%at) +"%B %e, %Y") CFLAGS ?= CPPFLAGS ?= LDFLAGS ?= OUTDIR ?= out/ OBJDIR ?= $(OUTDIR)obj/ CMDDIR ?= $(OUTDIR)cmd/ MANDIR ?= $(OUTDIR)man/ HTMLMANDIR ?= $(OUTDIR)man-html/ AS_NEEDED := -Wl,--as-needed SONAME := -soname SYSTEM := $(shell uname -s) ifeq "$(SYSTEM)" "NetBSD" # else ifeq "$(SYSTEM)" "OpenBSD" # else ifeq "$(SYSTEM)" "Darwin" AS_NEEDED := SONAME := -install_name else # endif CXXVER := $(shell $(CXX) --version | head -1) ifneq "$(findstring clang,$(CXXVER))" "" # GCC doesn't have this granularity CXXSPECIFICCC := -Wpedantic -Wno-c++20-designator -Wno-c99-extensions -Wno-unknown-warning-option ifneq "$(findstring Apple,$(CXXVER))" "" # CMSG_SPACE() is a macro, and it's decidedly constexpr. i don't care if appleclang can't figure that out CXXSPECIFICCC += -Wno-vla-extension endif CXXSPECIFICCC += -Wno-gnu-conditional-omitted-operand ifeq "$(LTO)" "y" CXXSPECIFICLD := -flto=full # Clang produces .o files with LLVM bitcode, which cannot be linked to if put in .as else CXXSPECIFICLD := endif else CXXSPECIFICCC := -Wno-missing-field-initializers -fno-common ifeq "$(LTO)" "y" CXXSPECIFICCC += -flto endif CXXSPECIFICLD := endif ifeq "$(SYMLINK)" "y" SYMFLAG := s endif CCAR := -g -O3 -pipe -Wall -Wextra $(CXXSPECIFICCC) $(CFLAGS) LDAR := $(AS_NEEDED) -L$(OUTDIR) $(CXXSPECIFICLD) $(LDFLAGS) CPPAR := -Iinclude/ -DVOREUTILS_VERSION='"$(VOREUTILS_VERSION)"' -DVOREUTILS_DATE='"$(VOREUTILS_DATE)"' -include vore-id.h $(CPPFLAGS) BINARIES := $(filter-out cmd/aliases,$(wildcard cmd/*)) INCLUDES := $(wildcard include/*) MANPAGES := $(wildcard man/*.[18]) .PHONY : all binaries manpages htmlpages nomandoc clean test .SECONDARY: all : binaries manpages htmlpages allpages : manpages htmlpages clean: rm -rf $(OUTDIR) $(OBJDIR) test : binaries CMDDIR=$(realpath $(CMDDIR))/ find "tests/" -mindepth 1 -maxdepth 1 -type f -print -execdir ./{} \; 3>$(OBJDIR)testpsko CMDDIR=$(realpath $(CMDDIR))/ find "tests/" -mindepth 2 -maxdepth 2 -type f -name test -print -execdir ./{} \; 3>>$(OBJDIR)testpsko @cat $(OBJDIR)testpsko >&2 @! [ -s $(OBJDIR)testpsko ] binaries : $(patsubst %.c,%,$(patsubst %.cpp,%,$(patsubst cmd/%,$(CMDDIR)%,$(BINARIES)))) $(OBJDIR)aliases manpages : $(patsubst %,$(MANDIR)%,$(patsubst %.8,man8/%.8,$(patsubst %.1,man1/%.1,$(patsubst man/%,%,$(MANPAGES))))) $(OBJDIR)man/aliases htmlpages : $(patsubst %,$(HTMLMANDIR)%.html,$(patsubst %.8,man8/%.8,$(patsubst %.1,man1/%.1,$(patsubst man/%,%,$(MANPAGES))))) $(OBJDIR)man/aliases $(HTMLMANDIR)style.css nomandoc : $(MANPAGES) $(OBJDIR)man/aliases sh -xc 'for p; do cp "man/$$p" "$(MANDIR)man$${p##*.}/"; done' sh $(patsubst man/%,%,$(MANPAGES)) $(OBJDIR)man/aliases : man/aliases @mkdir -p $(dir $@) $(MANDIR) $(HTMLMANDIR) $(AWK) '!/^$$/ { \ sec1 = substr($$1, length($$1)); \ sec2 = substr($$2, length($$2)); \ rel = (sec1 == sec2) ? "" : "../man" sec1 "/"; \ print "(mkdir -p man" sec1 " man" sec2 " && cd man" sec2 " && set -x && ln -fs " rel $$1 "$$suff " $$2 "$$suff)"; \ }' $^ > $@ { cd $(MANDIR) && suff= sh; } < $@ { cd $(HTMLMANDIR) && suff=".html" sh; } < $@ # This ordering is suboptimal $(OBJDIR)aliases : cmd/aliases $(patsubst %.c,%,$(patsubst %.cpp,%,$(patsubst cmd/%,$(CMDDIR)%,$(BINARIES)))) @mkdir -p $(dir $@) $(CMDDIR) $(AWK) '!/^$$/ {print "ln -f$(SYMFLAG) " $$1 " " $$2}' $< > $@ { cd $(CMDDIR) && sh -x; } < $@ $(OBJDIR)man/% : man/% @mkdir -p $(dir $@) $(SED) 's/^\.Dd/.Dd $(VOREUTILS_DATE)/' $< > $@ ! $(MANDOC) -I os="voreutils $(VOREUTILS_VERSION)" -Tlint $@ 2>&1 | grep -vE -e 'mandoc: outdated mandoc.db' -e 'STYLE: referenced manual not found' $(MANDIR)man1/% $(MANDIR)man8/% : $(OBJDIR)man/% @mkdir -p $(dir $@) $(MANDOC) -I os="voreutils $(VOREUTILS_VERSION)" -Tman $< | grep -vF 'Automatically generated from an mdoc input file.' > $@ $(HTMLMANDIR)man1/%.html $(HTMLMANDIR)man8/%.html : $(OBJDIR)man/% @mkdir -p $(dir $@) $(MANDOC) -I os="voreutils $(VOREUTILS_VERSION)" -Thtml -Ostyle="../style.css",man="../man%S/%N.%S.html" $< | \ $(AWK) '/^

$@ $(HTMLMANDIR)style.css : man/style.css @mkdir -p $(dir $@) cp $^ $@ $(CMDDIR)% : $(OBJDIR)cmd/%.o @mkdir -p $(dir $@) $(CXX) $(CCAR) $(LDAR) -std=c++17 -fno-exceptions -o $@ $^ $(OBJDIR)%.o : %.c @mkdir -p $(dir $@) $(CC) $(CCAR) $(CPPAR) -c -o $@ $^ $(OBJDIR)%.o : %.cpp $(INCLUDES) @mkdir -p $(dir $@) $(CXX) $(CCAR) $(CPPAR) -std=c++17 -fno-exceptions -c -o $@ $<