summaryrefslogtreecommitdiff
blob: dbbdbd2de31cd079842a6437b1785d50608cf36e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# Copyright 1999-2023 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=8

inherit flag-o-matic toolchain-funcs

DESCRIPTION="Free Win64 runtime and import library definitions"
HOMEPAGE="https://www.mingw-w64.org/"
SRC_URI="mirror://sourceforge/mingw-w64/mingw-w64/mingw-w64-release/mingw-w64-v${PV}.tar.bz2"
S="${WORKDIR}/mingw-w64-v${PV}"

LICENSE="ZPL BSD BSD-2 ISC LGPL-2+ LGPL-2.1+ MIT public-domain tools? ( GPL-3+ )"
SLOT="0"
KEYWORDS="~amd64 ~x86"
# USE=libraries needs working stage2 compiler: bug #665512
IUSE="default-ucrt headers-only idl libraries tools"
RESTRICT="strip"

PATCHES=(
	"${FILESDIR}"/${PN}-7.0.0-fortify-only-ssp.patch
	"${FILESDIR}"/${P}-msvcr-extra-race.patch
)

pkg_setup() {
	: ${CBUILD:=${CHOST}}
	: ${CTARGET:=${CHOST}}
	[[ ${CTARGET} == ${CHOST} && ${CATEGORY} == cross-* ]] &&
		CTARGET=${CATEGORY#cross-}

	[[ ${CHOST} != ${CTARGET} ]] && MW_CROSS=true || MW_CROSS=false

	[[ ${CBUILD} == ${CHOST} && ${CTARGET} == ${CHOST} ]] &&
		die "Invalid configuration, please see: https://wiki.gentoo.org/wiki/Mingw"
}

mingw-foreach_tool() {
	use !tools || use headers-only && return

	local tool=widl
	if use !amd64 && use !x86 && use !arm64 && use !arm; then
		einfo "Skipping widl due to unsupported platform" #853250
		tool=
	fi

	for tool in gendef genidl ${tool}; do
		# not using top-level --with-tools given it skips widl
		pushd mingw-w64-tools/${tool} >/dev/null || die
		"${@}"
		popd >/dev/null || die
	done
}

src_configure() {
	# native tools, see #644556
	local toolsconf=()
	# normally only widl is prefixed, but avoids clash with other targets
	${MW_CROSS} && toolsconf+=( --program-prefix=${CTARGET}- )

	mingw-foreach_tool econf "${toolsconf[@]}"

	MW_LDFLAGS=${LDFLAGS} # keep non-stripped for gendef not respecting it

	# likely cross-compiling from here, update toolchain variables
	if ${MW_CROSS} && [[ ! -v MINGW_BYPASS ]]; then
		unset AR AS CC CPP CXX LD NM OBJCOPY OBJDUMP RANLIB RC STRIP
		filter-flags '-fstack-clash-protection' #758914
		filter-flags '-fstack-protector*' #870136
		filter-flags '-fuse-ld=*'
		filter-flags '-mfunction-return=thunk*' #878849
	fi
	local CHOST=${CTARGET}

	# -mavx with mingw-gcc has a history of obscure issues and
	# disabling is seen as safer, e.g. `WINEARCH=win32 winecfg`
	# crashes with -march=skylake >=wine-8.10, similar issues with
	# znver4: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110273
	tc-is-gcc && append-flags -mno-avx

	strip-unsupported-flags

	# Normally mingw64 does not use dynamic linker.
	# But at configure time it uses $LDFLAGS.
	# When default -Wl,--hash-style=gnu is passed
	# __CTORS_LIST__ / __DTORS_LIST__ is mis-detected
	# for target ld and binaries crash at shutdown.
	filter-ldflags '-Wl,--hash-style=*'

	local prefix=${EPREFIX}/usr
	${MW_CROSS} && prefix+=/${CTARGET}/usr

	local conf=(
		--prefix="${prefix}"
		--libdir="${prefix}"/lib
		$(use_with !headers-only crt)
		$(usev default-ucrt --with-default-msvcrt=ucrt)

		# By default configure tries to set --sysroot=${prefix}. We disable
		# this behaviour with --with-sysroot=no to use gcc's sysroot default.
		# That way we can cross-build mingw64-runtime with cross-emerge.
		--with-sysroot=no
	)

	if use !headers-only; then
		conf+=(
			$(use_enable idl)
			$(use_with libraries)
		)

		# prefer tuple to determine if should do 32 or 64bits, but fall
		# back to cpp test if missing (bug #584858, see also #840662)
		local b32=true
		case ${CHOST} in
			x86_64-*) b32=false;;
			i*86-*) ;;
			*) [[ $($(tc-getCPP) -dM - <<<'') =~ __MINGW64__ ]] && b32=false;;
		esac
		${b32} &&
			conf+=( --enable-lib32 --disable-lib64 ) ||
			conf+=( --disable-lib32 --enable-lib64 )

		# prepare temporary headers install to build against same-version
		mkdir ../headers || die
		pushd ../headers >/dev/null || die
		ECONF_SOURCE=${S} econf --prefix="${T}"/root --without-crt
		popd >/dev/null || die

		append-cppflags "-I${T}/root/include"
	fi

	econf "${conf[@]}"
}

src_compile() {
	use headers-only || emake -C ../headers install
	emake
	mingw-foreach_tool emake LDFLAGS="${MW_LDFLAGS}"
}

src_install() {
	default

	mingw-foreach_tool emake DESTDIR="${D}" install

	if ${MW_CROSS}; then
		# gcc is configured to look at specific hard-coded paths for mingw #419601
		dosym usr /usr/${CTARGET}/mingw
		dosym usr /usr/${CTARGET}/${CTARGET}
		dosym usr/include /usr/${CTARGET}/sys-include
	fi

	rm -r "${ED}"/usr/share || die
}