[CRIU] [PATCH 01/12] build: nmk -- Initial import

Cyrill Gorcunov gorcunov at openvz.org
Fri Feb 12 10:05:07 PST 2016


This is initial import of NMK engine which we gonna use for
CRIU and related tools building.

It's very tiny and while here we merge it as is in future
it gonna be rather a submodule from

	https://github.com/cyrillos/nmk

An idea is to have unified build engine for most tools
we're gonna use.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 scripts/nmk/.gitignore             |   3 +
 scripts/nmk/Documentation/Makefile |  42 +++++++++
 scripts/nmk/Documentation/nmk.txt  |  70 ++++++++++++++
 scripts/nmk/Makefile               |  40 ++++++++
 scripts/nmk/README.md              |   5 +
 scripts/nmk/scripts/build.mk       | 184 +++++++++++++++++++++++++++++++++++++
 scripts/nmk/scripts/include.mk     | 100 ++++++++++++++++++++
 scripts/nmk/scripts/macro.mk       |  27 ++++++
 scripts/nmk/scripts/main.mk        |  31 +++++++
 scripts/nmk/scripts/rules.mk       |  66 +++++++++++++
 scripts/nmk/scripts/tools.mk       |  32 +++++++
 scripts/nmk/scripts/utils.mk       |  28 ++++++
 12 files changed, 628 insertions(+)
 create mode 100644 scripts/nmk/.gitignore
 create mode 100644 scripts/nmk/Documentation/Makefile
 create mode 100644 scripts/nmk/Documentation/nmk.txt
 create mode 100644 scripts/nmk/Makefile
 create mode 100644 scripts/nmk/README.md
 create mode 100644 scripts/nmk/scripts/build.mk
 create mode 100644 scripts/nmk/scripts/include.mk
 create mode 100644 scripts/nmk/scripts/macro.mk
 create mode 100644 scripts/nmk/scripts/main.mk
 create mode 100644 scripts/nmk/scripts/rules.mk
 create mode 100644 scripts/nmk/scripts/tools.mk
 create mode 100644 scripts/nmk/scripts/utils.mk

diff --git a/scripts/nmk/.gitignore b/scripts/nmk/.gitignore
new file mode 100644
index 000000000000..9166105d212f
--- /dev/null
+++ b/scripts/nmk/.gitignore
@@ -0,0 +1,3 @@
+*.swp
+*.swo
+.git-ignore
diff --git a/scripts/nmk/Documentation/Makefile b/scripts/nmk/Documentation/Makefile
new file mode 100644
index 000000000000..981449979b73
--- /dev/null
+++ b/scripts/nmk/Documentation/Makefile
@@ -0,0 +1,42 @@
+ASCIIDOC	:= asciidoc
+A2X		:= a2x
+XMLTO		:= xmlto
+PS2PDF		:= ps2pdf
+
+SRC		+= nmk.txt
+XMLS		:= $(patsubst %.txt,%.xml,$(SRC))
+MANS		:= $(patsubst %.txt,%.8,$(SRC))
+
+GROFF		:= groff
+PAPER		:= $(shell paperconf 2>/dev/null || echo letter)
+GROFF_OPTS	:= -Tps -t -dpaper=$(PAPER) -P-p$(PAPER) -man -msafer -rC1 -rD1 -rS11
+PSS		:= $(MANS:%.8=%.ps)
+PDFS		:= $(MANS:%.8=%.pdf)
+
+ps: $(PSS)
+pdf: $(PDFS)
+all: check $(MANS)
+
+.PHONY: all ps pdf check clean
+
+check:
+	$(Q) for B in $(ASCIIDOC) $(A2X) $(XMLTO); do	\
+		$$B --version > /dev/null || exit 1;	\
+	done
+
+%.8: %.txt
+	$(call msg-gen, $@)
+	$(Q) $(ASCIIDOC) -b docbook -d manpage -o $(patsubst %.8,%.xml,$@) $<
+	$(Q) $(XMLTO) man --skip-validation $(patsubst %.8,%.xml,$@) 2>/dev/null
+
+%.ps: %.8
+	$(call msg-gen, $@)
+	$(Q) $(GROFF) $(GROFF_OPTS) $^ > $@
+
+%.pdf: %.ps
+	$(call msg-gen, $@)
+	$(Q) $(PS2PDF) $< $@
+
+clean:
+	$(call msg-clean, "docs")
+	$(Q) $(RM) $(XMLS) $(MANS) $(PSS) $(PDFS)
diff --git a/scripts/nmk/Documentation/nmk.txt b/scripts/nmk/Documentation/nmk.txt
new file mode 100644
index 000000000000..8e97864d02cf
--- /dev/null
+++ b/scripts/nmk/Documentation/nmk.txt
@@ -0,0 +1,70 @@
+nmk(8)
+======
+
+NAME
+----
+nmk - a framework to minimize Makefile code needed for simple projects
+
+
+SYNOPSIS
+--------
+*make* -f main.mk makefile=Makefile obj=<dir>
+
+
+OVERVIEW
+--------
+Most of projects have similar source code structure:
+
+ * Toplevel 'Makefile'
+ * Source code itself in directory '<src>'
+ * Headers are gathered into directory '<include>'
+
+so that building procedure is invoking *make* to read toplevel 'Makefile',
+compile sources and link a final executable program. Taking this into account
+*nmk* is trying to minimize efforts needed to write 'Makefile'.
+
+
+USAGE
+-----
+First of all the *nmk* scripts are to be placed into some known place so the
+*make* would be able to read them from a command line. Internally *nmk* uses
+*__nmk_dir* variable to find own sources. Thus one can export
+
+----------
+    export __nmk_dir=<directory>/
+----------
+
+in a makefile or do it via environment variables. Note the ending slash is mandatory.
+
+As been mentioned earlier source code tree should include toplevel 'Makefile'
+and source code in '<src>' directory. Source code '<src>' should provide own
+'Makefile' (secondlevel) where files to be compiled are enumerated.
+
+A typical source code tree will look like
+
+----------
+    Makefile        # toplevel Makefile
+    <scripts>       # directory with nmk scripts
+    <src>           # source code directory
+        Makefile    # secondlevel Makefile
+        src1.c      # source code
+        src2.c
+        ...
+----------
+
+In toplevel 'Makefile' we should plug in *nmk* itself
+
+----------
+    export __nmk_dir=scripts/
+    include $(__nmk_dir)include.mk
+----------
+
+In secondlevel 'Makefile' we should enumerate files to be compiled.
+
+----------
+    obj-y   += src1.o
+    obj-y   += src2.o
+    ...
+----------
+
+That is basically all one need to build a program.
diff --git a/scripts/nmk/Makefile b/scripts/nmk/Makefile
new file mode 100644
index 000000000000..d9885c23aec0
--- /dev/null
+++ b/scripts/nmk/Makefile
@@ -0,0 +1,40 @@
+__nmk_dir=scripts/
+export __nmk_dir
+
+include $(__nmk_dir)include.mk
+
+MAKEFLAGS := -r -R --no-print-directory
+
+.PHONY: all help test docs clean install
+
+help:
+	@echo '    Targets:'
+	@echo '      install dir=<dir>  - Install scripts into directory <dir>'
+	@echo '      docs               - Build documentation'
+	@echo '      clean              - Clean everything'
+
+test:
+	$(Q) $(MAKE) -C tests all
+
+docs:
+	$(Q) $(MAKE) -C Documentation all
+
+install:
+	@echo 'Copying scripts into $(dir)'
+	@cp scripts/build.mk $(dir)
+	@cp scripts/include.mk $(dir)
+	@cp scripts/macro.mk $(dir)
+	@cp scripts/main.mk $(dir)
+	@cp scripts/rules.mk $(dir)
+	@cp scripts/tools.mk $(dir)
+	@cp scripts/utils.mk $(dir)
+
+all:
+	@true
+
+clean:
+	$(call msg-clean, "nmk")
+	$(Q) $(MAKE) -C Documentation clean
+	$(Q) $(MAKE) -C tests clean
+
+.DEFAULT_GOAL ?= all
diff --git a/scripts/nmk/README.md b/scripts/nmk/README.md
new file mode 100644
index 000000000000..3c0b570b9434
--- /dev/null
+++ b/scripts/nmk/README.md
@@ -0,0 +1,5 @@
+NMK
+===
+
+NMK stands for NetMaKe --  is a very simple framework for make build system.
+Most ideas are taken from the Linux kernel kbuild system.
diff --git a/scripts/nmk/scripts/build.mk b/scripts/nmk/scripts/build.mk
new file mode 100644
index 000000000000..d976390cc830
--- /dev/null
+++ b/scripts/nmk/scripts/build.mk
@@ -0,0 +1,184 @@
+ifndef ____nmk_defined__build
+
+#
+# General helpers for simplified Makefiles.
+#
+src		:= $(obj)
+obj-y		:=
+lib-y		:=
+target          :=
+deps-y		:=
+all-y		:=
+builtin-name	:=
+lib-name	:=
+ld_flags	:=
+cleanup-y	:=
+
+MAKECMDGOALS := $(call uniq,$(MAKECMDGOALS))
+
+ifndef obj
+        $(error obj is undefined)
+endif
+
+include $(call objectify,$(makefile))
+
+ifneq ($(strip $(target)),)
+	target := $(sort $(call uniq,$(target)))
+endif
+
+#
+# Prepare the unique entries.
+obj-y           := $(sort $(call uniq,$(obj-y)))
+lib-y           := $(filter-out $(obj-y),$(sort $(call uniq,$(lib-y))))
+
+#
+# Add subdir path
+obj-y           := $(call objectify,$(obj-y))
+lib-y           := $(call objectify,$(lib-y))
+
+#
+# Strip custom names.
+lib-name	:= $(strip $(lib-name))
+builtin-name	:= $(strip $(builtin-name))
+
+#
+# Link flags.
+ld_flags	:= $(strip $(LDFLAGS) $(ldflags-y))
+
+#
+# Prepare targets.
+ifneq ($(lib-y),)
+        lib-target :=
+        ifneq ($(lib-name),)
+                lib-target := $(obj)/$(lib-name)
+        else
+                lib-target := $(obj)/lib.a
+        endif
+        cleanup-y += $(lib-target)
+        all-y += $(lib-target)
+endif
+
+ifneq ($(obj-y),)
+        builtin-target :=
+        ifneq ($(builtin-name),)
+                builtin-target := $(obj)/$(builtin-name)
+        else
+                builtin-target := $(obj)/built-in.o
+        endif
+        cleanup-y += $(builtin-target)
+        all-y += $(builtin-target)
+endif
+
+#
+# Helpers for targets.
+define gen-ld-target-rule
+$(1): $(3)
+	$$(call msg-link, $$@)
+	$$(Q) $$(LD) $(2) -r -o $$@ $(4)
+endef
+
+define gen-ar-target-rule
+$(1): $(3)
+	$$(call msg-link, $$@)
+	$$(Q) $$(AR) -rcs$(2) $$@ $(4)
+endef
+
+#
+# Predefined (builtins) targets rules.
+ifdef builtin-target
+        $(eval $(call gen-ld-target-rule,                               \
+                        $(builtin-target),                              \
+                        $(ld_flags),                                    \
+                        $(obj-y),$(obj-y) $(call objectify,$(obj-e))))
+endif
+
+ifdef lib-target
+        $(eval $(call gen-ar-target-rule,                               \
+                        $(lib-target),                                  \
+                        $(ARFLAGS) $(arflags-y),                        \
+                        $(lib-y),$(lib-y) $(call objectify,$(lib-e))))
+endif
+
+#
+# Custom targets rules.
+define gen-custom-target-rule
+        ifneq ($($(1)-obj-y),)
+                $(eval $(call gen-ld-target-rule,                       \
+                                $(obj)/$(1).built-in.o,                 \
+                                $(ld_flags) $($(1)-ldflags-y),          \
+                                $(call objectify,$($(1)-obj-y)),        \
+                                $(call objectify,$($(1)-obj-y))         \
+                                $(call objectify,$($(1)-obj-e))))
+                all-y += $(obj)/$(1).built-in.o
+                cleanup-y += $(obj)/$(1).built-in.o
+        endif
+        ifneq ($($(1)-lib-y),)
+                $(eval $(call gen-ar-target-rule,                       \
+                                $(obj)/$(1).lib.a,                      \
+                                $(ARFLAGS) $($(1)-arflags-y),           \
+                                $(call objectify,$($(1)-lib-y))         \
+                                $(call objectify,$($(1)-lib-e)),        \
+                                $(call objectify,$($(1)-lib-y))))
+                all-y += $(obj)/$(1).lib.a
+                cleanup-y += $(obj)/$(1).lib.a
+        endif
+endef
+
+$(foreach t,$(target),$(eval $(call gen-custom-target-rule,$(t))))
+
+#
+# Figure out if the target we're building needs deps to include.
+define collect-deps
+        ifneq ($(filter-out %.d,$(1)),)
+                ifneq ($(filter %.o %.i %.s,$(1)),)
+                        deps-y += $(addsuffix .d,$(basename $(1)))
+                endif
+        endif
+        ifeq ($(builtin-target),$(1))
+                deps-y += $(obj-y:.o=.d)
+        endif
+        ifeq ($(lib-target),$(1))
+                deps-y += $(lib-y:.o=.d)
+        endif
+        ifneq ($(filter all $(all-y) $(target),$(1)),)
+                deps-y += $(obj-y:.o=.d)
+                deps-y += $(lib-y:.o=.d)
+                deps-y += $(foreach t,$(target),$($(t)-lib-y:.o=.d) $($(t)-obj-y:.o=.d))
+        endif
+endef
+
+ifneq ($(MAKECMDGOALS),)
+        ifneq ($(MAKECMDGOALS),clean)
+                $(foreach goal,$(MAKECMDGOALS),$(eval $(call collect-deps,$(goal))))
+                deps-y := $(call uniq,$(deps-y))
+                ifneq ($(deps-y),)
+                        $(eval -include $(deps-y))
+                endif
+        endif
+endif
+
+#
+# Main phony rule.
+all: $(all-y)
+	@true
+.PHONY: all
+
+#
+# List of object files.
+objlist:
+	$(E) $(obj-y) $(lib-y)
+.PHONY: objlist
+
+#
+# Clean everything up.
+clean:
+	$(call msg-clean, $(obj))
+	$(Q) $(RM) $(obj)/*.o $(obj)/*.d $(obj)/*.i $(obj)/*.s $(cleanup-y)
+.PHONY: clean
+
+#
+# Footer.
+$(__nmk_dir)scripts/build.mk:
+	@true
+____nmk_defined__build = y
+endif
diff --git a/scripts/nmk/scripts/include.mk b/scripts/nmk/scripts/include.mk
new file mode 100644
index 000000000000..6216fead961f
--- /dev/null
+++ b/scripts/nmk/scripts/include.mk
@@ -0,0 +1,100 @@
+ifndef ____nmk_defined__include
+
+#
+# Silent make rules.
+ifeq ($(strip $(V)),)
+        E := @echo
+        Q := @
+else
+        E := @\#
+        Q :=
+endif
+
+export E Q
+
+#
+# Message helpers.
+define msg-gen
+        $(E) "  GEN     " $(1)
+endef
+
+define msg-clean
+        $(E) "  CLEAN   " $(1)
+endef
+
+define msg-cc
+        $(E) "  CC      " $(1)
+endef
+
+define msg-dep
+        $(E) "  DEP     " $(1)
+endef
+
+define msg-link
+        $(E) "  LINK    " $(1)
+endef
+
+define msg-ar
+        $(E) "  AR      " $(1)
+endef
+
+define msg-build
+        $(E) "  BUILD   " $(1)
+endef
+
+#
+# Common vars.
+SUBARCH := $(shell uname -m | sed       \
+                -e s/i.86/x86/          \
+                -e s/x86_64/x86/        \
+                -e s/sun4u/sparc64/     \
+                -e s/arm.*/arm/         \
+                -e s/sa110/arm/         \
+                -e s/s390x/s390/        \
+                -e s/parisc64/parisc/   \
+                -e s/ppc.*/powerpc/     \
+                -e s/mips.*/mips/       \
+                -e s/sh[234].*/sh/      \
+                -e s/aarch64.*/arm64/)
+
+ARCH		?= $(SUBARCH)
+SRCARCH 	:= $(ARCH)
+
+export SUBARCH ARCH SRCARCH
+
+ifndef ____nmk_defined__tools
+        include $(__nmk_dir)tools.mk
+endif
+
+# Do not use make's built-in rules and variables
+# (this increases performance and avoids hard-to-debug behaviour).
+MAKEFLAGS += -rR --no-print-directory
+export MAKEFLAGS
+
+# Avoid funny character set dependencies.
+unexport LC_ALL
+LC_COLLATE=C
+LC_NUMERIC=C
+export LC_COLLATE LC_NUMERIC
+
+# Avoid interference with shell env settings.
+unexport GREP_OPTIONS
+
+# Shorthand for build.
+build := -r -R -f $(__nmk_dir)main.mk makefile=Makefile obj
+export build
+
+# With specified Makefile
+build-as := -r -R -f $(__nmk_dir)main.mk makefile=$$(1) obj=$$(2)
+export build-as
+
+#
+# Dummy target for force building.
+FORCE: ;
+
+#
+# Footer.
+$(__nmk_dir)scripts/include.mk:
+	@true
+____nmk_defined__include = y
+endif
diff --git a/scripts/nmk/scripts/macro.mk b/scripts/nmk/scripts/macro.mk
new file mode 100644
index 000000000000..be6bf0a5e03a
--- /dev/null
+++ b/scripts/nmk/scripts/macro.mk
@@ -0,0 +1,27 @@
+ifndef ____nmk_defined__macro
+
+#
+# Helper to include makefile only once.
+#
+define include-once
+        ifndef $(join ____nmk_defined__,$(1:.mk=))
+                include $(__nmk_dir)$(1)
+        endif
+endef
+
+# Helper to build built-in target in directory.
+# $(eval $(call gen-built-in,<dir>))
+define gen-built-in
+$(1)/%:
+	$$(Q) $$(MAKE) $$(build)=$(1) $$@
+$(1):
+	$$(Q) $$(MAKE) $$(build)=$(1) all
+$(1)/built-in.o: $(1)
+endef
+
+#
+# Footer.
+$(__nmk_dir)scripts/macro.mk:
+	@true
+____nmk_defined__macro = y
+endif
diff --git a/scripts/nmk/scripts/main.mk b/scripts/nmk/scripts/main.mk
new file mode 100644
index 000000000000..7c86f95e7e6d
--- /dev/null
+++ b/scripts/nmk/scripts/main.mk
@@ -0,0 +1,31 @@
+ifndef ____nmk_defined__main
+
+#
+# Genaral inclusion statement
+
+ifndef ____nmk_defined__include
+        include $(__nmk_dir)include.mk
+endif
+
+ifndef ____nmk_defined__macro
+        include $(__nmk_dir)macro.mk
+endif
+
+#
+# Anything else might be included with
+#
+#       $(eval $(call include-once,<name.mk>))
+#
+# Note the order does matter!
+
+$(eval $(call include-once,tools.mk))
+$(eval $(call include-once,utils.mk))
+$(eval $(call include-once,rules.mk))
+$(eval $(call include-once,build.mk))
+
+#
+# Footer
+$(__nmk_dir)scripts/main.mk:
+	@true
+____nmk_defined__main = y
+endif
diff --git a/scripts/nmk/scripts/rules.mk b/scripts/nmk/scripts/rules.mk
new file mode 100644
index 000000000000..e589e449954d
--- /dev/null
+++ b/scripts/nmk/scripts/rules.mk
@@ -0,0 +1,66 @@
+ifndef ____nmk_defined__rules
+
+#
+# Accumulate common flags.
+define nmk-ccflags
+        $(CFLAGS) $(ccflags-y) $(CFLAGS_$@)
+endef
+
+define nmk-asflags
+        $(CFLAGS) $(ASFLAGS) $(asflags-y) $(ASFLAGS_$@)
+endef
+
+#
+# General rules.
+define gen-rule-o-from-c-by-name
+$(1).o: $(2).c
+	$$(call msg-cc, $$@)
+	$$(Q) $$(CC) -c $$(strip $$(nmk-ccflags)) $$< -o $$@
+endef
+define gen-rule-i-from-c-by-name
+$(1).i: $(2).c
+	$$(call msg-cc, $$@)
+	$$(Q) $$(CC) -E $$(strip $$(nmk-ccflags)) $$< -o $$@
+endef
+define gen-rule-s-from-c-by-name
+$(1).s: $(2).c
+	$$(call msg-cc, $$@)
+	$$(Q) $$(CC) -S -fverbose-asm $$(strip $$(nmk-ccflags)) $$< -o $$@
+endef
+define gen-rule-o-from-S-by-name
+$(1).o: $(2).S
+	$$(call msg-cc, $$@)
+	$$(Q) $$(CC) -c $$(strip $$(nmk-asflags)) $$< -o $$@
+endef
+define gen-rule-d-from-c-by-name
+$(1).d: $(2).c
+	$$(call msg-dep, $$@)
+	$$(Q) $$(CC) -M -MT $$@ -MT $$(patsubst %.d,%.o,$$@) $$(strip $$(nmk-ccflags)) $$< -o $$@
+endef
+define gen-rule-d-from-S-by-name
+$(1).d: $(2).S
+	$$(call msg-dep, $$@)
+	$$(Q) $$(CC) -M -MT $$@ -MT $$(patsubst %.d,%.o,$$@) $$(strip $$(nmk-asflags)) $$< -o $$@
+endef
+define gen-rule-i-from-S-by-name
+$(1).i: $(2).S
+	$$(call msg-cc, $$@)
+	$$(Q) $$(CC) -E $$(strip $$(nmk-asflags)) $$< -o $$@
+endef
+
+#
+# Expand early which matched all implicits.
+$(eval $(call gen-rule-o-from-c-by-name,%,%))
+$(eval $(call gen-rule-i-from-c-by-name,%,%))
+$(eval $(call gen-rule-s-from-c-by-name,%,%))
+$(eval $(call gen-rule-o-from-S-by-name,%,%))
+$(eval $(call gen-rule-d-from-c-by-name,%,%))
+$(eval $(call gen-rule-d-from-S-by-name,%,%))
+$(eval $(call gen-rule-i-from-S-by-name,%,%))
+
+#
+# Footer.
+$(__nmk_dir)scripts/rules.mk:
+	@true
+____nmk_defined__rules = y
+endif
diff --git a/scripts/nmk/scripts/tools.mk b/scripts/nmk/scripts/tools.mk
new file mode 100644
index 000000000000..6e7ba6725a4c
--- /dev/null
+++ b/scripts/nmk/scripts/tools.mk
@@ -0,0 +1,32 @@
+ifndef ____nmk_defined__tools
+
+#
+# System tools shorthands
+RM		:= rm -f
+LD		:= $(CROSS_COMPILE)ld
+CC		:= $(CROSS_COMPILE)gcc
+CPP		:= $(CC) -E
+AS		:= $(CROSS_COMPILE)as
+AR		:= $(CROSS_COMPILE)ar
+STRIP		:= $(CROSS_COMPILE)strip
+OBJCOPY		:= $(CROSS_COMPILE)objcopy
+OBJDUMP		:= $(CROSS_COMPILE)objdump
+NM		:= $(CROSS_COMPILE)nm
+MAKE		:= make
+MKDIR		:= mkdir -p
+AWK		:= awk
+PERL		:= perl
+PYTHON		:= python
+SH		:= $(shell if [ -x "$$BASH" ]; then echo $$BASH;        \
+                        else if [ -x /bin/bash ]; then echo /bin/bash;  \
+                        else echo sh; fi ; fi)
+
+export RM LD CC CPP AS AR STRIP OBJCOPY OBJDUMP
+export NM SH MAKE MKDIR AWK PERL PYTHON SH
+
+#
+# Footer.
+$(__nmk_dir)scripts/tools.mk:
+	@true
+____nmk_defined__tools = y
+endif
diff --git a/scripts/nmk/scripts/utils.mk b/scripts/nmk/scripts/utils.mk
new file mode 100644
index 000000000000..50ceb7af5f98
--- /dev/null
+++ b/scripts/nmk/scripts/utils.mk
@@ -0,0 +1,28 @@
+ifndef ____nmk_defined__utils
+
+#
+# Usage: option = $(call try-cc,source-to-build,cc-options,cc-defines)
+try-cc = $(shell sh -c                                                          \
+                'TMP="$(OUTPUT)$(TMPOUT).$$$$";                                 \
+                 echo "$(1)" |                                                  \
+                 $(CC) $(3) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y;  \
+                 rm -f "$$TMP"')
+
+# pkg-config-check
+# Usage: ifeq ($(call pkg-config-check, library),y)
+pkg-config-check = $(shell sh -c 'pkg-config $(1) && echo y')
+
+#
+# Remove duplicates.
+uniq = $(strip $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1))))
+
+#
+# Add $(obj)/ for paths that are not relative
+objectify       = $(foreach o,$(sort $(call uniq,$(1))),$(if $(filter /% ./% ../%,$(o)),$(o),$(obj)/$(o)))
+
+#
+# Footer.
+$(__nmk_dir)scripts/utils.mk:
+	@true
+____nmk_defined__utils = y
+endif
-- 
2.5.0



More information about the CRIU mailing list