# Maintainer: Mateusz Mikuła <oss@mateuszmikula.dev>

_compiler=clang

pkgbase=llvm
pkgname=("llvm"
         "clang"
         "clang-analyzer"
         "compiler-rt"
         "lld")
_version=20.1.7
_rc=""
_tag=llvmorg-${_version}${_rc}
pkgver=${_version}${_rc/-/}
pkgrel=1
pkgdesc="C language family frontend for LLVM"
arch=('i686' 'x86_64')
url="https://llvm.org/"
msys2_references=(
  "cpe: cpe:/a:llvm:llvm"
)
license=("spdx:Apache-2.0 WITH LLVM-exception")
makedepends=('cmake'
             "$_compiler"
             'ninja'
             'pkgconf'
             'python'
             'git'
             'libzstd-devel'
             'zlib-devel'
             )
_url=https://github.com/llvm/llvm-project/releases/download/${_tag}
source=("${_url}/llvm-${pkgver}.src.tar.xz"{,.sig}
        "${_url}/clang-${pkgver}.src.tar.xz"{,.sig}
        "${_url}/compiler-rt-${pkgver}.src.tar.xz"{,.sig}
        "${_url}/lld-${pkgver}.src.tar.xz"{,.sig}
        "${_url}/cmake-${pkgver}.src.tar.xz"{,.sig}
        "${_url}/libunwind-${pkgver}.src.tar.xz"{,.sig}
        "${_url}/runtimes-${pkgver}.src.tar.xz"{,.sig}
        "${_url}/third-party-${pkgver}.src.tar.xz"{,.sig}
        "0001-LLVM-Cygwin-Fix-symbol-visibility-definition.patch"
        "0002-LLVM-Cygwin-Remove-special-case-for-CXX-extensions-o.patch"
        "0003-LLVM-Cygwin-Fix-shared-library-name-136599.patch"
        "0004-LLVM-Cygwin-Fix-Signals-compatibility-with-Cygwin-AP.patch"
        "0005-LLVM-TargetParser-Handle-msys-targets-the-same-as-cy.patch"
        "0006-LLVM-Cygwin-Define-_GNU_SOURCE-on-Cygwin-as-well.-13.patch"
        "0007-Cygwin-Emit-COMDAT-name-correctly-for-Cygwin-138621.patch"
        "0008-LLVM-Cygwin-add-workaround-for-blocking-connect-acce.patch"
        "0009-Support-Cygwin-Fix-handling-of-Process-symbol-lookup.patch"
        "0010-Cygwin-Define-LLVM_ABI-for-Cygwin-143222.patch"
        "0011-Cygwin-CYGWIN-is-not-WIN32-in-current-CMake-143130.patch"
        "0012-Cygwin-Don-t-use-version-script-for-Cygwin-target-14.patch"
        "0013-LLVM-Tests-remove-exeext-from-lli-child-target-param.patch"
        "0101-Cygwin-Global-symbols-should-be-external-by-default-.patch"
        "0102-Clang-Cygwin-Enable-few-conditions-that-are-shared-w.patch"
        "0103-Cygwin-Enable-TLS-on-Cygwin-target-138618.patch"
        "0104-Clang-Cygwin-Fix-symbol-visibility-definition-138118.patch"
        "0105-Cygwin-RTTI-and-VTable-should-be-dllexport-ed-139798.patch"
        "0106-Clang-Cygwin-Disable-shared-libs-on-Cygwin-by-defaul.patch"
        "0107-Clang-Cygwin-Remove-erroneous-_WIN32-define-and-clea.patch"
        "0108-Clang-Cygwin-don-t-use-Bsymbolic-functions-138217.patch"
        "0109-hack-cygwin-allow-multiple-definition-c-index-test.patch"
        "0110-Clang-Driver-add-a-Cygwin-ToolChain-135691.patch"
        "0111-Clang-Driver-use-__cxa_atexit-by-default-on-Cygwin.-.patch"
        "0112-Clang-CMake-use-CMakePushCheckState-138783.patch"
        "0113-CMake-respect-LLVMConfig.cmake-s-LLVM_DEFINITIONS.patch"
        "0114-Cygwin-Internal-class-in-explicitly-instantiation-de.patch"
        "0115-Cygwin-Template-instantiations-should-be-exported-by.patch"
        "0116-Clang-Cygwin-va_list-must-be-treated-like-normal-Win.patch"
        "0117-Clang-Cygwin-wint_t-is-unsigned-int-143117.patch"
        "0118-scan-build-Windows-Fix-driver-name-transformation-in.patch"
        "0201-LLD-Cygwin-Implement-dll-search-prefix-143263.patch"
        "0203-LLD-COFF-add-__-data-bss-_-start-end-__-symbols-for-.patch"
        "0204-LLD-MinGW-Fall-back-to-using-default-target-if-no-m-.patch"
        "0205-LLD-COFF-Ensure-.bss-is-merged-at-the-end-of-a-secti.patch"
        "0206-LLD-CMake-fix-testing-standalone-build-without-insta.patch"
        "0207-LLD-Cygwin-Add-libcygwin-and-libmsys-2.0-to-exclude-.patch"
        )
sha256sums=('10b62d003f16afbd1a5ee0aa6397704c13d9a12a2562103998a8c1eff4a0f1ea'
            'SKIP'
            'cb74965a2481008ae405419357a55fda2df6fa3aee262a0a9293a558532a29ae'
            'SKIP'
            '326d6deb8eaf60bc4a66a1cbab20409f328bdddcafe77207c6bcd88d768076e3'
            'SKIP'
            '9cb94dac7db0e1f2b664469e1574c0b350bec3eacd0cbc524481a6f65fc0f185'
            'SKIP'
            'afdab526c9b337a4eacbb401685beb98a18fb576037ecfaa93171d4c644fe791'
            'SKIP'
            '46081293b2f857caca68a266cf11fad8366315c470a9a6766868ed6c369bac0c'
            'SKIP'
            '9357bba8ec103cfb48a271420251a057636aae346b9bad880801e11d19dcbfc6'
            'SKIP'
            '592019ad4d17ffa6e0162c7584474b2ae8883a61bbfade5f15382ed26b7ce52a'
            'SKIP'
            'a50b341c89dba8a263d7b5d375dd49971665cc3199cc47f875d0d486cb48346b'
            '8c9285bb1ba3ba656964b661f0a6ed41c9cca4ad4a867f2811e8121476801b27'
            '255fed9b059c2457cae6954e646937d179958e3c830352354278a4a5881fd429'
            'ad55afac07e9da3489c12cd8fa56ae91d5c14e6832a5d88741efa946e6a3da4f'
            '700ba03dc477e9519ef183209251232ae2b2a1afd48dc0500b4d2e0f466b0b4a'
            '0dfd4cf437e3caa146b733aae46e20e1d5809268722eb796b9627ec0bcfcac57'
            '822ccbe30d99a5ba2ae2fbf14e0de58239cae485c8086950e7913695d301009f'
            '2eac65eb56613152a42a33e799a8e1acd696e9a167d5d5e730d6b53893573736'
            'ccda5ddd2090dc715f7e9653639a2ff0b2791515224b245d3e22d2b2eeb488d1'
            'e3ad58755439b8efa05fa12058756b4a34ecf8ded35a6d849f9a5eae22ae26ed'
            '54d963085035ea418148b66d54707ff46485fdf3fa46310ebfd5952460638f00'
            '816044654e1b1e99985325e0cbe42f51b956d34cae25e34e5b51e206b1c32e00'
            '9844b102656f6b3527f3c5aa9a74245063cdd7b7839d326f10cb7c1c5944d3e6'
            '6879ebd71bb8b6dbb1243f7fa1cfd3f96b93e5894e656f95b3ad1b41ba8fa8d5'
            'bc1208f91b2fada48cfacb1cf65f884c734a5753cac4bae955f190605fe0ed6d'
            '0905a5f3ce123ea6b15d0728e6249540ffb9e6352adf674007229ef11530f230'
            '078699dca61b04ee89c1be802ae57897379173ceafb3930a393839d492bb9347'
            '17a94e951f7df8c59f84aa8a40d1d38d2020829a984a5e4188103db0a019f8e4'
            '458b93fb20abe5cf84ecda447ca7a05c0ab34fd66fa9cf5d9eefc310295c4e25'
            '24828fed935c9970318236397112a83d42c9e3dc23f6f28b75808edafb7dd17e'
            'f3b4ffae990e7e5636ce7fab40f0739b2717fe88a0e5d8fea47692f98c8f7d77'
            '010d246460b0d62a5ec8e977dd5428596c7a99c32d8a23c0185d400b7056fd69'
            'f2f4f9ed2856bf5609dae740decf27de39d6f3d29ed5b386b43fcf41f8fadf23'
            '616cbdb3a8b386c91b8e725334d4a5ce60ffe611cc59a65085e19a61be82b3b1'
            '5a215c2eb7d3cbf36da880ed5d7a1bb46cf7e872e5265a7d0afa53bb5cb0c94c'
            '2e2a624eedb546a2fcbc43c013515ebc5f821719a5cab43c5bd0489d1a5f0991'
            '6a22c3255245a415e70a5e84aae9f20197515ced9e7f80df8713e102c1906f7f'
            '524efb3e032e6f7c13e706b04d079b7a785c8b5da60be925d05b9c02e659e677'
            'b9589b1d3d28425d73b64ccc8e91ca1e7915d6ad4bec32d395b803236a70d1e4'
            '61169398fe0aafdb75219206edf0490af1a1dfac653eed1d54f504bbb637adfc'
            '37780c65f2ea088081319eebfaa820451ce55475d6fad0badcc95a2bb20840af'
            '94f0a65835d156392e4db4fd4bbd4e6439294ae5e024e48a7e105f17512eb98b'
            'e14ba4b45df74122a98c6ff2ffe17c789c3e14456ac695c3bfa58c988f65d283'
            '36e766b91ecd627f720dae352b689c2f32dde1abfd46dae0da7c890b5b279a29'
            'd4ef3823aacc37bdd518de214192edf94fd5ce2e1422084422a86aa0880266da'
            '71161ed122803e9f6a7662631b4b2caa0a3528385d89cc8e5f96c49b2fdbc12f'
            '745ea7c631977b939e06e28fdc06dc67b4e41e113c2be432d74e6cf4dc581d0d')
validpgpkeys=('B6C8F98282B944E3B0D5C2530FC3042E345AD05D'  # Hans Wennborg, Google.
              '474E22316ABF4785A88C6E8EA2C794A986419D8A'  # Tom Stellard
              'D574BD5D1D0E98895E3BF90044F2485E45D59042') # Tobias Hieta
noextract=(clang-${pkgver}.src.tar.xz)

apply_patch_with_msg() {
  for _patch in "$@"
  do
    msg2 "Applying ${_patch}"
    patch -Nbp1 -i "${srcdir}/${_patch}"
  done
}

revert_patch_with_msg() {
  for _patch in "$@"
  do
    msg2 "Reverting ${_patch}"
    patch -p1 -i "${srcdir}/${_patch}"
  done
}

apply_git_patch_with_msg() {
  for _patch in "$@"
  do
    msg2 "Applying ${_patch}"
    patch -Nbp2 -i "${srcdir}/${_patch}"
  done
}

prepare() {
  cd "${srcdir}"
  plain "Extracting clang-${pkgver}.src.tar.xz due to symlink(s) without pre-existing target(s)"
  tar -xJf "${srcdir}"/clang-${pkgver}.src.tar.xz -C "${srcdir}" || true

  # Rename Directories
  # We need libunwind for LLD: https://github.com/llvm/llvm-project/issues/48572
  for pkg in llvm clang compiler-rt lld cmake libunwind runtimes third-party; do
    mv ${pkg}-$pkgver.src ${pkg}
  done

  # Patch llvm
  cd "${srcdir}"/llvm
  apply_git_patch_with_msg 0001-LLVM-Cygwin-Fix-symbol-visibility-definition.patch
  apply_git_patch_with_msg 0002-LLVM-Cygwin-Remove-special-case-for-CXX-extensions-o.patch
  apply_git_patch_with_msg 0003-LLVM-Cygwin-Fix-shared-library-name-136599.patch
  apply_git_patch_with_msg 0004-LLVM-Cygwin-Fix-Signals-compatibility-with-Cygwin-AP.patch
  apply_git_patch_with_msg 0005-LLVM-TargetParser-Handle-msys-targets-the-same-as-cy.patch
  apply_git_patch_with_msg 0006-LLVM-Cygwin-Define-_GNU_SOURCE-on-Cygwin-as-well.-13.patch
  apply_git_patch_with_msg 0007-Cygwin-Emit-COMDAT-name-correctly-for-Cygwin-138621.patch
  apply_git_patch_with_msg 0008-LLVM-Cygwin-add-workaround-for-blocking-connect-acce.patch
  apply_git_patch_with_msg 0009-Support-Cygwin-Fix-handling-of-Process-symbol-lookup.patch
  apply_git_patch_with_msg 0010-Cygwin-Define-LLVM_ABI-for-Cygwin-143222.patch
  apply_git_patch_with_msg 0011-Cygwin-CYGWIN-is-not-WIN32-in-current-CMake-143130.patch
  apply_git_patch_with_msg 0012-Cygwin-Don-t-use-version-script-for-Cygwin-target-14.patch
  apply_git_patch_with_msg 0013-LLVM-Tests-remove-exeext-from-lli-child-target-param.patch

  # Patch clang
  cd "${srcdir}"/clang
  apply_git_patch_with_msg 0101-Cygwin-Global-symbols-should-be-external-by-default-.patch
  apply_git_patch_with_msg 0102-Clang-Cygwin-Enable-few-conditions-that-are-shared-w.patch
  apply_git_patch_with_msg 0103-Cygwin-Enable-TLS-on-Cygwin-target-138618.patch
  apply_git_patch_with_msg 0104-Clang-Cygwin-Fix-symbol-visibility-definition-138118.patch
  apply_git_patch_with_msg 0105-Cygwin-RTTI-and-VTable-should-be-dllexport-ed-139798.patch
  apply_git_patch_with_msg 0106-Clang-Cygwin-Disable-shared-libs-on-Cygwin-by-defaul.patch
  apply_git_patch_with_msg 0107-Clang-Cygwin-Remove-erroneous-_WIN32-define-and-clea.patch
  apply_git_patch_with_msg 0108-Clang-Cygwin-don-t-use-Bsymbolic-functions-138217.patch
  apply_git_patch_with_msg 0109-hack-cygwin-allow-multiple-definition-c-index-test.patch
  apply_git_patch_with_msg 0110-Clang-Driver-add-a-Cygwin-ToolChain-135691.patch
  apply_git_patch_with_msg 0111-Clang-Driver-use-__cxa_atexit-by-default-on-Cygwin.-.patch
  apply_git_patch_with_msg 0112-Clang-CMake-use-CMakePushCheckState-138783.patch
  apply_git_patch_with_msg 0113-CMake-respect-LLVMConfig.cmake-s-LLVM_DEFINITIONS.patch
  apply_git_patch_with_msg 0114-Cygwin-Internal-class-in-explicitly-instantiation-de.patch
  apply_git_patch_with_msg 0115-Cygwin-Template-instantiations-should-be-exported-by.patch
  apply_git_patch_with_msg 0116-Clang-Cygwin-va_list-must-be-treated-like-normal-Win.patch
  apply_git_patch_with_msg 0117-Clang-Cygwin-wint_t-is-unsigned-int-143117.patch
  apply_git_patch_with_msg 0118-scan-build-Windows-Fix-driver-name-transformation-in.patch

  # Patch lld
  cd "${srcdir}"/lld
  apply_git_patch_with_msg 0201-LLD-Cygwin-Implement-dll-search-prefix-143263.patch
  apply_git_patch_with_msg 0203-LLD-COFF-add-__-data-bss-_-start-end-__-symbols-for-.patch
  apply_git_patch_with_msg 0204-LLD-MinGW-Fall-back-to-using-default-target-if-no-m-.patch
  apply_git_patch_with_msg 0205-LLD-COFF-Ensure-.bss-is-merged-at-the-end-of-a-secti.patch
  apply_git_patch_with_msg 0206-LLD-CMake-fix-testing-standalone-build-without-insta.patch
  apply_git_patch_with_msg 0207-LLD-Cygwin-Add-libcygwin-and-libmsys-2.0-to-exclude-.patch
}

build() {
  local -a platform_config
  local -a common_cmake_args

  if check_option "debug" "y"; then
    common_cmake_args+=(-DCMAKE_BUILD_TYPE=Debug
                        -DLLVM_ENABLE_ASSERTIONS=ON)
    VERBOSE="VERBOSE=1"
  else
    common_cmake_args+=(-DCMAKE_BUILD_TYPE=Release
                        -DLLVM_ENABLE_ASSERTIONS=OFF
                        -DLLVM_ENABLE_DUMP=ON)
  fi
  common_cmake_args+=(-Wno-dev
    -DCMAKE_INSTALL_PREFIX=/usr
    -DCOMPILER_RT_BUILD_ORC=OFF
    -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON
    -DLLVM_DEFAULT_TARGET_TRIPLE=${CARCH}-pc-windows-cygnus
    -DLLVM_ENABLE_THREADS=ON
    -DLLVM_HOST_TRIPLE=${CARCH}-pc-windows-cygnus
    -DLLVM_INCLUDE_BENCHMARKS=OFF
    -DLLVM_INCLUDE_TESTS=OFF
    -DLLVM_USE_SYMLINKS=OFF
    -DPython3_EXECUTABLE=/usr/bin/python.exe
  )

  if [ "${_compiler}" == "gcc" ]; then
    common_cmake_args+=(
      -DLIBCLANG_BUILD_STATIC=ON
      -DLLVM_ENABLE_PIC=OFF
    )
  elif [ "${_compiler}" == "clang" ]; then
    export CC='clang'
    export CXX='clang++'
    common_cmake_args+=(
      -DLLVM_BUILD_LLVM_DYLIB=ON
      -DLLVM_LINK_LLVM_DYLIB=ON
    )
  else
    error "Unsupported compiler: $_compiler"
    exit 1
  fi

  local _projects="clang;lld"

  platform_config+=(-DLLVM_TARGETS_TO_BUILD="AArch64;ARM;X86")

  cmake \
    -GNinja \
    -B build \
    -DLLVM_ENABLE_PROJECTS="${_projects}" \
    -DLLVM_ENABLE_RUNTIMES="compiler-rt" \
    -DLLVM_ENABLE_RTTI=ON \
    -DLLD_DEFAULT_LD_LLD_IS_MINGW=ON \
    "${common_cmake_args[@]}" \
    "${platform_config[@]}" \
    llvm

  cmake --build build
}

package_clang() {
  pkgdesc="C language family frontend for LLVM"
  url="https://clang.llvm.org/"
  depends=("gcc" "llvm=${pkgver}")
  optdepends=("compiler-rt: for -rtlib=compiler-rt")

  # Disable automatic installation of components that go into subpackages
  # -i.orig to check what has been removed in-case it starts dropping more than it should
  sed -i.orig '/\(extra\|scan-build\|scan-build-py\|scan-view\)\/cmake_install.cmake/d' "${srcdir}"/build/tools/clang/tools/cmake_install.cmake
  DESTDIR="${pkgdir}" cmake --install "${srcdir}"/build/tools/clang

  install -Dm644 "${srcdir}"/clang/LICENSE.TXT "${pkgdir}"/usr/share/licenses/clang/LICENSE

  # Install Python bindings
  site_packages=$(python -c "import site; print(site.getsitepackages()[0])")
  install -d "${pkgdir}"/${site_packages}
  cp -a "${srcdir}"/clang/bindings/python/clang "${pkgdir}"/${site_packages}
  python -m compileall -o 0 -o 1 "${pkgdir}"/${site_packages}
}

package_clang-analyzer() {
  pkgdesc="A source code analysis framework"
  url="https://clang-analyzer.llvm.org/"
  depends=("clang=${pkgver}" "python")

  local _analyzer
  for _analyzer in scan-build scan-build-py scan-view; do
    DESTDIR="${pkgdir}" cmake --install "${srcdir}"/build/tools/clang/tools/${_analyzer}
  done

  # Compile Python scripts
  python -m compileall -o 0 -o 1 "${pkgdir}"/usr/lib/libscanbuild

  install -Dm644 "${srcdir}"/clang/LICENSE.TXT "${pkgdir}"/usr/share/licenses/clang-analyzer/LICENSE
}

package_compiler-rt() {
  pkgdesc="Runtime libraries for Clang and LLVM"
  url="https://compiler-rt.llvm.org/"
  depends=("gcc-libs")

  DESTDIR="${pkgdir}" cmake --install "${srcdir}"/build/runtimes/builtins-bins
  DESTDIR="${pkgdir}" cmake --install "${srcdir}"/build/runtimes/runtimes-bins

  install -Dm644 "${srcdir}"/compiler-rt/LICENSE.TXT "${pkgdir}"/usr/share/licenses/compiler-rt/LICENSE
}

package_lld() {
  pkgdesc="Linker tools for LLVM"
  url="https://lld.llvm.org/"
  depends=("gcc-libs" "llvm=${pkgver}")

  DESTDIR="${pkgdir}" cmake --install "${srcdir}"/build/tools/lld

  install -Dm644 "${srcdir}"/lld/LICENSE.TXT "${pkgdir}"/usr/share/licenses/lld/LICENSE
}

package_llvm() {
  pkgdesc="Low Level Virtual Machine"
  depends=("gcc-libs" "libzstd" "zlib")

  # Disable automatic installation of components that go into subpackages
  # -i.orig to check what has been removed in-case it starts dropping more than it should
  sed -i.orig '/\(clang\|lld\)\/cmake_install.cmake/d' "${srcdir}"/build/tools/cmake_install.cmake
  sed -i.orig '/\(builtins\|runtimes\)-bins\/\+cmake_install.cmake/d' "${srcdir}"/build/runtimes/cmake_install.cmake
  DESTDIR="${pkgdir}" cmake --install "${srcdir}"/build

  install -Dm644 "${srcdir}"/llvm/LICENSE.TXT "${pkgdir}"/usr/share/licenses/llvm/LICENSE

  # Install CMake stuff
  install -d "${pkgdir}"/usr/share/llvm/cmake/{modules,platforms}
  install -Dm644 "${srcdir}"/llvm/cmake/modules/*.cmake "${pkgdir}"/usr/share/llvm/cmake/modules/
  install -Dm644 "${srcdir}"/llvm/cmake/platforms/*.cmake "${pkgdir}"/usr/share/llvm/cmake/platforms/

  # fix cmake files.
  sed -e "s|${srcdir}/build|/usr|g" -i ${pkgdir}/usr/lib/cmake/llvm/LLVMConfig.cmake
}
