1# Building ASTC Encoder 2 3This page provides instructions for building `astcenc` from the sources in 4this repository. 5 6Builds must use CMake 3.15 or higher as the build system generator. The 7examples on this page show how to use it to generate build systems for NMake 8(Windows) and Make (Linux and macOS), but CMake supports other build system 9backends. 10 11## Windows 12 13Builds for Windows are tested with CMake 3.17, and Visual Studio 2019 or newer. 14 15### Configuring the build 16 17To use CMake you must first configure the build. Create a build directory in 18the root of the `astcenc` checkout, and then run `cmake` inside that directory 19to generate the build system. 20 21```shell 22# Create a build directory 23mkdir build 24cd build 25 26# Configure your build of choice, for example: 27 28# x86-64 using a Visual Studio solution 29cmake -G "Visual Studio 16 2019" -T ClangCL -DCMAKE_INSTALL_PREFIX=..\ ^ 30 -DASTCENC_ISA_AVX2=ON -DASTCENC_ISA_SSE41=ON -DASTCENC_ISA_SSE2=ON .. 31 32# x86-64 using NMake 33cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=..\ ^ 34 -DASTCENC_ISA_AVX2=ON -DASTCENC_ISA_SSE41=ON -DASTCENC_ISA_SSE2=ON .. 35``` 36 37A single CMake configure can build multiple binaries for a single target CPU 38architecture, for example building x64 for both SSE2 and AVX2. Each binary name 39will include the build variant as a postfix. It is possible to build any set of 40the supported SIMD variants by enabling only the ones you require. 41 42Using the Visual Studio Clang-CL LLVM toolchain (`-T ClangCL`) is optional but 43produces significantly faster binaries than the default toolchain. The C++ LLVM 44toolchain component must be installed via the Visual Studio installer. 45 46### Building 47 48Once you have configured the build you can use NMake to compile the project 49from your build dir, and install to your target install directory. 50 51```shell 52# Run a build and install build outputs in `${CMAKE_INSTALL_PREFIX}/bin/` 53cd build 54nmake install 55``` 56 57## macOS and Linux using Make 58 59Builds for macOS and Linux are tested with CMake 3.17, and clang++ 9.0 or 60newer. 61 62> Compiling using g++ is supported, but clang++ builds are faster by ~15%. 63 64### Configuring the build 65 66To use CMake you must first configure the build. Create a build directory 67in the root of the astcenc checkout, and then run `cmake` inside that directory 68to generate the build system. 69 70```shell 71# Select your compiler (clang++ recommended, but g++ works) 72export CXX=clang++ 73 74# Create a build directory 75mkdir build 76cd build 77 78# Configure your build of choice, for example: 79 80# Arm arch64 81cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../ \ 82 -DASTCENC_ISA_NEON=ON .. 83 84# x86-64 85cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../ \ 86 -DASTCENC_ISA_AVX2=ON -DASTCENC_ISA_SSE41=ON -DASTCENC_ISA_SSE2=ON .. 87 88# macOS universal binary build 89cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../ .. 90``` 91 92A single CMake configure can build multiple binaries for a single target CPU 93architecture, for example building x64 for both SSE2 and AVX2. Each binary name 94will include the build variant as a postfix. It is possible to build any set of 95the supported SIMD variants by enabling only the ones you require. 96 97For macOS, we additionally support the ability to build a universal binary. 98This build includes SSE4.1 (`x86_64`), AVX2 (`x86_64h`), and NEON (`arm64`) 99build slices in a single output binary. The OS will select the correct variant 100to run for the machine being used. This is the default build target for a macOS 101build, but single-target binaries can still be built by setting 102`-DASTCENC_UNIVERSAL_BINARY=OFF` and then manually selecting the specific ISA 103variants that are required. 104 105### Building 106 107Once you have configured the build you can use Make to compile the project from 108your build dir, and install to your target install directory. 109 110```shell 111# Run a build and install build outputs in `${CMAKE_INSTALL_PREFIX}/bin/` 112# for executable binaries and `${CMAKE_INSTALL_PREFIX}/lib/` for libraries 113cd build 114make install -j16 115``` 116 117## macOS using XCode 118 119Builds for macOS and Linux are tested with CMake 3.17, and XCode 14.0 or 120newer. 121 122### Configuring the build 123 124To use CMake you must first configure the build. Create a build directory 125in the root of the astcenc checkout, and then run `cmake` inside that directory 126to generate the build system. 127 128```shell 129# Create a build directory 130mkdir build 131cd build 132 133# Configure a universal build 134cmake -G Xcode -DCMAKE_INSTALL_PREFIX=../ .. 135``` 136 137### Building 138 139Once you have configured the build you can use CMake to compile the project 140from your build dir, and install to your target install directory. 141 142```shell 143cmake --build . --config Release 144 145# Optionally install the binaries to the installation directory 146cmake --install . --config Release 147``` 148 149## Advanced build options 150 151For codec developers and power users there are a number of useful features in 152the build system. 153 154### Build Types 155 156We support and test the following `CMAKE_BUILD_TYPE` options. 157 158| Value | Description | 159| ---------------- | -------------------------------------------------------- | 160| Release | Optimized release build | 161| RelWithDebInfo | Optimized release build with debug info | 162| Debug | Unoptimized debug build with debug info | 163 164Note that optimized release builds are compiled with link-time optimization, 165which can make profiling more challenging ... 166 167### Shared Libraries 168 169We support building the core library as a shared object by setting the CMake 170option `-DASTCENC_SHAREDLIB=ON` at configure time. For macOS build targets the 171shared library supports the same universal build configuration as the command 172line utility. 173 174Note that the command line tool is always statically linked; the shared objects 175are an extra build output that are not currently used by the command line tool. 176 177### Constrained block size builds 178 179All normal builds will support all ASTC block sizes, including the worst case 1806x6x6 3D block size (216 texels per block). Compressor memory footprint and 181performance can be improved by limiting the block sizes supported in the build 182by adding `-DASTCENC_BLOCK_MAX_TEXELS=<texel_count>` to to CMake command line 183when configuring. Legal block sizes that are unavailable in a restricted build 184will return the error `ASTCENC_ERR_NOT_IMPLEMENTED` during context creation. 185 186### Non-invariant builds 187 188All normal builds are designed to be invariant, so any build from the same git 189revision will produce bit-identical results for all compilers and CPU 190architectures. To achieve this we sacrifice some performance, so if this is 191not required you can specify `-DASTCENC_INVARIANCE=OFF` to enable additional 192optimizations. This has most benefit for AVX2 builds where we are able to 193enable use of the FMA instruction set extensions. 194 195### No intrinsics builds 196 197All normal builds will use SIMD accelerated code paths using intrinsics, as all 198supported target architectures (x86 and arm64) guarantee SIMD availability. For 199development purposes it is possible to build an intrinsic-free build which uses 200no explicit SIMD acceleration (the compiler may still auto-vectorize). 201 202To enable this binary variant add `-DASTCENC_ISA_NONE=ON` to the CMake command 203line when configuring. It is NOT recommended to use this for production; it is 204significantly slower than the vectorized SIMD builds. 205 206### Test builds 207 208We support building unit tests. These use the `googletest` framework, which is 209pulled in though a git submodule. On first use, you must fetch the submodule 210dependency: 211 212```shell 213git submodule init 214git submodule update 215``` 216 217To build unit tests add `-DASTCENC_UNITTEST=ON` to the CMake command line when 218configuring. 219 220To run unit tests use the CMake `ctest` utility from your build directory after 221you have built the tests. 222 223```shell 224cd build 225ctest --verbose 226``` 227 228### Address sanitizer builds 229 230We support building with ASAN on Linux and macOS when using a compiler that 231supports it. To build binaries with ASAN checking enabled add `-DASTCENC_ASAN=ON` 232to the CMake command line when configuring. 233 234### Android builds 235 236Builds of the command line utility for Android are not officially supported, but can be a useful 237development build for testing on e.g. different Arm CPU microarchitectures. 238 239The build script below shows one possible route to building the command line tool for Android. Once 240built the application can be pushed to e.g. `/data/local/tmp` and executed from an Android shell 241terminal over `adb`. 242 243```shell 244ANDROID_ABI=arm64-v8a 245ANDROID_NDK=/work/tools/android/ndk/22.1.7171670 246 247BUILD_TYPE=RelWithDebInfo 248 249BUILD_DIR=build 250 251mkdir -p ${BUILD_DIR} 252cd ${BUILD_DIR} 253 254cmake \ 255 -DCMAKE_INSTALL_PREFIX=./ \ 256 -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ 257 -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \ 258 -DANDROID_ABI=${ANDROID_ABI} \ 259 -DANDROID_ARM_NEON=ON \ 260 -DANDROID_PLATFORM=android-21 \ 261 -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \ 262 -DANDROID_TOOLCHAIN=clang \ 263 -DANDROID_STL=c++_static \ 264 -DARCH=aarch64 \ 265 -DASTCENC_ISA_NEON=ON \ 266 .. 267 268make -j16 269``` 270 271## Packaging a release bundle 272 273We support building a release bundle of all enabled binary configurations in 274the current CMake configuration using the `package` build target 275 276Configure CMake with: 277 278* `-DASTCENC_PACAKGE=<arch>` to set the package architecture/variant name used 279to name the package archive (not set by default). 280 281```shell 282# Run a build and package build outputs in `./astcenc-<ver>-<os>-<arch>.<fmt>` 283cd build 284make package -j16 285``` 286 287Windows packages will use the `.zip` format, other packages will use the 288`.tar.gz` format. 289 290## Integrating as a library into another project 291 292The core codec of `astcenc` is built as a library, and so can be easily 293integrated into other projects using CMake. An example of the CMake integration 294and the codec API usage can be found in the `./Utils/Example` directory in the 295repository. See the [Example Readme](../Utils/Example/README.md) for more 296details. 297 298- - - 299 300_Copyright © 2019-2023, Arm Limited and contributors. All rights reserved._ 301