%global toolchain clang

# Opt out of https://fedoraproject.org/wiki/Changes/fno-omit-frame-pointer
# https://bugzilla.redhat.com/show_bug.cgi?id=2158587
%undefine _include_frame_pointers

%global maj_ver 16
%global min_ver 0
#global rc_ver 4
%global patch_ver 0
%global bolt_version %{maj_ver}.%{min_ver}.%{patch_ver}
%global bolt_srcdir llvm-project-%{bolt_version}%{?rc_ver:rc%{rc_ver}}.src

Name: llvm-bolt
Version: %{bolt_version}%{?rc_ver:~rc%{rc_ver}}
Release: 1%{?dist}
Summary: a post-link optimizer developed to speed up large applications

License: Apache-2.0 WITH LLVM-exception
URL: https://github.com/llvm/llvm-project/tree/main/bolt
Source0: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{maj_ver}.%{min_ver}.%{patch_ver}%{?rc_ver:-rc%{rc_ver}}/%{bolt_srcdir}.tar.xz
Source1: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{maj_ver}.%{min_ver}.%{patch_ver}%{?rc_ver:-rc%{rc_ver}}/%{bolt_srcdir}.tar.xz.sig
Source2: release-keys.asc

# BOLT is not respecting the component split of LLVM and requires some private
# header to be able in order to compile. Try to disable as much libraries as
# possible in order to reduce build time.
Patch12: rm-llvm-libs.diff
# Backports from LLVM 17.
Patch13: 0001-BOLT-NFC-Remove-C-style-out-of-bounds-array-ref.patch
Patch14: 0001-AArch64-fix-bug-55005-handle-DW_CFA_GNU_NegateRAStat.patch

BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: cmake
BuildRequires: ninja-build
BuildRequires: zlib-devel
BuildRequires: llvm-devel = %{version}
BuildRequires: llvm-test = %{version}
BuildRequires: python3-lit
BuildRequires: python3-psutil
BuildRequires: clang
BuildRequires: lld
BuildRequires: doxygen

# For origin certification
BuildRequires: gnupg2

# BOLT only supports aarch64 and x86_64
ExcludeArch:    s390x ppc64le i686

# As hinted by bolt documentation
Recommends:     gperftools-devel

%description

BOLT is a post-link optimizer developed to speed up large applications.
It achieves the improvements by optimizing application's code layout based on
execution profile gathered by sampling profiler, such as Linux `perf` tool.

%package doc
Summary: Documentation for BOLT
BuildArch: noarch
Requires: %{name} = %{version}-%{release}

%description doc
Documentation for the BOLT optimizer

%prep
%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'
%autosetup -n %{bolt_srcdir} -p1


%build

%global _lto_cflags %{nil}

%cmake  -S llvm -GNinja \
        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
        -DCMAKE_SKIP_RPATH=ON \
        -DLLVM_DIR=%{_libdir}/cmake/llvm \
        -DLLVM_TABLEGEN_EXE=%{_bindir}/llvm-tblgen \
        -DLLVM_BUILD_UTILS:BOOL=ON \
        -DBOLT_INCLUDE_DOCS:BOOL=ON \
        -DLLVM_INCLUDE_TESTS:BOOL=ON \
        -DBUILD_SHARED_LIBS:BOOL=OFF \
        -DLLVM_LINK_LLVM_DYLIB:BOOL=OFF \
%if 0%{?__isa_bits} == 64
        -DLLVM_LIBDIR_SUFFIX=64 \
%else
        -DLLVM_LIBDIR_SUFFIX= \
%endif
        -DBOLT_INCLUDE_TESTS:BOOL=ON \
        -DBOLT_CLANG_EXE=%{_bindir}/clang\
        -DBOLT_LLD_EXE=%{_bindir}/ld.lld\
        -DLLVM_EXTERNAL_LIT=%{_bindir}/lit \
        -DLLVM_ENABLE_PROJECTS="bolt" \
        -DLLVM_TARGETS_TO_BUILD="X86;AArch64"

# Set LD_LIBRARY_PATH now because we skip rpath generation and the build uses
# some just built libraries.
export LD_LIBRARY_PATH=%{_builddir}/%{bolt_srcdir}/%{_vpath_builddir}/%{_lib}
# Set DESTDIR now because bolt sneaks in an install step in its build step.
export DESTDIR=%{buildroot}
%cmake_build --target bolt


%install
%cmake_install --component bolt

# Remove files installed during the build phase.
rm -f %{buildroot}/%{_builddir}/%{bolt_srcdir}/%{_vpath_builddir}/%{_lib}/lib*.a

# We don't ship libLLVMBOLT*.a
rm -f %{buildroot}%{_libdir}/libLLVMBOLT*.a

# There currently is not support upstream for building html doc from BOLT
install -d %{buildroot}%{_pkgdocdir}
mv bolt/README.md bolt/docs/*.md %{buildroot}%{_pkgdocdir}

%check

%ifarch x86_64
# Bolt makes incorrect assumptions on the location of libbolt_rt_*.a.
mkdir -p %{_builddir}/%{bolt_srcdir}/%{_lib}
for rt in libbolt_rt_instr libbolt_rt_hugify libbolt_rt_instr_osx
do
    ln -s %{buildroot}/%{_libdir}/${rt}.a %{_builddir}/%{bolt_srcdir}/%{_vpath_builddir}/%{_lib}
done
%endif

%ifarch aarch64
# Failing test cases on aarch64
rm bolt/test/cache+-deprecated.test bolt/test/bolt-icf.test bolt/test/R_ABS.pic.lld.cpp
%endif

export LD_LIBRARY_PATH=%{_builddir}/%{bolt_srcdir}/%{_vpath_builddir}/%{_lib}
export DESTDIR=%{buildroot}
%cmake_build --target check-bolt

# Remove files installed during the check phase.
rm -f %{buildroot}/%{_builddir}/%{bolt_srcdir}/%{_vpath_builddir}/%{_lib}/lib*.a


%files
%license LICENSE.TXT
%{_bindir}/llvm-bolt
%{_bindir}/llvm-boltdiff
%{_bindir}/merge-fdata
%{_bindir}/perf2bolt

%ifarch x86_64
%{_libdir}/libbolt_rt_hugify.a
%{_libdir}/libbolt_rt_instr.a
%{_libdir}/libbolt_rt_instr_osx.a
%endif


%files doc
%doc %{_pkgdocdir}

%changelog
* Tue Mar 21 2023 Tulio Magno Quites Machado Filho <tuliom@redhat.com> - 16.0.0-1
- Update to LLVM 16.0.0

* Wed Mar 15 2023 Tulio Magno Quites Machado Filho <tuliom@redhat.com> - 16.0.0~rc4-1
- Update to LLVM 16.0.0 RC4

* Fri Mar 03 2023 Tulio Magno Quites Machado Filho <tuliom@redhat.com> - 16.0.0~rc3-1
- Update to LLVM 16.0.0 RC3

* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 15.0.7-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild

* Fri Jan 13 2023 Nikita Popov <npopov@redhat.com> - 15.0.7-1
- Update to LLVM 15.0.7

* Fri Jan 13 2023 Tom Stellard <tstellar@redhat.com> - 15.0.6-2
- Omit frame pointers when building

* Tue Dec 06 2022 Nikita Popov <npopov@redhat.com> - 15.0.6-1
- Update to LLVM 15.0.6

* Mon Jul 11 2022 sguelton@redhat.com - 15.0.0-1
- Initial version.