# Copyright 2025 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # @ECLASS: wine.eclass # @MAINTAINER: # Wine # @AUTHOR: # Ionen Wolkens # @SUPPORTED_EAPIS: 8 # @BLURB: Common functions for app-emuluation/wine-* ebuilds # @DESCRIPTION: # Given the large amount of Wine ebuilds (and variants) that need # duplicated code, this is used to offload the more complex bits # (primarily toolchain and slotting) and leave ebuilds to only need # to deal with dependencies and configure options like any other. # # Note to overlays: this can be used to package other variants of # Wine, but there is currently no garantee that eclass changes may # not break these ebuilds now and then without real warnings case ${EAPI} in 8) ;; *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; esac if [[ -z ${_WINE_ECLASS} ]]; then _WINE_ECLASS=1 inherit autotools flag-o-matic multilib prefix toolchain-funcs wrapper # @ECLASS_VARIABLE: WINE_USEDEP # @DESCRIPTION: # Meant be used like multilib-build.eclass' MULTILIB_USEDEP. Handled # specially here given Wine ebuilds are not *really* multilib and are # abusing abi_x86_* with some specific requirements. # # TODO: when the *new* wow64 mode (aka USE=wow64) is mature enough to # be preferred over abi_x86_32, this should be removed and support for # 32bit-only-on-64bit be dropped matching how /no-multilib/ handles it # (USE=wow64 should be enabled by default on amd64 then, but not arm64) readonly WINE_USEDEP="abi_x86_32(-)?,abi_x86_64(-)?" IUSE=" +abi_x86_32 +abi_x86_64 crossdev-mingw custom-cflags +mingw +strip wow64 " REQUIRED_USE=" || ( abi_x86_32 abi_x86_64 arm64 ) crossdev-mingw? ( mingw ) wow64? ( !arm64? ( abi_x86_64 !abi_x86_32 ) ) " BDEPEND=" || ( sys-devel/binutils:* llvm-core/lld:* ) dev-lang/perl mingw? ( !crossdev-mingw? ( wow64? ( dev-util/mingw64-toolchain[abi_x86_32] ) !wow64? ( dev-util/mingw64-toolchain[${WINE_USEDEP}] ) ) ) !mingw? ( llvm-core/clang:* llvm-core/lld:* strip? ( llvm-core/llvm:* ) ) " IDEPEND=">=app-eselect/eselect-wine-2" # @ECLASS_VARIABLE: WINE_SKIP_INSTALL # @DESCRIPTION: # Array of files to delete from the installation relative # to ${ED}, must be set before running wine_src_install. WINE_SKIP_INSTALL=() # @FUNCTION: wine_pkg_pretend # @DESCRIPTION: # Verifies if crossdev-mingw is used properly, ignored if # ``MINGW_BYPASS`` is set. wine_pkg_pretend() { [[ ${MERGE_TYPE} == binary ]] && return if use crossdev-mingw && [[ ! -v MINGW_BYPASS ]]; then local arches=( $(usev abi_x86_64 x86_64) $(usev abi_x86_32 i686) $(usev wow64 i686) $(usev arm64 aarch64) ) local mingw for mingw in "${arches[@]/%/-w64-mingw32}"; do if ! type -P ${mingw}-gcc >/dev/null; then eerror "With USE=crossdev-mingw, you must prepare the MinGW toolchain" eerror "yourself by installing sys-devel/crossdev then running:" eerror eerror " crossdev --target ${mingw}" eerror eerror "For more information, please see: https://wiki.gentoo.org/wiki/Mingw" die "USE=crossdev-mingw is enabled, but ${mingw}-gcc was not found" fi done fi } # @FUNCTION: wine_src_prepare # @DESCRIPTION: # Apply various minor adjustments, run eautoreconf, make_requests, and # perform a version mismatch sanity check if WINE_GECKO and WINE_MONO # are set. # # If need more than make_requests, it should be either handled in # the ebuild or (for users) optionally through portage hooks, e.g. # # @CODE # echo "post_src_prepare() { tools/make_specfiles || die; }" \ # > /etc/portage/env/app-emulation/wine-vanilla # @CODE wine_src_prepare() { default if [[ ${WINE_GECKO} && ${WINE_MONO} ]]; then # sanity check, bumping these has a history of oversights local geckomono=$(sed -En '/^#define (GECKO|MONO)_VER/{s/[^0-9.]//gp}' \ dlls/appwiz.cpl/addons.c || die) if [[ ${WINE_GECKO}$'\n'${WINE_MONO} != "${geckomono}" ]]; then local gmfatal= has live ${PROPERTIES} && gmfatal=nonfatal ${gmfatal} die -n "gecko/mono mismatch in ebuild, has: " ${geckomono} " (please file a bug)" fi fi if tc-is-clang && use mingw; then # -mabi=ms was ignored by =wine-10, # do a one-arch best effort fallback CROSSCFLAGS="${CROSSCFLAGS_amd64:-${CROSSCFLAGS:-$(_wine_flags c amd64)}}" CROSSLDFLAGS="${CROSSLDFLAGS_amd64:-${CROSSLDFLAGS:-$(_wine_flags ld amd64)}}" ) elif use abi_x86_32; then conf+=( CROSSCFLAGS="${CROSSCFLAGS_x86:-${CROSSCFLAGS:-$(_wine_flags c x86)}}" CROSSLDFLAGS="${CROSSLDFLAGS_x86:-${CROSSLDFLAGS:-$(_wine_flags ld x86)}}" ) fi if use abi_x86_64 && use abi_x86_32 && use !wow64; then # multilib dual build method for "old" wow64 (must do 64 first) local bits for bits in 64 32; do ( einfo "Configuring for ${bits}bits in ${WORKDIR}/build${bits} ..." mkdir ../build${bits} || die cd ../build${bits} || die if (( bits == 64 )); then conf+=( --enable-win64 ) else conf+=( --with-wine64=../build64 TARGETFLAGS=-m32 # for widl ) # optional, but prefer over Wine's auto-detect (+#472038) multilib_toolchain_setup x86 fi ECONF_SOURCE=${S} econf "${conf[@]}" "${wineconfargs[@]}" ) done else # new --enable-archs method, or 32bit-only local archs=( $(usev abi_x86_64 x86_64) $(usev wow64 i386) # 32-on-64bit "new" wow64 $(usev arm64 aarch64) ) conf+=( ${archs:+--enable-archs="${archs[*]}"} ) econf "${conf[@]}" "${wineconfargs[@]}" fi } # @FUNCTION: wine_src_compile # @DESCRIPTION: # Handle running emake. wine_src_compile() { if use abi_x86_64 && use abi_x86_32 && use !wow64; then emake -C ../build64 # do first emake -C ../build32 else emake fi } # @FUNCTION: wine_src_install # @DESCRIPTION: # Handle running emake install, creating slot wrappers, and # stripping binaries built for Windows. wine_src_install() { if use abi_x86_64 && use abi_x86_32 && use !wow64; then emake DESTDIR="${D}" -C ../build32 install emake DESTDIR="${D}" -C ../build64 install # do last else emake DESTDIR="${D}" install fi if use abi_x86_64 || use arm64; then if ver_test -ge 10.2; then # wine64 was removed, but keep a symlink for old scripts # TODO: can remove this -e guard eventually, only there to # avoid overwriting 9999's wine64 if go into <10.2 commits [[ ! -e ${ED}${WINE_PREFIX}/bin/wine64 ]] && dosym wine ${WINE_PREFIX}/bin/wine64 else # # @INTERNAL # @DESCRIPTION: # Filter and test current {C,LD}FLAGS for usage with the cross # toolchain (using ``wcc_*`` variables, see wine_src_configure), # and echo back working flags. # # Note that this ignores checking USE for simplicity, if compiler # is unusable (e.g. not found) then it will return empty flags # which is fine. _wine_flags() { local -n wcc=wcc_${2} wccflags=wcc_${2}_testflags case ${1} in c) # many hardening options are unlikely to work right filter-flags '-fstack-protector*' #870136 filter-flags '-mfunction-return=thunk*' #878849 # bashrc-mv users often do CFLAGS="${LDFLAGS}" and then # compile-only tests miss stripping unsupported linker flags filter-flags '-Wl,*' # -mavx with mingw-gcc has a history of problems and still see # users have issues despite Wine's -mpreferred-stack-boundary=2 use mingw && append-cflags -mno-avx # same as strip-unsupported-flags but echos only for CC CC="${wcc} ${wccflags}" test-flags-CC ${CFLAGS} ;; ld) # let compiler figure out the right linker for cross filter-flags '-fuse-ld=*' CC="${wcc} ${wccflags}" test-flags-CCLD ${LDFLAGS} ;; esac } fi EXPORT_FUNCTIONS pkg_pretend src_prepare src_configure src_compile src_install pkg_postinst pkg_postrm