Issue 31359: configure script incorrectly detects symbols as available on Mac w/ Xcode 8+ (original) (raw)

At Dropbox, we use a custom fork of Python to deploy our Desktop Client onto various platforms, including macOS. We currently use the Mac OS X 10.11 SDK, but are considering updating to the macOS 10.12 SDK, which introduced new low-level functions, such as getentropy. Apple uses a series of "availability macros" with new warnings in Clang to consider the case when the MACOSX_DEPLOYMENT_TARGET is below the introduction version for a given symbol.

This has caused significant issues for autoconf-based projects, as running configure mistakes the built version into believing certain symbols are available, when they're not. As a result, deploying a viable build to users on older versions of Mac is rather complicated.

Current "solutions" (in recent versions of Xcode) include:

In our testing, neither had any effect on Python's configure, though these solutions worked for some other projects. We've implemented a workaround based on patching pyconfig.h after configure is complete, but ideally, Python's configure should detect MACOSX_DEPLOYMENT_TARGET and act accordingly (e.g. if MACOSX_DEPLOYMENT_TARGET is below 10.12, getentropy should not be considered available).

The following symbols are affected:

New in 10.13 (Python 3 only): utimensat HAVE_UTIMENSAT futimens HAVE_FUTIMENS

New in 10.12: getentropy HAVE_GETENTROPY (Python 2/3) clock_gettime HAVE_CLOCK_GETTIME (Python 2/3) clock_settime HAVE_CLOCK_SETTIME (Python 3) clock_getres HAVE_CLOCK_GETRES (Python 3)

New in 10.10 (Python 3 only): fstatat HAVE_FSTATAT faccessat HAVE_FACCESSAT fchmodat HAVE_FCHMODAT fchownat HAVE_FCHOWNAT linkat HAVE_LINKAT fdopendir HAVE_FDOPENDIR mkdirat HAVE_MKDIRAT renameat HAVE_RENAMEAT unlinkat HAVE_UNLINKAT readlinkat HAVE_READLINKAT symlinkat HAVE_SYMLINKAT openat HAVE_OPENAT

An alternative solution, which is more invasive is to explicitly use weak linking, as is already used for some ancient APIs in posixmodule.c (look for "lchown" in Modules/posixmodule.c).

This is more invasive, but would be helpful for upstream as well because this allows building binaries that work on older versions of macOS but still make it possible to use new features when running on newer releases (and hence allows us to have a single installer for macOS 10.6+ without loosing features).