# Maintainer: Torsten Keßler <tpkessler at archlinux dot org>
# Maintainer: Christian Heusel <gromit@archlinux.org>
# Contributor: acxz <akashpatel2008 at yahoo dot com>

pkgbase=rocm-llvm
pkgname=(rocm-llvm rocm-device-libs comgr)
epoch=2
pkgver=7.2.4
pkgrel=2
arch=(aarch64)
url='https://rocm.docs.amd.com/en/latest/reference/rocmcc.html'
makedepends=('git' 'cmake' 'python' 'ninja' 'rocm-core' 'rocm-cmake' 'perl'
             'gcc-libs' 'zlib' 'zstd' 'libffi' 'libedit' 'ncurses' 'libxml2' 'patchelf')
source=("$pkgbase::git+https://github.com/ROCm/llvm-project#tag=rocm-$pkgver"
        '0001-compiler-rt-sanitizer-Remove-linux-scc.h.patch')
sha256sums=('cda215d04dfb6ede38c542d4604711d4a4623267df0f3d678491cd9fbcc32fd9'
            '3592a157f9c8c748a5f75d79c9e328f1c359ec6609d260a58d4b68ba97f7fe9b')
options=(staticlibs !lto)

prepare() {
    # linux/scc.h is gone from linux-api-headers >= 7.1
    patch -Np1 -d "$pkgbase" -i "$srcdir/0001-compiler-rt-sanitizer-Remove-linux-scc.h.patch"
}

build() {
    CXXFLAGS+=' -Wno-error -Wno-narrowing'
    CFLAGS+=' -Wno-error -Wno-narrowing'
    # Build only minimal debug info to reduce size
    CFLAGS+=' -g1'
    CXXFLAGS+=' -g1'

    # flang-rt compiles the Fortran modules with the just-built flang, which
    # errors out on the C-only flags makepkg exports in FFLAGS (see
    # /usr/share/makepkg/buildenv/fortran.sh) instead of ignoring them. Drop
    # exactly those and keep the rest, so -march, -O2, -g and
    # -fno-omit-frame-pointer still apply. If Arch ever adds another C-only flag
    # this fails loudly rather than silently dropping hardening.
    local _unsupported='-(pipe|fno-plt|fexceptions|fstack-clash-protection)\b'
    _unsupported+='|-(mno-omit-leaf-frame-pointer|Wformat|Werror=format-security)\b'
    _unsupported+='|-fcf-protection(=[^ ]*)?|-ffile-prefix-map=[^ ]*|-Wp,[^ ]*'
    FFLAGS=$(sed -E "s@($_unsupported)@@g" <<<"$FFLAGS")
    FCFLAGS=$(sed -E "s@($_unsupported)@@g" <<<"$FCFLAGS")
    export FFLAGS FCFLAGS

    local _rocm_exe_rpath='\$ORIGIN/../lib:\$ORIGIN/../../../lib'
    local _rocm_lib_rpath='\$ORIGIN'
    # Flags according to
    # https://github.com/ROCm/ROCm/blob/87bc26e672e06294bd2a6a1b507ad5c9ae4cffba/tools/rocm-build/build_lightning.sh#L302
    local cmake_args=(
        -G Ninja
        -B build
        -S "$pkgbase/llvm"
        -D CMAKE_BUILD_TYPE=Release
        -D CMAKE_INSTALL_PREFIX="/opt/rocm/lib/llvm"
        -D LLVM_HOST_TRIPLE=$CHOST
        # mlir is a hard dependency of flang. flang provides the `flang` driver
        # that `amdflang` dispatches to; without it CLANG_ENABLE_AMDCLANG still
        # installs `amdflang`, leaving it pointing at a non-existent binary.
        -D LLVM_ENABLE_PROJECTS='clang;lld;clang-tools-extra;mlir;flang'
        -D CLANG_ENABLE_AMDCLANG=ON
        -D PACKAGE_VENDOR="AMD"
        # flang-rt is the Fortran runtime; without it flang cannot link anything.
        # The OpenMP host runtime and the AMDGPU offload plugin are built by the
        # separate rocm-openmp package, because the plugin needs the HSA headers
        # from hsa-rocr, which in turn makedepends on this package.
        -D LLVM_ENABLE_RUNTIMES='compiler-rt;libunwind;libcxx;libcxxabi;flang-rt'
        -D LIBCXX_ENABLE_SHARED=OFF
        -D LIBCXX_ENABLE_STATIC=ON
        -D LIBCXX_INSTALL_LIBRARY=OFF
        -D LIBCXX_INSTALL_HEADERS=OFF
        -D LIBCXXABI_ENABLE_SHARED=OFF
        -D LIBCXXABI_ENABLE_STATIC=ON
        -D LIBCXXABI_INSTALL_STATIC_LIBRARY=OFF
        -D LLVM_TARGETS_TO_BUILD='AMDGPU;NVPTX;Native'
        -D CLANG_DEFAULT_LINKER=lld
        -D ENABLE_LINKER_BUILD_ID=ON
        -D CLANG_DEFAULT_RTLIB=compiler-rt
        -D CLANG_DEFAULT_UNWINDLIB=libgcc
        -D LLVM_INSTALL_UTILS=ON
        -D LLVM_ENABLE_BINDINGS=OFF
        -D LLVM_LINK_LLVM_DYLIB=OFF
        -D LLVM_BUILD_LLVM_DYLIB=OFF
        -D OCAMLFIND=NO
        -D LLVM_ENABLE_OCAMLDOC=OFF
        -D LLVM_INCLUDE_BENCHMARKS=OFF
        -D LLVM_BUILD_TESTS=OFF
        -D LLVM_INCLUDE_TESTS=OFF
        -D CLANG_INCLUDE_TESTS=OFF
        -D LLVM_BINUTILS_INCDIR=/usr/include
        -D CMAKE_SKIP_BUILD_RPATH=TRUE
        -D CMAKE_SKIP_INSTALL_RPATH=TRUE
        -D CMAKE_EXE_LINKER_FLAGS="-Wl,--enable-new-dtags,--build-id=sha1,--rpath,$_rocm_exe_rpath"
        -D CMAKE_SHARED_LINKER_FLAGS="-Wl,--enable-new-dtags,--build-id=sha1,--rpath,$_rocm_lib_rpath"
        -D CMAKE_CXX_STANDARD=17
        # Fortran driver and runtime. FLANG_RT_INCLUDE_AMD additionally builds
        # libflang_rt.amd.a, the part of the Fortran runtime that rocm-openmp
        # needs to make Fortran callable from inside OpenMP target regions.
        -D FLANG_RT_INCLUDE_AMD=ON
        -D FLANG_INCLUDE_DOCS=OFF
        -D FLANG_INCLUDE_TESTS=OFF
    )
    cmake "${cmake_args[@]}"

    local cmake_device_libs_args=(
        -Wno-dev
        -S "$pkgbase/amd/device-libs"
        -B build-device-libs
        -D CMAKE_BUILD_TYPE=None
        -D CMAKE_INSTALL_PREFIX=/opt/rocm
        -D CMAKE_PREFIX_PATH="$srcdir/build"
    )

    # The ROCm fork adds FIR/HLFIR includes to flang/Support/OpenMP-utils.h that
    # upstream does not have, without declaring the matching TableGen
    # dependencies in flang/lib/Support/CMakeLists.txt. FortranSupport therefore
    # races the TableGen step and intermittently fails with
    # "flang/Optimizer/HLFIR/HLFIRDialect.h.inc: No such file or directory".
    # Building the dialects first materialises every generated header it needs;
    # neither dialect depends on FortranSupport, so this does not deadlock.
    cmake --build build -- HLFIRDialect CUFDialect

    # Bootstrapping libcxx, see
    # https://github.com/ROCm/ROCm/blob/87bc26e672e06294bd2a6a1b507ad5c9ae4cffba/tools/rocm-build/build_lightning.sh#L352-L359
    # llvm-link and opt are pulled in early because device-libs needs them.
    cmake --build build -- clang lld compiler-rt llvm-link opt
    cmake --build build -- runtimes cxx
    cmake --build build
    cmake --build build -- clang-tidy

    cmake "${cmake_device_libs_args[@]}"
    cmake --build build-device-libs

    local cmake_comgr_args=(
        -Wno-dev
        -S "$pkgbase/amd/comgr"
        -B build-comgr
        -D CMAKE_BUILD_TYPE=None
        -D CMAKE_INSTALL_PREFIX=/opt/rocm
        -D BUILD_TESTING=OFF
        -D CMAKE_PREFIX_PATH="$srcdir/build;$srcdir/build-device-libs"
    )
    cmake "${cmake_comgr_args[@]}"
    cmake --build build-comgr
}

package_rocm-llvm() {
    pkgdesc='Radeon Open Compute - LLVM toolchain (llvm, clang, lld, flang)'
    license=('Apache-2.0 WITH LLVM-exception')
    depends=('rocm-core' 'perl' 'glibc' 'libgcc' 'libstdc++' 'zlib' 'zstd' 'libffi' 'libedit'
             'ncurses' 'libxml2')
    optdepends=('rocm-openmp: OpenMP host runtime and GPU offloading')

    DESTDIR="$pkgdir" cmake --install build

    # Provide symlink to old LLVM location, pre ROCm 6.0.0
    ln -s /opt/rocm/lib/llvm "$pkgdir/opt/rocm/llvm"

    # Some packages require amdclang to be found in /opt/rocm/bin
    mkdir -p "$pkgdir/opt/rocm/bin"
    local _compiler
    for _compiler in amdclang amdclang++ amdclang-cl amdclang-cpp amdflang amdlld; do
        ln -s /opt/rocm/lib/llvm/bin/$_compiler "$pkgdir/opt/rocm/bin/$_compiler"
    done

    # https://bugs.archlinux.org/task/28479
    install -d "$pkgdir/opt/rocm/lib/llvm/lib/bfd-plugins"
    ln -s /opt/rocm/lib/llvm/lib/LLVMgold.so "$pkgdir/opt/rocm/lib/llvm/lib/bfd-plugins/LLVMgold.so"

    cd "$pkgbase"
    install -Dm644 llvm/LICENSE.TXT "$pkgdir/usr/share/licenses/$pkgname/llvm-LICENSE"
    install -Dm644 clang/LICENSE.TXT "$pkgdir/usr/share/licenses/$pkgname/clang-LICENSE"
    install -Dm644 clang-tools-extra/LICENSE.TXT "$pkgdir/usr/share/licenses/$pkgname/clang-tools-extra-LICENSE"
    install -Dm644 compiler-rt/LICENSE.TXT "$pkgdir/usr/share/licenses/$pkgname/compiler-rt-LICENSE"
    install -Dm644 lld/LICENSE.TXT "$pkgdir/usr/share/licenses/$pkgname/lld-LICENSE"
    install -Dm644 flang/LICENSE.TXT "$pkgdir/usr/share/licenses/$pkgname/flang-LICENSE"
    install -Dm644 flang-rt/LICENSE.TXT "$pkgdir/usr/share/licenses/$pkgname/flang-rt-LICENSE"
    install -Dm644 mlir/LICENSE.TXT "$pkgdir/usr/share/licenses/$pkgname/mlir-LICENSE"
}

package_rocm-device-libs() {
    pkgdesc='AMD specific device-side language runtime libraries'
    license=('NCSA')
    depends=('rocm-core')

    DESTDIR="$pkgdir" cmake --install build-device-libs
    cd "$pkgbase/amd/device-libs"
    install -Dm644 LICENSE.TXT "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
}

package_comgr() {
    pkgdesc='AMDGPU GPU Code Object Manager'
    license=('NCSA')
    depends=('glibc' 'libgcc' 'libstdc++' 'zstd' 'zlib' 'ncurses'
             'rocm-core' 'rocm-llvm' 'rocm-device-libs')

    DESTDIR="$pkgdir" cmake --install build-comgr
    cd "$pkgbase/amd/comgr"
    install -Dm644 LICENSE.txt "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
}
