AUTHORS: Update Joey Hess's email address.
[metastore.git] / Makefile
blob33e9c3ded045d84159fed7e9ae3c7e4a48c0a1d3
1 ## Almost Universal Makefile
2 ## Author: Przemysław Pawełczyk
4 BINS := \
5 metastore
7 LIBS := \
9 ### Directories
10 PROJ_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
11 SRCS_DIR = $(PROJ_DIR)src/
12 INCS_DIR = $(PROJ_DIR)include/
13 CFGS_DIR = $(PROJ_DIR)etc/
14 SHRS_DIR = $(PROJ_DIR)share/
15 OBJS_DIR = $(PROJ_DIR)obj/
16 BINS_DIR = $(PROJ_DIR)bin/
17 LIBS_DIR = $(PROJ_DIR)lib/
18 DOCS_DIR = $(PROJ_DIR)
19 MANS_DIR = $(PROJ_DIR)
21 ###
22 METASTORE_VER := $(shell "$(PROJ_DIR)"/version.sh)
23 UNAME_S := $(shell uname -s)
25 ###
27 DOCS := \
28 AUTHORS \
29 FILEFORMAT \
30 LICENSE.GPLv2 \
31 NEWS \
32 README \
33 metastore.txt \
34 examples \
36 metastore_COMP := CC
38 metastore_SRCS := \
39 metaentry.c \
40 metastore.c \
41 utils.c \
43 metastore_DLIBS := \
45 metastore_MANS := \
46 man1/metastore.1 \
48 ifeq ($(findstring BSD,$(UNAME_S)),)
49 ifneq (DragonFly,$(UNAME_S))
50 ifneq (Darwin,$(UNAME_S))
51 metastore_DLIBS += -lbsd
52 endif
53 endif
54 endif
56 PVER := $(PROJ_DIR)Makefile.ver
58 SDEP := Makefile.dep
60 -include $(PVER)
62 # when building from project tree, then always use the same output layout
63 # otherwise use current working directory
64 ifneq (,$(findstring ^$(realpath $(PROJ_DIR)),^$(realpath ./)))
65 SDEP := $(PROJ_DIR)$(SDEP)
66 else
67 OBJS_DIR := ./obj/
68 BINS_DIR := ./bin/
69 LIBS_DIR := ./lib/
70 endif
73 # library name prefix
74 LIB_PRE := lib
75 # Dynamic Shared Object extension
76 DSO_EXT := .so
77 # Statically-Linked Library extension
78 SLL_EXT := .a
81 ### Default target
82 all: libs bins
84 bins: $(BINS)
85 libs: $(LIBS)
87 ### Flags
88 MUSTHAVE_FLAGS := \
89 -DMETASTORE_VER="\"$(METASTORE_VER)\"" \
90 -D_FILE_OFFSET_BITS=64 \
91 -Wall -Wextra -pedantic \
92 -g \
94 MUSTHAVE_CFLAGS := -std=c99
95 MUSTHAVE_CXXFLAGS := -std=c++11
96 OPTIONAL_FLAGS := -O2
98 ### Install paths
99 PREFIX := /usr/local
100 EXECPREFIX := $(PREFIX)
101 BINDIR := $(EXECPREFIX)/bin
102 LIBDIR := $(EXECPREFIX)/lib
103 INCLUDEDIR := $(PREFIX)/include
104 SYSCONFDIR := $(PREFIX)/etc
105 DATAROOTDIR := $(PREFIX)/share
106 DATADIR := $(DATAROOTDIR)
107 DOCDIR := ${DATAROOTDIR}/doc/metastore
108 MANDIR := ${DATAROOTDIR}/man
110 ### Phony targets
111 .PHONY: \
112 all bins libs \
113 strip strip-bins strips-libs \
114 install install-bins install-libs install-includes \
115 install-configs install-docs install-mans install-shares \
116 uninstall uninstall-bins uninstall-libs uninstall-includes \
117 clean distclean \
118 dep \
120 ### Install tools
121 INSTALL := install
122 INSTALL_EXEC := $(INSTALL) -m 0755
123 COPY_NODEREF := cp -P
125 ### Build tools
126 DEFCC := gcc
127 DEFCXX := g++
128 ifeq ($(origin CC),default)
129 CC := $(DEFCC)
130 endif
131 ifeq ($(origin CXX),default)
132 CXX := $(DEFCXX)
133 endif
134 ifneq ($(origin CC),environment)
135 CC := $(CROSS_COMPILE)$(CC)
136 endif
137 ifneq ($(origin CXX),environment)
138 CXX := $(CROSS_COMPILE)$(CXX)
139 endif
140 ifneq ($(origin CCLD),environment)
141 CCLD := $(CC)
142 endif
143 ifneq ($(origin CXXLD),environment)
144 CXXLD := $(CXX)
145 endif
146 ifneq ($(origin STRIP),environment)
147 STRIP := $(CROSS_COMPILE)strip
148 endif
149 CC_PARAMS = $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH)
150 CXX_PARAMS = $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)
152 ### Helpers
153 comma := ,
155 ### Final flags
156 ifneq ($(origin CFLAGS),environment)
157 CFLAGS = $(OPTIONAL_FLAGS)
158 endif
159 ifneq ($(origin CXXFLAGS),environment)
160 CXXFLAGS = $(OPTIONAL_FLAGS)
161 endif
162 override CFLAGS += $(MUSTHAVE_FLAGS) $(MUSTHAVE_CFLAGS) \
163 $(if $(INCS_DIR),-I$(INCS_DIR),) -I$(SRCS_DIR)
164 override CXXFLAGS += $(MUSTHAVE_FLAGS) $(MUSTHAVE_CXXFLAGS) \
165 $(if $(INCS_DIR),-I$(INCS_DIR),) -I$(SRCS_DIR)
166 override LDFLAGS := $(subst -Wl$(comma),,$(LDFLAGS))
167 ifneq ($(origin CCLDFLAGS),environment)
168 CCLDFLAGS := $(addprefix -Wl$(comma),$(LDFLAGS))
169 endif
170 ifneq ($(origin CXXLDFLAGS),environment)
171 CXXLDFLAGS := $(addprefix -Wl$(comma),$(LDFLAGS))
172 endif
174 vpath %.h $(SRCS_DIR) $(INCS_DIR)
175 vpath %.c $(SRCS_DIR)
176 vpath %.cpp $(SRCS_DIR)
178 ### Support for hiding command-line
179 V ?= 0
180 HIDE_0 := @
181 HIDE_1 :=
182 HIDE := $(HIDE_$(V))
185 ### Rules for directories
187 $(sort $(OBJS_DIR) $(BINS_DIR) $(LIBS_DIR)):
188 @mkdir -p $@
190 ### Templated rules
192 define BIN_template
194 $(1)_OBJS := $$(addsuffix .o,$$(basename $$($(1)_SRCS)))
196 $$(BINS_DIR)$(1): \
197 $$(addsuffix $$(DSO_EXT),$$(addprefix $$(LIBS_DIR)$$(LIB_PRE),$$($(1)_DEPS))) \
198 $$(addsuffix $$(SLL_EXT),$$(addprefix $$(LIBS_DIR)$$(LIB_PRE),$$($(1)_DEPS))) \
199 $$(addprefix $$(OBJS_DIR),$$($(1)_OBJS)) $$(SDEP) | $$(BINS_DIR)
200 ifeq ($$($(1)_COMP),CC)
201 @echo " CCLD $$@"
202 else
203 @echo " CXXLD $$@"
204 endif
205 $$(HIDE)$$($$($(1)_COMP)LD) $$($$($(1)_COMP)LDFLAGS) $$(TARGET_ARCH) \
206 -o $$@ $$(filter %.o,$$^) \
207 -Wl,-Bstatic $$($(1)_SLIBS) -Wl,-Bdynamic $$($(1)_DLIBS)
209 $(1): $$(BINS_DIR)$(1)
210 .PHONY: $(1)
212 SRCS += $$($(1)_SRCS)
213 OBJS += $$($(1)_OBJS)
215 CFGS += $$($(1)_CFGS)
216 MANS += $$($(1)_MANS)
217 SHRS += $$($(1)_SHRS)
219 endef
221 define LIB_template
223 $(1)_OBJS := $$(addsuffix .o,$$(basename $$($(1)_SRCS)))
225 $(1)_SOLINK := $$(LIB_PRE)$(1)$$(DSO_EXT)
226 $(1)_SONAME := $$(LIB_PRE)$(1)$$(DSO_EXT).$$($(1)_MAJV)
227 $(1)_SOFILE := $$(LIB_PRE)$(1)$$(DSO_EXT).$$($(1)_MAJV)$$($(1)_MINV)
228 $(1)_ARFILE := $$(LIB_PRE)$(1)$$(SLL_EXT)
230 $$(LIBS_DIR)$$($(1)_SOLINK): $$(LIBS_DIR)$$($(1)_SONAME)
231 @echo " LN $$@ -> $$($(1)_SONAME)"
232 $$(HIDE)(cd "$(LIBS_DIR)" && ln -sf $$($(1)_SONAME) $$($(1)_SOLINK))
234 ifneq ($$($(1)_SONAME),$$($(1)_SOFILE))
235 $$(LIBS_DIR)$$($(1)_SONAME): $$(LIBS_DIR)$$($(1)_SOFILE)
236 @echo " LN $$@ -> $$($(1)_SOFILE)"
237 $$(HIDE)(cd "$$(LIBS_DIR)" && ln -sf $$($(1)_SOFILE) $$($(1)_SONAME))
238 endif
240 $$(LIBS_DIR)$$($(1)_SOFILE): \
241 $$(addsuffix $$(DSO_EXT),$$(addprefix $$(LIBS_DIR)$$(LIB_PRE),$$($(1)_DEPS))) \
242 $$(addsuffix $$(SLL_EXT),$$(addprefix $$(LIBS_DIR)$$(LIB_PRE),$$($(1)_DEPS))) \
243 $$(addprefix $$(OBJS_DIR),$$($(1)_OBJS)) $$(SDEP) | $$(LIBS_DIR)
244 ifeq ($$($(1)_COMP),CC)
245 @echo " CCLD $$@"
246 else
247 @echo " CXXLD $$@"
248 endif
249 $$(HIDE)$$($$($(1)_COMP)LD) $$($$($(1)_COMP)LDFLAGS) $$(TARGET_ARCH) \
250 -shared -Wl,-soname,$$($(1)_SONAME) \
251 -o $$@ $$(filter %.o,$$^) \
252 -Wl,-Bstatic $$($(1)_SLIBS) -Wl,-Bdynamic $$($(1)_DLIBS)
254 $$(LIBS_DIR)$$($(1)_ARFILE): \
255 $$(addprefix $$(OBJS_DIR),$$($(1)_OBJS)) $$(SDEP) | $$(LIBS_DIR)
256 @echo " AR $$@"
257 $$(HIDE)$$(AR) r $$@ $$(filter %.o,$$^)
259 $(1): \
260 $$(LIBS_DIR)$$($(1)_SOFILE) \
261 $$(LIBS_DIR)$$($(1)_SOLINK) \
262 $$(LIBS_DIR)$$($(1)_ARFILE)
263 .PHONY: $(1)
265 SRCS += $$($(1)_SRCS)
266 OBJS += $$($(1)_OBJS)
268 INCS += $$($(1)_INCS)
269 CFGS += $$($(1)_CFGS)
270 MANS += $$($(1)_MANS)
271 SHRS += $$($(1)_SHRS)
273 LIBS_FILES += $$($(1)_SOFILE) $$($(1)_ARFILE)
274 LIBS_ALL_FILES += $$($(1)_SOLINK) $$($(1)_SONAME) $$($(1)_SOFILE) \
275 $$($(1)_ARFILE)
277 endef
279 $(foreach BIN,$(BINS),$(eval $(call BIN_template,$(BIN))))
281 $(foreach LIB,$(LIBS),$(eval $(call LIB_template,$(LIB))))
284 ### Rules for normal targets
286 $(OBJS_DIR)%.o: %.c
287 @echo " CC $@"
288 $(HIDE)mkdir -p $(dir $@)
289 $(HIDE)$(CC) $(CC_PARAMS) -c -o $@ $<
291 $(OBJS_DIR)%.o: %.cpp
292 @echo " CXX $@"
293 $(HIDE)mkdir -p $(dir $@)
294 $(HIDE)$(CXX) $(CXX_PARAMS) -c -o $@ $<
296 $(SDEP): SRCS_PATH := $(SRCS_DIR)
297 $(SDEP): SRCS_DIR := ./
298 $(SDEP): PROJ_DIR := ../
299 $(SDEP): $(SRCS) $(PROJ_DIR)Makefile
300 @echo " DEPS";
301 $(HIDE)echo "# This file is automatically (re)generated by make." >$(SDEP)
302 $(HIDE)echo >>$(SDEP)
303 $(HIDE)(cd "$(SRCS_PATH)" && for FILE in $(SRCS); do \
304 if [ "$${FILE##*.}" = "c" ]; then \
305 $(CC) $(CFLAGS) -MT "\$$(OBJS_DIR)$${FILE%.*}.o" -MM "$$FILE"; \
306 else \
307 $(CXX) $(CXXFLAGS) -MT "\$$(OBJS_DIR)$${FILE%.*}.o" -MM "$$FILE"; \
308 fi \
309 done) >>$(SDEP)
311 $(DOCS_DIR)%.txt: $(MANS_DIR)/man1/%.1
312 @echo " GROFF $@"
313 $(HIDE)groff -mandoc -Kutf8 -Tutf8 $^ | col -bx >$@
316 ### Rules for phony targets
318 clean:
319 @echo " CLEAN"
320 $(HIDE)$(RM) $(addprefix $(BINS_DIR),$(BINS)) \
321 $(addprefix $(LIBS_DIR),$(LIBS_ALL_FILES)) \
322 $(addprefix $(OBJS_DIR),$(OBJS)) \
323 $(SDEP)
325 distclean: clean
326 $(HIDE)(find \
327 $(OBJS_DIR) \
328 $(LIBS_DIR) \
329 $(BINS_DIR) \
330 -type d -exec rmdir --parents {} \; \
331 2>/dev/null ; exit 0)
333 dep: $(SDEP)
335 strip: strip-bins strip-libs
337 strip-bins: $(addprefix $(BINS_DIR),$(BINS))
338 ifneq ($(strip $(BINS)),)
339 @echo " STRIP $^"
340 $(HIDE)$(STRIP) $^
341 endif
343 strip-libs: $(addprefix $(LIBS_DIR),$(LIBS_FILES))
344 ifneq ($(strip $(LIBS)),)
345 @echo " STRIP $^"
346 $(HIDE)$(STRIP) $^
347 endif
349 install: install-bins install-libs install-includes \
350 install-configs install-docs install-mans install-shares \
352 install-bins: $(addprefix $(BINS_DIR),$(BINS))
353 ifneq ($(strip $(BINS)),)
354 @echo " INSTALL $^"
355 $(HIDE)$(INSTALL) -d $(DESTDIR)$(BINDIR)
356 $(HIDE)$(INSTALL_EXEC) \
357 $(addprefix $(BINS_DIR),$(BINS)) \
358 $(DESTDIR)$(BINDIR)/
359 endif
361 install-libs: $(addprefix $(LIBS_DIR),$(LIBS_ALL_FILES))
362 ifneq ($(strip $(LIBS)),)
363 @echo " INSTALL $^"
364 $(HIDE)$(INSTALL) -d $(DESTDIR)$(LIBDIR)
365 $(HIDE)$(COPY_NODEREF) \
366 $(addprefix $(LIBS_DIR),$(LIBS_ALL_FILES)) \
367 $(DESTDIR)$(LIBDIR)/
368 endif
370 install-includes: $(addprefix $(INCS_DIR),$(INCS))
371 ifneq ($(strip $(INCS)),)
372 @echo " INSTALL $^"
373 $(HIDE)$(INSTALL) -d $(DESTDIR)$(INCLUDEDIR)
374 $(HIDE)( cd $(INCS_DIR) && $(COPY_NODEREF) --parents \
375 $(INCS) \
376 $(DESTDIR)$(INCLUDEDIR)/ \
378 endif
380 install-configs: $(addprefix $(CFGS_DIR),$(CFGS))
381 ifneq ($(strip $(CFGS)),)
382 @echo " INSTALL $^"
383 $(HIDE)$(INSTALL) -d $(DESTDIR)$(SYSCONFDIR)
384 $(HIDE)( cd $(CFGS_DIR) && $(COPY_NODEREF) --parents \
385 $(CFGS) \
386 $(DESTDIR)$(SYSCONFDIR)/ \
388 endif
390 install-docs: $(addprefix $(DOCS_DIR),$(DOCS))
391 ifneq ($(strip $(DOCS)),)
392 @echo " INSTALL $^"
393 $(HIDE)$(INSTALL) -d $(DESTDIR)$(DOCDIR)
394 $(HIDE)( cd $(DOCS_DIR) && $(COPY_NODEREF) --parents -r \
395 $(DOCS) \
396 $(DESTDIR)$(DOCDIR)/ \
398 endif
400 install-mans: $(addprefix $(MANS_DIR),$(MANS))
401 ifneq ($(strip $(MANS)),)
402 @echo " INSTALL $^"
403 $(HIDE)$(INSTALL) -d $(DESTDIR)$(MANDIR)
404 $(HIDE)( cd $(MANS_DIR) && $(COPY_NODEREF) --parents \
405 $(MANS) \
406 $(DESTDIR)$(MANDIR)/ \
408 endif
410 install-shares: $(addprefix $(SHRS_DIR),$(SHRS))
411 ifneq ($(strip $(SHRS)),)
412 @echo " INSTALL $^"
413 $(HIDE)$(INSTALL) -d $(DESTDIR)$(DATADIR)
414 $(HIDE)( cd $(SHRS_DIR) && $(COPY_NODEREF) --parents \
415 $(SHRS) \
416 $(DESTDIR)$(DATADIR)/ \
418 endif
420 uninstall: uninstall-bins uninstall-libs uninstall-includes \
421 uninstall-docs uninstall-mans uninstall-shares \
423 uninstall-bins:
424 ifneq ($(strip $(BINS)),)
425 @echo " UNINST $(addprefix $(DESTDIR)$(BINDIR)/,$(BINS))"
426 $(HIDE)$(RM) $(addprefix $(DESTDIR)$(BINDIR)/,$(BINS))
427 endif
429 uninstall-libs:
430 ifneq ($(strip $(LIBS)),)
431 @echo " UNINST $(addprefix $(DESTDIR)$(LIBDIR)/,$(LIBS_ALL_FILES))"
432 $(HIDE)$(RM) $(addprefix $(DESTDIR)$(LIBDIR)/,$(LIBS_ALL_FILES))
433 endif
435 uninstall-includes:
436 ifneq ($(strip $(INCS)),)
437 @echo " UNINST $(addprefix $(DESTDIR)$(INCLUDEDIR)/,$(INCS))"
438 $(HIDE)$(RM) $(addprefix $(DESTDIR)$(INCLUDEDIR)/,$(INCS))
439 endif
441 uninstall-docs:
442 ifneq ($(strip $(DOCS)),)
443 @echo " UNINST $(addprefix $(DESTDIR)$(DOCDIR)/,$(DOCS))"
444 $(HIDE)$(RM) -r $(addprefix $(DESTDIR)$(DOCDIR)/,$(DOCS))
445 endif
447 uninstall-mans:
448 ifneq ($(strip $(MANS)),)
449 @echo " UNINST $(addprefix $(DESTDIR)$(MANDIR)/,$(MANS))"
450 $(HIDE)$(RM) $(addprefix $(DESTDIR)$(MANDIR)/,$(MANS))
451 endif
453 uninstall-shares:
454 ifneq ($(strip $(SHRS)),)
455 @echo " UNINST $(addprefix $(DESTDIR)$(DATADIR)/,$(SHRS))"
456 $(HIDE)$(RM) $(addprefix $(DESTDIR)$(DATADIR)/,$(SHRS))
457 endif
460 ### Dependencies
461 ifneq ($(MAKECMDGOALS),distclean)
462 ifneq ($(MAKECMDGOALS),clean)
463 -include $(SDEP)
464 endif
465 endif