ifeq ($(FONTSHIPDIR),)
$(error Please initialize Fontship by sourcing fontship.mk first, then include your project rules, then source this rules.mk file)
endif
$(MAKEFILE_LIST):;
SOURCES_SFD ?= $(filter %.sfd,$(SOURCES))
SOURCES_UFO ?= $(filter %.ufo,$(SOURCES))
SOURCES_GLYPHS ?= $(filter %.glyphs,$(SOURCES))
SOURCES_DESIGNSPACE ?= $(filter %.designspace,$(SOURCES))
CANONICAL ?= $(or $(and $(SOURCES_GLYPHS),glyphs),$(and $(SOURCES_SFD),sfd),$(and $(SOURCES_UFO),ufo))
isVariable ?= $(and $(SOURCES_GLYPHS)$(SOURCES_DESIGNSPACE),true)
ifeq ($(CANONICAL),glyphs)
_FamilyNames := $(sort $(foreach SOURCE,$(SOURCES_GLYPHS),$(call glyphsFamilyNames,$(SOURCE))))
_FontInstances := $(sort $(foreach SOURCE,$(SOURCES_GLYPHS),$(call glyphsInstances,$(SOURCE))))
_FamilyMasters := $(sort $(foreach SOURCE,$(SOURCES_GLYPHS),$(call designspaceMasters,$(SOURCE))))
endif
ifeq ($(CANONICAL),sfd)
_FamilyNames := $(sort $(foreach SOURCE,$(SOURCES_SFD),$(call sfdFamilyNames,$(SOURCE))))
_FontInstances := $(sort $(foreach SOURCE,$(SOURCES_SFD),$(call sfdInstances,$(SOURCE))))
endif
ifeq ($(CANONICAL),ufo)
ifeq ($(isVariable),true)
_FamilyNames := $(sort $(foreach SOURCE,$(SOURCES_DESIGNSPACE),$(call designspaceFamilyNames,$(SOURCE))))
_FontInstances := $(sort $(foreach SOURCE,$(SOURCES_DESIGNSPACE),$(call designspaceInstances,$(SOURCE))))
_FamilyMasters := $(sort $(foreach SOURCE,$(SOURCES_DESIGNSPACE),$(call designspaceMasters,$(SOURCE))))
else
_FamilyNames := $(sort $(foreach SOURCE,$(SOURCES_UFO),$(call ufoFamilyNames,$(SOURCE))))
_FontInstances := $(sort $(foreach SOURCE,$(SOURCES_UFO),$(call ufoInstances,$(SOURCE))))
endif
endif
FamilyNames ?= $(_FamilyNames)
FontInstances ?= $(_FontInstances)
FamilyMasters ?= $(_FamilyMasters)
HINT ?= true
STATICOTF ?= true
STATICTTF ?= true
STATICWOFF ?= true
STATICWOFF2 ?= true
VARIABLEOTF ?=
VARIABLETTF ?= $(isVariable)
VARIABLEWOFF ?= $(isVariable)
VARIABLEWOFF2 ?= $(isVariable)
INSTANCES ?= $(foreach FamilyName,$(FamilyNames),$(foreach STYLE,$(FontInstances),$(FamilyName)-$(STYLE)))
isTagged := $(and $(findstring -r0-,$(GitVersion)),true)
DEBUG ?=
VERBOSE ?=
QUIET ?=
ifeq ($(DEBUG),true)
.SHELLFLAGS += -x
FONTMAKEFLAGS ?= --verbose DEBUG
FONTVFLAGS ?=
PSAUTOHINTFLAGS ?= -vv --traceback
TTFAUTOHINTFLAGS ?= -v --debug
TTXFLAGS ?= -v
WOFF2COMPRESSFLAGS ?=
GFTOOLSFLAGS ?=
PYTHONFLAGS ?= -d
SFDNORMALIZEFLAGS ?=
SFNT2WOFFFLAGS ?=
UFONORMALIZERFLAGS ?= -v
else
ifeq ($(VERBOSE),true)
FONTMAKEFLAGS ?= --verbose INFO
FONTVFLAGS ?=
GFTOOLSFLAGS ?=
PSAUTOHINTFLAGS ?= -vv
PYTHONFLAGS ?= -v
SFDNORMALIZEFLAGS ?=
SFNT2WOFFFLAGS ?=
TTFAUTOHINTFLAGS ?= -v
TTXFLAGS ?= -v
WOFF2COMPRESSFLAGS ?=
UFONORMALIZERFLAGS ?= -v
else
ifeq ($(QUIET),true)
FONTMAKEFLAGS ?= --verbose ERROR 2> /dev/null
FONTVFLAGS ?= 2> /dev/null
GFTOOLSFLAGS ?= > /dev/null
PSAUTOHINTFLAGS ?= 2> /dev/null
PYTHONFLAGS ?= 2> /dev/null
SFDNORMALIZEFLAGS ?= 2> /dev/null
SFNT2WOFFFLAGS ?= 2> /dev/null
TTFAUTOHINTFLAGS ?= 2> /dev/null
TTXFLAGS ?= 2> /dev/null
WOFF2COMPRESSFLAGS ?= 2> /dev/null
UFONORMALIZERFLAGS ?= -q 2> /dev/null
else
FONTMAKEFLAGS ?= --verbose WARNING
FONTVFLAGS ?=
GFTOOLSFLAGS ?=
PSAUTOHINTFLAGS ?= -v
PYTHONFLAGS ?=
SFDNORMALIZEFLAGS ?=
SFNT2WOFFFLAGS ?=
TTFAUTOHINTFLAGS ?=
TTXFLAGS ?=
WOFF2COMPRESSFLAGS ?=
UFONORMALIZERFLAGS ?=
endif
endif
endif
STATICOTFS = $(and $(STATICOTF),$(addsuffix .otf,$(INSTANCES)))
STATICTTFS = $(and $(STATICTTF),$(addsuffix .ttf,$(INSTANCES)))
STATICWOFFS = $(and $(STATICWOFF),$(addsuffix .woff,$(INSTANCES)))
STATICWOFF2S = $(and $(STATICWOFF2),$(addsuffix .woff2,$(INSTANCES)))
VARIABLEOTFS = $(and $(VARIABLEOTF),$(addsuffix -VF.otf,$(FamilyMasters)))
VARIABLETTFS = $(and $(VARIABLETTF),$(addsuffix -VF.ttf,$(FamilyMasters)))
VARIABLEWOFFS = $(and $(VARIABLEWOFF),$(addsuffix -VF.woff,$(FamilyMasters)))
VARIABLEWOFF2S = $(and $(VARIABLEWOFF2),$(addsuffix -VF.woff2,$(FamilyMasters)))
.PHONY: debug
debug:
echo "FONTSHIPDIR = $(FONTSHIPDIR)"
echo "GITNAME = $(GITNAME)"
echo "PROJECT = $(PROJECT)"
echo "PROJECTDIR = $(PROJECTDIR)"
echo "BUILDDIR = $(BUILDDIR)"
echo "SOURCEDIR = $(SOURCEDIR)"
echo "CONTAINERIZED = $(CONTAINERIZED)"
echo "----------------------------"
echo "FamilyNames = $(FamilyNames)"
echo "FontInstances = $(FontInstances)"
echo "FontVersion = $(FontVersion)"
echo "GitVersion = $(GitVersion)"
echo "isTagged = $(isTagged)"
echo "isVariable = $(isVariable)"
echo "CANONICAL = $(CANONICAL)"
echo "DISTDIR = $(DISTDIR)"
echo "----------------------------"
echo "SOURCES = $(SOURCES)"
echo "SOURCES_SFD = $(SOURCES_SFD)"
echo "SOURCES_GLYPHS = $(SOURCES_GLYPHS)"
echo "SOURCES_UFO = $(SOURCES_UFO)"
echo "SOURCES_DESIGNSPACE = $(SOURCES_DESIGNSPACE)"
echo "INSTANCES = $(INSTANCES)"
echo "STATICOTFS = $(STATICOTFS)"
echo "STATICTTFS = $(STATICTTFS)"
echo "STATICWOFFS = $(STATICWOFFS)"
echo "STATICWOFF2S = $(STATICWOFF2S)"
echo "VARIABLEOTFS = $(VARIABLEOTFS)"
echo "VARIABLETTFS = $(VARIABLETTFS)"
echo "VARIABLEWOFFS = $(VARIABLEWOFFS)"
echo "VARIABLEWOFF2S = $(VARIABLEWOFF2S)"
.PHONY: force
force:;
.PHONY: fail
.PHONY: _gha
_gha:
exec >> $${GITHUB_OUTPUT:-/dev/stdout}
echo "family-names=$(FamilyNames)"
echo "font-version=$(FontVersion)"
echo "DISTDIR=$(DISTDIR)"
echo "PROJECT=$(PROJECT)"
.PHONY: all
all: fonts $(call ifTrue,$(DEBUG),debug)
.PHONY: clean
clean:
$(GIT) clean -dxf
.PHONY: ufo
ufo: $$(addsuffix .ufo,$$(INSTANCES))
.PHONY: glyphs
glyphs: $$(addsuffix .glyphs,$$(INSTANCES))
.PHONY: sfd
sfd: $$(addsuffix .sfd,$$(INSTANCES))
.PHONY: fonts
fonts: static variable
.PHONY: static
static: static-otf static-ttf static-woff static-woff2
.PHONY: variable
variable: variable-otf variable-ttf variable-woff variable-woff2
.PHONY: otf
otf: static-otf variable-otf
.PHONY: ttf
ttf: static-ttf variable-ttf
.PHONY: woff
woff: static-woff variable-woff
.PHONY: woff2
woff2: static-woff2 variable-woff2
.PHONY: static-otf
static-otf: $$(STATICOTFS)
.PHONY: static-ttf
static-ttf: $$(STATICTTFS)
.PHONY: static-woff
static-woff: $$(STATICWOFFS)
.PHONY: static-woff2
static-woff2: $$(STATICWOFF2S)
.PHONY: variable-otf
variable-otf: $$(VARIABLEOTFS)
.PHONY: variable-ttf
variable-ttf: $$(VARIABLETTFS)
.PHONY: variable-woff
variable-woff: $$(VARIABLEWOFFS)
.PHONY: variable-woff2
variable-woff2: $$(VARIABLEWOFF2S)
.PHONY: normalize
normalize: NORMALIZE_MODE = true
normalize: $(SOURCES)
.gitignore: force
$(abort_if_not_clean)
$(call addline,.fontship)
$(call addline,*.otf)
$(call addline,*.ttf)
$(call addline,*.woff)
$(call addline,*.woff2)
$(call addline,$(PROJECT)-*)
$(call addline,!*/$(PROJECT)-*)
$(call addline,.DS_Store)
$(call addline,$(SOURCEDIR)/*$(lparen)Autosaved$(rparen).glyphs)
$(call addline,$(SOURCEDIR)/*_backups)
ifneq ($(CANONICAL),glyphs)
$(call addline,$(SOURCEDIR)/*.glyphs)
else
$(call delline,$(SOURCEDIR)/*.glyphs)
endif
ifneq ($(CANONICAL),sfd)
$(call addline,$(SOURCEDIR)/*.sfd)
else
$(call delline,$(SOURCEDIR)/*.sfd)
endif
ifneq ($(CANONICAL),ufo)
$(call addline,$(SOURCEDIR)/*.ufo)
else
$(call delline,$(SOURCEDIR)/*.ufo)
endif
.PHONY: check
check: $(addsuffix -check,$(SOURCES))
$(BUILDDIR):
mkdir -p $@
ifeq ($(PROJECT),Data)
$(warning We cannot read the Project’s name inside Docker. Please manually specify it by adding PROJECT='Name' as an agument to your command invocation)
endif
-include $(FONTSHIPDIR)/rules/$(CANONICAL).mk
$(foreach FamilyName,$(FamilyNames),$(eval $(call otf_instance_template,$(FamilyName))))
$(foreach FamilyName,$(FamilyNames),$(eval $(call ttf_instance_template,$(FamilyName))))
_VTTSOURCES := $(wildcard $(SOURCEDIR)/*-vtt.ttx)
ifneq ($(_VTTSOURCES),)
$(BUILDDIR)/%-VF-variable-vtthinted.otf: $(BUILDDIR)/%-VF-variable.otf $(SOURCEDIR)/%-vtt.ttx
cp $< $@
python -m vttLib mergefile $(filter %.ttx,$^) $@
$(BUILDDIR)/%-VF-variable-vtthinted.ttf: $(BUILDDIR)/%-VF-variable.ttf $(SOURCEDIR)/%-vtt.ttx
cp $< $@
python -m vttLib mergefile $(filter %.ttx,$^) $@
$(BUILDDIR)/%-hinted.otf: $(BUILDDIR)/%-vtthinted.otf
$(PYTHON) -m vttLib compile --ship $< $@
$(BUILDDIR)/%-hinted.ttf: $(BUILDDIR)/%-vtthinted.ttf
$(PYTHON) -m vttLib compile --ship $< $@
endif
$(BUILDDIR)/%-hinted.otf: $(BUILDDIR)/%.otf
$(PSAUTOHINT) $(PSAUTOHINTFLAGS) -o $@ $<
$(BUILDDIR)/%-hinted.ttf: $(BUILDDIR)/%.ttf
$(TTFAUTOHINT) $(TTFAUTOHINTFLAGS) -n $< $@
$(STATICTTFS): %.ttf: $(BUILDDIR)/%-instance$(and $(HINT),-hinted).ttf $(BUILDDIR)/last-commit
export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
$(GFTOOLS) $(GFTOOLSFLAGS) fix-font -o $@ $<
$(normalizeVersion)
$(BUILDDIR)/%-subr.otf: $(BUILDDIR)/%-instance$(and $(HINT),-hinted).otf
$(PYTHON) -m cffsubr -o $@ $<
$(STATICOTFS): %.otf: $(BUILDDIR)/%-subr.otf $(BUILDDIR)/last-commit
export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
$(GFTOOLS) $(GFTOOLSFLAGS) fix-font -o $@ $<
$(normalizeVersion)
$(VARIABLEOTFS): %.otf: $(BUILDDIR)/%-variable$(and $(_VTTSOURCES),-hinted).otf $(BUILDDIR)/last-commit
export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
$(GFTOOLS) $(GFTOOLSFLAGS) fix-font -o $@ $<
$(normalizeVersion)
$(VARIABLETTFS): %.ttf: $(BUILDDIR)/%-variable$(and $(_VTTSOURCES),-hinted).ttf $(BUILDDIR)/last-commit
export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
$(GFTOOLS) $(GFTOOLSFLAGS) fix-font -o $@ $<
$(normalizeVersion)
ifneq ($(STATICTTF),true)
%.woff: %.otf
$(SFNT2WOFF) $(SFNT2WOFFFLAGS) $<
%.woff2: %.otf
$(WOFF2COMPRESS) $(WOFF2COMPRESSFLAGS) $<
else
%.woff: %.ttf
$(SFNT2WOFF) $(SFNT2WOFFFLAGS) $<
%.woff2: %.ttf
$(WOFF2COMPRESS) $(WOFF2COMPRESSFLAGS) $<
endif
forceiftagchange = $(shell $(_ENV) $(CMP) -s $@ - <<< "$(GitVersion)" || echo force)
$(BUILDDIR)/last-commit: $$(forceiftagchange) | $(BUILDDIR)
$(GIT) update-index --refresh --ignore-submodules ||:
$(GIT) diff-index --quiet --cached HEAD -- $(SOURCES)
echo $(GitVersion) > $@
DISTDIR ?= $(PROJECT)-$(if $(isTagged),$(FontVersion),$(GitVersion))
DISTEXT ?= zip tar.zst
$(DISTDIR):
mkdir -p $@
.PHONY: dist
dist: $(foreach EXT,$(DISTEXT),$(DISTDIR).$(EXT))
$(DISTDIR).tar.bz2 $(DISTDIR).tar.gz $(DISTDIR).tar.xz $(DISTDIR).zip: install-dist
bsdtar -acf $@ $(DISTDIR)
$(DISTDIR).tar.zst: install-dist
bsdtar --zstd --options zstd:compression-level=19 -cf $@ $(DISTDIR)
_E = md txt markdown
dist_doc_DATA ?= $(wildcard $(foreach B,readme README contributors CONTRIBUTORS fontlog FONTLOG,$(foreach E,$(_E),$(B).$(E))))
dist_license_DATA ?= $(wildcard $(foreach B,ofl OFL ofl-faq OFL-FAQ license LICENSE copying COPYING copyingn-ofl COPYING-OFL authors AUTHORS,$(foreach E,$(_E),$(B).$(E))))
.PHONY: install-dist
install-dist: fonts | $(DISTDIR)
$(and $(dist_doc_DATA),install -Dm644 -t "$(DISTDIR)/" $(dist_doc_DATA))
$(and $(dist_license_DATA),install -Dm644 -t "$(DISTDIR)/" $(dist_license_DATA))
$(and $(STATICOTFS),install -Dm644 -t "$(DISTDIR)/static/OTF/" $(STATICOTFS))
$(and $(STATICTTFS),install -Dm644 -t "$(DISTDIR)/static/TTF/" $(STATICTTFS))
$(and $(STATICWOFFS),install -Dm644 -t "$(DISTDIR)/static/WOFF/" $(STATICWOFFS))
$(and $(STATICWOFF2S),install -Dm644 -t "$(DISTDIR)/static/WOFF2/" $(STATICWOFF2S))
$(and $(VARIABLEOTFS),install -Dm644 -t "$(DISTDIR)/variable/OTF/" $(VARIABLEOTFS))
$(and $(VARIABLETTFS),install -Dm644 -t "$(DISTDIR)/variable/TTF/" $(VARIABLETTFS))
$(and $(VARIABLEWOFFS),install -Dm644 -t "$(DISTDIR)/variable/WOFF/" $(VARIABLEWOFFS))
$(and $(VARIABLEWOFF2S),install -Dm644 -t "$(DISTDIR)/variable/WOFF2/" $(VARIABLEWOFF2S))
install-local: install-local-otf
install-local-otf: otf
$(and $(STATICOTFS),install -Dm644 -t "$${HOME}/.local/share/fonts/OTF/" $(STATICOTFS))
$(and $(VARIABLEOTFS),install -Dm644 -t "$${HOME}/.local/share/fonts/variable/" $(VARIABLEOTFS))
install-local-ttf: ttf
$(and $(STATICTTFS),install -Dm644 -t "$${HOME}/.local/share/fonts/TTF/" $(STATICTTFS))
$(and $(VARIABLETTFS),install -Dm644 -t "$${HOME}/.local/share/fonts/variable/" $(VARIABLETTFS))
POSTFONTSHIPEVAL ?=
ifneq (,$(POSTFONTSHIPEVAL))
$(eval $(POSTFONTSHIPEVAL))
endif
POSTFONTSHIPINCLUDE ?=
ifneq (,$(POSTFONTSHIPINCLUDE))
-include $(POSTFONTSHIPINCLUDE)
endif