#!/usr/bin/make -f # -*- makefile -*- # Build gcc-mingw-w64 using gcc-13-source. # Copyright © 2010-2024 Stephen Kitt # Copyright © 2022-2024 Konstantin Demin # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ifeq (,$(filter terse,$(DEB_BUILD_OPTIONS))) export DH_VERBOSE := 1 endif # Disable package mangling in Launchpad; it currently fails to parse # Built-Using, which results in build failures export NO_PKG_MANGLE=1 target_version := 13 target32 := i686-w64-mingw32 target64 := x86_64-w64-mingw32 targets := $(target32) $(target64) threads := posix win32 gnat_arches := alpha amd64 arm64 armel armhf hppa i386 mips64el mipsel ppc64 ppc64el riscv64 s390x sh4 sparc64 x32 include /usr/share/dpkg/pkg-info.mk include /usr/share/dpkg/architecture.mk top_dir := $(shell pwd) gcc_dir := /usr/src/gcc-$(target_version) upstream_dir := $(top_dir)/src build_dir := $(top_dir)/build stampdir := $(top_dir)/stamps source_version := $(shell dpkg-query -W -f='$${Version}' gcc-$(target_version)-source) deb_version := $(source_version)+$(DEB_VERSION) deb_upstream_version := $(word 1,$(subst -, ,$(source_version))) base_version := $(target_version) export deb_upstream_version # Languages to build (full build only) languages := c,c++,fortran,objc,obj-c++ ifneq (,$(filter $(DEB_HOST_ARCH),$(gnat_arches))) languages := $(languages),ada endif %: dh $@ comma := , debian/control: $(wildcard debian/control.*) debian/rules echo \# This file is generated using debian/rules control, do not edit > $@ cat debian/control.source >> $@ echo >> $@ cat debian/control.bootstrap >> $@ for language in $(subst $(comma), ,$(languages)); do \ echo >> $@; \ sed -f debian/control.$$language.sed debian/control.template >> $@; \ done for target in $(subst -w64-mingw32,,$(subst _,-,$(targets))); do \ echo >> $@; \ sed "s/@@TARGET@@/$$target/g" debian/control.runtime >> $@; \ done echo >> $@ cat debian/control.base >> $@ sed -i '/^Recommends: $$/d' $@ sed -i '/^Breaks: $$/d' $@ sed -i '/^Conflicts: $$/d' $@ sed -i '/^Replaces: $$/d' $@ sed -i 's/@@VERSION@@/$(target_version)/g' $@ ifeq (,$(gnat_arches)) sed -i '/@@GNAT_ARCHES@@/d' $@ else sed -i 's/@@GNAT_ARCHES@@/$(gnat_arches)/' $@ endif sed -i 's/, $$/,/' $@ # Hardening on the host, none on the target # Format fails the build currently; using PIE produces a compiler # which can't build with pre-compiled headers dpkg_buildflags_host = DEB_BUILD_MAINT_OPTIONS="hardening=+all,-format,-pie" dpkg-buildflags dpkg_buildflags_target = DEB_BUILD_MAINT_OPTIONS="hardening=-all qa=-bug-implicit-func" dpkg-buildflags ifeq (,$(filter stage1,$(DEB_BUILD_PROFILES))) CC = gcc-$(target_version) CXX = g++-$(target_version) else CC = gcc CXX = g++ endif CFLAGS := $(shell $(dpkg_buildflags_host) --get CFLAGS) CFLAGS += -Wall CFLAGS_FOR_TARGET := $(shell $(dpkg_buildflags_target) --get CFLAGS) CFLAGS_FOR_TARGET += -Wall CPPFLAGS := $(shell $(dpkg_buildflags_host) --get CPPFLAGS) CPPFLAGS_FOR_TARGET = $(shell $(dpkg_buildflags_target) --get CPPFLAGS) CXXFLAGS := $(shell $(dpkg_buildflags_host) --get CXXFLAGS) CXXFLAGS += -Wall CXXFLAGS_FOR_TARGET := $(shell $(dpkg_buildflags_target) --get CXXFLAGS) CXXFLAGS_FOR_TARGET += -Wall FCFLAGS := $(shell $(dpkg_buildflags_target) --get FCFLAGS) FCFLAGS_FOR_TARGET := $(shell $(dpkg_buildflags_target) --get FCFLAGS) FFLAGS := $(shell $(dpkg_buildflags_host) --get FFLAGS) FFLAGS_FOR_TARGET := $(shell $(dpkg_buildflags_target) --get FFLAGS) LDFLAGS := $(shell $(dpkg_buildflags_host) --get LDFLAGS) LDFLAGS += -Wl,--as-needed LDFLAGS_FOR_TARGET := $(shell $(dpkg_buildflags_target) --get LDFLAGS) LDFLAGS_FOR_TARGET += -Wl,--as-needed export CC CXX CFLAGS CFLAGS_FOR_TARGET CPPFLAGS CPPFLAGS_FOR_TARGET export CXXFLAGS CXXFLAGS_FOR_TARGET FFLAGS FFLAGS_FOR_TARGET FCFLAGS FCFLAGS_FOR_TARGET LDFLAGS LDFLAGS_FOR_TARGET # Number of jobs to run for build ifeq (no,$(USE_NJOBS)) NJOBS := USE_CPUS := 1 else # Increase to 192 if building Java MEM_PER_CPU = 128 NUM_CPUS := $(shell if echo $(USE_NJOBS) | grep -q -E '^[0-9]+$$'; \ then echo $(USE_NJOBS); \ else getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1; fi) USE_CPUS := $(shell awk -vn=$(NUM_CPUS) -vm=$(MEM_PER_CPU) '/^MemTotal/ { mt = $$2 } \ END { n2 = int(mt/1024/m); print (n==1 || n2<=1) ? 1 : (n2<=n ? n2 : n) }' /proc/meminfo) ifneq (,$(strip $(USE_CPUS))) NJOBS := -j $(USE_CPUS) endif endif # Support parallel= in DEB_BUILD_OPTIONS (see #209008) ifneq (,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS)))) NJOBS := -j $(subst parallel=,,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS)))) endif # Patch targets patchdir = $(gcc_dir)/debian/patches series_file = series unpack_stamp = $(stampdir)/unpack patch_stamp = $(stampdir)/patch GFDL_INVARIANT_FREE=yes srcdir=$(upstream_dir) include $(gcc_dir)/debian/rules.patch unpack: $(unpack_stamp) $(unpack_stamp): tar xf $(gcc_dir)/gcc-*.tar.* rm -rf $(upstream_dir) mv gcc-* $(upstream_dir) # Apply our first series of patches (those which need to be applied # before gcc-?-source’s) QUILT_SERIES=debian/patches/series1 QUILT_PATCHES=debian/patches quilt push -a # Drop the quilt cache so we can process other series rm -rf .pc mkdir -p $(stampdir) # gcov-dump.texi is missing in some source tarballs if [ ! -f $(upstream_dir)/gcc/doc/gcov-dump.texi ]; then cp $(gcc_dir)/debian/dummy.texi $(upstream_dir)/gcc/doc/gcov-dump.texi; fi touch $@ execute_before_dh_clean: debian/control rm -rf $(stampdir) $(build_dir) $(upstream_dir) .pc autotools_files series *-stamp rm -f $(patsubst %.in,%,$(wildcard debian/*.in)) # Configuration constructed as in the gcc package PF=usr libdir=lib libexecdir=$(PF)/$(libdir) # Standard Debian configuration flags CONFFLAGS = \ --prefix=/$(PF) \ --enable-shared \ --enable-static \ --disable-multilib \ --with-system-zlib \ --libexecdir=/$(libexecdir) \ --without-included-gettext \ --libdir=/$(PF)/$(libdir) \ --enable-libstdcxx-time=yes \ --with-tune=generic # Tell GCC we have headers (this enables gcov) CONFFLAGS += \ --with-headers # MinGW-w64 flags # version-specific-runtime-libs puts target-specific libraries in # /usr/lib/gcc rather than /usr/$(target) CONFFLAGS += \ --enable-version-specific-runtime-libs \ --enable-fully-dynamic-string \ --enable-libgomp # Target-dependent CONFFLAGS += \ --program-prefix=$$target- \ --target=$$target \ --with-as=/usr/bin/$$target-as \ --with-ld=/usr/bin/$$target-ld # Enable libatomic CONFFLAGS += \ --enable-libatomic # Enable experimental::filesystem and std::filesystem CONFFLAGS += \ --enable-libstdcxx-filesystem-ts=yes # Enable dependency tracking (disabled by dh; see # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55930 for details) CONFFLAGS += \ --enable-dependency-tracking # Use the most compatible path for sed (e.g. non-usrmerge). CONFFLAGS += \ SED=/bin/sed # BOOTFLAGS are used for the bootstrap build, FULLFLAGS for the full build BOOTFLAGS += \ --enable-languages=c,c++ FULLFLAGS += \ --enable-languages=$(languages) # Thread-model-dependent FULLFLAGS += \ --enable-threads=$$threads \ --program-suffix=-$$threads # LTO BOOTFLAGS += \ --disable-lto FULLFLAGS += \ --enable-lto # FLAGS32 are 32-bit-specific, FLAGS64 64-bit-specific # For 32-bit targets, force Dwarf2 exception handling FLAGS32 += \ --disable-sjlj-exceptions --with-dwarf2 spelling = echo "--- Fix spelling of \"$(1)\" -> \"$(2)\"" >&2 ; find $(upstream_dir)/ -type f -exec grep -FZl -e "$(1)" {} + | xargs -0t sed -i "s/$(1)/$(2)/g" || echo "--- The above fix is no longer necessary" # Patches applied or unapplied after the upstream sources have been # unpacked and patched using the gcc-?-source package's patches mingw-w64-patch: mingw-w64-patch-stamp mingw-w64-patch-stamp: $(patch_stamp) # Apply our second series of patches rm -rf .pc QUILT_SERIES=debian/patches/series2 QUILT_PATCHES=debian/patches quilt push -a # Spelling fixes $(call spelling,Allow to,Allow one to) $(call spelling,Var befor:,Var before:) $(call spelling,eroneous,erroneous) $(call spelling,identifer,identifier) $(call spelling,informations,information) $(call spelling,interchage,interchange) $(call spelling,intial,initial) $(call spelling,intrument,instrument) $(call spelling,mininum,minimum) $(call spelling,mutiple,multiple) $(call spelling,occurence,occurrence) $(call spelling,refrence,reference) $(call spelling,should't,shouldn't) $(call spelling,splitted,split) $(call spelling,Staticly,Statically) $(call spelling,temorary,temporary) $(call spelling,suported,supported) $(call spelling,wihout,without) # Force /bin/sh in mkheaders sed -i sX@SHELL@X/bin/shX $(upstream_dir)/fixincludes/mkheaders.in # Fix the date and time of patched files find . -type f -a -newermt '@$(SOURCE_DATE_EPOCH)' \ -exec touch --no-dereference --date='@$(SOURCE_DATE_EPOCH)' {} + touch $@ # 32- and 64-bit targets are split: 32-bit uses Dwarf2, 64-bit the default SEH override_dh_auto_configure: debian/control mingw-w64-patch-stamp ifeq (,$(filter stage1,$(DEB_BUILD_PROFILES))) set -e; \ for threads in $(threads); do \ echo $(base_version)-$$threads > $(upstream_dir)/gcc/BASE-VER; \ touch -r $(top_dir)/debian/changelog $(upstream_dir)/gcc/BASE-VER; \ mkdir -p $(build_dir)/$(target32)-$$threads $(build_dir)/$(target64)-$$threads; \ target=$(target32); \ cd $(build_dir)/$(target32)-$$threads && $(upstream_dir)/configure \ $(CONFFLAGS) $(FULLFLAGS) $(FLAGS32); \ target=$(target64); \ cd $(build_dir)/$(target64)-$$threads && $(upstream_dir)/configure \ $(CONFFLAGS) $(FULLFLAGS) $(FLAGS64); \ done else set -e; \ mkdir -p $(build_dir)/$(target32) $(build_dir)/$(target64); \ target=$(target32); \ cd $(build_dir)/$(target32) && $(upstream_dir)/configure \ $(CONFFLAGS) $(BOOTFLAGS) $(FLAGS32); \ target=$(target64); \ cd $(build_dir)/$(target64) && $(upstream_dir)/configure \ $(CONFFLAGS) $(BOOTFLAGS) $(FLAGS64) endif override_dh_auto_build-arch: ifeq (,$(filter stage1,$(DEB_BUILD_PROFILES))) set -e; \ for target in $(targets); do \ for threads in $(threads); do \ echo $(base_version)-$$threads > $(upstream_dir)/gcc/BASE-VER && \ touch -r $(top_dir)/debian/changelog $(upstream_dir)/gcc/BASE-VER && \ cd $(build_dir)/$$target-$$threads && \ $(MAKE) $(NJOBS); \ done; \ done else set -e; \ for target in $(targets); do \ cd $(build_dir)/$$target && \ $(MAKE) $(NJOBS) all-gcc; \ done endif override_dh_auto_build-indep: override_dh_auto_install-arch: # Base installation, move misplaced DLLs and libraries ifeq (,$(filter stage1,$(DEB_BUILD_PROFILES))) set -e; \ for target in $(targets); do \ for threads in $(threads); do \ echo $(base_version)-$$threads > $(upstream_dir)/gcc/BASE-VER && \ touch -r $(top_dir)/debian/changelog $(upstream_dir)/gcc/BASE-VER && \ cd $(build_dir)/$$target-$${threads} && \ $(MAKE) DESTDIR=$(top_dir)/debian/tmp install install-lto-plugin; \ if [ -f $(top_dir)/debian/tmp/usr/lib/gcc/$$target/lib/*.a ]; then \ mv $(top_dir)/debian/tmp/usr/lib/gcc/$$target/lib/*.a $(top_dir)/debian/tmp/usr/lib/gcc/$$target/$(base_version)-$$threads/; \ fi; \ if [ -f $(top_dir)/debian/tmp/usr/lib/gcc/$$target/*.dll ]; then \ mv $(top_dir)/debian/tmp/usr/lib/gcc/$$target/*.dll $(top_dir)/debian/tmp/usr/lib/gcc/$$target/$(base_version)-$$threads/; \ fi; \ done; \ done else set -e; \ for target in $(targets); do \ cd $(build_dir)/$$target && \ $(MAKE) DESTDIR=$(top_dir)/debian/tmp install-gcc; \ if [ -f $(top_dir)/debian/tmp/usr/lib/gcc/$$target/lib/*.a ]; then \ mv $(top_dir)/debian/tmp/usr/lib/gcc/$$target/lib/*.a $(top_dir)/debian/tmp/usr/lib/gcc/$$target/$(base_version)/; \ fi; \ if [ -f $(top_dir)/debian/tmp/usr/lib/gcc/$$target/*.dll ]; then \ mv $(top_dir)/debian/tmp/usr/lib/gcc/$$target/*.dll $(top_dir)/debian/tmp/usr/lib/gcc/$$target/$(base_version)/; \ fi; \ done endif # Remove files which conflict with other packages # gcc-$(target_version)-locales rm -rf $(top_dir)/debian/tmp/usr/share/locale # binutils-dev rm -f $(top_dir)/debian/tmp/usr/lib/libiberty.a # libstdc++6-$(target_version)-dbg (potentially) rm -rf $(top_dir)/debian/tmp/usr/share/gcc/python # -doc packages rm -rf $(top_dir)/debian/tmp/usr/share/info rm -rf $(top_dir)/debian/tmp/usr/share/man/man7 # libcc1-0 rm -f $(top_dir)/debian/tmp/usr/lib/libcc1* # No need to ship empty manpages rm -rf $(top_dir)/debian/tmp/usr/share/man/man1 # Drop .la files find $(top_dir)/debian/tmp/ -name \*.la -delete for i in 1 2; do \ find $(top_dir)/debian/tmp/ -type d -empty -delete; \ done override_dh_installchangelogs: dh_installchangelogs $(upstream_dir)/ChangeLog override_dh_gencontrol: dh_gencontrol -- -v$(deb_version) -Vlocal:Version=$(deb_upstream_version) -Vgcc:Version=$(source_version) execute_before_dh_install-arch: for file in debian/*.in; do sed 's/@@VERSION@@/$(target_version)/g;s/@@BASEVERSION@@/$(base_version)/g' < $$file > $${file%%.in}; chmod --reference=$$file $${file%%.in}; done ifeq (,$(filter ada,$(subst $(COMMA), ,$(languages)))) sed -i /adalib/d debian/*-runtime.install endif override_dh_installdocs-arch: dh_installdocs -a --link-doc=gcc-mingw-w64-base override_dh_strip-arch: # Strip the binaries dh_strip -a -Xw64-mingw32/lib $(patsubst %,-Xw64-mingw32/$(base_version)-%/lib,$(threads)) \ $(if $(findstring ada,$(languages)),$(patsubst %,-Xw64-mingw32/$(base_version)-%/adalib,$(threads))) # Strip the libraries ifeq (,$(filter nostrip,$(DEB_BUILD_OPTIONS))) find $(top_dir)/debian -type f -name liblto_plugin.so \ -exec strip --remove-section=.comment --remove-section=.note --strip-unneeded {} + for target in $(targets); do \ find $(top_dir)/debian -path \*/$$target/\* \( \( -path \*/plugin -prune \) -o \( -type f -name lib\*.a -exec $$target-strip --strip-unneeded {} + \) \); \ done endif execute_after_dh_fixperms-arch: # Fix permissions further - *.ali files must be read-only find $(top_dir)/debian -name \*.ali -exec chmod 444 {} + .PHONY: mingw-w64-patch