Skip to content

Allow static, non-framework iOS builds #156109

Description

@clementperon

Feature or enhancement

Proposal:

configure refuses any iOS build that is not a framework build, in both the explicit and the default path:

configure.ac:582   iOS) AC_MSG_ERROR([iOS builds must use --enable-framework]) ;;   # --disable-framework
configure.ac:692   iOS) AC_MSG_ERROR([iOS builds must use --enable-framework]) ;;   # no framework option given

The requirement is sound for a shared Python: an iOS app can only load a signed framework, never a bare dylib, so a dynamically loaded libpython has to be packaged as one. It does not hold for a static one. A --disable-shared build produces libpython3.x.a, which is linked into the app binary and loads nothing at runtime, so there is no framework to sign, package or load — but configure rejects that configuration before it can be attempted.

This matters for embedders, which link libpython statically into a single signed executable. Today they have to either patch configure locally or give up sys.platform == "ios" and cross-build as Darwin, which misreports the platform to the stdlib.

Two other places assume the framework exists whenever ac_sys_system is iOS:

configure.ac:3838  LINKFORSHARED="… $(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK)"
configure.ac:6767  MODULE_DEPS_SHARED="… $(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK)"

The Darwin arm immediately above the first one already guards the identical append with if test "$enable_framework"; the iOS arm does it unconditionally.

Suggested shape, keeping the change conservative:

  • refuse only the combination that genuinely cannot work — a shared build with no framework — checked once PY_ENABLE_SHARED is known;
  • gate the two framework appends on enable_framework, matching the Darwin arm;
  • leave the default path (no framework option at all) erroring, so a non-framework build stays an explicit opt-in, with the message naming --disable-framework.

I have this working against main and will open a PR. Verified locally on macOS/arm64:

  • --host=arm64-apple-ios12.0 --disable-shared --disable-framework configures and make libpython3.16.a succeeds, producing an arm64 archive with LC_BUILD_VERSION platform 2, minos 12.0;
  • --disable-framework --enable-shared is rejected with the new message;
  • no framework option is still rejected;
  • --enable-framework produces a byte-identical Makefile and pyconfig.h to unpatched main, so the supported framework build is unaffected.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS-iosbuildThe build process and cross-buildtype-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions