Skip to content

compat:libarchive does not build for macOS under openkal: TargetConditionals.h is not in the closure #434

Description

@Sunrisepeak

compat:libarchive 3.8.7 fails to compile for any macOS target in an openkal graph, because its
POSIX backend reaches for an Apple SDK header that openkal does not supply.

compat-x-libarchive/3.8.7/libarchive-3.8.7/libarchive/archive_write_disk_posix.c:125:10:
fatal error: 'TargetConditionals.h' file not found

Reproduced on both paths CI takes: a native build on macos-14, and a cross-build from Linux to
aarch64-macos. The Linux target builds fine.

Why the header is absent rather than merely unfound. openkal-macos ships no headers at all --
neither does openkal-windows -- and every C header in the graph comes from openkal-musl (210 of
them). So the intended shape is a POSIX C environment provided by openkal on every platform, and
TargetConditionals.h is an Apple SDK header that has no counterpart there. libarchive reaches for
it under #ifdef __APPLE__, which the macOS triple defines, so the branch is taken on a target that
cannot satisfy it.

What would fix it, in the order I would try them:

  1. Build libarchive's POSIX backend without __APPLE__-conditional paths for openkal targets, so it
    takes the generic POSIX branch it already has for other systems.
  2. Or have the recipe define the handful of TARGET_OS_* macros the file needs, since under openkal
    the answer is fixed at configure time.
  3. Or declare the package unsupported on openkal macOS targets, so the failure arrives at resolution
    rather than three minutes into a compile.

Found while replacing a packaging tool's Python (tarfile + zipfile) with libarchive so the
project would stop needing an interpreter to package itself. libarchive is otherwise a good fit --
it reads both formats through one reader, and it builds and passes tests on Linux.

Related, same shape, different package: mcpplibs:tinyhttps fails on Windows targets for
winsock2.h. Both are packages assuming the host platform SDK where openkal is meant to be the
whole closure.

Activity

  1. Sunrisepeak commented on Sep 17, 2026

    @Sunrisepeak
    MemberAuthor

    Re-measured against the versions released since: openkal 0.13.0 / openkal-linux 0.13.0 /
    openkal-musl 0.14.0 / openkal-llvm-runtime 0.10.0, tinyhttps 0.3.1, mcpp 2026.9.17.3.

    This is now the only thing left, and it is wider than I filed. libarchive reaches for a host SDK
    header on both non-Linux platforms, not just macOS:

    --target aarch64-macos
      libarchive/archive_write_disk_posix.c:125:10: fatal error: 'TargetConditionals.h' file not found
    
    --target x86_64-windows-gnu
      libarchive/archive_entry.h:50:10: fatal error: 'windows.h' file not found
    

    Linux builds and passes its tests.

    Worth recording because it changes what the fix has to cover: the Windows half is in
    archive_entry.h, a public header, so it is not only libarchive's own sources that need the
    generic path — a consumer including archive_entry.h meets it too.

    The two neighbours it was filed alongside are both fixed, and I verified each rather than assuming:

    • tinyhttps 0.3.1 (mcpplibs:tinyhttps does not build for Windows under openkal: winsock2.h is not in the closure #435) — the winsock2 include is gone; it compiles for the Windows target now.
    • mcpp#662 — the host mingw sysroot is no longer searched. The evidence is the shape of the
      failure above: it used to be musl-versus-mingw conflicting type errors (because the host's
      headers were found and disagreed), and it is now a clean file not found. That is the difference
      between "the host leaked in" and "the closure lacks it", which is what #664 was for.
    • openkal#31 — chmod works. One detail that cost me a wrong conclusion and is worth passing on:
      openkal-musl grants only a mode it can honestly report back (one read triple and one write triple,
      each all-set or all-clear), so chmod(p, 0755) is refused with ENOSYS while 0777 succeeds.
      Asking for the owner's execute bit alone fails; asking for all three works.
  2. Sunrisepeak commented on Sep 17, 2026

    @Sunrisepeak
    MemberAuthor

    Correction to my previous comment: the macOS half is fixed, and my report of it failing was a
    false negative from my own stale index.
    Apologies — that reading could have sent you looking at a
    fix that already works.

    What happened: I measured locally against a store that still had the older descriptor, concluded the
    fix was not live, and said so. CI disagreed — cross-build from Linux (aarch64-macos) passed there
    on the same commit — and after mcpp index update the same build passes locally too. CI had the
    right answer before I did, because it resolves the index fresh and I did not.

    Re-measured after updating, mcpp 2026.9.17.3:

    --target aarch64-macos       Finished dev   ✅   (-U__APPLE__ does it)
    --target x86_64-windows-gnu  archive_entry.h:50:10: fatal error: 'windows.h' file not found   ❌
    x86_64-linux-gnu             Finished dev, 26 tests pass   ✅
    

    So only the Windows half is left, and it is narrower than the macOS one was — three facts that
    may save some looking:

    1. archive.h does not include windows.h at all. Only archive_entry.h does.
    2. It includes it for exactly one declaration: archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *) at line 346. The include (line 48-50) and that declaration sit
      under the same #if defined(_WIN32) && !defined(__CYGWIN__).
    3. A Win32 handle-based convenience function is of no use to an openkal graph, where the target is
      POSIX through musl.

    The -U__APPLE__ shape does not transfer, and the recipe's own comment says why before the fact:
    "archive_entry.h and archive.h do not test __APPLE__, so consumers read the same declarations."
    Here the test is in the public header, so a flag confined to libarchive's own translation units
    would not help a consumer — my platform/archive.cpp includes archive_entry.h with _WIN32
    defined by its own target. And -U_WIN32 for libarchive's own units would be much more invasive
    than -U__APPLE__ was, since archive_windows.c and its neighbours genuinely use the Win32 API.

    Two shapes that would work, for whichever you prefer:

    • An opt-out macro upstream, so the include and that one declaration are skipped together.
    • Or entirely within the recipe: it already generates localcharset.h and
      mcpp_libarchive_config.h, so a minimal generated windows.h declaring just
      BY_HANDLE_FILE_INFORMATION would satisfy both the include and the declaration — no upstream
      change at all. Worth checking it does not get picked up by libarchive's own *_windows.c units.
  3. Sunrisepeak commented on Sep 17, 2026

    @Sunrisepeak
    MemberAuthor

    One more, found by the native macOS job in the same run, and it is a link failure rather than a
    compile one — so it survives the -U__APPLE__ fix and would not show up in a header-only check:

    build and unit tests (macos-14):  25 passed; 1 failed
      test_archive ... FAIL (compile)
      ld64.lld: error: undefined symbol: memset_pattern16
    

    memset_pattern16 is Darwin libSystem's, and musl does not have it. Nothing in the source asks for
    it: clang targeting Darwin lowers certain fill loops to a call on it, the same way it lowers loops
    to strlen/wcslen elsewhere — an optimisation that assumes the platform libc, made after
    __APPLE__ has already been undefined, so the preprocessor fix cannot reach it.

    Scope, measured rather than assumed:

    • cross-build from Linux --target aarch64-macos passes — the server links only libarchive's
      reader.
    • The native macOS job compiles everything and links 25 test binaries fine; only test_archive
      fails, and it is the only target that uses libarchive's writer (my fixtures are written with
      archive_write_* so no archives need checking in).

    So the symbol comes in through the write path, which is why a reader-only consumer does not meet it.

    What would fix it: -fno-builtin-memset_pattern16 in the same cfg(all(macos, c-abi = "musl"))
    entry that carries -U__APPLE__ — it is the same class of problem as the -fno-builtin that
    openkal-windows needed when clang lowered loops to wcslen/strlen. Providing the symbol in musl's
    port would also work, but the flag keeps the decision next to the reason.

    Full picture after today's re-measure, so the remaining work is visible in one place:

    target state
    x86_64-linux-gnu builds, 26 tests pass
    aarch64-macos (cross) builds
    macos-14 (native) builds; test_archive fails to link (memset_pattern16)
    x86_64-windows-gnu archive_entry.h:50 needs windows.h
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions