#!/usr/bin/make -f # -*- makefile -*- # Build mingw-w64. empty:= space:=$(empty) $(empty) xsedx:=$(shell printf '\027') # Silence huge amount of warnings in "arch:all" build mute_warn := expansion-to-defined cpp_nowarn := $(foreach w,$(mute_warn),-Wno-$(w)) export DEB_CPPFLAGS_MAINT_APPEND = $(cpp_nowarn) # Hardening is for host binaries only (no support in targets for now) export DEB_BUILD_MAINT_OPTIONS := hardening=+all optimize=+lto TARGET_DEB_BUILD_OPTIONS := hardening=-all optimize=-lto ifeq (,$(filter terse,$(DEB_BUILD_OPTIONS))) export DH_VERBOSE := 1 endif include /usr/share/dpkg/default.mk build := $(CURDIR)/build stamp := $(build)/stamp tmpdst := $(build)/tmp # Target architectures target32 := i686-w64-mingw32 target64 := x86_64-w64-mingw32 targets := $(target32) $(target64) # Host architecture host = $(DEB_HOST_GNU_TYPE) # Host-based tools tools_host := gendef genidl genlib genpeimg # Targetted tools tools_target := widl # Targetted projects # Nota bene: crt is built before libraries lib_target := winpthreads lib_target32 := ifeq ($(filter stage1,$(DEB_BUILD_PROFILES)),) lib_target += winstorecompat lib_target32 += pseh endif %: dh $@ .NOTPARALLEL: override_dh_update_autotools_config: override_dh_autoreconf: # General rules # Format: host~target~source~folder # E.g. i486-linux-gnu~i686-w64-mingw32~tools~widl to build a 32-bit # Linux-hosted widl targeting 32-bit Windows rule_words = $(subst ~,$(space),$(1)) rule_host = $(word 1,$(call rule_words,$(1))) rule_target = $(word 2,$(call rule_words,$(1))) rule_path = $(subst $(space),/,$(wordlist 3,$(words $(call rule_words,$(1))),$(call rule_words,$(1)))) source_folder = $(CURDIR)/mingw-w64-$(call rule_path,$(1)) build_folder = $(build)/$(call rule_host,$(1))_$(call rule_target,$(1))_$(subst /,-,$(call rule_path,$(1))) build_flags = $(call build_folder,$(1)).flags build_ldspec = $(call build_folder,$(1)).ldspecs ###################################################################### # Tools # gendef requires libmangle $(stamp)/$(host)~$(host)~tools~gendef~configure: \ $(stamp)/%~tools~gendef~configure: \ $(stamp)/%~libraries~libmangle~install \ $(stamp)/%~tools~gendef~preconf # cd '$(call build_folder,$(*)~tools~gendef)' ; \ . '$(call build_flags,$(*)~tools~gendef)' ; \ '$(call source_folder,$(*)~tools~gendef)/configure' \ --host=$(call rule_host,$(*)~tools~gendef) \ --target=$(call rule_target,$(*)~tools~gendef) \ --prefix=/usr \ --with-mangle='$(tmpdst)/usr' touch '$(stamp)/$(*)~tools~gendef~configure' # genlib requires libmangle and is installed as mingw-genlib # to avoid a conflict with alliance $(stamp)/$(host)~$(host)~tools~genlib~configure: \ $(stamp)/%~tools~genlib~configure: \ $(stamp)/%~libraries~libmangle~install \ $(stamp)/%~tools~genlib~preconf # cd '$(call build_folder,$(*)~tools~genlib)' ; \ . '$(call build_flags,$(*)~tools~genlib)' ; \ '$(call source_folder,$(*)~tools~genlib)/configure' \ --host=$(call rule_host,$(*)~tools~genlib) \ --target=$(call rule_target,$(*)~tools~genlib) \ --program-prefix=mingw- \ --prefix=/usr \ --with-mangle'=$(tmpdst)/usr' touch '$(stamp)/$(*)~tools~genlib~configure' ###################################################################### # Libraries # Override the header configuration $(stamp)/%~headers~configure: \ $(stamp)/%~headers~preconf # cd '$(call build_folder,$(*)~headers)' ; \ . '$(call build_flags,$(*)~headers)' ; \ '$(call source_folder,$(*)~headers)/configure' \ --host=$(call rule_host,$(*)~headers) \ --target=$(call rule_target,$(*)~headers) \ --prefix=/usr/$(call rule_target,$(*)~headers) touch '$(stamp)/$(*)~headers~configure' # Override CRT configuration to avoid multilib builds $(foreach t,$(targets),$(stamp)/$(t)~$(t)~crt~configure): \ $(stamp)/%~crt~configure: \ $(stamp)/%~headers~install \ $(stamp)/%~crt~preconf # cd '$(call build_folder,$(*)~crt)' ; \ . '$(call build_flags,$(*)~crt)' ; \ '$(call source_folder,$(*)~crt)/configure' \ --host=$(call rule_host,$(*)~crt) \ --target=$(call rule_target,$(*)~crt) \ --prefix=/usr/$(call rule_target,$(*)~crt) \ --$(if $(filter $(call rule_target,$(*)~crt),$(target64)),enable,disable)-lib64 \ --$(if $(filter $(call rule_target,$(*)~crt),$(target32)),enable,disable)-lib32 touch '$(stamp)/$(*)~crt~configure' # Special target to call autoreconf only and only when required $(stamp)/%~autoreconf: cd '$(call source_folder,$(*))' ; \ [ -x configure ] || autoreconf -fiv touch '$(stamp)/$(*)~autoreconf' $(stamp)/%~ldspecs: $(stamp)/%~autoreconf if [ '$(host)' != '$(call rule_host,$(*))' ] ; then \ sed 's$(xsedx)@@PATH@@$(xsedx)$(tmpdst)/usr/$(call rule_host,$(*))/lib$(xsedx)g' \ < debian/specs.in \ > '$(call build_ldspec,$(*))' ; \ fi touch '$(stamp)/$(*)~ldspecs' $(stamp)/%~builddir: $(stamp)/%~ldspecs mkdir -p '$(call build_folder,$(*))' touch '$(stamp)/$(*)~builddir' # No hardening support for now, except in the tools (override_dh_auto_build-arch) $(stamp)/%~flags: $(stamp)/%~builddir if [ '$(host)' != '$(call rule_host,$(*))' ] ; then \ export DEB_BUILD_MAINT_OPTIONS='$(TARGET_DEB_BUILD_OPTIONS)' ; \ export DEB_CPPFLAGS_MAINT_PREPEND='-I$(tmpdst)/usr/$(call rule_target,$(*))/include' ; \ export DEB_LDFLAGS_MAINT_PREPEND='-L$(tmpdst)/usr/$(call rule_target,$(*))/lib' ; \ fi ; \ dpkg-buildflags --export=sh > '$(call build_flags,$(*))' # Add -f*-prefix-map flag for build directory sed -i -E '/-f.+-prefix-map/{s$(xsedx)"$$$(xsedx) -ffile-prefix-map=$(call build_folder,$(*))=/build"$(xsedx)}' \ '$(call build_flags,$(*))' # Add -f*-prefix-map flag for staging directory sed -i -E '/-f.+-prefix-map/{s$(xsedx)"$$$(xsedx) -ffile-prefix-map=$(tmpdst)/=/"$(xsedx)}' \ '$(call build_flags,$(*))' # Adjust CFLAGS to pass --debug-prefix-map for `as' # ref: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93371 . '$(call build_flags,$(*))' ; \ for o in $${CFLAGS} ; do \ case "$$o" in \ -f*-prefix-map=*) \ map=$${o#*=} ; \ sed -i -E '/^export CFLAGS=/{s$(xsedx)"$$$(xsedx) -Wa,--debug-prefix-map,'"$${map}"'"$(xsedx)}' \ '$(call build_flags,$(*))' ; \ ;; \ esac ; \ done # Adjust flags for target: # - correct -specs in LDFLAGS # - provide RCFLAGS (fixes "stage1" build) if [ '$(host)' != '$(call rule_host,$(*))' ] ; then \ sed -i -E '/^export LDFLAGS=/{s$(xsedx)-specs=[^"[:space:]]+$(xsedx)$(xsedx)}' \ '$(call build_flags,$(*))' ; \ sed -i -E '/^export LDFLAGS=/{s$(xsedx)"$$$(xsedx) -specs=$(call build_ldspec,$(*))"$(xsedx)}' \ '$(call build_flags,$(*))' ; \ RCFLAGS="-I$(tmpdst)/usr/$(call rule_target,$(*))/include$${RCFLAGS:+ }$${RCFLAGS}" ; \ printf 'export RCFLAGS="%s"\n' "$${RCFLAGS}" >> '$(call build_flags,$(*))' ; \ fi touch '$(stamp)/$(*)~flags' $(stamp)/%~preconf: $(stamp)/%~flags touch '$(stamp)/$(*)~preconf' # If we're targetting the build host, configure for hardening # If we're targetting the target host, disable hardening (see above), # change the prefix and use the new headers and libraries $(stamp)/%~configure: $(stamp)/%~preconf cd '$(call build_folder,$(*))' ; \ . '$(call build_flags,$(*))' ; \ if [ '$(host)' = '$(call rule_host,$(*))' ] ; then \ '$(call source_folder,$(*))/configure' \ --host=$(call rule_host,$(*)) \ --target=$(call rule_target,$(*)) \ --prefix=/usr \ ; \ else \ '$(call source_folder,$(*))/configure' \ --host=$(call rule_host,$(*)) \ --target=$(call rule_target,$(*)) \ --prefix=/usr/$(call rule_target,$(*)) \ --with-widl-includedir=/usr/$(call rule_target,$(*))/include \ ; \ fi touch '$(stamp)/$(*)~configure' $(stamp)/%~postconf: $(stamp)/%~configure touch '$(stamp)/$(*)~postconf' $(stamp)/%~build: $(stamp)/%~postconf . '$(call build_flags,$(*))' ; \ dh_auto_build --sourcedir='$(call source_folder,$(*))' --builddir='$(call build_folder,$(*))' touch '$(stamp)/$(*)~build' $(stamp)/%~install: $(stamp)/%~build dh_auto_install --sourcedir='$(call source_folder,$(*))' --builddir='$(call build_folder,$(*))' --destdir='$(tmpdst)' touch '$(stamp)/$(*)~install' execute_before_dh_auto_configure: # perform source cleanup from tarball to repository state (close enough) for n in aclocal.m4 'build-aux/*' config.h.in configure Makefile.in ; do \ find -wholename "*/$$n" -type f -delete ; \ done # remove extra libtool/m4 files for n in libtool ltoptions ltsugar ltversion 'lt~obsolete' ; do \ find -wholename "*/$$n.m4" -type f -delete ; \ done mkdir -p '$(build)' '$(stamp)' '$(tmpdst)' override_dh_auto_configure-arch: $(foreach x,$(tools_host),$(stamp)/$(host)~$(host)~tools~$(x)~install) override_dh_auto_configure-indep: $(foreach t,$(targets),$(stamp)/$(t)~$(t)~crt~install) override_dh_auto_build-arch: $(foreach x,$(tools_target),$(foreach t,$(targets),$(stamp)/$(host)~$(t)~tools~$(x)~install)) override_dh_auto_build-indep: $(foreach x,$(lib_target),$(foreach t,$(targets),$(stamp)/$(t)~$(t)~libraries~$(x)~install)) override_dh_auto_build-indep: $(foreach x,$(lib_target32),$(stamp)/$(target32)~$(target32)~libraries~$(x)~install) # Nothing to test here yet override_dh_auto_test: override_dh_auto_install-indep: # Move DLLs to lib, drop .la files d='$(tmpdst)/usr' ; \ for T in $(targets) ; do \ find "$$d/$$T/lib/" -name '*.la' -delete ; \ find "$$d/$$T/bin/" -name '*.dll' -exec mv -nt "$$d/$$T/lib" '{}' '+' ; \ done # Move duplicate files to mingw-w64-common s='$(tmpdst)/usr' ; \ d='usr/share/mingw-w64' ; \ refT='$(word 1,$(targets))' ; \ testT='$(wordlist 2,$(words $(targets)),$(targets))' ; \ for file in $$(cd "$$s/$$refT" ; find . -type f ! -name '*.a' -printf '%P\n') ; do \ dupT="$$refT" ; \ for target in $$testT ; do \ [ -f "$$s/$$target/$$file" ] || continue ; \ if cmp -s "$$s/$$refT/$$file" "$$s/$$target/$$file" ; then \ dupT="$$dupT $$target" ; \ fi ; \ done ; \ if [ "$$dupT" = "$$refT" ] ; then continue ; fi ; \ mkdir -p "debian/mingw-w64-common/$$d/$$(dirname $$file)" ; \ cp "$$s/$$refT/$$file" "debian/mingw-w64-common/$$d/$$file" ; \ for duptarget in $$dupT ; do \ rm -f "$$s/$$duptarget/$$file" ; \ ln -sf "/$$d/$$file" "$$s/$$duptarget/$$file" ; \ done ; \ done override_dh_auto_install-arch: # Remove mingw-w64 libmangle artifacts (if any) rm -f \ '$(tmpdst)/usr/include/libmangle.h' \ '$(tmpdst)/usr/lib/libmangle.a' execute_after_dh_auto_install: # Move files to appropriate location for debhelper mkdir -p debian/tmp mv -t debian/tmp '$(tmpdst)/'*