# Zyryn custom VLCKit App Store build

Zyryn keeps MobileVLCKit and TVVLCKit enabled in Apple builds. The upstream
VLCKit 3.6.0 binaries import `fstatfs` from libVLC's file-access module only to
classify the backing filesystem for cache and read-ahead hints. That behavior
does not match an approved Apple Disk Space required-reason purpose, so the
release must not use the unmodified CocoaPods binaries or declare a false
privacy reason.

## Pinned source

- VLCKit tag `3.6.0`, commit
  `c73b779f2d1e3d3c1598a27811679ce2c1a005db`.
- VLC tag `3.0.21`, commit
  `dd8bfdbabe8ae3974ca3864ad3125879f523e3a2`.
- The original CocoaPods archives are
  `MobileVLCKit-3.6.0-c73b779f-dd8bfdba.tar.xz` (SHA-256
  `1a5077beeb7bf943a3fbbb91523752e50a10d490a3046cb9808d906784ddbc36`)
  and `TVVLCKit-3.6.0-c73b779f-dd8bfdba.tar.xz` (SHA-256
  `90d85d85528286d7ef9cb27187e0e3027cccd602e8d2379587e65c698f04498c`).

`patches/vlckit-3.6.0-no-fstatfs.patch` keeps macOS's existing filesystem
classification behavior. On iOS/tvOS it takes the same conservative local-file
fallback already used when `fstatfs` fails. File opening, reads, seeking,
decoding, and VLC's public API remain unchanged. The only behavioral difference
is selection of the file-cache/read-ahead hint instead of inspecting the
backing filesystem.

`patches/vlckit-3.6.0-xcode26.patch` contains build-only compatibility fixes
for zlib 1.2.13 and libpng 1.6.37. Modern Apple SDKs define both
`TARGET_OS_MAC` and `TARGET_OS_IPHONE` for iOS, so their old conditions
incorrectly replace `fdopen` and include the removed classic-Mac `fp.h`. The
patch restricts those legacy branches to non-iPhone Apple targets.

`patches/vlckit-3.6.0-build-script.patch` pins the inconsistent simulator
`pipe2` probe to VLC's portable fallback and makes the upstream plugin-flatten
step retry-safe without changing the produced module set.

## Build and stage

From the repository root:

```bash
bash scripts/appstore/build_custom_vlckit.sh all
```

The script checks out the pinned official sources, applies the upstream VLCKit
patch series and the reviewed Zyryn patches, then builds release XCFrameworks.
It also pins the autoconf `pipe2` probe off: current simulator SDKs can link the
symbol while hiding its declaration at VLCKit's deployment target, and VLC's
existing portable `pipe` plus close-on-exec fallback is the correct path.
Artifacts and retained source stay under the ignored directory
`.appstore-cache/vlckit-3.6.0-c73b779f-dd8bfdba`. Set
`ZYRYN_CUSTOM_VLCKIT_DIR` and `ZYRYN_VLCKIT_SOURCE_DIR` only when an equivalent
persistent cache location is required.

The delivery scripts stage and re-verify the matching platform automatically.
iOS staging also regenerates CocoaPods' XCFramework selector in deployment
mode. Both platforms fail closed unless every generated slice identifier
exactly matches the verified custom XCFramework's `Info.plist`. This prevents
CocoaPods from trying to copy legacy slice names after the source-built package
is staged.
To do that without building or uploading:

```bash
bash scripts/appstore/stage_custom_vlckit.sh ios
bash scripts/appstore/stage_custom_vlckit.sh tvos
```

The verifier requires:

- arm64 device and arm64/x86_64 simulator slices;
- minimum OS versions no higher than Zyryn's iOS 15/tvOS 13 floors, except
  for the arm64 tvOS simulator's Apple-defined 14.0 architecture floor (the
  device and x86_64 simulator remain at or below tvOS 13);
- the original VLCKit 3.6.0 public/private headers, module map, install name,
  and complete exported-symbol set, plus only the four additional Xcode 26
  dependency exports `_kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder`,
  `_kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder`,
  `_nfs_set_interface`, and `_rpc_set_interface` in each platform build;
- exact source/patch provenance and the LGPL license text;
- no `statfs`, `fstatfs`, `statvfs`, or `fstatvfs` import in any slice.

The 32-bit armv7/armv7s/i386 slices in VideoLAN's old binary archive cannot run
on Zyryn's supported iOS versions and cannot be produced by the current Xcode
toolchain. They are intentionally excluded; all architectures supported by the
app's current deployment targets are preserved.

## License/source obligations

VLCKit and libVLC are distributed under LGPL-2.1-or-later terms; their codec
dependencies retain their own licenses. Every staged package includes the
upstream `COPYING` text. The end-user notice, corresponding-source links, and
source-request offer are published at <https://zyryn.com/open-source> and
linked from Settings > Legal > Open Source Licenses. Before distributing the
app:

1. Keep these patches and the exact corresponding-source instructions publicly
   accessible for the distributed binary.
2. Preserve upstream copyright and license notices and provide the LGPL text to
   recipients.
3. Do not use the app's EULA or technical controls to prohibit reverse
   engineering required to debug a user's modification of the LGPL library.
4. Retain the corresponding source, upstream VLCKit patch series, build script,
   and dependency sources for the required distribution period.
5. Re-run a legal/license review whenever VLCKit, VLC, or its enabled codec
   dependency set changes.

This file records the engineering provenance and is not a substitute for legal
advice.
