# Maintainer: Evangelos Foutras <evangelos@foutrelis.com>
# Contributor: Jan "heftig" Steffens <jan.steffens@gmail.com>

pkgname=('llvm' 'llvm-libs')
pkgver=17.0.6
pkgrel=2.1
arch=('host')
url="https://llvm.org/"
license=('custom:Apache 2.0 with LLVM Exception')
ncxfab_makedepends=('cmake' 'ninja' 'python-setuptools' 'python-psutil' 'python-sphinx'
                    'python-recommonmark')
ncxfah_makedepends=('zlib' 'zstd' 'libffi' 'ncurses' 'libxml2') #'libedit'
ncxfat_makedepends=('gcc' 'glibc')
xah_makedepends=('binutils')
options=('staticlibs' '!lto') # tools/llvm-shlib/typeids.test fails with LTO
_source_base=https://github.com/llvm/llvm-project/releases/download/llvmorg-$pkgver
source=($_source_base/llvm-$pkgver.src.tar.xz{,.sig}
        $_source_base/cmake-$pkgver.src.tar.xz{,.sig}
        $_source_base/third-party-$pkgver.src.tar.xz{,.sig}
        aarch64.cmake)
sha256sums=('b638167da139126ca11917b6880207cc6e8f9d1cbb1a48d87d017f697ef78188'
            'SKIP'
            '807f069c54dc20cb47b21c1f6acafdd9c649f3ae015609040d6182cab01140f4'
            'SKIP'
            '3054d0a9c9375dab1a4539cc2cc45ab340341c5d71475f9599ba7752e222947b'
            'SKIP'
            'SKIP')
validpgpkeys=('474E22316ABF4785A88C6E8EA2C794A986419D8A'  # Tom Stellard <tstellar@redhat.com>
              'D574BD5D1D0E98895E3BF90044F2485E45D59042') # Tobias Hieta <tobias@hieta.se>

# Utilizing LLVM_DISTRIBUTION_COMPONENTS to avoid
# installing static libraries; inspired by Gentoo
_get_distribution_components() {
  local target
  ninja -t targets | grep -Po 'install-\K.*(?=-stripped:)' | while read -r target; do
    case $target in
      llvm-libraries|distribution)
        continue
        ;;
      # shared libraries
      LLVM|LLVMgold)
        ;;
      # libraries needed for clang-tblgen
      LLVMDemangle|LLVMSupport|LLVMTableGen)
        ;;
      # testing libraries
      LLVMTestingAnnotations|LLVMTestingSupport)
        ;;
      # exclude static libraries
      LLVM*)
        continue
        ;;
      # exclude llvm-exegesis (doesn't seem useful without libpfm)
      llvm-exegesis)
        continue
        ;;
    esac
    echo $target
  done
}

prepare() {
  rename -v -- "-$pkgver.src" '' {cmake,third-party}-$pkgver.src
  cd llvm-$pkgver.src
  mkdir -p build-$MPKG_TARGETMACHINE
  if [[ x"$MPKG_TARGETMACHINE" != x"$MPKG_HOSTMACHINE" ]]; then
    mkdir -p build-$MPKG_HOSTMACHINE
  fi
}

_build_for_arch() {
  local _host=$1

  pushd llvm-$pkgver.src/build-$_host

  # Build only minimal debug info to reduce size
  CFLAGS=${CFLAGS/-g /-g1 }
  CXXFLAGS=${CXXFLAGS/-g /-g1 }

  local cmake_args=(
    -G Ninja
    -DCMAKE_BUILD_TYPE=Release
    -DCMAKE_INSTALL_DOCDIR=share/doc
    -DCMAKE_INSTALL_PREFIX=$MPKG_USRPATH
    -DCMAKE_SKIP_RPATH=ON
    -DLLVM_BUILD_DOCS=OFF
    -DLLVM_BUILD_LLVM_DYLIB=ON
    -DLLVM_BUILD_TESTS=OFF
    -DLLVM_ENABLE_BINDINGS=OFF
    -DLLVM_ENABLE_FFI=ON
    -DLLVM_ENABLE_RTTI=ON
    -DLLVM_ENABLE_SPHINX=OFF
    -DLLVM_HOST_TRIPLE=$MPKG_HOSTMACHINE
    -DLLVM_DEFAULT_TARGET_TRIPLE=$MPKG_TARGETMACHINE
    -DLLVM_TARGET_ARCH=$MPKG_TARGETMACHINE
    -DLLVM_INCLUDE_BENCHMARKS=OFF
    -DLLVM_INSTALL_GTEST=ON
    -DLLVM_INSTALL_UTILS=ON
    -DLLVM_LINK_LLVM_DYLIB=ON # ON because otherwise llvm-config wants component libraries but we haven't built them
    -DLLVM_USE_PERF=ON
    -DSPHINX_WARNINGS_AS_ERRORS=OFF
  )

  if [[ x"$MPKG_BUILDMACHINE" != x"$_host" ]]; then
    cmake_args+=(
      -DLLVM_BINUTILS_INCDIR=$MPKG_BUILDSYSROOT/include
      -DCMAKE_TOOLCHAIN_FILE=$(realpath ../../$MPKG_TARGETARCH.cmake)
      -DCMAKE_CXX_FLAGS=-I/usr/$MPKG_BUILDMACHINE/$_host/include
    )
  fi

  cmake .. "${cmake_args[@]}"
  local distribution_components=$(_get_distribution_components | paste -sd\;)
  test -n "$distribution_components"
  cmake_args+=(-DLLVM_DISTRIBUTION_COMPONENTS="$distribution_components")

  cmake .. "${cmake_args[@]}"
  ninja
  popd
}

build() {
  _build_for_arch $MPKG_TARGETMACHINE
  if [[ x"$MPKG_HOSTMACHINE" != x"$MPKG_TARGETMACHINE" ]]; then
    _build_for_arch $MPKG_HOSTMACHINE
  fi
}

check() {
  cd llvm-$pkgver.src/build
  LD_LIBRARY_PATH=$PWD/lib ninja check
}

package_llvm() {
  pkgdesc="Compiler infrastructure"
  ncxfah_depends=('perl')
  ncxfat_depends=('llvm-libs')
  cah_depends=('llvm-libs')

  cd llvm-$pkgver.src/build-$MPKG_TARGETMACHINE

  DESTDIR="$pkgdir" ninja install-distribution

  # Only install lit for native
  if [[ x"$MPKG_HOSTMACHINE" == x"$MPKG_TARGETMACHINE" ]]; then
    # Include lit for running lit-based tests in other projects
    pushd ../utils/lit
    python3 setup.py install --root="$pkgdir" -O1
    popd
  else
    # We need different binaries in the cross-case
    rm -rf "$pkgdir"$MPKG_USRPATH/bin/*
    mkdir -p "$pkgdir/usr/bin"

    pushd ../build-$MPKG_HOSTMACHINE
    rm -rf "$srcdir"/native
    mkdir -p "$srcdir"/native
    DESTDIR="$srcdir/native" ninja install-distribution
    for x in "$srcdir"/native/$MPKG_USRPATH/bin/*; do
      bnx=$(basename "$x")
      mv "$x" "$pkgdir"$MPKG_USRPATH/bin/"$bnx"
      ln -s  ../../$MPKG_USRPATH/bin/"$bnx" $pkgdir/usr/bin/$MPKG_TARGETMACHINE-"$bnx"
    done
    popd
  fi

  # The runtime libraries go into llvm-libs
  mv -f "$pkgdir"$MPKG_USRPATH/lib/lib{LLVM,LTO,Remarks}*.so* "$srcdir"
  mv -f "$pkgdir"$MPKG_USRPATH/lib/LLVMgold.so "$srcdir"

  # Remove documentation sources
  #rm -rf "$pkgdir"/usr/share/doc/llvm/html/{_sources,.buildinfo}

  install -Dm644 ../LICENSE.TXT "$pkgdir/usr/share/licenses/$pkgname/LICENSE"

}

package_llvm-libs() {
  pkgdesc="LLVM runtime libraries"
  ncxfat_depends=('gcc-libs' 'zlib' 'zstd' 'libffi' 'ncurses' 'libxml2') #'libedit'

  install -d "$pkgdir"$MPKG_USRPATH/lib
  cp -P \
    "$srcdir"/lib{LLVM,LTO,Remarks}*.so* \
    "$srcdir"/LLVMgold.so \
    "$pkgdir"$MPKG_USRPATH/lib/

  # Symlink LLVMgold.so from /usr/lib/bfd-plugins
  # https://bugs.archlinux.org/task/28479
  install -d "$pkgdir"$MPKG_USRPATH/lib/bfd-plugins
  ln -s ../LLVMgold.so "$pkgdir"$MPKG_USRPATH/lib/bfd-plugins/LLVMgold.so

  install -Dm644 "$srcdir/llvm-$pkgver.src/LICENSE.TXT" \
    "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
}

# vim:set ts=2 sw=2 et:
