[flac-dev] Enabling universal building of libFLAC

Robert Kausch robert.kausch at freac.org
Sun Sep 18 17:02:08 UTC 2022

As an integrator targeting four different architectures on Mac (ppc, 
x86, x86-64 and aarch64), I build all the libraries separately for each 
architecture and then combine the resulting binaries into a universal 
binary using the lipo tool.

That's the standard way to build universal binaries when dealing with 
Autotools or CMake build systems. It's quick and easy, so I don't really 
see a need for supporting one-step universal binary builds.

Basically, with the latter, you'll never know if anything will be broken 
on some architecture unless there is no configure step for the 
respective project or you're dealing with your own code. Many things can 
go wrong. It's not only about architecture macros, but also about 
different integer type sizes (many projects detect those in configure 
scripts), byte-order etc.

That said, if you really want to support one-step universal binary 
builds of FLAC, the main issue probably are the currently used 
architecture macros. Those could be set by an architecture.h header, 
though. It should not be necessary to detect the architecture during 

Preprocessor defines for different architectures are mostly standardized 
and should work on all systems (no need to use Apple-specific defines). 
Microsoft uses a different scheme, though, as expected... And of course 
there may be the usual bunch of embedded toolchains doing non-standard 

Here are some of the most common, the _M_xxx ones are Microsoft-specific:

    x86: __i386__ or _M_IX86
    x86-64: __x86_64__ or _M_AMD64
    ARM: __arm__ or _M_ARM
    aarch64: __aarch64__ or _M_ARM64
    MIPS: __mips__
    PPC: __ppc__
    PPC64: __ppc64__
    RISC-V: __riscv

I got most of these from this page, which, however, is a bit outdated 
now: https://sourceforge.net/p/predef/wiki/Architectures/
The Microsoft-specific macros are documented here: 
https://learn.microsoft.com/cpp/preprocessor/predefined-macros (there 
are more, like _M_ALPHA and _M_PPC, though, which are no longer documented)

During a one-step universal binary build, the different instances of the 
compiler define the correct macros for the respective architecture being 
compiled. No need to work around any build-system logic doing its own thing.


Robert Kausch
robert.kausch at freac.org

Am 18.09.2022 um 16:39 schrieb brianw:
> Ah, yes, the preprocessor defines. Now I see what you're talking about. Those are crucial because there is often code specific to a particular architecture.
> NeXT and Apple have supported up to four-processor multi-architecture builds since the nineties. I don't know whether they modified the compiler to do this, or what. But the standard practice is to learn the #define values that signal a specific architecture, and work with those. At no time would a NeXT/Apple developer manually set these preprocessor defines, nor would the make process. The tools allow a list, and the compiler is called repeatedly, each time with the preprocessor values set appropriately.
> If these values differ from the ones that libFLAC is already using (and they almost surely are spelled differently, or have more or fewer underscores), then perhaps a macOS section in a common header (like config.h) would be needed to read the Apple-supplied preprocessor values and then set the corresponding "FLAC" compatible values. Even if this works, it would probably require defeating any Make logic that hard-codes those values (otherwise the build would still be stuck with one architecture).
> I recall that `configure` has long supported NeXT and Mac OS X, but I do not recall whether anyone has shipped an open-source product that can build multi-architecture. Hopefully, someone has done this, somewhere, and their setup could be used as an example.
> It's possible that I've always punted, built for each architecture separately, and then manually combined the architectures into a single segmented loader file (whatever the official name for that is, and the format has changed since NeXT, of course). I hope it's not still like that. ;-)
> Brian
> On Sep 18, 2022, at 4:19 PM, Martijn van Beurden <mvanb1 at gmail.com> wrote:
>> Op zo 18 sep. 2022 om 16:06 schreef brianw <brianw at audiobanshee.com>:
>>> When you refer to "runtime variables," do you really mean build time?
>> Yes, build time. That was formulated wrong.
>>> I would assume that the source code does not need to change in order to support multiple architectures on macOS, but the compiler and/or make options may need to change.
>> What I mean by changing code is mostly changing preprocessor defines. Certain code is included or excluded from compilation by the preprocessor based on defines that use variables set or unset by the configure or CMake configuration. However, if these decisions need to be made at build time instead of at configuration time for MacOS, these preprocessor defines needs to change, hence the source code needs to change.
>> It might be possible to not touch the code by solving this in config.h for CMake. In CMake config.h one can add conditional statements. I'm unsure whether that is also possible for configure.
>> One could choose to support universal building only through CMake, as this seems to easier to solve.
>>> I have not dug into the details yet. If someone does not find a solution before I get back from vacation, I'll take a look. Usually, Xcode makes this easy, and Xcode even produces a Makefile that works outside of the GUI Xcode.app (i.e. it supports command-line building), so that might be a reasonably quick option. However, I admit that keeping Xcode files up to date - like any other GUI build environment - might not be worth the effort, but at least the Makefile could be useful.
>> It could be such a Makefile provides clues on how and where to change the build system as it is, yes.
> _______________________________________________
> flac-dev mailing list
> flac-dev at xiph.org
> http://lists.xiph.org/mailman/listinfo/flac-dev

More information about the flac-dev mailing list