# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem          1.0
PortGroup           github 1.0

github.setup        mingw-w64 mingw-w64 13.0.0 v
github.tarball_from archive
revision            0
set mingw_name      w64-mingw32

license             ZPL-2.1
categories          cross devel
maintainers         {@Gcenx gmail.com:gcenx83} openmaintainer

description         GCC cross-compiler for Windows 64 & 32 bits
long_description    Mingw-w64 is an advancement of the original mingw.org project, \
                    created to support the GCC compiler on Windows systems.

homepage            https://mingw-w64.sourceforge.net/

checksums           rmd160  43433d25e37f0f835b99cce9572a0cb8a4d8b2ff \
                    sha256  1a910473313a329316025fa4563160deae378884e4b8ee573d1d03ac006b2e61 \
                    size    15256061

# needs an out-of-source build
configure.dir       ${workpath}/build
build.dir           ${configure.dir}
post-extract {      file mkdir "${build.dir}" }

# create eight subports:
# - i686-w64-mingw32-headers
# - i686-w64-mingw32-crt
# - i686-w64-mingw32-winpthreads
# - i686-w64-mingw32-widl
# - x86_64-w64-mingw32-headers
# - x86_64-w64-mingw32-crt
# - x86_64-w64-mingw32-winpthreads
# - x86_64-w64-mingw32-widl
foreach arch {i686 x86_64} {
    foreach component {crt headers winpthreads widl} {
        subport ${arch}-${mingw_name}-${component} {
            set mingw_arch      ${arch}
            set mingw_comp      ${component}
            if {${component} eq "winpthreads"} {
                set mingw_dir   mingw-w64-libraries/${component}
            } elseif {${component} eq "widl"} {
                set mingw_dir   mingw-w64-tools/${component}
            } else {
                set mingw_dir   mingw-w64-${component}
            }
        }
    }
}

if {${subport} ne ${name}} {
    set mingw_target            ${mingw_arch}-${mingw_name}

    configure.cmd               ${worksrcpath}/${mingw_dir}/configure

    if {${mingw_comp} ne "widl"} {
        configure.pre_args-replace  --prefix=${prefix} --prefix=${prefix}/${mingw_target}
    }
    configure.args-append       --host=${mingw_target}

    # *-widl subports
    if {${mingw_comp} eq "widl"} {
        # Need a compiler that supports __builtin_ms_va_list
        compiler.blacklist-append   {*gcc-[3-4].*} {clang < 800} {macports-clang-3.*}

        configure.args-append       --program-prefix="${mingw_target}-"
    # *-headers subports'
    } elseif {${mingw_comp} eq "headers"} {
        supported_archs         noarch
        platforms               any
        configure.args-append   --enable-secure-api

        # winpthreads installs four files which conflict with placeholders provided by "headers"
        #
        # a relatively ugly workaround is to copy those four files from "winpthreads" to "headers"
        # and then delete them from "winpthreads" again
        post-extract {
            foreach f {compat signal time unistd} {
                set f_src  ${worksrcpath}/mingw-w64-libraries/winpthreads/include/pthread_${f}.h
                set f_dest ${worksrcpath}/${mingw_dir}/crt
                copy -force ${f_src} ${f_dest}
            }
        }
    # *-crt and *-winpthreads subports
    } else {
        # We only need a dependency on either of the two GCC compilers:
        #   - ${mingw_target}-gcc-bootstrap
        #   - ${mingw_target}-gcc
        # to build. The rest of dependencies (*-headers, *-binutils)
        # are pulled in by one of those two ports.
        #
        # Runtime dependency on GCC is not added to avoid dependency cycles,
        # but in fact it's GCC that needs CRT at runtime, not the other way around.
        if {${mingw_comp} eq "crt"} {
            depends_build-append    bin:${mingw_target}-gcc:${mingw_target}-gcc-bootstrap

            # Resolves "Too many open files in system"
            use_parallel_build  no
        # *-winpthreads
        } else {
            # winpthreads needs at least stage 2 compiler (or the final one)
            # as well as the latest version of crt
            depends_build-append    path:${mingw_target}/lib/libgcc_s.a:${mingw_target}-gcc-nothreads \
                                    port:${arch}-${mingw_name}-crt
            depends_lib-append      port:${arch}-${mingw_name}-crt

            # see above
            post-destroot {
                foreach f {compat signal time unistd} {
                    delete ${destroot}${prefix}/${mingw_target}/include/pthread_${f}.h
                }
            }
        }

        #depends_run-append     bin:${mingw_target}-gcc:${mingw_target}-gcc-bootstrap
        #depends_lib-append     port:${mingw_target}-binutils
        #depends_lib-append     port:${mingw_target}-headers
        configure.cppflags      "-I${prefix}/${mingw_target}/include"

        # prevent MacPorts from adding -syslibroot to linker flags
        configure.sdkroot

        # ----- copied from crossgcc (not sure if needed) ----
        # the generated compiler doesn't accept -arch
        configure.cc_archflags
        configure.cxx_archflags
        configure.objc_archflags
        configure.ld_archflags

        # the bootstrap compiler doesn't accept -stdlib
        configure.cxx_stdlib

        # We don't need system includes(this prevents xgcc to include system-wide
        # unwind.h if it is present)!
        compiler.cpath
        # -----

        # is there a more elegant way?
        configure.cc  ${prefix}/bin/${mingw_target}-gcc
        configure.cxx ${prefix}/bin/${mingw_target}-g++
        configure.cpp ${prefix}/bin/${mingw_target}-cpp
        # configure.env-append PATH=...

        # TODO: Is this also noarch? It uses object files, but probably only for windows.
    }

    destroot.violate_mtree  yes
    livecheck.type          none
} else {
    PortGroup               stub 1.0

    supported_archs         noarch
    platforms               any
    description             GCC cross-compiler toolchain for Windows 64 & 32 bits (meta port)

    depends_run             port:i686-${mingw_name}-gcc \
                            port:i686-${mingw_name}-widl \
                            port:x86_64-${mingw_name}-gcc \
                            port:x86_64-${mingw_name}-widl
}
