Sunday, 20 November 2022

Building GCC 12.2.0 on Ventura for aarch64

These are notes on building GCC 12.2.0 and GNAT tools for Apple silicon.

There were two main problems:

  • the base package was built on an Intel machine (lockheed - named after Shadowcat’s companion dragon), running Monterey (macOS 12).
  • the build machine, an M1 mac Mini (temeraire - named after Naomi Novik’s dragon) was by this time running Ventura (macOS 13), but I wanted to make sure that users could continue to run on Monterey.

The base package built on Intel

This first showed up while building gprbuild, but in fact started earlier (while building xmlada). The generated libraries were built for x86_64, not aarch64.

This turned out to have two causes. The first was that, at the point this build was attempted, the PATH contained new-compiler/bin:base-package/bin. base-package contained an x86_64 gprconfig, which by default looks for an x86_64 compiler, which it finds in base-package.

You would have thought that the build script saying

./configure                                     \
  --prefix=$PREFIX                              \
  --host=$BUILD                                 \
  --target=$BUILD                               \
  --build=$BUILD                                \
  --enable-shared                               \
  PACKAGE_VERSION=v23.0.0

($BUILD was aarch64-apple-darwin21) would have done the trick, and it might have done but for a feature of Makefile.in:

GPROPTS=-XXMLADA_BUILD_MODE=${MODE} -XPROCESSORS=${PROCESSORS}

ifeq (${HOST},${TARGET})
IPREFIX=${DESTDIR}${prefix}
else
GPROPTS+=--target=${TARGET_ALIAS}
IPREFIX=${DESTDIR}${prefix}/${TARGET_ALIAS}
endif

which says that if HOST and TARGET are the same, the installation directory is specified by prefix (DESTDIR being empty), but that if they’re different then

  • add the --target= flag to the gprbuild options (e.g. --target=aarch64-apple-darwin21)
  • the installation directory is below the standard installation

the first of which is what’s needed but the second is – unhelpful.

The fixes I adopted were to change Makefile.in to

GPROPTS=-XXMLADA_BUILD_MODE=${MODE} -XPROCESSORS=${PROCESSORS}
GPROPTS+=--target=${TARGET_ALIAS}

IPREFIX=${DESTDIR}${prefix}

A similar problem occurred in gprbuild’s Makefile, fixed with this patch:

-# target options for cross-build
-ifeq ($(HOST),$(TARGET))
-GTARGET=
-# INSTALLER=exe/$(BUILD)/$(LIB_INSTALLER)
-else
 GTARGET=--target=$(TARGET)
-endif

Building for Monterey on Ventura

I’d thought that building with --target=aarch64-apple-darwin21 (the triplet for Monterey) would do the trick even if building on Ventura (--target=aarch64-apple-darwin22); and failing that using -mmacosx-min-version=12 (which, anyway, is hard to pass on the command line using gprbuild).

Not so; the binary products all know what OS release they were built on; e.g in

$ otool -l bin/gcc | grep -A5 LC_BUILD_VERSION
      cmd LC_BUILD_VERSION
  cmdsize 32
 platform 1
    minos 13.0
      sdk 10.18
   ntools 1

it’s the minos 13.0.

The way to handle this is to set

$ export MACOSX_DEPLOYMENT_TARGET=12.0

and rebuild the world.


Interesting behavior

There seems to be a bug in gnatlink in that it doesn’t pass all the switches when it compiles the binder-generated Ada: running on Ventura,

$ gnatmake raiser.adb -mmacosx-version-min=12
gcc -c -mmacosx-version-min=12 raiser.adb
gnatbind -x raiser.ali
gnatlink raiser.ali -mmacosx-version-min=12
ld: warning: object file (b~raiser.o) was built for newer macOS version (13.0) than being linked (12.0)

No comments:

Post a Comment