view Makefile.in @ 3256:7fb479d0241c

Update build tools for native mingw * src/build-m4.mk: do nothing for native mingw build * Makefile.in: - add bison, m4 as natve mingw, and python as jit build requirements. - remove build-bison as a mingw build dependancy * index.html: Add msys-bison to mingw required packages and mention ghostscript and python.
author John Donoghue <john.donoghue@ieee.org>
date Thu, 26 Sep 2013 21:18:39 -0400
parents bd4487905031
children 869f160d71b6
line wrap: on
line source

# This file is part of MXE.
# See index.html for further information.

PWD := $(shell pwd)

## Configuration variables.

# Set the following configuration variables with a configure script?

# Current valid values are mingw (cross) and gnu-linux (native).
MXE_SYSTEM := @MXE_SYSTEM@

# Set to "no" if doing a cross compile build.
MXE_NATIVE_BUILD := @MXE_NATIVE_BUILD@

# Set to "yes" to use the versions of GCC and binutils already
# installed on your system (default is yes if doing native build).
USE_SYSTEM_GCC := @USE_SYSTEM_GCC@

# Set to "yes" to use the version of fontconfig already installed
# on your system (default is yes if doing native build). 
USE_SYSTEM_FONTCONFIG := @USE_SYSTEM_FONTCONFIG@

# Should match what config.guess prints for your system.
# If cross compiling, you must set it manually.
ifeq ($(MXE_NATIVE_BUILD),yes)
  TARGET := $(shell tools/config.guess)
else
  TARGET := i686-pc-mingw32
endif
BUILD_SYSTEM := $(shell tools/config.guess)

# Enable shared or static libs, or perhaps both.  Probably it doesn't
# make sense to disable both...
BUILD_SHARED := @BUILD_SHARED@
BUILD_STATIC := @BUILD_STATIC@

USE_PIC_FLAG := @USE_PIC_FLAG@

# Attempt to build Octave and dependencies with 64-bit indexing
# enabled (experimental; requires 64-bit system and compiler).
ENABLE_64 := @ENABLE_64@

# Attempt to build LLVM and enable Octave's experimental JIT compiler.
ENABLE_JIT := @ENABLE_JIT@

# Use openblas for octave
ENABLE_OPENBLAS := @ENABLE_OPENBLAS@

# Look in lib64 directory.
MXE_USE_LIB64_DIRECTORY := @ENABLE_LIB64_DIRECTORY@

## end of configuration variables.

ifneq ($(MXE_NATIVE_BUILD),yes)
  ifeq ($(MXE_SYSTEM),msvc)
    $(error Cross-compiling to MSVC is not supported)
  endif
  HOST_AND_BUILD_CONFIGURE_OPTIONS := \
    --host='$(TARGET)' --build='$(BUILD_SYSTEM)'
endif

# are we doing a native mingw build ?
ifeq ($(MXE_NATIVE_BUILD),yes)
  ifeq ($(MXE_SYSTEM),mingw)
    MXE_NATIVE_MINGW_BUILD := yes
  endif
  ifeq ($(MXE_SYSTEM),msvc)
    MXE_NATIVE_MINGW_BUILD := yes
  endif
endif

# These can't be chosen arbitrarily.  The way things are configured now,
# GCC expects to find cross-compiler include files in $(PREFIX)/$(TARGET).
# and it's not clear to me how to change that.
#
# For native builds, dump everything all together in one directory tree.
BUILD_TOOLS_PREFIX := $(PWD)/usr
ifeq ($(MXE_NATIVE_BUILD),yes)
  HOST_PREFIX := $(BUILD_TOOLS_PREFIX)
else
  HOST_PREFIX := $(PWD)/usr/$(TARGET)
endif

# At least one package uses --with instead of --enable.  
ifeq ($(BUILD_SHARED),yes)
  ifeq ($(BUILD_STATIC),yes)
    ENABLE_SHARED_OR_STATIC := --enable-shared --enable-static
    WITH_SHARED_OR_STATIC := --with-shared --with-static
  else
    ENABLE_SHARED_OR_STATIC := --enable-shared --disable-static
    WITH_SHARED_OR_STATIC := --with-shared --without-static
  endif
else
  ENABLE_SHARED_OR_STATIC := --disable-shared --enable-static
  WITH_SHARED_OR_STATIC := --without-shared --with-static
endif

ifeq ($(USE_PIC_FLAG),yes)
  MXE_CC_PICFLAG := -fPIC
  MXE_CXX_PICFLAG := -fPIC
  MXE_F77_PICFLAG := -fPIC
endif

JOBS               := 1
SOURCEFORGE_MIRROR := freefr.dl.sourceforge.net
PKG_MIRROR         := s3.amazonaws.com/mxe-pkg
PKG_CDN            := d1yihgixbnrglp.cloudfront.net

SHELL := @SHELL@

INSTALL    := $(shell ginstall --help >/dev/null 2>&1 && echo g)install
PATCH      := $(shell gpatch --help >/dev/null 2>&1 && echo g)patch
SED        := $(shell gsed --help >/dev/null 2>&1 && echo g)sed
WGET       := wget --no-check-certificate \
                   --user-agent=$(shell wget --version | \
                   $(SED) -n 's,GNU \(Wget\) \([0-9.]*\).*,\1/\2,p')
# The MSYS GNU tar does not support long uid/gid, leading to unpacking
# errors for some archives. Bsdtar does not have that limitation, so
# use it on Win32 platform if GNU tar fails to unpack the archive.
ifeq ($(MXE_NATIVE_MINGW_BUILD),yes)
    TAR  := tar
    TAR2 := bsdtar
else
    TAR  := tar
endif

REQUIREMENTS := bash bzip2 $(MAKE) openssl $(PATCH) $(PERL) \
                $(SED) tar unzip wget

ifeq ($(MXE_NATIVE_MINGW_BUILD),yes)
  REQUIREMENTS += bsdtar
endif

# if we want jit (llvm) we need python
ifeq ($(ENABLE_JIT),yes)
  REQUIREMENTS += python
endif

LIBTOOL     := libtool
LIBTOOLIZE  := libtoolize

## Build tools are tools that we need to build everything else.
## They run on the build system.  Some, like gcc and binutils may
## generate output that runs on the host system (TARGET in MXE terms).
ALL_BUILD_TOOLS := $(patsubst src/%.mk, %, $(wildcard src/build-*.mk))
BUILD_COMPILER_TOOLS := build-gcc build-binutils
BUILD_TOOLS := $(ALL_BUILD_TOOLS)
# Building flex for native mingw fails, so disable it.
ifeq ($(MXE_NATIVE_MINGW_BUILD),yes)
  REQUIREMENTS += flex
  BUILD_TOOLS := $(filter-out build-flex, $(BUILD_TOOLS))
endif
# Building bison for native mingw creates a bison that doesnt  
# allow push-pull mode so disable
ifeq ($(MXE_NATIVE_MINGW_BUILD),yes)
  REQUIREMENTS += bison
  BUILD_TOOLS := $(filter-out build-bison, $(BUILD_TOOLS))
endif
# use the msys m4 in native mingw
ifeq ($(MXE_NATIVE_MINGW_BUILD),yes)
  REQUIREMENTS += m4
endif


ifeq ($(USE_SYSTEM_GCC),yes)
  BUILD_TOOLS := $(filter-out $(BUILD_COMPILER_TOOLS), $(BUILD_TOOLS))
endif
ifneq ($(MXE_SYSTEM),msvc)
  BUILD_TOOLS := $(filter-out build-msvctools, $(BUILD_TOOLS))
endif

STAMP_DIR  := $(PWD)/installed-packages
MSYS_INFO_DIR := $(PWD)/msys-info
LOG_DIR    := $(PWD)/log
TIMESTAMP  := $(shell date +%Y%m%d_%H%M%S)
PKG_DIR    := $(PWD)/pkg
TMP_DIR     = $(PWD)/tmp-$(1)
TOP_DIR    := $(PWD)
MAKEFILE   := $(TOP_DIR)/Makefile
PKGS       := $(filter-out $(ALL_BUILD_TOOLS), $(shell $(SED) -n 's/^.* id="\([^"]*\)-package">.*$$/\1/p' '$(TOP_DIR)/index.html'))

PATH := $(BUILD_TOOLS_PREFIX)/bin:$(PATH)

CONFIGURE_CPPFLAGS := CPPFLAGS='-I$(HOST_PREFIX)/include'
ifeq ($(MXE_USE_LIB64_DIRECTORY),yes)
  CONFIGURE_LDFLAGS := LDFLAGS='-L$(HOST_PREFIX)/lib -L$(HOST_PREFIX)/lib64'
else
  CONFIGURE_LDFLAGS := LDFLAGS='-L$(HOST_PREFIX)/lib'
endif
CONFIGURE_POST_HOOK := true

ifeq ($(MXE_NATIVE_BUILD),yes)
  MXE_TOOL_PREFIX := 
  ifeq ($(MXE_SYSTEM),msvc)
    MXE_AR := ar
    MXE_RANLIB := true
    MXE_CC := clgcc
    MXE_CCAS := gcc
    MXE_CXX := clg++
    MXE_F77 := clgfortran
    MXE_DLLTOOL := true
    MXE_NM := nm
    MXE_STRIP := true
    MXE_WINDRES := windres
    MXE_PKG_CONFIG := pkg-config
    MXE_QMAKE := qmake
    # Although the Fortran compiler is internally gfortran, we still
    # want to make it look like non-GNU compiler, otherwise libtool is
    # not playing nicely and trips over different variable values for
    # different configuration tags.
    HOST_AND_BUILD_CONFIGURE_OPTIONS := \
	    CC='$(MXE_CC)' CXX='$(MXE_CXX)' F77='$(MXE_F77)' DLLTOOL='$(MXE_DLLTOOL)' CCAS='$(MXE_CCAS)' \
	    CFLAGS='-O2' CXXFLAGS='-O2' ac_cv_f77_compiler_gnu=no RANLIB='$(MXE_RANLIB)'
    # Use native paths for compiler flags. Note: at this point, we can't
    # rely on the existence of HOST_PREFIX directory, so recompute the
    # native path from $(PWD) instead.
    HOST_PREFIX_NATIVE := $(shell cd $(PWD) && pwd -W)/usr
    CONFIGURE_CPPFLAGS := CPPFLAGS='-I$(HOST_PREFIX_NATIVE)/include'
    CONFIGURE_LDFLAGS := LDFLAGS='-L$(HOST_PREFIX_NATIVE)/lib'
  else
    MXE_AR := ar
    MXE_RANLIB := ranlib
    MXE_CC := gcc
    MXE_CCAS := gcc
    MXE_CXX := g++
    MXE_F77 := gfortran
    MXE_DLLTOOL := dlltool
    MXE_NM := nm
    MXE_STRIP := strip
    ifeq ($(MXE_SYSTEM),mingw)
      MXE_WINDRES := windres
    else
      MXE_WINDRES := true
    endif
    MXE_PKG_CONFIG := pkg-config
    MXE_QMAKE := qmake
  endif
else
  MXE_TOOL_PREFIX := $(TARGET)-
  MXE_AR := '$(BUILD_TOOLS_PREFIX)/bin/$(MXE_TOOL_PREFIX)ar'
  MXE_RANLIB := '$(BUILD_TOOLS_PREFIX)/bin/$(MXE_TOOL_PREFIX)ranlib'
  MXE_CC := '$(BUILD_TOOLS_PREFIX)/bin/$(MXE_TOOL_PREFIX)gcc'
  MXE_CCAS := '$(BUILD_TOOLS_PREFIX)/bin/$(MXE_TOOL_PREFIX)gcc'
  MXE_CXX := '$(BUILD_TOOLS_PREFIX)/bin/$(MXE_TOOL_PREFIX)g++'
  MXE_F77 := '$(BUILD_TOOLS_PREFIX)/bin/$(MXE_TOOL_PREFIX)gfortran'
  MXE_DLLTOOL := '$(BUILD_TOOLS_PREFIX)/bin/$(MXE_TOOL_PREFIX)dlltool'
  MXE_NM := '$(BUILD_TOOLS_PREFIX)/bin/$(MXE_TOOL_PREFIX)nm'
  MXE_STRIP := '$(BUILD_TOOLS_PREFIX)/bin/$(MXE_TOOL_PREFIX)strip'
  ifeq ($(MXE_SYSTEM),mingw)
    MXE_WINDRES := '$(BUILD_TOOLS_PREFIX)/bin/$(MXE_TOOL_PREFIX)windres'
  else
    MXE_WINDRES := true
  endif
  MXE_PKG_CONFIG := '$(BUILD_TOOLS_PREFIX)/bin/pkg-config'
  MXE_QMAKE := '$(BUILD_TOOLS_PREFIX)/bin/$(MXE_TOOL_PREFIX)qmake'
endif

ifeq ($(MXE_SYSTEM),mingw)
  MAKE_SHARED_FROM_STATIC_OPTIONS := --windowsdll
endif

HOST_BINDIR := $(HOST_PREFIX)/bin
HOST_LIBDIR := $(HOST_PREFIX)/lib
HOST_LIB64DIR := $(HOST_PREFIX)/lib64
HOST_INCDIR := $(HOST_PREFIX)/include

ifeq ($(MXE_SYSTEM),mingw)
  ifneq ($(MXE_NATIVE_BUILD),yes)
    MSYS_BASE_URL := http://sourceforge.net/projects/mingw/files/MSYS/Base
    MSYS_BASE_VER := 1.0.13
    MSYS_BASE_DIR := $(TOP_DIR)/msys-base
    MSYS_BASE_PACKAGES := $(addprefix msys-,bash coreutils diffutils file findutils gawk grep gzip less libiconv libintl libmagic make msys-core regex sed tar termcap)

    NOTEPAD_BASE_DIR := $(TOP_DIR)/notepad++
  endif
else ifneq ($(MXE_SYSTEM),msvc)
  MXE_CPPFLAGS := '-I$(HOST_INCDIR)'
  ifeq ($(MXE_USE_LIB64_DIRECTORY),yes)
    MXE_LDFLAGS := '-L$(HOST_LIBDIR) -L$(HOST_LIB64DIR)'
    LD_LIBRARY_PATH := $(HOST_LIBDIR):$(HOST_LIB64DIR)
  else
    MXE_LDFLAGS := '-L$(HOST_LIBDIR)'
    LD_LIBRARY_PATH := $(HOST_LIBDIR)
  endif
  export LD_LIBRARY_PATH
endif

LN := ln
LN_S := $(LN) -s
LN_SF := $(LN_S) -f
ifeq ($(MXE_NATIVE_BUILD),yes)
  ifeq ($(MXE_SYSTEM),mingw)
    LN := cp
    LN_S := $(LN)
    LN_SF := $(LN_S)
  endif
  ifeq ($(MXE_SYSTEM),msvc)
    LN := cp
    LN_S := $(LN)
    LN_SF := $(LN_S)
  endif
endif

LIBRARY_PREFIX :=
LIBRARY_SUFFIX :=

ifeq ($(MXE_SYSTEM),msvc)
  CL_VERSION := $(shell cl -? 2>&1 | $(SED) -n -e 's/.*Compiler Version \([0-9]\+\).*/\1/p')
  MSVC_VERSION := $(if $(filter 17,$(CL_VERSION)),110, \
		  $(if $(filter 16,$(CL_VERSION)),100, \
		  $(if $(filter 15,$(CL_VERSION)),90)))
  LIBRARY_PREFIX := vc$(strip $(MSVC_VERSION))-lib
  CONFIGURE_POST_HOOK := lt-postproc -p '$(LIBRARY_PREFIX)' -s '$(LIBRARY_SUFFIX)'
  MAKE_SHARED_FROM_STATIC_OPTIONS := --windowsdll --msvc --libprefix '$(LIBRARY_PREFIX)' --libsuffix '$(LIBRARY_SUFFIX)'
endif

OCTAVE_FORGE_BASE_URL := 'http://sourceforge.net/projects/octave/files/Octave Forge Packages/Individual Package Releases'
OCTAVE_FORGE_PACKAGES := $(addprefix of-,miscellaneous struct optim specfun general signal communications image io statistics control)

MAKE_SHARED_FROM_STATIC := \
  $(TOP_DIR)/tools/make-shared-from-static $(MAKE_SHARED_FROM_STATIC_OPTIONS)

CMAKE_TOOLCHAIN_FILE := $(HOST_PREFIX)/share/cmake/mxe-conf.cmake

# unexport any environment variables that might cause trouble
unexport AR CC CFLAGS C_INCLUDE_PATH CPATH CPLUS_INCLUDE_PATH CPP F77 FFLAGS
unexport CPPFLAGS CROSS CXX CXXCPP CXXFLAGS EXEEXT EXTRA_CFLAGS
unexport EXTRA_LDFLAGS LD LDFLAGS LIBRARY_PATH LIBS NM
unexport OBJC_INCLUDE_PATH PKG_CONFIG QMAKESPEC RANLIB STRIP

SHORT_PKG_VERSION = \
    $(word 1,$(subst ., ,$($(1)_VERSION))).$(word 2,$(subst ., ,$($(1)_VERSION)))

UNPACK_ARCHIVE = \
    $(if $(filter %.tgz,     $(1)),$(3) xzf '$(1)', \
    $(if $(filter %.tar.gz,  $(1)),$(3) xzf '$(1)', \
    $(if $(filter %.tar.bz2, $(1)),$(3) xjf '$(1)', \
    $(if $(filter %.tar.lzma,$(1)),xz -dc -F lzma '$(1)' | $(3) xf -, \
    $(if $(filter %.tar.xz,$(1)),xz -dc '$(1)' | $(3) xf -, \
    $(if $(filter %.zip,     $(1)),unzip -q '$(1)', \
    $(error Unknown archive format for $(2): $(1))))))))

UNPACK_PKG_ARCHIVE = \
    $(if $(value $(1)_FILE),$(call UNPACK_ARCHIVE,$(PKG_DIR)/$($(1)_FILE),$(1),$(2)),true)

PKG_CHECKSUM = \
    openssl sha1 '$(PKG_DIR)/$($(1)_FILE)' 2>/dev/null | $(SED) -n 's,^.*\([0-9a-f]\{40\}\)$$,\1,p'

CHECK_PKG_ARCHIVE = \
    [ -z "$($(1)_CHECKSUM)" -o '$($(1)_CHECKSUM)' == "`$$(call PKG_CHECKSUM,$(1))`" ]

DOWNLOAD_PKG_ARCHIVE = \
    mkdir -p '$(PKG_DIR)' && \
    $(if $($(1)_URL_2), \
        ( $(WGET) -T 30 -t 3 -O- '$($(1)_URL)' || \
          $(WGET) -O- '$($(1)_URL_2)' || \
          $(WGET) -O- '$(PKG_MIRROR)/$($(1)_FILE)' || \
          $(WGET) -O- '$(PKG_CDN)/$($(1)_FILE)' ), \
        ( $(WGET) -O- '$($(1)_URL)' || \
          $(WGET) -O- '$(PKG_MIRROR)/$($(1)_FILE)' || \
          $(WGET) -O- '$(PKG_CDN)/$($(1)_FILE)' )) \
    $(if $($(1)_FIX_GZIP), \
        | gzip -d | gzip -9n, \
        ) \
    > '$(PKG_DIR)/$($(1)_FILE)' || rm -f '$(PKG_DIR)/$($(1)_FILE)'

ifeq ($(IGNORE_SETTINGS),yes)
    $(info [ignore settings.mk])
else ifeq ($(wildcard $(PWD)/settings.mk),$(PWD)/settings.mk)
    include $(PWD)/settings.mk
else
    $(info [create settings.mk])
    $(shell { \
        echo '#JOBS = $(JOBS)'; \
        echo '#PKGS ='; \
    } >'$(PWD)/settings.mk')
endif

.PHONY: all
all: configure Makefile octave

.PHONY: all-packages
all-packages: $(PKGS)

$(PKGS): $(BUILD_TOOLS) cmake-toolchain-file.stamp

.PHONY: msys-base
msys-base:  $(MSYS_BASE_PACKAGES)

.PHONY: octave-forge-packages
octave-forge-packages: $(OCTAVE_FORGE_PACKAGES)

configure: configure.ac
	autoconf

config.status: configure
	$(SHELL) ./config.status --recheck

Makefile: Makefile.in config.status
	$(SHELL) ./config.status Makefile

.PHONY: check-requirements
define CHECK_REQUIREMENT
    @if ! $(1) --help &>/dev/null; then \
        echo; \
        echo 'Missing requirement: $(1)'; \
        echo; \
        echo 'Please have a look at "index.html" to ensure'; \
        echo 'that your system meets all requirements.'; \
        echo; \
        exit 1; \
    fi

endef
define CHECK_REQUIREMENT_VERSION
    @if ! $(1) --version | head -1 | grep ' \($(2)\)$$' >/dev/null; then \
        echo; \
        echo 'Wrong version of requirement: $(1)'; \
        echo; \
        echo 'Please have a look at "index.html" to ensure'; \
        echo 'that your system meets all requirements.'; \
        echo; \
        exit 1; \
    fi

endef
check-requirements: $(STAMP_DIR)/check-requirements
$(STAMP_DIR)/check-requirements: $(MAKEFILE)
	@echo '[check requirements]'
	$(foreach REQUIREMENT,$(REQUIREMENTS),$(call CHECK_REQUIREMENT,$(REQUIREMENT)))
	@[ -d '$(STAMP_DIR)' ] || mkdir -p '$(STAMP_DIR)'
	@if test "$(USE_SYSTEM_GCC)" = yes; then \
	  $(INSTALL) -d '$(BUILD_TOOLS_PREFIX)/bin' ; \
	  $(INSTALL) -m 755 tools/config.guess '$(BUILD_TOOLS_PREFIX)/bin/config.guess' ; \
	  $(INSTALL) -m 755 tools/config.sub '$(BUILD_TOOLS_PREFIX)/bin/config.sub' ; \
	fi
	@touch '$@'

define newline


endef
$(eval $(subst #,$(newline),$(shell \
    $(SED) -n \
        's/^.* id="\([A-Za-z0-9_+-]*\)-version">\([^<]*\)<.*$$/\1_VERSION := \2#/p' \
        '$(TOP_DIR)/index.html' \
)))

include $(patsubst %,$(TOP_DIR)/src/%.mk,$(ALL_BUILD_TOOLS))
include $(patsubst %,$(TOP_DIR)/src/%.mk,$(PKGS))

.PHONY: download
download: $(addprefix download-,$(PKGS)) $(addprefix download-,$(BUILD_TOOLS))

define PKG_RULE
.PHONY: download-$(1)
download-$(1): $(addprefix download-,$($(1)_DEPS))
	if ! $(call CHECK_PKG_ARCHIVE,$(1)); then \
	    $(call DOWNLOAD_PKG_ARCHIVE,$(1)); \
	    $(call CHECK_PKG_ARCHIVE,$(1)) || { echo 'Wrong checksum!'; exit 1; }; \
	fi

.PHONY: $(1)
$(1): $(STAMP_DIR)/$(1)
$(STAMP_DIR)/$(1): $(TOP_DIR)/src/$(1).mk \
                          $(wildcard $(TOP_DIR)/src/$(1)-*.patch) \
                          $(wildcard $(TOP_DIR)/src/$(MXE_SYSTEM)-$(1)-*.patch) \
                          $(wildcard $(TOP_DIR)/src/$(1)-test*) \
			  $(shell test -d $(TOPDIR)/src/$(1) && find $(TOPDIR)/src/$(1) -type f) \
                          $(addprefix $(STAMP_DIR)/,$($(1)_DEPS)) \
                          | check-requirements
	@[ -d '$(LOG_DIR)/$(TIMESTAMP)' ] || mkdir -p '$(LOG_DIR)/$(TIMESTAMP)'
	@if ! $(call CHECK_PKG_ARCHIVE,$(1)); then \
	    echo '[download] $(1)'; \
	    touch '$(LOG_DIR)/$(TIMESTAMP)/$(1)-download'; \
	    ln -sf '$(TIMESTAMP)/$(1)-download' '$(LOG_DIR)/$(1)-download'; \
	    ($(call DOWNLOAD_PKG_ARCHIVE,$(1))) &> '$(LOG_DIR)/$(1)-download'; \
	    if ! $(call CHECK_PKG_ARCHIVE,$(1)); then \
	        echo; \
	        echo 'Wrong checksum of package $(1)!'; \
	        echo '------------------------------------------------------------'; \
	        tail -n 10 '$(LOG_DIR)/$(1)-download' | $(SED) -n '/./p'; \
	        echo '------------------------------------------------------------'; \
	        echo '[log]      $(LOG_DIR)/$(1)-download'; \
	        echo; \
	        exit 1; \
	    fi; \
	fi
	$(if $(value $(1)_BUILD),
	    @echo '[build]    $(1)'
	    ,)
	@touch '$(LOG_DIR)/$(TIMESTAMP)/$(1)'
	@ln -sf '$(TIMESTAMP)/$(1)' '$(LOG_DIR)/$(1)'
	@if ! (time $(MAKE) -f '$(MAKEFILE)' 'build-only-$(1)') &> '$(LOG_DIR)/$(1)'; then \
	    echo; \
	    echo 'Failed to build package $(1)!'; \
	    echo '------------------------------------------------------------'; \
	    tail -n 10 '$(LOG_DIR)/$(1)' | $(SED) -n '/./p'; \
	    echo '------------------------------------------------------------'; \
	    echo '[log]      $(LOG_DIR)/$(1)'; \
	    echo; \
	    exit 1; \
	fi
	@echo '[done]     $(1)'

.PHONY: build-only-$(1)
build-only-$(1): PKG = $(1)
build-only-$(1):
	$(if $(value $(1)_BUILD),
	    rm -rf   '$(2)'
	    mkdir -p '$(2)'
	    ( cd '$(2)' && $(call UNPACK_PKG_ARCHIVE,$(1),$(TAR)) ) || \
		    $(if $(TAR2), \
		         ( rm -rf '$(2)'; mkdir -p '$(2)'; \
		           cd '$(2)' && $(call UNPACK_PKG_ARCHIVE,$(1),$(TAR2)) ), \
			 false )
	    test ! -d '$(TOP_DIR)/src/$(1)' || cp -a '$(TOP_DIR)/src/$(1)' '$(2)'
	    cd '$(2)/$($(1)_SUBDIR)'
	    $(foreach PKG_PATCH,$(sort $(wildcard $(TOP_DIR)/src/$(1)-*.patch)),
	        (cd '$(2)/$($(1)_SUBDIR)' && $(PATCH) -p1 -u) < $(PKG_PATCH))
	    $(foreach PKG_PATCH,$(sort $(wildcard $(TOP_DIR)/src/$(MXE_SYSTEM)-$(1)-*.patch)),
	        (cd '$(2)/$($(1)_SUBDIR)' && $(PATCH) -p1 -u) < $(PKG_PATCH))
	    $$(call $(1)_BUILD,$(2)/$($(1)_SUBDIR),$(TOP_DIR)/src/$(1)-test)
	    (du -k -d 0 '$(2)' 2>/dev/null || du -k --max-depth 0 '$(2)') | $(SED) -n 's/^\(\S*\).*/du: \1 KiB/p'
	    rm -rfv  '$(2)'
	    ,)
	[ -d '$(STAMP_DIR)' ] || mkdir -p '$(STAMP_DIR)'
	touch '$(STAMP_DIR)/$(1)'
endef
$(foreach PKG,$(PKGS),$(eval $(call PKG_RULE,$(PKG),$(call TMP_DIR,$(PKG)))))
$(foreach TOOL,$(BUILD_TOOLS),$(eval $(call PKG_RULE,$(TOOL),$(call TMP_DIR,$(TOOL)))))

.PHONY: clean
clean:
	rm -rf $(call TMP_DIR,*) $(BUILD_TOOLS_PREFIX)
	rm -rf $(STAMP_DIR) $(MSYS_INFO_DIR) $(LOG_DIR)
	rm -rf $(MSYS_BASE_DIR) $(NOTEPAD_BASE_DIR)
	rm -rf native-tools cross-tools octave gnuplot
	rm -f Makefile cmake-toolchain-file.stamp

.PHONY: clean-pkg
clean-pkg:
	rm -f $(patsubst %,'%', \
                  $(filter-out \
                      $(foreach PKG,$(PKGS),$(PKG_DIR)/$($(PKG)_FILE)), \
                      $(wildcard $(PKG_DIR)/*)))

.PHONY: update
define UPDATE
    $(if $(2),
        $(if $(filter $(2),$($(1)_IGNORE)),
            $(info IGNORED  $(1)  $(2)),
            $(if $(filter $(2),$($(1)_VERSION)),
                $(info .        $(1)  $(2)),
                $(info NEW      $(1)  $($(1)_VERSION) --> $(2))
                $(SED) -i 's/\( id="$(1)-version"\)>[^<]*/\1>$(2)/' '$(TOP_DIR)/index.html'
                $(MAKE) -f '$(MAKEFILE)' 'update-checksum-$(1)' \
                    || { $(SED) -i 's/\( id="$(1)-version"\)>[^<]*/\1>$($(1)_VERSION)/' '$(TOP_DIR)/index.html'; \
                         exit 1; })),
        $(error Unable to update version number of package $(1)))

endef
update:
	$(foreach PKG,$(PKGS),$(call UPDATE,$(PKG),$(shell $($(PKG)_UPDATE))))

update-checksum-%:
	$(call DOWNLOAD_PKG_ARCHIVE,$*)
	$(SED) -i 's/^\([^ ]*_CHECKSUM *:=\).*/\1 '"`$(call PKG_CHECKSUM,$*)`"'/' '$(TOP_DIR)/src/$*.mk'

cleanup-style:
	@$(foreach FILE,$(wildcard $(addprefix $(TOP_DIR)/,Makefile index.html CNAME src/*.mk src/*test.* tools/*)),\
            $(SED) ' \
                s/\r//g; \
                s/[ \t]\+$$//; \
                s,^#!/bin/bash$$,#!/usr/bin/env bash,; \
                $(if $(filter %Makefile,$(FILE)),,\
                    s/\t/    /g; \
                ) \
            ' < $(FILE) > $(TOP_DIR)/tmp-cleanup-style; \
            diff -u $(FILE) $(TOP_DIR)/tmp-cleanup-style >/dev/null \
                || { echo '[cleanup] $(FILE)'; \
                     cp $(TOP_DIR)/tmp-cleanup-style $(FILE); }; \
            rm -f $(TOP_DIR)/tmp-cleanup-style; \
        )

define build-cmake-toolchain-file
    # create the CMake toolchain file
    [ -d '$(dir $(CMAKE_TOOLCHAIN_FILE))' ] || mkdir -p '$(dir $(CMAKE_TOOLCHAIN_FILE))'
    (if [ $(MXE_SYSTEM) = mingw ]; then \
       echo 'set(CMAKE_SYSTEM_NAME Windows)'; \
       echo 'set(MSYS 1)'; \
     fi; \
     if [ $(MXE_SYSTEM) = msvc ]; then \
       echo 'set(MSVC 1)'; \
     fi; \
     if [ $(BUILD_SHARED) = yes ]; then \
       echo 'set(BUILD_SHARED_LIBS ON)'; \
     else \
       echo 'set(BUILD_SHARED_LIBS OFF)'; \
     fi; \
     if [ $(BUILD_STATIC) = yes ]; then \
       echo 'set(BUILD_STATIC_LIBS ON)'; \
     else \
       echo 'set(BUILD_STATIC_LIBS OFF)'; \
     fi; \
     echo 'set(CMAKE_BUILD_TYPE Release)'; \
     if [ $(MXE_SYSTEM) = msvc ]; then \
         echo 'set(CMAKE_FIND_ROOT_PATH $(HOST_PREFIX_NATIVE))'; \
         echo 'set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)'; \
     else \
         echo 'set(CMAKE_FIND_ROOT_PATH $(HOST_PREFIX))'; \
         echo 'set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)'; \
     fi; \
     echo 'set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)'; \
     echo 'set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)'; \
     echo 'set(CMAKE_C_COMPILER $(MXE_CC))'; \
     echo 'set(CMAKE_CXX_COMPILER $(MXE_CXX))'; \
     echo 'set(CMAKE_Fortran_COMPILER $(MXE_F77))'; \
     echo 'set(CMAKE_RC_COMPILER $(MXE_WINDRES))'; \
     echo 'set(PKG_CONFIG_EXECUTABLE $(MXE_PKG_CONFIG))'; \
     echo 'set(QT_QMAKE_EXECUTABLE $(MXE_QMAKE))'; \
     if [ $(MXE_SYSTEM) = msvc ]; then \
         echo 'set(CMAKE_INSTALL_PREFIX $(HOST_PREFIX_NATIVE) CACHE PATH "Installation Prefix")'; \
     else \
         echo 'set(CMAKE_INSTALL_PREFIX $(HOST_PREFIX) CACHE PATH "Installation Prefix")'; \
     fi; \
     echo 'set(CMAKE_BUILD_TYPE Release CACHE STRING "Debug|Release|RelWithDebInfo|MinSizeRel")') \
     > '$(CMAKE_TOOLCHAIN_FILE)'
endef

cmake-toolchain-file.stamp:
	$(build-cmake-toolchain-file)
	touch cmake-toolchain-file.stamp

# Files to distribute
include dist-files.mk

PACKAGE_VERSION := @PACKAGE_VERSION@
PACKAGE_TARNAME := @PACKAGE_TARNAME@

distdir := $(PACKAGE_TARNAME)-$(PACKAGE_VERSION)

.PHONY: dist
dist:
	rm -rf $(distdir)
	mkdir $(distdir)
	$(TAR) cf - $(DIST_FILES) | ( cd $(distdir) ; $(TAR) xpf - )
	$(TAR) czf $(distdir).tar.gz $(distdir)