1 ## Almost Universal Makefile
2 ## Author: Przemysław Pawełczyk
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
)
22 METASTORE_VER
:= $(shell "$(PROJ_DIR)"/version.sh
)
23 UNAME_S
:= $(shell uname
-s
)
48 ifeq ($(findstring BSD
,$(UNAME_S
)),)
49 ifneq (DragonFly
,$(UNAME_S
))
50 ifneq (Darwin
,$(UNAME_S
))
51 metastore_DLIBS
+= -lbsd
58 ADDITIONAL_FLAGS
+= -DNO_XATTR
62 PVER
:= $(PROJ_DIR
)Makefile.ver
68 # when building from project tree, then always use the same output layout
69 # otherwise use current working directory
70 ifneq (,$(findstring ^
$(realpath
$(PROJ_DIR
)),^
$(realpath .
/)))
71 SDEP
:= $(PROJ_DIR
)$(SDEP
)
81 # Dynamic Shared Object extension
83 # Statically-Linked Library extension
95 -DMETASTORE_VER
="\"$(METASTORE_VER)\"" \
96 -D_FILE_OFFSET_BITS
=64 \
97 -Wall
-Wextra
-pedantic \
101 MUSTHAVE_CFLAGS
:= -std
=c99
102 MUSTHAVE_CXXFLAGS
:= -std
=c
++11
103 OPTIONAL_FLAGS
:= -O2
107 EXECPREFIX
:= $(PREFIX
)
108 BINDIR
:= $(EXECPREFIX
)/bin
109 LIBDIR
:= $(EXECPREFIX
)/lib
110 INCLUDEDIR
:= $(PREFIX
)/include
111 SYSCONFDIR
:= $(PREFIX
)/etc
112 DATAROOTDIR
:= $(PREFIX
)/share
113 DATADIR
:= $(DATAROOTDIR
)
114 DOCDIR
:= ${DATAROOTDIR}/doc
/metastore
115 MANDIR
:= ${DATAROOTDIR}/man
120 strip strip-bins strips-libs \
121 install install-bins install-libs install-includes \
122 install-configs install-docs install-mans install-shares \
123 uninstall uninstall-bins uninstall-libs uninstall-includes \
130 @
$(foreach V
, $(sort $(.VARIABLES
)), \
131 $(if
$(filter-out environment
% default automatic
, $(origin $V)), \
132 $(warning
$V = $(value
$V)) \
133 $(if
$(findstring ^
$(value
$V)%,^
$($V)%),,$(warning
$V == $($V))) \
139 INSTALL_EXEC
:= $(INSTALL
) -m
0755
140 COPY_NODEREF
:= cp
-P
145 ifeq ($(origin CC
),default
)
148 ifeq ($(origin CXX
),default
)
151 ifneq ($(origin CC
),environment
)
152 CC
:= $(CROSS_COMPILE
)$(CC
)
154 ifneq ($(origin CXX
),environment
)
155 CXX
:= $(CROSS_COMPILE
)$(CXX
)
157 ifneq ($(origin CCLD
),environment
)
160 ifneq ($(origin CXXLD
),environment
)
163 ifneq ($(origin STRIP
),environment
)
164 STRIP
:= $(CROSS_COMPILE
)strip
166 CC_PARAMS
= $(CFLAGS
) $(CPPFLAGS
) $(TARGET_ARCH
)
167 CXX_PARAMS
= $(CXXFLAGS
) $(CPPFLAGS
) $(TARGET_ARCH
)
170 ifneq ($(origin CFLAGS
),environment
)
171 CFLAGS
= $(OPTIONAL_FLAGS
)
173 ifneq ($(origin CXXFLAGS
),environment
)
174 CXXFLAGS
= $(OPTIONAL_FLAGS
)
176 override CFLAGS
+= $(MUSTHAVE_FLAGS
) $(MUSTHAVE_CFLAGS
) \
177 $(if
$(INCS_DIR
),-I
$(INCS_DIR
),) -I
$(SRCS_DIR
)
178 override CXXFLAGS
+= $(MUSTHAVE_FLAGS
) $(MUSTHAVE_CXXFLAGS
) \
179 $(if
$(INCS_DIR
),-I
$(INCS_DIR
),) -I
$(SRCS_DIR
)
181 vpath
%.h
$(SRCS_DIR
) $(INCS_DIR
)
182 vpath
%.c
$(SRCS_DIR
)
183 vpath
%.
cpp $(SRCS_DIR
)
185 ### Support for hiding command-line
192 ### Rules for directories
194 $(sort $(OBJS_DIR
) $(BINS_DIR
) $(LIBS_DIR
)):
201 $(1)_OBJS
:= $$(addsuffix .o
,$$(basename $$($(1)_SRCS
)))
204 $$(addsuffix $$(DSO_EXT
),$$(addprefix $$(LIBS_DIR
)$$(LIB_PRE
),$$($(1)_DEPS
))) \
205 $$(addsuffix $$(SLL_EXT
),$$(addprefix $$(LIBS_DIR
)$$(LIB_PRE
),$$($(1)_DEPS
))) \
206 $$(addprefix $$(OBJS_DIR
),$$($(1)_OBJS
)) $$(SDEP
) |
$$(BINS_DIR
)
207 ifeq ($$($(1)_COMP
),CC
)
212 $$(HIDE
)$$($$($(1)_COMP
)LD
) $$(LDFLAGS
) $$(TARGET_ARCH
) \
213 -o
$$@
$$(filter %.o
,$$^
) \
214 -Wl
,-Bstatic
$$($(1)_SLIBS
) -Wl
,-Bdynamic
$$($(1)_DLIBS
)
216 $(1): $$(BINS_DIR
)$(1)
219 SRCS
+= $$($(1)_SRCS
)
220 OBJS
+= $$($(1)_OBJS
)
222 CFGS
+= $$($(1)_CFGS
)
223 MANS
+= $$($(1)_MANS
)
224 SHRS
+= $$($(1)_SHRS
)
230 $(1)_OBJS
:= $$(addsuffix .o
,$$(basename $$($(1)_SRCS
)))
232 $(1)_SOLINK
:= $$(LIB_PRE
)$(1)$$(DSO_EXT
)
233 $(1)_SONAME
:= $$(LIB_PRE
)$(1)$$(DSO_EXT
).
$$($(1)_MAJV
)
234 $(1)_SOFILE
:= $$(LIB_PRE
)$(1)$$(DSO_EXT
).
$$($(1)_MAJV
)$$($(1)_MINV
)
235 $(1)_ARFILE
:= $$(LIB_PRE
)$(1)$$(SLL_EXT
)
237 $$(LIBS_DIR
)$$($(1)_SOLINK
): $$(LIBS_DIR
)$$($(1)_SONAME
)
238 @echo
" LN $$@ -> $$($(1)_SONAME)"
239 $$(HIDE
)(cd
"$(LIBS_DIR)" && ln
-sf
$$($(1)_SONAME
) $$($(1)_SOLINK
))
241 ifneq ($$($(1)_SONAME
),$$($(1)_SOFILE
))
242 $$(LIBS_DIR
)$$($(1)_SONAME
): $$(LIBS_DIR
)$$($(1)_SOFILE
)
243 @echo
" LN $$@ -> $$($(1)_SOFILE)"
244 $$(HIDE
)(cd
"$$(LIBS_DIR)" && ln
-sf
$$($(1)_SOFILE
) $$($(1)_SONAME
))
247 $$(LIBS_DIR
)$$($(1)_SOFILE
): \
248 $$(addsuffix $$(DSO_EXT
),$$(addprefix $$(LIBS_DIR
)$$(LIB_PRE
),$$($(1)_DEPS
))) \
249 $$(addsuffix $$(SLL_EXT
),$$(addprefix $$(LIBS_DIR
)$$(LIB_PRE
),$$($(1)_DEPS
))) \
250 $$(addprefix $$(OBJS_DIR
),$$($(1)_OBJS
)) $$(SDEP
) |
$$(LIBS_DIR
)
251 ifeq ($$($(1)_COMP
),CC
)
256 $$(HIDE
)$$($$($(1)_COMP
)LD
) $$(LDFLAGS
) $$(TARGET_ARCH
) \
257 -shared
-Wl
,-soname
,$$($(1)_SONAME
) \
258 -o
$$@
$$(filter %.o
,$$^
) \
259 -Wl
,-Bstatic
$$($(1)_SLIBS
) -Wl
,-Bdynamic
$$($(1)_DLIBS
)
261 $$(LIBS_DIR
)$$($(1)_ARFILE
): \
262 $$(addprefix $$(OBJS_DIR
),$$($(1)_OBJS
)) $$(SDEP
) |
$$(LIBS_DIR
)
264 $$(HIDE
)$$(AR
) r
$$@
$$(filter %.o
,$$^
)
267 $$(LIBS_DIR
)$$($(1)_SOFILE
) \
268 $$(LIBS_DIR
)$$($(1)_SOLINK
) \
269 $$(LIBS_DIR
)$$($(1)_ARFILE
)
272 SRCS
+= $$($(1)_SRCS
)
273 OBJS
+= $$($(1)_OBJS
)
275 INCS
+= $$($(1)_INCS
)
276 CFGS
+= $$($(1)_CFGS
)
277 MANS
+= $$($(1)_MANS
)
278 SHRS
+= $$($(1)_SHRS
)
280 LIBS_FILES
+= $$($(1)_SOFILE
) $$($(1)_ARFILE
)
281 LIBS_ALL_FILES
+= $$($(1)_SOLINK
) $$($(1)_SONAME
) $$($(1)_SOFILE
) \
286 $(foreach BIN
,$(BINS
),$(eval
$(call BIN_template
,$(BIN
))))
288 $(foreach LIB
,$(LIBS
),$(eval
$(call LIB_template
,$(LIB
))))
291 ### Rules for normal targets
295 $(HIDE
)mkdir
-p
$(dir $@
)
296 $(HIDE
)$(CC
) $(CC_PARAMS
) -c
-o
$@
$<
298 $(OBJS_DIR
)%.o
: %.
cpp
300 $(HIDE
)mkdir
-p
$(dir $@
)
301 $(HIDE
)$(CXX
) $(CXX_PARAMS
) -c
-o
$@
$<
303 $(SDEP
): SRCS_PATH
:= $(SRCS_DIR
)
304 $(SDEP
): SRCS_DIR
:= .
/
305 $(SDEP
): PROJ_DIR
:= ..
/
306 $(SDEP
): $(SRCS
) $(PROJ_DIR
)Makefile
308 $(HIDE
)echo
"# This file is automatically (re)generated by make." >$(SDEP
)
309 $(HIDE
)echo
>>$(SDEP
)
310 $(HIDE
)(cd
"$(SRCS_PATH)" && for FILE in
$(SRCS
); do \
311 if
[ "$${FILE##*.}" = "c" ]; then \
312 $(CC
) $(CFLAGS
) -MT
"\$$(OBJS_DIR)$${FILE%.*}.o" -MM
"$$FILE"; \
314 $(CXX
) $(CXXFLAGS
) -MT
"\$$(OBJS_DIR)$${FILE%.*}.o" -MM
"$$FILE"; \
318 $(DOCS_DIR
)%.txt
: $(MANS_DIR
)/man1
/%.1
320 $(HIDE
)groff
-mandoc
-Kutf8
-Tutf8
$^ | col
-bx
>$@
323 ### Rules for phony targets
327 $(HIDE
)$(RM
) $(addprefix $(BINS_DIR
),$(BINS
)) \
328 $(addprefix $(LIBS_DIR
),$(LIBS_ALL_FILES
)) \
329 $(addprefix $(OBJS_DIR
),$(OBJS
)) \
337 -type d
-exec rmdir
--parents
{} \
; \
338 2>/dev
/null
; exit
0)
342 strip: strip-bins strip-libs
344 strip-bins
: $(addprefix $(BINS_DIR
),$(BINS
))
345 ifneq ($(strip $(BINS
)),)
350 strip-libs
: $(addprefix $(LIBS_DIR
),$(LIBS_FILES
))
351 ifneq ($(strip $(LIBS
)),)
356 install: install-bins install-libs install-includes \
357 install-configs install-docs install-mans install-shares \
359 install-bins
: $(addprefix $(BINS_DIR
),$(BINS
))
360 ifneq ($(strip $(BINS
)),)
362 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(BINDIR
)
363 $(HIDE
)$(INSTALL_EXEC
) \
364 $(addprefix $(BINS_DIR
),$(BINS
)) \
368 install-libs
: $(addprefix $(LIBS_DIR
),$(LIBS_ALL_FILES
))
369 ifneq ($(strip $(LIBS
)),)
371 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(LIBDIR
)
372 $(HIDE
)$(COPY_NODEREF
) \
373 $(addprefix $(LIBS_DIR
),$(LIBS_ALL_FILES
)) \
377 install-includes
: $(addprefix $(INCS_DIR
),$(INCS
))
378 ifneq ($(strip $(INCS
)),)
380 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(INCLUDEDIR
)
381 $(HIDE
)( cd
$(INCS_DIR
) && $(COPY_NODEREF
) --parents \
383 $(DESTDIR
)$(INCLUDEDIR
)/ \
387 install-configs
: $(addprefix $(CFGS_DIR
),$(CFGS
))
388 ifneq ($(strip $(CFGS
)),)
390 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(SYSCONFDIR
)
391 $(HIDE
)( cd
$(CFGS_DIR
) && $(COPY_NODEREF
) --parents \
393 $(DESTDIR
)$(SYSCONFDIR
)/ \
397 install-docs
: $(addprefix $(DOCS_DIR
),$(DOCS
))
398 ifneq ($(strip $(DOCS
)),)
400 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(DOCDIR
)
401 $(HIDE
)( cd
$(DOCS_DIR
) && $(COPY_NODEREF
) --parents
-r \
403 $(DESTDIR
)$(DOCDIR
)/ \
407 install-mans
: $(addprefix $(MANS_DIR
),$(MANS
))
408 ifneq ($(strip $(MANS
)),)
410 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(MANDIR
)
411 $(HIDE
)( cd
$(MANS_DIR
) && $(COPY_NODEREF
) --parents \
413 $(DESTDIR
)$(MANDIR
)/ \
417 install-shares
: $(addprefix $(SHRS_DIR
),$(SHRS
))
418 ifneq ($(strip $(SHRS
)),)
420 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(DATADIR
)
421 $(HIDE
)( cd
$(SHRS_DIR
) && $(COPY_NODEREF
) --parents \
423 $(DESTDIR
)$(DATADIR
)/ \
427 uninstall: uninstall-bins uninstall-libs uninstall-includes \
428 uninstall-docs uninstall-mans uninstall-shares \
431 ifneq ($(strip $(BINS
)),)
432 @echo
" UNINST $(addprefix $(DESTDIR)$(BINDIR)/,$(BINS))"
433 $(HIDE
)$(RM
) $(addprefix $(DESTDIR
)$(BINDIR
)/,$(BINS
))
437 ifneq ($(strip $(LIBS
)),)
438 @echo
" UNINST $(addprefix $(DESTDIR)$(LIBDIR)/,$(LIBS_ALL_FILES))"
439 $(HIDE
)$(RM
) $(addprefix $(DESTDIR
)$(LIBDIR
)/,$(LIBS_ALL_FILES
))
443 ifneq ($(strip $(INCS
)),)
444 @echo
" UNINST $(addprefix $(DESTDIR)$(INCLUDEDIR)/,$(INCS))"
445 $(HIDE
)$(RM
) $(addprefix $(DESTDIR
)$(INCLUDEDIR
)/,$(INCS
))
449 ifneq ($(strip $(DOCS
)),)
450 @echo
" UNINST $(addprefix $(DESTDIR)$(DOCDIR)/,$(DOCS))"
451 $(HIDE
)$(RM
) -r
$(addprefix $(DESTDIR
)$(DOCDIR
)/,$(DOCS
))
455 ifneq ($(strip $(MANS
)),)
456 @echo
" UNINST $(addprefix $(DESTDIR)$(MANDIR)/,$(MANS))"
457 $(HIDE
)$(RM
) $(addprefix $(DESTDIR
)$(MANDIR
)/,$(MANS
))
461 ifneq ($(strip $(SHRS
)),)
462 @echo
" UNINST $(addprefix $(DESTDIR)$(DATADIR)/,$(SHRS))"
463 $(HIDE
)$(RM
) $(addprefix $(DESTDIR
)$(DATADIR
)/,$(SHRS
))
468 ifneq ($(MAKECMDGOALS
),distclean)
469 ifneq ($(MAKECMDGOALS
),clean)