@@ -197,19 +197,48 @@ that the Botan libraries were installed into.
197197On macOS
198198--------------
199199
200- A build on macOS works much like that on any other Unix-like system.
200+ A standard build on macOS works much like that on any other Unix-like system.
201+
202+ One notable difference with macOS is the common usage of "universal binaries",
203+ which is effectively a multiarch binary. This was used first for the PowerPC to
204+ x86 transition, and more recently for the x86 to Aarch64 transition.
205+
206+ Building a universal binary is a bit trickier for Botan compared with a standard
207+ application, as the library makes use of many architecture specific extensions,
208+ for example AES-NI and AVX2 on x86, and NEON and the ARMv8 crypto extensions on
209+ Aarch64. Botan's build system also assumes that it is knowable at setup time
210+ which files are to be compiled.
211+
212+ Typically (for software with no architecture dependent code) a universal binary
213+ is built by adding additional compilation flags that look something like
214+ ``-force_cpusubtype_ALL -arch x86_64 -arch arm64 ``. This effectively causes XCode
215+ to compile each file twice, once for x86_64 and again for Aarch64. For most source
216+ files this works fine, but for architecture-specific files it will result in errors
217+ when code specific to one architecture is encountered when compiling for a different
218+ architecture, resulting in errors like::
201219
202- To build a universal binary for macOS, for older macOs releases,
203- you need to set some additional build flags.
204- Do this with the `configure.py ` flag `--cc-abi-flags `::
205-
206- --cc-abi-flags="-force_cpusubtype_ALL -mmacosx-version-min=10.4 -arch i386 -arch ppc"
207-
208-
209- for mac M1 on arm64, you can build the x86_64 arch version via Rosetta separately.
210- Do this with with `arch -x86_64 configure.py --library-suffix=-x86_64 `
211- Then using lipo to create a fat binary.
212- `lipo -create libbotan-arm64.dylib libbotan-x86_64.dylib -o libbotan.dylib `
220+ $ make
221+ ...
222+ error: unknown target CPU 'armv8.2-a+sha3'
223+ note: valid target CPU values are: ...
224+
225+ There are currently two ways of proceeding.
226+
227+ The first is to use ``--cpu=generic ``. This disables all architecture specific
228+ code, which has performance implications, especially for algorithms with
229+ dedicated hardware support like AES. This can be alleviated somewhat by making
230+ sure the CommonCrypto provider (module ``commoncrypto ``) is built, since then
231+ Botan offloads many of these specific operations to CommonCrypto, which will be
232+ able to use the CPU instructions.
233+
234+ The second, and recommended, approach is to build twice and use ``lipo `` to
235+ combine the two binaries. This looks something like::
236+
237+ $ ./configure.py --with-build-dir=botan_x86_64 --disable-cc-tests --build-targets=shared --cpu=x86_64 --extra-cxxflags='-arch x86_64' --ldflags='-arch x86_64' --library-suffix=-x86_64
238+ $ make -j8 -f botan_x86_64/Makefile
239+ $ ./configure.py --with-build-dir=botan_aarch64 --disable-cc-tests --build-targets=shared --cpu=aarch64 --extra-cxxflags='-arch arm64' --ldflags='-arch arm64' --library-suffix=-aarch64
240+ $ make -j8 -f botan_aarch64/Makefile
241+ $ lipo -create botan_aarch64/libbotan-3-aarch64.dylib botan_x86_64/libbotan-3-x86_64.dylib -o libbotan-3.dylib
213242
214243On Windows
215244--------------
0 commit comments