# SLEEF - Compiling and installing the library

## Table of contents

- Introduction
- Compiling and installing the library

- Preliminaries
- Quick start
- Compiling and installing the library on Linux
- Compiling the library with Microsoft Visual C++
- Compiling and running "Hello SLEEF"
- Importing SLEEF into your project
- Cross compilation for Linux

- Math library reference
- Quad-precision math library reference
- DFT library reference
- Other tools included in the package
- Benchmark results
- Additional notes

## Preliminaries

In order to build SLEEF, you need CMake, which is an open-source and cross-platform building tool. In order to test the library, it is better to have the GNU MPFR Library, Libssl and FFTW.

CMake works by allowing the developer to specify build parameters and rules in a simple text file that cmake then processes to generate project files for the actual native build tools (e.g. UNIX Makefiles, Microsoft Visual Studio, Apple XCode, etc). If you are not already familiar with cmake, please refer to the official documentation or the basic introductions in the wiki.

## Quick start

You will find quick start instructions in the sources or via GitHub in the README.adoc file.

## Compiling and installing the library on Linux

In order to build the library, you may want to install OpenMP (optional). In order to test the library, you need to install libmpfr, libssl and libfftw3 (optional). Availability of these libraries are checked upon execution of cmake. Please change the directory to sleef-3.X and run the following commands.

    $ sudo apt-get install libmpfr-dev libssl-dev libfftw3-dev
    $ cmake -S . -B build/
    $ cmake --build build/ --clean-first -j `nproc`
    $ ctest --test-dir build/ -j `nproc`
    $ sudo cmake --install build/ --prefix /path/to/install/dir

In order to uninstall the libraries and headers, run the following command.

    $ sudo xargs rm -v < build/install_manifest.txt

### Building the library with LTO support

You can build the library with link time opimization(LTO) support with the following commands. Note that you can only build static libraries with LTO support. You also have to use the same compiler with the same version to build the library and other source codes.

    $ CC=gcc CXX=g++ cmake -DBUILD_SHARED_LIBS=FALSE -DSLEEF_ENABLE_LTO=TRUE ..

In order to build the library with thinLTO support with clang, you need to specify LLVM AR command that exactly corresponds to the clang compiler.

    $ CC=clang-19 CXX=clang++-19 cmake -DBUILD_SHARED_LIBS=FALSE -DSLEEF_ENABLE_LTO=TRUE -DSLEEF_LLVM_AR_COMMAND=llvm-ar-19 -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld-19 ..

### Building the header files for inlining the whole SLEEF functions

Header files for inlining the whole SLEEF functions can be built with the following commands. With these header files, it may be easier to inline the whole SLEEF functions than using LTO. You have to specify "-ffp-contract=off" compiler option when compiling a source code that includes one of these header files.

    $ cmake -DSLEEF_BUILD_INLINE_HEADERS=TRUE ..

## Compiling the library with Microsoft Visual C++

Open developer command prompt for VS2022 and change directory to sleef-3.X. You can use the accompanying batch file named winbuild-msvc.bat to build the library. The arguments of this batch file are passed to cmake.

Below is an example of commands for building SLEEF with Visual Studio.

    D:\sleef-3.X> winbuild-msvc -DCMAKE_BUILD_TYPE=Release -DSLEEF_BUILD_DFT=True -DSLEEF_BUILD_QUAD=True

### Compiling the library with Clang on Windows

Install ninja and clang via VS2022 installer. Below is an example of commands for building SLEEF with Clang on Windows.

    D:\sleef-3.X> winbuild-clang -DCMAKE_BUILD_TYPE=Release -DSLEEF_BUILD_DFT=True -DSLEEF_BUILD_QUAD=True

You can choose your own installation of LLVM executable by setting CLANGINSTALLDIR environment variable.

    D:\sleef-3.X> set CLANGINSTALLDIR=C:\Program Files\LLVM
    D:\sleef-3.X> winbuild-clang -DCMAKE_BUILD_TYPE=Release -DSLEEF_BUILD_DFT=True -DSLEEF_BUILD_QUAD=True

## Compiling and running "Hello SLEEF"

Now, let's try compiling the source code shown in Fig. 2.1.

    #include <stdio.h>
    #include <x86intrin.h>
    #include <sleef.h>

    int main(int argc, char **argv) {
      double a[] = {2, 10};
      double b[] = {3, 20};

      __m128d va, vb, vc;

      va = _mm_loadu_pd(a);
      vb = _mm_loadu_pd(b);

      vc = Sleef_powd2_u10(va, vb);

      double c[2];

      _mm_storeu_pd(c, vc);

      printf("pow(%g, %g) = %g\n", a[0], b[0], c[0]);
      printf("pow(%g, %g) = %g\n", a[1], b[1], c[1]);
    }

Fig. 2.1: Source code for testing

Fig.2.2 shows typical commands for compiling and executing the hello code on Linux computers.

    $ gcc hellox86.c -o hellox86 -lsleef
    $ ./hellox86
    pow(2, 3) = 8
    pow(10, 20) = 1e+20
    $ █

Fig. 2.2: Commands for compiling and executing hellox86.c

You may need to set LD_LIBRARY_PATH environment variable appropriately. If you are trying to execute the program on Mac OSX or Windows, try copying the DLLs to the current directory.

## Importing SLEEF into your project

Below is an example CMakeLists.txt for compiling the above hellox86.c. CMake will automatically download SLEEF from GitHub repository, and thus there is no need to include SLEEF in your software package. If you prefer importing SLEEF as a submodule in git, you can use SOURCE_DIR option instead of GIT_REPOSITORY option for ExternalProject_Add.

    cmake_minimum_required(VERSION 3.5.1)
    include(ExternalProject)
    find_package(Git REQUIRED)

    ExternalProject_Add(libsleef
      GIT_REPOSITORY https://github.com/shibatch/sleef
      CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/contrib
    )

    include_directories(${CMAKE_BINARY_DIR}/contrib/include)
    link_directories(${CMAKE_BINARY_DIR}/contrib/lib)

    add_executable(hellox86 hellox86.c)
    add_dependencies(hellox86 libsleef)
    target_link_libraries(hellox86 sleef)

Fig. 2.3: Example CMakeLists.txt

## Cross compilation for Linux

Below, we explain two methods for cross-compiling SLEEF. Both rely on the toolchain files provided under toolchains directory. Below are examples of cross-compiling SLEEF for AArch64 on a platform with x86_64 Linux.

### Method 1

Please run the following from the root directory of SLEEF:

1. First, compile the native SLEEF.

    $ cmake -S . -B build-native
    $ cmake --build build-native -j --clean-first

2. Cross-compile the target platform's SLEEF.

    $ cmake -DCMAKE_TOOLCHAIN_FILE=./toolchains/aarch64-gcc.cmake -DNATIVE_BUILD_DIR=$(pwd)/build-native/ -S . -B build
    $ cmake --build build -j --clean-first

### Method 2

If QEMU is available on your environement, there is no need to compile the native SLEEF. Please run the following from the root directory of SLEEF.

1. Install qemu on Ubuntu.

    $ sudo apt install -y qemu-user-static binfmt-support

2. Set the environment variable.

    $ export SLEEF_TARGET_EXEC_USE_QEMU=ON

3. Set the dynamic linker/loader path.

    $ export QEMU_LD_PREFIX=/usr/aarch64-linux-gnu/

4. Cross-compile the target platform's SLEEF.

    $ cmake -DCMAKE_TOOLCHAIN_FILE=./toolchains/aarch64-gcc.cmake -S . -B build
    $ cmake --build build -j --clean-first