1*8975f5c5SAndroid Build Coastguard Worker // 2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2020 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker // 6*8975f5c5SAndroid Build Coastguard Worker 7*8975f5c5SAndroid Build Coastguard Worker // SoftLinking.h: Macros for soft-linking Frameworks and Functions. 8*8975f5c5SAndroid Build Coastguard Worker 9*8975f5c5SAndroid Build Coastguard Worker #ifndef SOFT_LINKING_APPLE_H_ 10*8975f5c5SAndroid Build Coastguard Worker #define SOFT_LINKING_APPLE_H_ 11*8975f5c5SAndroid Build Coastguard Worker 12*8975f5c5SAndroid Build Coastguard Worker #include "common/platform.h" 13*8975f5c5SAndroid Build Coastguard Worker 14*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE) 15*8975f5c5SAndroid Build Coastguard Worker 16*8975f5c5SAndroid Build Coastguard Worker # include "common/debug.h" 17*8975f5c5SAndroid Build Coastguard Worker 18*8975f5c5SAndroid Build Coastguard Worker # import <dispatch/dispatch.h> 19*8975f5c5SAndroid Build Coastguard Worker # import <dlfcn.h> 20*8975f5c5SAndroid Build Coastguard Worker # import <objc/runtime.h> 21*8975f5c5SAndroid Build Coastguard Worker 22*8975f5c5SAndroid Build Coastguard Worker # define RELEASE_ASSERT(expression, message) \ 23*8975f5c5SAndroid Build Coastguard Worker (expression \ 24*8975f5c5SAndroid Build Coastguard Worker ? static_cast<void>(0) \ 25*8975f5c5SAndroid Build Coastguard Worker : (FATAL() << "\t! Assert failed in " << __FUNCTION__ << " (" << __FILE__ << ":" \ 26*8975f5c5SAndroid Build Coastguard Worker << __LINE__ << "): " << #expression << "\n\t! Message: " << message)) 27*8975f5c5SAndroid Build Coastguard Worker 28*8975f5c5SAndroid Build Coastguard Worker # ifdef __cplusplus 29*8975f5c5SAndroid Build Coastguard Worker # define EXTERN_C_BEGIN extern "C" { 30*8975f5c5SAndroid Build Coastguard Worker # define EXTERN_C_END } 31*8975f5c5SAndroid Build Coastguard Worker # else 32*8975f5c5SAndroid Build Coastguard Worker # define EXTERN_C_BEGIN 33*8975f5c5SAndroid Build Coastguard Worker # define EXTERN_C_END 34*8975f5c5SAndroid Build Coastguard Worker # endif 35*8975f5c5SAndroid Build Coastguard Worker 36*8975f5c5SAndroid Build Coastguard Worker # define SOFT_LINK_FRAMEWORK_HEADER(framework) extern void *framework##Library(); 37*8975f5c5SAndroid Build Coastguard Worker 38*8975f5c5SAndroid Build Coastguard Worker # define SOFT_LINK_FRAMEWORK_SOURCE(framework) \ 39*8975f5c5SAndroid Build Coastguard Worker void *framework##Library() \ 40*8975f5c5SAndroid Build Coastguard Worker { \ 41*8975f5c5SAndroid Build Coastguard Worker static dispatch_once_t once = 0; \ 42*8975f5c5SAndroid Build Coastguard Worker static void *frameworkLibrary = NULL; \ 43*8975f5c5SAndroid Build Coastguard Worker dispatch_once(&once, ^{ \ 44*8975f5c5SAndroid Build Coastguard Worker frameworkLibrary = dlopen( \ 45*8975f5c5SAndroid Build Coastguard Worker "/System/Library/Frameworks/" #framework ".framework/" #framework, RTLD_NOW); \ 46*8975f5c5SAndroid Build Coastguard Worker RELEASE_ASSERT(frameworkLibrary, "Unable to load " #framework ".framework"); \ 47*8975f5c5SAndroid Build Coastguard Worker }); \ 48*8975f5c5SAndroid Build Coastguard Worker return frameworkLibrary; \ 49*8975f5c5SAndroid Build Coastguard Worker } 50*8975f5c5SAndroid Build Coastguard Worker 51*8975f5c5SAndroid Build Coastguard Worker # define SOFT_LINK_FUNCTION_HEADER(framework, functionName, resultType, parameterDeclarations, \ 52*8975f5c5SAndroid Build Coastguard Worker parameterNames) \ 53*8975f5c5SAndroid Build Coastguard Worker EXTERN_C_BEGIN \ 54*8975f5c5SAndroid Build Coastguard Worker resultType functionName parameterDeclarations; \ 55*8975f5c5SAndroid Build Coastguard Worker EXTERN_C_END \ 56*8975f5c5SAndroid Build Coastguard Worker extern resultType init##framework##functionName parameterDeclarations; \ 57*8975f5c5SAndroid Build Coastguard Worker extern resultType(*softLink##framework##functionName) parameterDeclarations; \ 58*8975f5c5SAndroid Build Coastguard Worker inline __attribute__((__always_inline__)) resultType functionName parameterDeclarations \ 59*8975f5c5SAndroid Build Coastguard Worker { \ 60*8975f5c5SAndroid Build Coastguard Worker return softLink##framework##functionName parameterNames; \ 61*8975f5c5SAndroid Build Coastguard Worker } 62*8975f5c5SAndroid Build Coastguard Worker 63*8975f5c5SAndroid Build Coastguard Worker # define SOFT_LINK_FUNCTION_SOURCE(framework, functionName, resultType, parameterDeclarations, \ 64*8975f5c5SAndroid Build Coastguard Worker parameterNames) \ 65*8975f5c5SAndroid Build Coastguard Worker resultType(*softLink##framework##functionName) parameterDeclarations = \ 66*8975f5c5SAndroid Build Coastguard Worker init##framework##functionName; \ 67*8975f5c5SAndroid Build Coastguard Worker resultType init##framework##functionName parameterDeclarations \ 68*8975f5c5SAndroid Build Coastguard Worker { \ 69*8975f5c5SAndroid Build Coastguard Worker static dispatch_once_t once; \ 70*8975f5c5SAndroid Build Coastguard Worker dispatch_once(&once, ^{ \ 71*8975f5c5SAndroid Build Coastguard Worker softLink##framework##functionName = \ 72*8975f5c5SAndroid Build Coastguard Worker (resultType(*) parameterDeclarations)dlsym(framework##Library(), #functionName); \ 73*8975f5c5SAndroid Build Coastguard Worker }); \ 74*8975f5c5SAndroid Build Coastguard Worker return softLink##framework##functionName parameterNames; \ 75*8975f5c5SAndroid Build Coastguard Worker } 76*8975f5c5SAndroid Build Coastguard Worker 77*8975f5c5SAndroid Build Coastguard Worker # define SOFT_LINK_CLASS_HEADER(className) \ 78*8975f5c5SAndroid Build Coastguard Worker @class className; \ 79*8975f5c5SAndroid Build Coastguard Worker extern Class (*get##className##Class)(); \ 80*8975f5c5SAndroid Build Coastguard Worker className *alloc##className##Instance(); \ 81*8975f5c5SAndroid Build Coastguard Worker inline className *alloc##className##Instance() { return [get##className##Class() alloc]; } 82*8975f5c5SAndroid Build Coastguard Worker 83*8975f5c5SAndroid Build Coastguard Worker # define SOFT_LINK_CLASS(framework, className) \ 84*8975f5c5SAndroid Build Coastguard Worker @class className; \ 85*8975f5c5SAndroid Build Coastguard Worker static Class init##className(); \ 86*8975f5c5SAndroid Build Coastguard Worker Class (*get##className##Class)() = init##className; \ 87*8975f5c5SAndroid Build Coastguard Worker static Class class##className; \ 88*8975f5c5SAndroid Build Coastguard Worker \ 89*8975f5c5SAndroid Build Coastguard Worker static Class className##Function() { return class##className; } \ 90*8975f5c5SAndroid Build Coastguard Worker \ 91*8975f5c5SAndroid Build Coastguard Worker static Class init##className() \ 92*8975f5c5SAndroid Build Coastguard Worker { \ 93*8975f5c5SAndroid Build Coastguard Worker static dispatch_once_t once; \ 94*8975f5c5SAndroid Build Coastguard Worker dispatch_once(&once, ^{ \ 95*8975f5c5SAndroid Build Coastguard Worker framework##Library(); \ 96*8975f5c5SAndroid Build Coastguard Worker class##className = objc_getClass(#className); \ 97*8975f5c5SAndroid Build Coastguard Worker RELEASE_ASSERT(class##className, "objc_getClass failed for " #className); \ 98*8975f5c5SAndroid Build Coastguard Worker get##className##Class = className##Function; \ 99*8975f5c5SAndroid Build Coastguard Worker }); \ 100*8975f5c5SAndroid Build Coastguard Worker return class##className; \ 101*8975f5c5SAndroid Build Coastguard Worker } \ 102*8975f5c5SAndroid Build Coastguard Worker _Pragma("clang diagnostic push") \ 103*8975f5c5SAndroid Build Coastguard Worker _Pragma("clang diagnostic ignored \"-Wunused-function\"") static className \ 104*8975f5c5SAndroid Build Coastguard Worker *alloc##className##Instance() \ 105*8975f5c5SAndroid Build Coastguard Worker { \ 106*8975f5c5SAndroid Build Coastguard Worker return [get##className##Class() alloc]; \ 107*8975f5c5SAndroid Build Coastguard Worker } \ 108*8975f5c5SAndroid Build Coastguard Worker _Pragma("clang diagnostic pop") 109*8975f5c5SAndroid Build Coastguard Worker 110*8975f5c5SAndroid Build Coastguard Worker #endif // defined(ANGLE_PLATFORM_APPLE) 111*8975f5c5SAndroid Build Coastguard Worker 112*8975f5c5SAndroid Build Coastguard Worker #endif // SOFT_LINKING_APPLE_H_ 113