platform.mk 5.98 KB
Newer Older
1 2 3 4
# Platform-specific stuff
# Don't touch this unless you're changing the way targets are compiled
# You have been warned

5
# Platform-dependent stuff checks
Marek Vavruša's avatar
Marek Vavruša committed
6
CCLD := $(CC)
7
CLANG_TIDY ?= clang-tidy -quiet
8
CGO := go tool cgo
9
GO := go
10
CAT := cat
11
SED := sed
12
LCOV := lcov
13
GENHTML := genhtml
Marek Vavruša's avatar
Marek Vavruša committed
14
LIBEXT := .so
15
AREXT  := .a
Marek Vavruša's avatar
Marek Vavruša committed
16 17
LIBTYPE := shared
MODTYPE := shared
18
ARTYPE  := static
Marek Vavruša's avatar
Marek Vavruša committed
19 20
BINEXT :=
PLATFORM = Linux
21
ARCH := $(word 1, $(subst -, ,$(shell $(CC) -dumpmachine)))
22
# Library versioning flags (platform-specific)
23 24
comma := ,
SOVER = $(if $(1),-Wl$(comma)-soname$(comma)$(3)$(call SOVER_EXT,$(1)))
25 26
# Library versioned extension (platform-specific)
SOVER_EXT = $(LIBEXT).$(1)
Marek Vavruša's avatar
Marek Vavruša committed
27 28 29 30 31 32 33 34
ifeq ($(OS),Windows_NT)
	PLATFORM := Windows
	RM := del
	LN := link
	LIBEXT := .lib
	BINEXT := .exe
else
	UNAME := $(shell uname -s)
35 36 37 38 39 40 41 42 43 44 45 46 47
	ifeq ($(UNAME),Darwin)
		PLATFORM := Darwin
		LIBEXT := .dylib
		MODTYPE := dynamiclib
                # 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
48
		LDFLAGS += -pthread -lm -Wl,-E
49 50 51 52 53 54 55 56 57
                # ELF hardening options
		ifneq ($(HARDENING),no)
			BINFLAGS += -pie
			LDFLAGS += -Wl,-z,relro,-z,now
		endif
		ifeq ($(UNAME),Linux)
		LDFLAGS += -ldl
		endif
	endif
Marek Vavruša's avatar
Marek Vavruša committed
58 59 60 61 62 63 64
endif

# Silent compilation
ifeq ($(V),1)
	quiet = $($1)
else
	quiet = @echo "  $1	$2"; $($1)
65
endif
Marek Vavruša's avatar
Marek Vavruša committed
66 67 68 69 70 71 72

# Make objects and depends (name)
define make_objs
$(1)_OBJ := $$($(1)_SOURCES:.c=.o)
$(1)_DEP := $$($(1)_SOURCES:.c=.d)
-include $$($(1)_DEP)
endef
73 74 75 76
define make_objrule
$(1): $(1:.o=.c)
	$$(call quiet,CC,$$<) $(2) -MMD -MP -c $$< -o $$@
endef
Marek Vavruša's avatar
Marek Vavruša committed
77

78
# Make target (name,path,ext,ldflags, 5:dst,amalgable,abiver)
Marek Vavruša's avatar
Marek Vavruša committed
79
define make_target
80 81 82 83 84 85 86 87 88
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
Marek Vavruša's avatar
Marek Vavruša committed
89
$$(eval $$(call make_objs,$(1)))
90
endif
91
# Rules to generate objects with custom CFLAGS and binary/library
92
$$(foreach obj,$$($(1)_OBJ),$$(eval $$(call make_objrule,$$(obj),$$(BUILD_CFLAGS) $$($(1)_CFLAGS))))
93
$(1) := $(2)/$(1)$(3)
Marek Vavruša's avatar
Marek Vavruša committed
94
$(2)/$(1)$(3): $$($(1)_OBJ) $$($(1)_DEPEND)
95 96
ifeq ($(4),-$(ARTYPE))
	$(call quiet,AR,$$@) rcs $$@ $$($(1)_OBJ)
97 98 99 100
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)) $$@
101
else
102
	$(call quiet,CCLD,$$@) $$($(1)_CFLAGS) $(BUILD_CFLAGS) $$($(1)_OBJ) $(call SOVER,$(7),$(7),$(1)) -o $$@ $(4) $$($(1)_LIBS) $(BUILD_LDFLAGS) $$($(1)_LDFLAGS)
103
endif
104
endif
105 106 107
# Linter rules
$(1)-lint: $$($(1)_SOURCES)
	$(call quiet,CLANG_TIDY,$(1)) $$($(1)_SOURCES) -- $(BUILD_CFLAGS) $$($(1)_CFLAGS) -DMP_FREELIST_SIZE=0 -D__clang_analyzer__
108
# Additional rules
Marek Vavruša's avatar
Marek Vavruša committed
109
$(1)-clean:
110 111 112 113
	$(RM) $$($(1)_OBJ) $$($(1)_DEP) $(2)/$(1)$(3)
ifeq ($(6), yes)
	$(RM) $(1).amalg.c $(1).amalg.o
endif
Marek Vavruša's avatar
Marek Vavruša committed
114
$(1)-install: $(2)/$(1)$(3)
115
# Modules install to special path
116
ifneq ($(5),$(MODULEDIR))
Marek Vavruša's avatar
Marek Vavruša committed
117
	$(INSTALL) -d $(DESTDIR)$(5)
118
endif
119 120
# Versioned library install
ifneq ($(strip $(7)),)
121
	$(INSTALL) $(2)/$(1)$(call SOVER_EXT,$(7)) $(DESTDIR)$(5)/
122 123
	$(LN) -f $(1)$(call SOVER_EXT,$(7)) $(DESTDIR)$(5)/$(1)$(3)
else
Marek Vavruša's avatar
Marek Vavruša committed
124
	$(INSTALL) $(2)/$(1)$(3) $(DESTDIR)$(5)
125
endif
Marek Vavruša's avatar
Marek Vavruša committed
126
ifneq ($$(strip $$($(1)_HEADERS)),)
Marek Vavruša's avatar
Marek Vavruša committed
127 128
	$(INSTALL) -d $(DESTDIR)$(INCLUDEDIR)/$(1)
	$(INSTALL) -m 644 $$($(1)_HEADERS) $(DESTDIR)$(INCLUDEDIR)/$(1)
Marek Vavruša's avatar
Marek Vavruša committed
129
endif
130
.PHONY: $(1)-clean $(1)-install
Marek Vavruša's avatar
Marek Vavruša committed
131 132
endef

133
# Make targets (name,path,amalgable yes|no,abiver)
134
make_bin = $(call make_target,$(1),$(2),$(BINEXT),$(BINFLAGS),$(BINDIR),$(3))
135
make_sbin = $(call make_target,$(1),$(2),$(BINEXT),$(BINFLAGS),$(SBINDIR),$(3))
136
make_lib = $(call make_target,$(1),$(2),$(LIBEXT),-$(LIBTYPE),$(LIBDIR),$(3),$(4))
137 138
make_module = $(call make_target,$(1),$(2),$(LIBEXT),-$(LIBTYPE),$(MODULEDIR),$(3))
make_static = $(call make_target,$(1),$(2),$(AREXT),-$(ARTYPE),$(LIBDIR),$(3))
Marek Vavruša's avatar
Marek Vavruša committed
139 140 141

# Find library (pkg-config)
define find_lib
142
	$(call find_alt,$(1),$(1),$(2))
Marek Vavruša's avatar
Marek Vavruša committed
143 144
endef

145 146
# Find library alternative (pkg-config)
define find_alt
Marek Vavruša's avatar
Marek Vavruša committed
147
	ifeq ($$(strip $$($(1)_LIBS)),)
148 149 150 151 152 153 154
		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
Marek Vavruša's avatar
Marek Vavruša committed
155
	endif
156 157 158 159 160
	ifeq ($$(strip $$($(1)_LIBS)),)
		HAS_$(1) := no
	else
		HAS_$(1) := yes
	endif
161 162
endef

163 164 165
# Find binary
define find_bin
	ifeq ($$(strip $$($(1)_BIN)),)
Marek Vavruša's avatar
Marek Vavruša committed
166 167 168 169
		$(1)_BIN := $(shell which $(1))
	endif
	ifeq ($$(strip $$($(1)_BIN)),)
		HAS_$(1) := no
170 171 172 173 174
	else
		HAS_$(1) := yes
		$(1) := $$($(1)_BIN)
	endif
endef
175 176 177

# Find version
define find_ver
178
	ifeq ($(shell test $(2) -ge $(3); echo $$?),0)
179 180 181 182 183 184
		HAS_$(1) := yes
	else
		HAS_$(1) := no
	endif
endef

185 186 187 188
# Find Go package
define find_gopkg
	HAS_$(1) := $(shell go list $(2) > /dev/null 2>&1 && echo yes || echo no)
endef
189

190 191 192 193 194
# 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

195 196 197 198 199
# Find Python package
define find_pythonpkg
	HAS_$(1) := $(shell python -c "import $(1)" > /dev/null 2>&1 && echo yes || echo no)
endef

200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
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
#