summaryrefslogtreecommitdiffstats
path: root/platform.mk
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--platform.mk230
1 files changed, 230 insertions, 0 deletions
diff --git a/platform.mk b/platform.mk
new file mode 100644
index 0000000..5498fec
--- /dev/null
+++ b/platform.mk
@@ -0,0 +1,230 @@
+# Platform-specific stuff
+# Don't touch this unless you're changing the way targets are compiled
+# You have been warned
+
+# Platform-dependent stuff checks
+CCLD := $(CC)
+CLANG_TIDY ?= clang-tidy -quiet
+CGO := go tool cgo
+GO := go
+CAT := cat
+SED := sed
+LCOV := lcov
+GENHTML := genhtml
+LIBEXT := .so
+AREXT := .a
+LIBTYPE := shared
+MODTYPE := shared
+ARTYPE := static
+BINEXT :=
+PLATFORM = Linux
+ARCH := $(word 1, $(subst -, ,$(shell $(CC) -dumpmachine)))
+# Library versioning flags (platform-specific)
+comma := ,
+SOVER = $(if $(1),-Wl$(comma)-soname$(comma)$(3)$(call SOVER_EXT,$(1)))
+# Library versioned extension (platform-specific)
+SOVER_EXT = $(LIBEXT).$(1)
+ifeq ($(OS),Windows_NT)
+ PLATFORM := Windows
+ RM := del
+ LN := link
+ LIBEXT := .lib
+ BINEXT := .exe
+else
+ UNAME := $(shell uname -s)
+ ifeq ($(UNAME),Darwin)
+ PLATFORM := Darwin
+ LIBEXT := .dylib
+ MODTYPE := dynamiclib
+ LDFLAGS += -Wl,-export_dynamic
+ # OS X specific hardening since -pie doesn't work
+ ifneq ($(HARDENING),no)
+ BINFLAGS += -Wl,-pie
+ endif
+ # Version is prepended to dylib
+ SOVER_EXT = .$(1)$(LIBEXT)
+ SOVER = $(if $(1), -compatibility_version $(2) -current_version $(1),)
+ else
+ PLATFORM := POSIX
+ LDFLAGS += -pthread -lm -Wl,--export-dynamic
+ # ELF hardening options
+ ifneq ($(HARDENING),no)
+ BINFLAGS += -pie
+ LDFLAGS += -Wl,-z,relro,-z,now
+ endif
+ ifeq ($(UNAME),Linux)
+ LDFLAGS += -ldl
+ endif
+ ifeq (GCC,$(shell $(CC) --version | grep -q -i '\<gcc\>' && echo GCC))
+ # Otherwise Fedora is making kresd symbols inaccessible for modules.
+ # Clang doesn't support this flag, so we hackily detect gcc.
+ BUILD_CFLAGS += -rdynamic
+ endif
+ endif
+endif
+
+# Silent compilation
+ifeq ($(V),1)
+ quiet = $($1)
+else
+ quiet = @echo " $1 $2"; $($1)
+endif
+
+# Make objects and depends (name)
+define make_objs
+$(1)_OBJ := $$($(1)_SOURCES:.c=.o)
+$(1)_DEP := $$($(1)_SOURCES:.c=.d)
+-include $$($(1)_DEP)
+endef
+define make_objrule
+$(1): $(1:.o=.c)
+ $$(call quiet,CC,$$<) $(2) -MMD -MP -c $$< -o $$@
+endef
+
+# Make target (name,path,ext,ldflags, 5:dst,amalgable,abiver)
+define make_target
+ifeq ($(AMALG)|$(6), yes|yes)
+$(1).amalg.c: $$($(1)_SOURCES)
+ $(call quiet,CAT,$$@) $$($(1)_SOURCES) > $$@
+# AR requires .o compiled
+$(1)_OBJ := $(1).amalg.c
+ifeq ($(4),-$(ARTYPE))
+$(1)_OBJ := $(1).amalg.o
+endif
+else
+$$(eval $$(call make_objs,$(1)))
+endif
+# Rules to generate objects with custom CFLAGS and binary/library
+$$(foreach obj,$$($(1)_OBJ),$$(eval $$(call make_objrule,$$(obj),$$(BUILD_CFLAGS) $$($(1)_CFLAGS))))
+$(1) := $(2)/$(1)$(3)
+$(2)/$(1)$(3): $$($(1)_OBJ) $$($(1)_DEPEND)
+ifeq ($(4),-$(ARTYPE))
+ $(call quiet,AR,$$@) rcs $$@ $$($(1)_OBJ)
+else
+ifneq ($(strip $(7)),)
+ $(call quiet,CCLD,$$@) $$($(1)_CFLAGS) $(BUILD_CFLAGS) $$($(1)_OBJ) $(call SOVER,$(7),$(7),$(1)) -o $(2)/$(1)$(call SOVER_EXT,$(7)) $(4) $$($(1)_LIBS) $(BUILD_LDFLAGS) $$($(1)_LDFLAGS)
+ $(LN) -f $(1)$(call SOVER_EXT,$(7)) $$@
+else
+ $(call quiet,CCLD,$$@) $$($(1)_CFLAGS) $(BUILD_CFLAGS) $$($(1)_OBJ) $(call SOVER,$(7),$(7),$(1)) -o $$@ $(4) $$($(1)_LIBS) $(BUILD_LDFLAGS) $$($(1)_LDFLAGS)
+endif
+endif
+# Linter rules
+$(1)-lint: $$($(1)_SOURCES)
+ $(call quiet,CLANG_TIDY,$(1)) $$($(1)_SOURCES) -- $(BUILD_CFLAGS) $$($(1)_CFLAGS) -DMP_FREELIST_SIZE=0 -D__clang_analyzer__
+# Additional rules
+$(1)-clean:
+ $(RM) $$($(1)_OBJ) $$($(1)_DEP) $(2)/$(1)$(3)
+ifeq ($(6), yes)
+ $(RM) $(1).amalg.c $(1).amalg.o
+endif
+$(1)-install: $(2)/$(1)$(3)
+# Modules install to special path
+ifneq ($(5),$(MODULEDIR))
+ $(INSTALL) -d $(DESTDIR)$(5)
+endif
+# Versioned library install
+ifneq ($(strip $(7)),)
+ $(INSTALL) $(2)/$(1)$(call SOVER_EXT,$(7)) $(DESTDIR)$(5)/
+ $(LN) -f $(1)$(call SOVER_EXT,$(7)) $(DESTDIR)$(5)/$(1)$(3)
+else
+ $(INSTALL) $(2)/$(1)$(3) $(DESTDIR)$(5)
+endif
+ifneq ($$(strip $$($(1)_HEADERS)),)
+ $(INSTALL) -d $(DESTDIR)$(INCLUDEDIR)/$(1)
+ $(INSTALL) -m 644 $$($(1)_HEADERS) $(DESTDIR)$(INCLUDEDIR)/$(1)
+endif
+.PHONY: $(1)-clean $(1)-install
+endef
+
+# Make targets (name,path,amalgable yes|no,abiver)
+make_bin = $(call make_target,$(1),$(2),$(BINEXT),$(BINFLAGS),$(BINDIR),$(3))
+make_sbin = $(call make_target,$(1),$(2),$(BINEXT),$(BINFLAGS),$(SBINDIR),$(3))
+make_lib = $(call make_target,$(1),$(2),$(LIBEXT),-$(LIBTYPE),$(LIBDIR),$(3),$(4))
+make_module = $(call make_target,$(1),$(2),$(LIBEXT),-$(LIBTYPE),$(MODULEDIR),$(3))
+make_static = $(call make_target,$(1),$(2),$(AREXT),-$(ARTYPE),$(LIBDIR),$(3))
+
+# Find library (pkg-config)
+define find_lib
+ $(call find_alt,$(1),$(1),$(2))
+endef
+
+# Find library alternative (pkg-config)
+define find_alt
+ ifeq ($$(strip $$($(1)_LIBS)),)
+ ifneq ($(strip $(3)),)
+ $(1)_VER := $(shell pkg-config --atleast-version=$(3) $(2) && echo $(3))
+ endif
+ ifeq ($(strip $(3)),$$($(1)_VER))
+ $(1)_CFLAGS := $(shell pkg-config --cflags $(2) --silence-errors)
+ $(1)_LIBS := $(shell pkg-config --libs $(2) --silence-errors)
+ endif
+ endif
+ ifeq ($$(strip $$($(1)_LIBS)),)
+ HAS_$(1) := no
+ else
+ HAS_$(1) := yes
+ endif
+endef
+
+# Find binary
+define find_bin
+ ifeq ($$(strip $$($(1)_BIN)),)
+ $(1)_BIN := $(shell which $(1))
+ endif
+ ifeq ($$(strip $$($(1)_BIN)),)
+ HAS_$(1) := no
+ else
+ HAS_$(1) := yes
+ $(1) := $$($(1)_BIN)
+ endif
+endef
+
+# Find version
+define find_ver
+ ifeq ($(shell test $(2) -ge $(3); echo $$?),0)
+ HAS_$(1) := yes
+ else
+ HAS_$(1) := no
+ endif
+endef
+
+# Find Go package
+define find_gopkg
+ HAS_$(1) := $(shell go list $(2) > /dev/null 2>&1 && echo yes || echo no)
+endef
+
+# Find Lua package
+define find_luapkg
+ HAS_$(1) := $(shell luajit -l $(1) -e "os.exit(0)"> /dev/null 2>&1 && echo yes || echo no)
+endef
+
+# Find Python package
+define find_pythonpkg
+ HAS_$(1) := $(shell python3 -c "import $(1)" > /dev/null 2>&1 && echo yes || echo no)
+endef
+
+define find_soname
+
+# N/A on Windows
+ifeq ($(PLATFORM),Windows)
+ $(1)_SONAME = $(1).dll
+endif
+
+# Use otool -D on OS X
+ifeq ($(PLATFORM),Darwin)
+ $(1)_SONAME = $$(shell otool -D $$$$(pkg-config --variable=libdir $(1))/$(1)$(LIBEXT) | sed -ne 's,.*/\($(1)\.[0-9]*.$(LIBEXT)\),\1,p')
+endif
+
+# Use objdump -p on Linux and BSDs
+ifeq ($(PLATFORM),POSIX)
+ifeq ($(UNAME),OpenBSD)
+ $(1)_SONAME = $$(shell basename $$$$(readlink -f $$$$(pkg-config --variable=libdir $(1))/$(1)$(LIBEXT)) | cut -f 1-3 -d .)
+else
+ $(1)_SONAME = $$(shell objdump -p $$$$(pkg-config --variable=libdir $(1))/$(1)$(LIBEXT) | sed -ne 's/[[:space:]]*SONAME[[:space:]]*\($(1)\.so\.[0-4]*\)/\1/p')
+endif
+endif
+
+endef # find_soname
+
+# Use this on OpenBSD
+#