Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Redlance Compat Shims

Backport library that supplies missing-on-old-macOS symbols and ObjC selectors, so applications built against modern SDKs can still load and run on legacy systems (Mavericks 10.9 onward).

Pairs well with macports-legacy-support which handles a different layer (POSIX/libc/Darwin headers and helpers). RCS specifically covers:

  • Modern ObjC ABI fast-paths (objc_alloc_init, objc_opt_new, etc.)
  • Compiler-emitted runtime helpers (__availability_version_check)
  • libc++ low-level ulock primitives (__ulock_wait2, __ulock_wake)
  • Tracing/logging APIs (os_log_create, os_signpost_*)
  • Quality-of-Service APIs (pthread_get_qos_class_np, etc.)
  • C++17 typeinfo/vtable for std::bad_variant_access, std::bad_optional_access
  • ObjC selector backports via +load categories

Build

make                                          # x86_64, deployment 10.9
make ARCHS="x86_64 arm64"                     # universal
make DEPLOYMENT_TARGET=10.7                   # bump back further
make CC=/opt/local/bin/clang-mp-19            # MacPorts clang
make SHARED=no                                # only static archive
make print-config                             # show resolved variables
make test                                     # run smoke tests

Outputs land in build/: libRedlanceCompatShims.a and libRedlanceCompatShims.dylib.

Install

make install PREFIX=/opt/local
make install PREFIX=/opt/local DESTDIR=/tmp/staging  # for packagers

Architecture

Every shim is gated by an #if RL_RCS_DEPLOYMENT < <version> guard. The RL_RCS_DEPLOYMENT macro is defined by the Makefile from the DEPLOYMENT_TARGET variable in standard form (e.g. 10.9100900, 10.14.4101404). On systems where the symbol exists natively, no code is emitted.

Sources:

src/objc-abi-shims.m         — objc_alloc, objc_alloc_init, objc_opt_new, ...
src/availability-check.c     — __availability_version_check via sysctl
src/ulock.c                  — __ulock_wait2, __ulock_wake (no-op fallback)
src/filesystem-shims.c       — renameatx_np
src/os-log.c                 — os_log_create, os_signpost_* (no-op)
src/qos.c                    — pthread_*_qos_*_np (no-op, return DEFAULT)
src/cxx17-polyfill.cpp       — std::bad_variant_access, std::bad_optional_access
src/NSToolbarItemGroup+Compat.m — example +load category backport

Coverage cheat-sheet

Symbol Native since Source
objc_alloc 10.10 objc-abi-shims.m
objc_allocWithZone 10.10 objc-abi-shims.m
objc_opt_new 10.10 objc-abi-shims.m
objc_unsafeClaimAutoreleasedReturnValue 10.11 objc-abi-shims.m
objc_alloc_init 10.14.4 objc-abi-shims.m
qos_class_self 10.10 qos.c
pthread_get_qos_class_np 10.10 qos.c
pthread_override_qos_class_*_np 10.10 qos.c
os_log_create 10.12 os-log.c
__ulock_wake 10.12 ulock.c
renameatx_np 10.12 filesystem-shims.c
os_signpost_* 10.14 os-log.c
std::bad_variant_access 10.14 libc++ cxx17-polyfill.cpp
std::bad_optional_access 10.14 libc++ cxx17-polyfill.cpp
__availability_version_check 10.15 availability-check.c
__ulock_wait2 11.0 ulock.c

Linker integration

For the ObjC ABI / C / C++ shims (anything with C-callable symbols), normal static linkage is enough. The linker picks them up through unresolved references just like any other library.

For ObjC +load categories (currently NSToolbarItemGroup+Compat.m), you MUST use -force_load because there are no C symbol references that could pull the .o in:

clang myapp.m -framework AppKit -framework Foundation \
  -Wl,-force_load,/opt/local/lib/libRedlanceCompatShims.a \
  -o myapp

In Kotlin/Native (Gradle):

binaries.all {
    linkerOpts(
        "-Wl,-force_load,/opt/local/lib/libRedlanceCompatShims.a",
    )
}

Adding a new shim

For a missing C function: add to an existing .c file (or create one), wrap in #if RL_RCS_DEPLOYMENT < <version> based on when it appeared natively, mark exported via __attribute__((visibility("default"))).

For a missing ObjC selector on an existing class: add a category file under src/. Inside +load, do class_respondsToSelector check, then class_addMethod with the right type encoding.

For a missing class entirely: harder — see project docs.

License

MIT.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages