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