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
56 PVER
:= $(PROJ_DIR
)Makefile.ver
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
)
75 # Dynamic Shared Object extension
77 # Statically-Linked Library extension
89 -DMETASTORE_VER
="\"$(METASTORE_VER)\"" \
90 -D_FILE_OFFSET_BITS
=64 \
91 -Wall
-Wextra
-pedantic \
94 MUSTHAVE_CFLAGS
:= -std
=c99
95 MUSTHAVE_CXXFLAGS
:= -std
=c
++11
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
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 \
123 @
$(foreach V
, $(sort $(.VARIABLES
)), \
124 $(if
$(filter-out environment
% default automatic
, $(origin $V)), \
125 $(warning
$V = $(value
$V)) \
126 $(if
$(findstring ^
$(value
$V)%,^
$($V)%),,$(warning
$V == $($V))) \
132 INSTALL_EXEC
:= $(INSTALL
) -m
0755
133 COPY_NODEREF
:= cp
-P
138 ifeq ($(origin CC
),default
)
141 ifeq ($(origin CXX
),default
)
144 ifneq ($(origin CC
),environment
)
145 CC
:= $(CROSS_COMPILE
)$(CC
)
147 ifneq ($(origin CXX
),environment
)
148 CXX
:= $(CROSS_COMPILE
)$(CXX
)
150 ifneq ($(origin CCLD
),environment
)
153 ifneq ($(origin CXXLD
),environment
)
156 ifneq ($(origin STRIP
),environment
)
157 STRIP
:= $(CROSS_COMPILE
)strip
159 CC_PARAMS
= $(CFLAGS
) $(CPPFLAGS
) $(TARGET_ARCH
)
160 CXX_PARAMS
= $(CXXFLAGS
) $(CPPFLAGS
) $(TARGET_ARCH
)
163 ifneq ($(origin CFLAGS
),environment
)
164 CFLAGS
= $(OPTIONAL_FLAGS
)
166 ifneq ($(origin CXXFLAGS
),environment
)
167 CXXFLAGS
= $(OPTIONAL_FLAGS
)
169 override CFLAGS
+= $(MUSTHAVE_FLAGS
) $(MUSTHAVE_CFLAGS
) \
170 $(if
$(INCS_DIR
),-I
$(INCS_DIR
),) -I
$(SRCS_DIR
)
171 override CXXFLAGS
+= $(MUSTHAVE_FLAGS
) $(MUSTHAVE_CXXFLAGS
) \
172 $(if
$(INCS_DIR
),-I
$(INCS_DIR
),) -I
$(SRCS_DIR
)
174 vpath
%.h
$(SRCS_DIR
) $(INCS_DIR
)
175 vpath
%.c
$(SRCS_DIR
)
176 vpath
%.
cpp $(SRCS_DIR
)
178 ### Support for hiding command-line
185 ### Rules for directories
187 $(sort $(OBJS_DIR
) $(BINS_DIR
) $(LIBS_DIR
)):
194 $(1)_OBJS
:= $$(addsuffix .o
,$$(basename $$($(1)_SRCS
)))
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
)
205 $$(HIDE
)$$($$($(1)_COMP
)LD
) $$(LDFLAGS
) $$(TARGET_ARCH
) \
206 -o
$$@
$$(filter %.o
,$$^
) \
207 -Wl
,-Bstatic
$$($(1)_SLIBS
) -Wl
,-Bdynamic
$$($(1)_DLIBS
)
209 $(1): $$(BINS_DIR
)$(1)
212 SRCS
+= $$($(1)_SRCS
)
213 OBJS
+= $$($(1)_OBJS
)
215 CFGS
+= $$($(1)_CFGS
)
216 MANS
+= $$($(1)_MANS
)
217 SHRS
+= $$($(1)_SHRS
)
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
))
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
)
249 $$(HIDE
)$$($$($(1)_COMP
)LD
) $$(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
)
257 $$(HIDE
)$$(AR
) r
$$@
$$(filter %.o
,$$^
)
260 $$(LIBS_DIR
)$$($(1)_SOFILE
) \
261 $$(LIBS_DIR
)$$($(1)_SOLINK
) \
262 $$(LIBS_DIR
)$$($(1)_ARFILE
)
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
) \
279 $(foreach BIN
,$(BINS
),$(eval
$(call BIN_template
,$(BIN
))))
281 $(foreach LIB
,$(LIBS
),$(eval
$(call LIB_template
,$(LIB
))))
284 ### Rules for normal targets
288 $(HIDE
)mkdir
-p
$(dir $@
)
289 $(HIDE
)$(CC
) $(CC_PARAMS
) -c
-o
$@
$<
291 $(OBJS_DIR
)%.o
: %.
cpp
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
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"; \
307 $(CXX
) $(CXXFLAGS
) -MT
"\$$(OBJS_DIR)$${FILE%.*}.o" -MM
"$$FILE"; \
311 $(DOCS_DIR
)%.txt
: $(MANS_DIR
)/man1
/%.1
313 $(HIDE
)groff
-mandoc
-Kutf8
-Tutf8
$^ | col
-bx
>$@
316 ### Rules for phony targets
320 $(HIDE
)$(RM
) $(addprefix $(BINS_DIR
),$(BINS
)) \
321 $(addprefix $(LIBS_DIR
),$(LIBS_ALL_FILES
)) \
322 $(addprefix $(OBJS_DIR
),$(OBJS
)) \
330 -type d
-exec rmdir
--parents
{} \
; \
331 2>/dev
/null
; exit
0)
335 strip: strip-bins strip-libs
337 strip-bins
: $(addprefix $(BINS_DIR
),$(BINS
))
338 ifneq ($(strip $(BINS
)),)
343 strip-libs
: $(addprefix $(LIBS_DIR
),$(LIBS_FILES
))
344 ifneq ($(strip $(LIBS
)),)
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
)),)
355 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(BINDIR
)
356 $(HIDE
)$(INSTALL_EXEC
) \
357 $(addprefix $(BINS_DIR
),$(BINS
)) \
361 install-libs
: $(addprefix $(LIBS_DIR
),$(LIBS_ALL_FILES
))
362 ifneq ($(strip $(LIBS
)),)
364 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(LIBDIR
)
365 $(HIDE
)$(COPY_NODEREF
) \
366 $(addprefix $(LIBS_DIR
),$(LIBS_ALL_FILES
)) \
370 install-includes
: $(addprefix $(INCS_DIR
),$(INCS
))
371 ifneq ($(strip $(INCS
)),)
373 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(INCLUDEDIR
)
374 $(HIDE
)( cd
$(INCS_DIR
) && $(COPY_NODEREF
) --parents \
376 $(DESTDIR
)$(INCLUDEDIR
)/ \
380 install-configs
: $(addprefix $(CFGS_DIR
),$(CFGS
))
381 ifneq ($(strip $(CFGS
)),)
383 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(SYSCONFDIR
)
384 $(HIDE
)( cd
$(CFGS_DIR
) && $(COPY_NODEREF
) --parents \
386 $(DESTDIR
)$(SYSCONFDIR
)/ \
390 install-docs
: $(addprefix $(DOCS_DIR
),$(DOCS
))
391 ifneq ($(strip $(DOCS
)),)
393 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(DOCDIR
)
394 $(HIDE
)( cd
$(DOCS_DIR
) && $(COPY_NODEREF
) --parents
-r \
396 $(DESTDIR
)$(DOCDIR
)/ \
400 install-mans
: $(addprefix $(MANS_DIR
),$(MANS
))
401 ifneq ($(strip $(MANS
)),)
403 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(MANDIR
)
404 $(HIDE
)( cd
$(MANS_DIR
) && $(COPY_NODEREF
) --parents \
406 $(DESTDIR
)$(MANDIR
)/ \
410 install-shares
: $(addprefix $(SHRS_DIR
),$(SHRS
))
411 ifneq ($(strip $(SHRS
)),)
413 $(HIDE
)$(INSTALL
) -d
$(DESTDIR
)$(DATADIR
)
414 $(HIDE
)( cd
$(SHRS_DIR
) && $(COPY_NODEREF
) --parents \
416 $(DESTDIR
)$(DATADIR
)/ \
420 uninstall: uninstall-bins uninstall-libs uninstall-includes \
421 uninstall-docs uninstall-mans uninstall-shares \
424 ifneq ($(strip $(BINS
)),)
425 @echo
" UNINST $(addprefix $(DESTDIR)$(BINDIR)/,$(BINS))"
426 $(HIDE
)$(RM
) $(addprefix $(DESTDIR
)$(BINDIR
)/,$(BINS
))
430 ifneq ($(strip $(LIBS
)),)
431 @echo
" UNINST $(addprefix $(DESTDIR)$(LIBDIR)/,$(LIBS_ALL_FILES))"
432 $(HIDE
)$(RM
) $(addprefix $(DESTDIR
)$(LIBDIR
)/,$(LIBS_ALL_FILES
))
436 ifneq ($(strip $(INCS
)),)
437 @echo
" UNINST $(addprefix $(DESTDIR)$(INCLUDEDIR)/,$(INCS))"
438 $(HIDE
)$(RM
) $(addprefix $(DESTDIR
)$(INCLUDEDIR
)/,$(INCS
))
442 ifneq ($(strip $(DOCS
)),)
443 @echo
" UNINST $(addprefix $(DESTDIR)$(DOCDIR)/,$(DOCS))"
444 $(HIDE
)$(RM
) -r
$(addprefix $(DESTDIR
)$(DOCDIR
)/,$(DOCS
))
448 ifneq ($(strip $(MANS
)),)
449 @echo
" UNINST $(addprefix $(DESTDIR)$(MANDIR)/,$(MANS))"
450 $(HIDE
)$(RM
) $(addprefix $(DESTDIR
)$(MANDIR
)/,$(MANS
))
454 ifneq ($(strip $(SHRS
)),)
455 @echo
" UNINST $(addprefix $(DESTDIR)$(DATADIR)/,$(SHRS))"
456 $(HIDE
)$(RM
) $(addprefix $(DESTDIR
)$(DATADIR
)/,$(SHRS
))
461 ifneq ($(MAKECMDGOALS
),distclean)
462 ifneq ($(MAKECMDGOALS
),clean)