Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: build xcframeworks to fix linking issue in Playground App #654

Merged
merged 1 commit into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ jobs:
run: npm install
working-directory: ./Apps/BRNPlayground

- name: Build Windows Bundle
- name: Build iOS Bundle
run: npm run build:ios
working-directory: ./Apps/BRNPlayground

Expand All @@ -140,6 +140,14 @@ jobs:
run: npx gulp buildIOSRNTA
working-directory: ./Package

- name: Cache XCFrameworks
uses: actions/cache@v2
with:
path: Modules/@babylonjs/react-native-iosandroid/ios/libs
key: ${{ runner.os }}-xcframeworks-${{ github.sha }}
restore-keys: |
${{ runner.os }}-xcframeworks

test-publish-android-ios:
runs-on: macos-latest
steps:
Expand Down
4 changes: 4 additions & 0 deletions Apps/BRNPlayground/postinstall.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ function postInstall() {
if (os.platform() === "darwin") {
iosCMake();

exec("npm install && npx gulp buildIOSRNTA", {
cwd: "../../Package",
});

console.log(chalk.black.bgCyan("Installing iOS pods..."));
exec("pod install", { cwd: "ios" });
}
Expand Down
3 changes: 2 additions & 1 deletion Modules/@babylonjs/react-native-iosandroid/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ DerivedData
*.ipa
*.xcuserstate
project.xcworkspace
ios/libs

# Android/IntelliJ
#
Expand All @@ -51,4 +52,4 @@ CMakeCache.txt
cmake_install.cmake
ReactNativeBabylon.xcodeproj
*.tgz
jsi
jsi
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ require "json"

package = JSON.parse(File.read(File.join(__dir__, "package.json")))

# This Podspec is used for local development

Pod::Spec.new do |s|
s.name = "react-native-babylon"
s.version = package["version"]
Expand All @@ -17,47 +19,32 @@ Pod::Spec.new do |s|
s.requires_arc = true
s.xcconfig = { 'USER_HEADER_SEARCH_PATHS' => '$(inherited) ${PODS_TARGET_SRCROOT}/shared ${PODS_TARGET_SRCROOT}/../react-native/shared' }

s.libraries = 'astc-encoder',
'etc1',
'etc2',
'nvtt',
'squish',
'pvrtc',
'iqa',
'edtaa3',
'tinyexr',
'BabylonNative',
'bgfx',
'bimg',
'bx',
'Canvas',
'GenericCodeGen',
'glslang',
'glslang-default-resource-limits',
'Graphics',
'jsRuntime',
'OGLCompiler',
'OSDependent',
'MachineIndependent',
'napi',
'NativeCamera',
'NativeCapture',
'NativeEngine',
'NativeInput',
'NativeOptimizations',
'NativeTracing',
'NativeXR',
'SPIRV',
'spirv-cross-core',
'spirv-cross-msl',
'tinyexr',
'UrlLib',
'Window',
'XMLHttpRequest',
'xr'
s.vendored_frameworks = "ios/libs/*.xcframework"

s.frameworks = "MetalKit", "ARKit"

s.dependency "React"
# install_modules_dependencies has been defined in RN 0.70
# This check ensure that the library can work on older versions of RN
if defined?(install_modules_dependencies)
install_modules_dependencies(s)
else
s.dependency "React-Core"

# Don't install the dependencies when we run `pod install` in the old architecture.
if new_arch_enabled then
s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
s.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
"OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
}
s.dependency "React-Codegen"
s.dependency "RCT-Folly"
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "ReactCommon/turbomodule/core"
s.dependency "React-RCTFabric"
end
end
okwasniewski marked this conversation as resolved.
Show resolved Hide resolved
end

67 changes: 65 additions & 2 deletions Package/gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ const buildIphoneSimulator = async () => {
exec('xcodebuild -sdk iphonesimulator -arch x86_64 -configuration Release -project ReactNativeBabylon.xcodeproj -scheme BabylonNative build CODE_SIGNING_ALLOWED=NO', 'iOS/Build');
};

const buildIOS = gulp.series(makeXCodeProj, buildIphoneOS, buildIphoneSimulator);
const buildIOSRNTA = gulp.series(makeXCodeProjRNTA, buildIphoneOS, buildIphoneSimulator);

const buildAndroid = async () => {
const basekitBuildProp = basekitBuild ? "-PBASEKIT_BUILD=1" : "";
Expand Down Expand Up @@ -235,6 +233,68 @@ const createIOSUniversalLibs = async () => {
libs.map(lib => exec(`lipo -create iOS/Build/Release-iphoneos/${lib} iOS/Build/Release-iphonesimulator/${lib} -output ${assemblediOSAndroidDir}/ios/libs/${lib}`));
};

const createXCFrameworks = async () => {
okwasniewski marked this conversation as resolved.
Show resolved Hide resolved
if (fs.existsSync('../Modules/@babylonjs/react-native-iosandroid/ios/libs/')) {
console.log('XCFrameworks already exist, skipping creation. If you want to recreate them, delete the ios/libs directory in the react-native-iosandroid module.');
return;
}

const PLATFORMS_MAP = {
'iphoneos': ['arm64'],
'iphonesimulator': ['x86_64', 'arm64'],
};

// Build static libraries for each platform
Object.keys(PLATFORMS_MAP).forEach(platform => {
const archs = PLATFORMS_MAP[platform];
archs.forEach(arch => {
const outputDir = `iOS/Build/${platform}-${arch}`;
shelljs.mkdir('-p', outputDir);
const buildCommand = `xcodebuild -sdk ${platform} -arch ${arch} -configuration Release -project ReactNativeBabylon.xcodeproj -scheme BabylonNative build CODE_SIGNING_ALLOWED=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES`;
exec(buildCommand, 'iOS/Build');
exec(`mv iOS/Build/Release-${platform}/*.a ${outputDir}`);
exec(`rm -rf iOS/Build/Release-${platform}`);
});
});

// Get the list of libraries
const libs = await readdirAsync(`iOS/Build/iphoneos-arm64`);

// Merge multi arch libraries into single libraries for platform with multiple archs
Object.keys(PLATFORMS_MAP).forEach(platform => {
const archs = PLATFORMS_MAP[platform];
if (archs.length === 1) {
// Copy the single arch library to the output directory
const outputDir = `${assemblediOSAndroidDir}/ios/libs/${platform}`;
shelljs.mkdir('-p', outputDir);
exec(`cp -r iOS/Build/${platform}-${archs[0]}/*.a ${outputDir}`);
return
}

const outputDir = `${assemblediOSAndroidDir}/ios/libs/${platform}`;
shelljs.mkdir('-p', outputDir);
libs.forEach(lib => {
let params = ""
archs.forEach(arch => {
params += ` iOS/Build/${platform}-${arch}/${lib}`
});
exec(`lipo -create ${params} -output ${outputDir}/${lib}`);
});
});

// Create xcframework for each library
libs.forEach(lib => {
const params = Object.keys(PLATFORMS_MAP).map(platform => ` -library ${assemblediOSAndroidDir}/ios/libs/${platform}/${lib}`).join('');
const outputDir = `${assemblediOSAndroidDir}/ios/libs/`;
const libName = lib.split('.')[0];
exec(`xcodebuild -create-xcframework ${params} -output ${outputDir}/${libName}.xcframework`);
});

shelljs.mkdir('-p', '../Modules/@babylonjs/react-native-iosandroid/ios/libs');
exec(`cp -r ${assemblediOSAndroidDir}/ios/libs/*.xcframework ../Modules/@babylonjs/react-native-iosandroid/ios/libs/`);
exec(`rm -rf ${assemblediOSAndroidDir}/ios/libs`);
};

const copyAndroidFiles = async () => {
await new Promise(resolve => {
gulp.src(`${basekitPackagePath}Android/build.gradle`)
Expand Down Expand Up @@ -621,6 +681,8 @@ const patchPackageVersion = async () => {

const copyFiles = gulp.parallel(copyIOSAndroidCommonFiles, copyIOSFiles, copyAndroidFiles);

const buildIOS = gulp.series(makeXCodeProj, buildIphoneOS, buildIphoneSimulator);
const buildIOSRNTA = gulp.series(makeXCodeProjRNTA, createXCFrameworks);
const buildTS = gulp.series(patchPackageVersion, copyCommonFiles, copySharedFiles, buildTypeScript, validateAssembled);
const buildIOSAndroid = gulp.series(patchPackageVersion, buildIOS, buildAndroid, createIOSUniversalLibs, copyFiles, validateAssemblediOSAndroid);
const build = gulp.series(buildIOSAndroid, switchToBaseKit, buildIOSAndroid);
Expand All @@ -635,6 +697,7 @@ exports.buildIOSRNTA = buildIOSRNTA;
exports.buildAndroid = buildAndroid;
exports.buildAndroidRNTA = buildAndroidRNTA;
exports.createIOSUniversalLibs = createIOSUniversalLibs;
exports.createXCFrameworks = createXCFrameworks;
exports.copyFiles = copyFiles;

exports.clean = clean;
Expand Down
Loading