Skip to content

Instantly share code, notes, and snippets.

@dlevi309
Last active February 19, 2026 18:57
Show Gist options
  • Select an option

  • Save dlevi309/ab45b4016479064833f50af4f4b0aa1f to your computer and use it in GitHub Desktop.

Select an option

Save dlevi309/ab45b4016479064833f50af4f4b0aa1f to your computer and use it in GitHub Desktop.
Compatibility shim for tools that export `ubrk_clone` (libicucore.A.dylib)
// Fix for dyld[8734]: Symbol not found: _ubrk_clone
// more info: https://github.com/oven-sh/bun/issues/6035
// cc -shared main.c -o libicucore_shim.dylib -Wl,-reexport-licucore -current_version 1.0.0 -compatibility_version 1.0.0
// install_name_tool -change /usr/lib/libicucore.A.dylib /usr/local/lib/libicucore_shim.dylib target_binary
#include <stdlib.h>
#include <stdint.h>
typedef struct UBreakIterator UBreakIterator;
typedef int32_t UErrorCode;
enum {
U_ZERO_ERROR = 0,
U_ILLEGAL_ARGUMENT_ERROR = 1,
U_MEMORY_ALLOCATION_ERROR = 7
};
extern UBreakIterator *ubrk_safeClone(const UBreakIterator *bi, void *stackBuffer, int32_t *pBufferSize, UErrorCode *status);
__attribute__((visibility("default")))
UBreakIterator * ubrk_clone(const UBreakIterator *bi, UErrorCode *status) {
if (status == NULL) return NULL;
if (*status != U_ZERO_ERROR) return NULL;
if (bi == NULL) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return NULL;
}
int32_t needed = 0;
UBreakIterator *it = ubrk_safeClone(bi, NULL, &needed, status);
if (it != NULL) return it;
if (*status != U_ZERO_ERROR && *status != U_MEMORY_ALLOCATION_ERROR) {
return NULL;
}
if (needed <= 0) {
*status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
void *buf = malloc((size_t)needed);
if (!buf) {
*status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
*status = U_ZERO_ERROR;
it = ubrk_safeClone(bi, buf, &needed, status);
return it;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment