Skip to content
Snippets Groups Projects
rules.mk 14.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • # SPDX-License-Identifier: GPL-2.0-only
    
    # Copyright (C) 2016 LEDE Project
    
    ifeq ($(DUMP),)
      -include $(TOPDIR)/.config
    endif
    
    Mike Baker's avatar
    Mike Baker committed
    include $(TOPDIR)/include/verbose.mk
    
    ifneq ($(filter check,$(MAKECMDGOALS)),)
    CHECK:=1
    DUMP:=1
    endif
    
    
    export TMP_DIR:=$(TOPDIR)/tmp
    
    export TMPDIR:=$(TMP_DIR)
    
    qstrip=$(strip $(subst ",,$(1)))
    
    confvar=$(shell echo '$(foreach v,$(1),$(v)=$(subst ','\'',$($(v))))' | $(MKHASH) md5)
    
    strip_last=$(patsubst %.$(lastword $(subst .,$(space),$(1))),%,$(1))
    
    paren_left = (
    paren_right = )
    chars_lower = a b c d e f g h i j k l m n o p q r s t u v w x y z
    chars_upper = A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    
    
    __tr_list = $(join $(join $(1),$(foreach char,$(1),$(comma))),$(2))
    __tr_head_stripped = $(subst $(space),,$(foreach cv,$(call __tr_list,$(1),$(2)),$$$(paren_left)subst$(cv)$(comma)))
    __tr_head = $(subst $(paren_left)subst,$(paren_left)subst$(space),$(__tr_head_stripped))
    __tr_tail = $(subst $(space),,$(foreach cv,$(1),$(paren_right)))
    __tr_template = $(__tr_head)$$(1)$(__tr_tail)
    
    $(eval toupper = $(call __tr_template,$(chars_lower),$(chars_upper)))
    $(eval tolower = $(call __tr_template,$(chars_upper),$(chars_lower)))
    
    
    version_abbrev = $(if $(if $(CHECK),,$(DUMP)),$(1),$(shell printf '%.8s' $(1)))
    
    
    ARCH:=$(subst i486,i386,$(subst i586,i386,$(subst i686,i386,$(call qstrip,$(CONFIG_ARCH)))))
    
    ARCH_PACKAGES:=$(call qstrip,$(CONFIG_TARGET_ARCH_PACKAGES))
    
    BOARD:=$(call qstrip,$(CONFIG_TARGET_BOARD))
    
    SUBTARGET:=$(call qstrip,$(CONFIG_TARGET_SUBTARGET))
    
    TARGET_OPTIMIZATION:=$(call qstrip,$(CONFIG_TARGET_OPTIMIZATION))
    
    Felix Fietkau's avatar
    Felix Fietkau committed
    TARGET_SUFFIX=$(call qstrip,$(CONFIG_TARGET_SUFFIX))
    
    BUILD_SUFFIX:=$(call qstrip,$(CONFIG_BUILD_SUFFIX))
    
    SUBDIR:=$(patsubst $(TOPDIR)/%,%,${CURDIR})
    
    BUILD_SUBDIR:=$(patsubst $(TOPDIR)/%,%,${CURDIR})
    
    NPROC:=$(shell sysctl -n hw.ncpu 2>/dev/null || nproc)
    
    IS_PACKAGE_BUILD := $(if $(filter package/%,$(BUILD_SUBDIR)),1)
    
    OPTIMIZE_FOR_CPU=$(subst i386,i486,$(ARCH))
    
    ifneq (,$(findstring $(ARCH) , aarch64 aarch64_be powerpc ))
    
    HOST_FPIC:=-DPIC -fPIC
    
    ARCH_SUFFIX:=$(call qstrip,$(CONFIG_CPU_TYPE))
    
    ifneq ($(ARCH_SUFFIX),)
      ARCH_SUFFIX:=_$(ARCH_SUFFIX)
    endif
    
    ifneq ($(filter -march=armv%,$(TARGET_OPTIMIZATION)),)
      GCC_ARCH:=$(patsubst -march=%,%,$(filter -march=armv%,$(TARGET_OPTIMIZATION)))
    endif
    
    ifdef CONFIG_HAS_SPE_FPU
      TARGET_SUFFIX:=$(TARGET_SUFFIX)spe
    endif
    
    ifdef CONFIG_MIPS64_ABI
      ifneq ($(CONFIG_MIPS64_ABI_O32),y)
    
         ARCH_SUFFIX:=$(ARCH_SUFFIX)_$(call qstrip,$(CONFIG_MIPS64_ABI))
    
    DEFAULT_SUBDIR_TARGETS:=clean download prepare compile update refresh prereq dist distcheck configure check check-depends
    
    $(foreach t,$(DEFAULT_SUBDIR_TARGETS) $(1),
      .$(t):
      $(t): .$(t)
      .PHONY: $(t) .$(t)
    
    DL_DIR=$(if $(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(TOPDIR)/dl)$(if $(DL_SUBDIR),/$(DL_SUBDIR))
    
    OUTPUT_DIR:=$(if $(call qstrip,$(CONFIG_BINARY_FOLDER)),$(call qstrip,$(CONFIG_BINARY_FOLDER)),$(TOPDIR)/bin)
    BIN_DIR:=$(OUTPUT_DIR)/targets/$(BOARD)/$(SUBTARGET)
    
    INCLUDE_DIR:=$(TOPDIR)/include
    
    Mike Baker's avatar
    Mike Baker committed
    SCRIPT_DIR:=$(TOPDIR)/scripts
    
    BUILD_DIR_BASE:=$(TOPDIR)/build_dir
    
    ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
      GCCV:=$(call qstrip,$(CONFIG_GCC_VERSION))
      LIBC:=$(call qstrip,$(CONFIG_LIBC))
      REAL_GNU_TARGET_NAME=$(OPTIMIZE_FOR_CPU)-openwrt-linux$(if $(TARGET_SUFFIX),-$(TARGET_SUFFIX))
      GNU_TARGET_NAME=$(OPTIMIZE_FOR_CPU)-openwrt-linux
    
      DIR_SUFFIX:=_$(LIBC)$(if $(CONFIG_arm),_eabi)
    
      BIN_DIR:=$(BIN_DIR)$(if $(CONFIG_USE_MUSL),,-$(LIBC))
    
      TARGET_DIR_NAME = target-$(ARCH)$(ARCH_SUFFIX)$(DIR_SUFFIX)$(if $(BUILD_SUFFIX),_$(BUILD_SUFFIX))
      TOOLCHAIN_DIR_NAME = toolchain-$(ARCH)$(ARCH_SUFFIX)_gcc-$(GCCV)$(DIR_SUFFIX)
    
    else
      ifeq ($(CONFIG_NATIVE_TOOLCHAIN),)
        GNU_TARGET_NAME=$(call qstrip,$(CONFIG_TARGET_NAME))
      else
        GNU_TARGET_NAME=$(shell gcc -dumpmachine)
      endif
      REAL_GNU_TARGET_NAME=$(GNU_TARGET_NAME)
    
      LIBC:=$(call qstrip,$(CONFIG_LIBC))
    
      TARGET_DIR_NAME:=target-$(GNU_TARGET_NAME)_$(LIBC)$(if $(BUILD_SUFFIX),_$(BUILD_SUFFIX))
      TOOLCHAIN_DIR_NAME:=toolchain-$(GNU_TARGET_NAME)
    
    ifeq ($(or $(CONFIG_EXTERNAL_TOOLCHAIN),$(CONFIG_TARGET_uml)),)
    
      iremap = -f$(if $(CONFIG_REPRODUCIBLE_DEBUG_INFO),file,macro)-prefix-map=$(1)=$(2)
    
    PACKAGE_DIR_ALL:=$(TOPDIR)/staging_dir/packages/$(BOARD)
    
    BUILD_DIR:=$(BUILD_DIR_BASE)/$(TARGET_DIR_NAME)
    STAGING_DIR:=$(TOPDIR)/staging_dir/$(TARGET_DIR_NAME)
    BUILD_DIR_TOOLCHAIN:=$(BUILD_DIR_BASE)/$(TOOLCHAIN_DIR_NAME)
    TOOLCHAIN_DIR:=$(TOPDIR)/staging_dir/$(TOOLCHAIN_DIR_NAME)
    
    STAMP_DIR:=$(BUILD_DIR)/stamp
    
    STAMP_DIR_HOST=$(BUILD_DIR_HOST)/stamp
    
    TARGET_ROOTFS_DIR?=$(if $(call qstrip,$(CONFIG_TARGET_ROOTFS_DIR)),$(call qstrip,$(CONFIG_TARGET_ROOTFS_DIR)),$(BUILD_DIR))
    TARGET_DIR:=$(TARGET_ROOTFS_DIR)/root-$(BOARD)
    
    STAGING_DIR_ROOT:=$(STAGING_DIR)/root-$(BOARD)
    
    STAGING_DIR_IMAGE:=$(STAGING_DIR)/image
    
    BUILD_LOG_DIR:=$(if $(call qstrip,$(CONFIG_BUILD_LOG_DIR)),$(call qstrip,$(CONFIG_BUILD_LOG_DIR)),$(TOPDIR)/logs)
    
    Mike Baker's avatar
    Mike Baker committed
    
    
    BUILD_DIR_HOST:=$(if $(IS_PACKAGE_BUILD),$(BUILD_DIR_BASE)/hostpkg,$(BUILD_DIR_BASE)/host)
    
    STAGING_DIR_HOST:=$(abspath $(STAGING_DIR)/../host)
    STAGING_DIR_HOSTPKG:=$(abspath $(STAGING_DIR)/../hostpkg)
    
    TARGET_PATH:=$(subst $(space),:,$(filter-out .,$(filter-out ./,$(subst :,$(space),$(PATH)))))
    
    TARGET_INIT_PATH:=$(call qstrip,$(CONFIG_TARGET_INIT_PATH))
    TARGET_INIT_PATH:=$(if $(TARGET_INIT_PATH),$(TARGET_INIT_PATH),/usr/sbin:/sbin:/usr/bin:/bin)
    
    TARGET_CFLAGS:=$(TARGET_OPTIMIZATION)$(if $(CONFIG_DEBUG), -g3) $(call qstrip,$(CONFIG_EXTRA_OPTIMIZATION))
    
    TARGET_ASFLAGS_DEFAULT = $(TARGET_CFLAGS)
    TARGET_ASFLAGS = $(TARGET_ASFLAGS_DEFAULT)
    
    ifneq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
    LIBGCC_S_PATH=$(realpath $(wildcard $(call qstrip,$(CONFIG_LIBGCC_ROOT_DIR))/$(call qstrip,$(CONFIG_LIBGCC_FILE_SPEC))))
    LIBGCC_S=$(if $(LIBGCC_S_PATH),-L$(dir $(LIBGCC_S_PATH)) -lgcc_s)
    
    LIBGCC_A=$(realpath $(lastword $(wildcard $(dir $(LIBGCC_S_PATH))/gcc/*/*/libgcc.a)))
    
    LIBGCC_A=$(lastword $(wildcard $(TOOLCHAIN_DIR)/lib/gcc/*/*/libgcc.a))
    
    LIBGCC_S=$(if $(wildcard $(TOOLCHAIN_DIR)/lib/libgcc_s.so),-L$(TOOLCHAIN_DIR)/lib -lgcc_s,$(LIBGCC_A))
    
    ifeq ($(CONFIG_ARCH_64BIT),y)
    
      ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
        -include $(TOOLCHAIN_DIR)/info.mk
    
        TARGET_CROSS:=$(if $(TARGET_CROSS),$(TARGET_CROSS),$(OPTIMIZE_FOR_CPU)-openwrt-linux$(if $(TARGET_SUFFIX),-$(TARGET_SUFFIX))-)
    
        TARGET_CPPFLAGS+= -I$(TOOLCHAIN_DIR)/usr/include
        ifeq ($(CONFIG_USE_MUSL),y)
          TARGET_CPPFLAGS+= -I$(TOOLCHAIN_DIR)/include/fortify
        endif
        TARGET_CPPFLAGS+= -I$(TOOLCHAIN_DIR)/include
    
        TARGET_LDFLAGS+= -L$(TOOLCHAIN_DIR)/usr/lib -L$(TOOLCHAIN_DIR)/lib
    
        TARGET_PATH:=$(TOOLCHAIN_DIR)/bin:$(TARGET_PATH)
    
      else
        ifeq ($(CONFIG_NATIVE_TOOLCHAIN),)
          TARGET_CROSS:=$(call qstrip,$(CONFIG_TOOLCHAIN_PREFIX))
          TOOLCHAIN_ROOT_DIR:=$(call qstrip,$(CONFIG_TOOLCHAIN_ROOT))
          TOOLCHAIN_BIN_DIRS:=$(patsubst ./%,$(TOOLCHAIN_ROOT_DIR)/%,$(call qstrip,$(CONFIG_TOOLCHAIN_BIN_PATH)))
          TOOLCHAIN_INC_DIRS:=$(patsubst ./%,$(TOOLCHAIN_ROOT_DIR)/%,$(call qstrip,$(CONFIG_TOOLCHAIN_INC_PATH)))
          TOOLCHAIN_LIB_DIRS:=$(patsubst ./%,$(TOOLCHAIN_ROOT_DIR)/%,$(call qstrip,$(CONFIG_TOOLCHAIN_LIB_PATH)))
          ifneq ($(TOOLCHAIN_BIN_DIRS),)
            TARGET_PATH:=$(subst $(space),:,$(TOOLCHAIN_BIN_DIRS)):$(TARGET_PATH)
          endif
          ifneq ($(TOOLCHAIN_INC_DIRS),)
            TARGET_CPPFLAGS+= $(patsubst %,-I%,$(TOOLCHAIN_INC_DIRS))
          endif
          ifneq ($(TOOLCHAIN_LIB_DIRS),)
            TARGET_LDFLAGS+= $(patsubst %,-L%,$(TOOLCHAIN_LIB_DIRS))
          endif
        endif
      endif
    
    TARGET_PATH_PKG:=$(STAGING_DIR)/host/bin:$(STAGING_DIR_HOSTPKG)/bin:$(TARGET_PATH)
    
    Imre Kaloz's avatar
    Imre Kaloz committed
    ifeq ($(CONFIG_SOFT_FLOAT),y)
    
    Nicolas Thill's avatar
    Nicolas Thill committed
      SOFT_FLOAT_CONFIG_OPTION:=--with-float=soft
    
      ifeq ($(CONFIG_arm),y)
        TARGET_CFLAGS+= -mfloat-abi=soft
      else
        TARGET_CFLAGS+= -msoft-float
      endif
    
    Imre Kaloz's avatar
    Imre Kaloz committed
    else
    
    Nicolas Thill's avatar
    Nicolas Thill committed
      SOFT_FLOAT_CONFIG_OPTION:=
    
      ifeq ($(CONFIG_arm),y)
        TARGET_CFLAGS+= -mfloat-abi=hard
      endif
    
    Imre Kaloz's avatar
    Imre Kaloz committed
    endif
    
    
    export ORIG_PATH:=$(if $(ORIG_PATH),$(ORIG_PATH),$(PATH))
    
    Mike Baker's avatar
    Mike Baker committed
    export PATH:=$(TARGET_PATH)
    
    export STAGING_DIR STAGING_DIR_HOST STAGING_DIR_HOSTPKG
    
    Mike Baker's avatar
    Mike Baker committed
    
    
    John Crispin's avatar
    John Crispin committed
    PKG_CONFIG:=$(STAGING_DIR_HOST)/bin/pkg-config
    
    export PKG_CONFIG
    
    
    Mike Baker's avatar
    Mike Baker committed
    HOSTCC:=gcc
    
    HOST_CPPFLAGS:=-I$(STAGING_DIR_HOST)/include $(if $(IS_PACKAGE_BUILD),-I$(STAGING_DIR_HOSTPKG)/include -I$(STAGING_DIR)/host/include)
    
    HOST_CFLAGS:=-O2 $(HOST_CPPFLAGS)
    
    HOST_LDFLAGS:=-L$(STAGING_DIR_HOST)/lib $(if $(IS_PACKAGE_BUILD),-L$(STAGING_DIR_HOSTPKG)/lib -L$(STAGING_DIR)/host/lib)
    
    FAKEROOT:=$(STAGING_DIR_HOST)/bin/fakeroot
    
    TARGET_AR:=$(TARGET_CROSS)gcc-ar
    TARGET_RANLIB:=$(TARGET_CROSS)gcc-ranlib
    TARGET_NM:=$(TARGET_CROSS)gcc-nm
    
    Mike Baker's avatar
    Mike Baker committed
    TARGET_CC:=$(TARGET_CROSS)gcc
    
    Jo-Philipp Wich's avatar
    Jo-Philipp Wich committed
    KPATCH:=$(SCRIPT_DIR)/patch-kernel.sh
    
    FILECMD:=$(STAGING_DIR_HOST)/bin/file
    
    SED:=$(STAGING_DIR_HOST)/bin/sed -i -e
    
    ESED:=$(STAGING_DIR_HOST)/bin/sed -E -i -e
    
    MKHASH:=$(STAGING_DIR_HOST)/bin/mkhash
    # MKHASH is used in /scripts, so we export it here.
    export MKHASH
    
    Mike Baker's avatar
    Mike Baker committed
    CP:=cp -fpR
    
    BASH:=bash
    TAR:=tar
    FIND:=find
    PATCH:=patch
    
    PYTHON:=python3
    
    ifeq ($(HOST_OS),Darwin)
      TRUE:=/usr/bin/env gtrue
      FALSE:=/usr/bin/env gfalse
    else
      TRUE:=/usr/bin/env true
      FALSE:=/usr/bin/env false
    endif
    
    
    INSTALL_BIN:=install -m0755
    
    INSTALL_SUID:=install -m4755
    
    INSTALL_DIR:=install -d -m0755
    INSTALL_DATA:=install -m0644
    
    INSTALL_CONF:=install -m0600
    
    John Crispin's avatar
    John Crispin committed
    TARGET_CC_NOCACHE:=$(TARGET_CC)
    TARGET_CXX_NOCACHE:=$(TARGET_CXX)
    HOSTCC_NOCACHE:=$(HOSTCC)
    
    HOSTCXX_NOCACHE:=$(HOSTCXX)
    
    John Crispin's avatar
    John Crispin committed
    export TARGET_CC_NOCACHE
    export TARGET_CXX_NOCACHE
    export HOSTCC_NOCACHE
    
    ifneq ($(CONFIG_CCACHE),)
    
    Paul Fertser's avatar
    Paul Fertser committed
      TARGET_CC:= ccache $(TARGET_CC)
      TARGET_CXX:= ccache $(TARGET_CXX)
    
      HOSTCC:= ccache $(HOSTCC)
    
      HOSTCXX:= ccache $(HOSTCXX)
    
      export CCACHE_BASEDIR:=$(TOPDIR)
      export CCACHE_DIR:=$(if $(call qstrip,$(CONFIG_CCACHE_DIR)),$(call qstrip,$(CONFIG_CCACHE_DIR)),$(TOPDIR)/.ccache)
      export CCACHE_COMPILERCHECK:=%compiler% -dumpmachine; %compiler% -dumpversion
    
      AS="$(TARGET_CC) -c $(TARGET_ASFLAGS)" \
    
    Mike Baker's avatar
    Mike Baker committed
      LD=$(TARGET_CROSS)ld \
    
      CC="$(TARGET_CC)" \
      GCC="$(TARGET_CC)" \
    
      RANLIB="$(TARGET_RANLIB)" \
    
      OBJDUMP=$(TARGET_CROSS)objdump \
      SIZE=$(TARGET_CROSS)size
    
    Mike Baker's avatar
    Mike Baker committed
    
    # strip an entire directory
    
    ifneq ($(CONFIG_NO_STRIP),)
    
        STRIP:=$(TARGET_CROSS)strip $(call qstrip,$(CONFIG_STRIP_ARGS))
    
          STRIP:=$(STAGING_DIR_HOST)/bin/sstrip $(call qstrip,$(CONFIG_SSTRIP_ARGS))
    
        export CROSS="$(TARGET_CROSS)" \
    
    		$(if $(PKG_BUILD_ID),KEEP_BUILD_ID=1) \
    
    		$(if $(CONFIG_KERNEL_KALLSYMS),NO_RENAME=1) \
    		$(if $(CONFIG_KERNEL_PROFILING),KEEP_SYMBOLS=1); \
    
        NM="$(TARGET_CROSS)nm" \
        STRIP="$(STRIP)" \
    
        STRIP_KMOD="$(SCRIPT_DIR)/strip-kmod.sh" \
    
        PATCHELF="$(STAGING_DIR_HOST)/bin/patchelf" \
    
        $(SCRIPT_DIR)/rstrip.sh
    endif
    
    Mike Baker's avatar
    Mike Baker committed
    
    
    NINJA = \
    	MAKEFLAGS="$(MAKE_JOBSERVER)" \
    	$(STAGING_DIR_HOST)/bin/ninja \
    		$(if $(findstring c,$(OPENWRT_VERBOSE)),-v) \
    		$(if $(MAKE_JOBSERVER),,-j1)
    
    
    ifeq ($(CONFIG_BUILD_LOG),y)
      BUILD_LOG:=1
    endif
    
    
    export BISON_PKGDATADIR:=$(STAGING_DIR_HOST)/share/bison
    
    Michael Pratt's avatar
    Michael Pratt committed
    export HOST_GNULIB_SRCDIR:=$(STAGING_DIR_HOST)/share/gnulib
    
    define shvar
    V_$(subst .,_,$(subst -,_,$(subst /,_,$(1))))
    endef
    
    define shexport
    
    export $(call shvar,$(1))=$$(call $(1))
    
    define include_mk
    $(eval -include $(if $(DUMP),,$(STAGING_DIR)/mk/$(strip $(1))))
    endef
    
    
    # Execute commands under flock
    # $(1) => The shell expression.
    # $(2) => The lock name. If not given, the global lock will be used.
    
    ifneq ($(wildcard $(STAGING_DIR_HOST)/bin/flock),)
      define locked
    
    		$(TMP_DIR)/.$(if $(2),$(strip $(2)),global).flock \
    		-c '$(subst ','\'',$(1))'
    
    # Recursively copy paths into another directory, purge dangling
    # symlinks before.
    # $(1) => File glob expression
    # $(2) => Destination directory
    define file_copy
    	for src_dir in $(sort $(foreach d,$(wildcard $(1)),$(dir $(d)))); do \
    		( cd $$src_dir; find -type f -or -type d ) | \
    			( cd $(2); while :; do \
    				read FILE; \
    				[ -z "$$FILE" ] && break; \
    				[ -L "$$FILE" ] || continue; \
    				echo "Removing symlink $(2)/$$FILE"; \
    				rm -f "$$FILE"; \
    			done; ); \
    	done; \
    
    # Calculate sha256sum of any plain file within a given directory
    # $(1) => Input directory
    
    # $(2) => If set, recurse into subdirectories
    
    define sha256sums
    
    	(cd $(1); find . $(if $(2),,-maxdepth 1) -type f -not -name 'sha256sums' -printf "%P\n" | sort | \
    
    		xargs -r $(MKHASH) -n sha256 | sed -ne 's!^\(.*\) \(.*\)$$!\1 *\2!p' > sha256sums)
    
    # file extension
    ext=$(word $(words $(subst ., ,$(1))),$(subst ., ,$(1)))
    
    
    # Count Git commits of a package
    # $(1) => if non-empty: count commits since last ": [uU]pdate to " or ": [bB]ump to " in commit message
    define commitcount
    $(shell \
      if git log -1 >/dev/null 2>/dev/null; then \
        if [ -n "$(1)" ]; then \
          last_bump="$$(git log --pretty=format:'%h %s' . | \
    
            grep -m 1 -e ': [uU]pdate to ' -e ': [bB]ump to ' | \
    
            cut -f 1 -d ' ')"; \
        fi; \
        if [ -n "$$last_bump" ]; then \
          echo -n $$(($$(git rev-list --count "$$last_bump..HEAD" .) + 1)); \
        else \
    
          git rev-list --count HEAD .; \
    
        fi; \
      else \
        secs="$$(($(SOURCE_DATE_EPOCH) % 86400))"; \
        date="$$(date --utc --date="@$(SOURCE_DATE_EPOCH)" "+%y%m%d")"; \
        printf '%s.%05d' "$$date" "$$secs"; \
      fi; \
    )
    endef
    
    
    abi_version_str = $(subst -,,$(subst _,,$(subst .,,$(1))))
    
    
    COMMITCOUNT = $(if $(DUMP),0,$(call commitcount))
    AUTORELEASE = $(if $(DUMP),0,$(call commitcount,1))
    
    Mike Baker's avatar
    Mike Baker committed
    FORCE: ;
    
    .PHONY: FORCE
    
    val.%:
    	@$(if $(filter undefined,$(origin $*)),\
    		echo "$* undefined" >&2, \
    		echo '$(subst ','"'"',$($*))' \
    	)
    
    var.%:
    	@$(if $(filter undefined,$(origin $*)),\
    		echo "$* undefined" >&2, \
    		echo "$*='"'$(subst ','"'\"'\"'"',$($*))'"'" \
    	)