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

PortSystem                  1.0
PortGroup                   cmake 1.1
PortGroup                   muniversal 1.0

# This port is dedicated to PowerPC. This way we can upgrade it without any impact
# on any other systems. Older Intel has its own implementation in libcxx port,
# which relies on Clang. This port in intended to be used with GCC.
name                        libcxx-powerpc

# Based on: https://github.com/iains/LLVM-7-branch
# with additional modifications.

# TODO: implement optional installation into system prefix.

# FIXME: get rid of dependency on system libs:
# https://trac.macports.org/ticket/69000

# FIXME: presently gcc13 will not work with libc++, use gcc12:
# https://trac.macports.org/ticket/68592
# https://github.com/iains/gcc-13-branch/issues/12

version                     7.1.1
revision                    1

categories                  lang devel
maintainers                 nomaintainer
license                     NCSA

description                 libc++ is an implementation of the C++ standard library, targeting C++11
long_description            {*}${description}. This is an experimental port for PowerPC systems.
platforms                   {darwin < 11}
# For now, let this port be powerpc-only. We wanna make sure it is not installed accidentally elsewhere.
supported_archs             ppc ppc64

set upstream_ver            7.1.0

homepage                    https://llvm.org
master_sites                https://releases.llvm.org/${upstream_ver}

if {[vercmp [macports_version] >= 2.12.99]} {
    extract.add_deps    no
}
depends_extract             port:xz-bootstrap
depends_skip_archcheck-append \
                            xz-bootstrap
use_xz                      yes
extract.suffix              .tar.xz

set libcxx_distname         libcxx-${upstream_ver}.src
set libcxxabi_distname      libcxxabi-${upstream_ver}.src

distfiles                   ${libcxx_distname}${extract.suffix} \
                            ${libcxxabi_distname}${extract.suffix}

checksums                   libcxx-${upstream_ver}.src${extract.suffix} \
                            rmd160  0ccb07c007c7f5998dea02aefa0c1c4a3f4bbb8a \
                            sha256  4442b408eaea3c1e4aa2cf21da38aba9f0856b4b522b1c3d555c3251af62b04e \
                            size    1638448 \
                            libcxxabi-${upstream_ver}.src${extract.suffix} \
                            rmd160  b75b738f195328ec6c362dbf5caf383b8528a145 \
                            sha256  6241e81f7c62e11cf54f865ae2d5b8e93943e5f007ccbb59f88f2b289bee98fd \
                            size    535180

depends_build-append        port:python27-bootstrap
depends_skip_archcheck-append \
                            python27-bootstrap

# Use cmake-bootstrap
depends_build-replace       path:bin/cmake:cmake port:cmake-bootstrap
depends_skip_archcheck-append \
                            cmake-bootstrap
configure.cmd               ${prefix}/libexec/cmake-bootstrap/bin/cmake

# Build with gcc10-boostrap:
depends_build-append        port:gcc10-bootstrap

configure.compiler.add_deps no

# Until standalone implementation of 8-byte atomics works. See below.
depends_lib-append          port:gcc10-bootstrap

set llvmdir                 ${workpath}/llvm/projects

post-extract {
    xinstall -d ${llvmdir}
    copy ${filespath}/CMakeLists.txt ${llvmdir}
    move ${workpath}/libcxx-${upstream_ver}.src ${llvmdir}/libcxx
    move ${workpath}/libcxxabi-${upstream_ver}.src ${llvmdir}/libcxxabi
}

patch.pre_args-replace  -p0 -p1
patch.dir                   ${llvmdir}
# Patches from: https://github.com/iains/LLVM-7-branch
# libcxxabi
patchfiles                  0001-more-ppc-hacks-on-libcxxabi.patch
# libcxx
patchfiles-append           0002-libcxx-test-UNSUPPORT-10.6-and-10.5-for-aligned-allo.patch \
                            0003-libcxx-Actually-push-macosx-version-so-that-UNSUPPOR.patch \
                            0004-libcxx-If-we-have-a-sysroot-don-t-try-to-use-xcrun-s.patch \
                            0005-more-ppc-hacks-on-libcxx.patch \
                            0006-libcxx-Updated-version-of-David-Fang-s-wrapper-for-m.patch \
                            0007-Fix-up-thread-constexpr-for-GCC-where-the-PPC-port-c.patch \
                            0008-libcxx-cmake-Make-sure-to-find-the-abi-lib-that-we-j.patch \
                            0009-libcxx-cmake-if-a-LIBCXX_SYSROOT-is-given-this-pre-e.patch
# https://github.com/iains/llvm-project/commit/0ec37d1e98f07379443c420569f282b12482595f
patchfiles-append           0010-Add-coroutine-header.patch

# Extra patches:
patchfiles-append           0011-libcxx-libcxxabi-minor-fix-to-linking.patch
# https://github.com/catap/llvm-project
patchfiles-append           0012-disable-Apple-libc-Availability-tests.patch \
                            0013-Fix-missing-long-long-math-prototypes-when-using-the.patch

# sterilize MacPorts build environment; we want nothing picked up from MP prefix
compiler.cpath
compiler.library_path

configure.cxx_stdlib

configure.cflags
configure.cxxflags
configure.cppflags
configure.optflags
configure.ldflags

configure.universal_cflags
configure.universal_cxxflags
configure.universal_cppflags
configure.universal_ldflags
configure.universal_args

configure.ccache            no
configure.distcc            no

# sterilize PATH
configure.env-append        PATH=${workpath}/bins:/usr/bin:/bin:/usr/sbin:/sbin
build.env-append            PATH=${workpath}/bins:/usr/bin:/bin:/usr/sbin:/sbin

cmake.build_type            Release
# No ninja to minimize dependencies:
cmake.generator             {Unix Makefiles}

# As long as the port is explicitly for PowerPC and in single version, we can install into the prefix:
cmake.install_prefix        ${prefix}/libexec/llvm-${version}

configure.pre_args-replace  {*}[cmake::system_prefix_path] \
                            -DCMAKE_SYSTEM_PREFIX_PATH="${cmake.install_prefix}\;/usr"

configure.pre_args-replace  {*}[cmake::rpath_flags] \
                            -DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=OFF

configure.pre_args-delete   {*}[cmake::module_path]

configure.pre_args-delete   {*}[cmake::ccaching]

configure.pre_args-delete   -DCMAKE_INSTALL_NAME_DIR="${cmake.install_prefix}/lib"

cmake.source_dir            ${llvmdir}

if {${configure.sdkroot} ne ""} {
    configure.args-append   -DDARWIN_osx_SYSROOT="${configure.sdkroot}" \
                            -DDEFAULT_SYSROOT="${configure.sdkroot}"
} else {
    # compiler-rt does a broad search for an SDK it likes, but this
    # search fails on older systems that don't have a MacOSX.sdk
    configure.args-append   -DDARWIN_osx_SYSROOT=/
}

configure.args-append       -DENABLE_NEW_DELETE_DEFAULT=OFF \
                            -DLIBCXX_BENCHMARK_NATIVE_STDLIB="libstdc++" \
                            -DLIBCXX_CXX_ABI="libcxxabi" \
                            -DLIBCXX_CXX_ABI_INCLUDE_PATHS="${llvmdir}/libcxxabi/include" \
                            -DLIBCXX_CXX_ABI_SYSTEM=OFF \
                            -DLIBCXX_ENABLE_ABI_LINKER_SCRIPT=OFF \
                            -DLIBCXX_ENABLE_FILESYSTEM=ON \
                            -DLIBCXX_ENABLE_SHARED=ON \
                            -DLIBCXX_GENERATE_COVERAGE=OFF \
                            -DLIBCXX_USE_COMPILER_RT=OFF \
                            -DLIBCXXABI_DYLIB_PATH="${cmake.build_dir}/lib" \
                            -DLIBCXXABI_LIBCXX_INCLUDES="${llvmdir}/libcxx/include" \
                            -DLIBCXXABI_LIBCXX_PATH="${cmake.build_dir}/lib" \
                            -DLIBCXXABI_USE_LLVM_UNWINDER=OFF \
                            -DLLVM_BUILD_DOCS=OFF \
                            -DPACKAGE_VERSION="${version}" \
                            -DPYTHON_EXECUTABLE=${prefix}/libexec/python27-bootstrap/bin/python2.7

compiler.cxx_standard       2011

# Leopard is the first macOS which supports Rosetta.
# See: https://trac.macports.org/ticket/67284
if {${os.major} > 8} {
    pre-configure {
        file mkdir ${workpath}/bins

        set gcc [open "${workpath}/bins/gcc" w 0755]
        puts ${gcc} "#!/bin/sh"
        puts ${gcc} "arch -arch $\{BUILD_ARCH:-${build_arch}\} ${prefix}/libexec/gcc10-bootstrap/bin/gcc \"\$@\""
        close ${gcc}

        set gxx [open "${workpath}/bins/g++" w 0755]
        puts ${gxx} "#!/bin/sh"
        puts ${gxx} "arch -arch $\{BUILD_ARCH:-${build_arch}\} ${prefix}/libexec/gcc10-bootstrap/bin/g++ \"\$@\""
        close ${gxx}
    }
    configure.cc            ${workpath}/bins/gcc
    configure.cxx           ${workpath}/bins/g++
} else {
    configure.cc            ${prefix}/libexec/gcc10-bootstrap/bin/gcc
    configure.cxx           ${prefix}/libexec/gcc10-bootstrap/bin/g++
}

# This is needed for linking to work:
configure.ldflags-append    -L/${cmake.build_dir}/lib

# As of now, it does link to system libs, regardless.
# prevent it from linking against gcc's libstdc++.6.dylib and libgcc_s.1.1.dylib
# configure.ldflags-append    -static-libstdc++ -static-libgcc

variant emutls description "Enable emulated TLS" {
    # libcxxabi emutls support
    patchfiles-append       0014-libcxxabi-support-emutls.patch

    configure.args-append   -DLIBCXXABI_ENABLE_THREADS=ON
}

variant lock_guard description "8-byte atomics via mutex lock_guard" {
    # The following patch is supposed to implement 8-byte atomics without libatomic;
    # unfortunately, it fails to build as is.
    # https://github.com/fangism/libcxx/issues/1
    patchfiles-append       0015-implement-atomic-using-mutex-lock_guard-for-64b-ops-.patch
}

# Universal variant code is borrowed from clang-11-bootstrap port.
if {[variant_exists universal] && [variant_isset universal]} {
    foreach arch ${universal_archs_supported} {
        lappend merger_configure_env(${arch}) BUILD_ARCH=${arch}
        lappend merger_build_env(${arch}) BUILD_ARCH=${arch}
        lappend merger_configure_args(${arch}) \
                            -DDARWIN_osx_BUILTIN_ALL_POSSIBLE_ARCHS=${arch}
    }
    merger_arch_flag        yes
    merger_arch_compiler    yes
    merger_must_run_binaries \
                            yes
}

default_variants-append     +emutls

post-destroot {
    system "ditto ${llvmdir}/libcxx/include ${destroot}${cmake.install_prefix}/include/c++/v1"
    system "ditto ${llvmdir}/libcxxabi/include ${destroot}${cmake.install_prefix}/include"

    # rpath does not work, we need absolute paths here:
    foreach dylib {libc++.1.dylib libc++abi.1.dylib} {
        system "install_name_tool -id ${cmake.install_prefix}/lib/${dylib} ${destroot}${cmake.install_prefix}/lib/${dylib}"
        system "install_name_tool -change @rpath/libc++.1.dylib ${cmake.install_prefix}/lib/libc++.1.dylib ${destroot}${cmake.install_prefix}/lib/${dylib}"
        system "install_name_tool -change @rpath/libc++abi.1.dylib ${cmake.install_prefix}/lib/libc++abi.1.dylib ${destroot}${cmake.install_prefix}/lib/${dylib}"
    }
}

notes "
The libraries have been installed into ${cmake.install_prefix}/lib. To use libc++ with Macports’s gcc compilers,\
those have to be built with +stdlib_flag variant enabled and includes’ path set to ${cmake.install_prefix}/include/c++/v1.
Unless the libs are moved into ${prefix}/lib or /usr/lib, ldflags should be set accordingly.
"

livecheck.type              none
