1import escapeRegExp from 'lodash/escapeRegExp'; 2import path from 'path'; 3 4import { transformString } from '../../Transforms'; 5import { FileTransform, FileTransforms, StringTransform } from '../../Transforms.types'; 6import { baseCmakeTransforms } from './cmakeTransforms'; 7import { JniLibNames } from './libraries'; 8import { packagesToRename } from './packagesConfig'; 9 10function pathFromPkg(pkg: string): string { 11 return pkg.replace(/\./g, '/'); 12} 13 14export function reactNativeTransforms( 15 versionedReactNativeRoot: string, 16 abiVersion: string 17): FileTransforms { 18 return { 19 path: [], 20 content: [ 21 // Update codegen folder to our customized folder 22 { 23 paths: './ReactAndroid/build.gradle', 24 find: /"REACT_GENERATED_SRC_DIR=.+?",/, 25 replaceWith: `"REACT_GENERATED_SRC_DIR=${versionedReactNativeRoot}",`, 26 }, 27 // Add generated java to sourceSets 28 { 29 paths: './ReactAndroid/build.gradle', 30 find: /(\bsrcDirs = \["src\/main\/java",.+)(\])/, 31 replaceWith: `$1, "${path.join(versionedReactNativeRoot, 'codegen')}/java"$2`, 32 }, 33 // Disable codegen plugin 34 { 35 paths: './ReactAndroid/build.gradle', 36 find: /(\bid\("com\.facebook\.react"\)$)/m, 37 replaceWith: '// $1', 38 }, 39 { 40 paths: './ReactAndroid/build.gradle', 41 find: /(^react {[^]+?\n\})/m, 42 replaceWith: '/* $1 */', 43 }, 44 { 45 paths: './ReactAndroid/build.gradle', 46 find: /(\bpreBuild\.dependsOn\("generateCodegenArtifactsFromSchema"\))/, 47 replaceWith: '// $1', 48 }, 49 { 50 paths: './ReactAndroid/build.gradle', 51 find: /(externalNativeBuild\s*\{)([\s\S]*?)(\}\s)/g, 52 replaceWith: (_, p1, p2, p3) => 53 [ 54 p1, 55 transformString( 56 p2, 57 JniLibNames.map((lib: string) => ({ 58 find: new RegExp(`"${escapeRegExp(lib)}"`, 'g'), 59 replaceWith: `"${lib}_${abiVersion}"`, 60 })) 61 ), 62 p3, 63 ].join(''), 64 }, 65 ...packagesToRename.map((pkg: string) => ({ 66 paths: ['./ReactCommon/**/*.{java,h,cpp}', './ReactAndroid/src/main/**/*.{java,h,cpp}'], 67 find: new RegExp(`${escapeRegExp(pathFromPkg(pkg))}`, 'g'), 68 replaceWith: `${abiVersion}/${pathFromPkg(pkg)}`, 69 })), 70 ...reactNativeCmakeTransforms(abiVersion), 71 { 72 paths: './ReactAndroid/hermes-engine/build.gradle', 73 find: 'libraryName "libhermes"', 74 replaceWith: `libraryName "libhermes_${abiVersion}"`, 75 }, 76 { 77 paths: './ReactAndroid/hermes-engine/build.gradle', 78 find: /(prefab {\s+libhermes)/, 79 replaceWith: `$1_${abiVersion}`, 80 }, 81 { 82 paths: './ReactAndroid/hermes-engine/build.gradle', 83 find: 'targets "libhermes"', 84 replaceWith: `targets "libhermes_${abiVersion}"`, 85 }, 86 ...[...JniLibNames, 'fb', 'fbjni'].map((libName) => ({ 87 paths: '*.java', 88 find: new RegExp(`SoLoader.loadLibrary\\\("${escapeRegExp(libName)}"\\\)`), 89 replaceWith: `SoLoader.loadLibrary("${libName}_${abiVersion}")`, 90 })), 91 // add HERMES_ENABLE_DEBUGGER for libhermes-executor-release.so 92 { 93 paths: './ReactAndroid/hermes-engine/build.gradle', 94 find: /-DHERMES_ENABLE_DEBUGGER=False/, 95 replaceWith: '-DHERMES_ENABLE_DEBUGGER=True', 96 }, 97 { 98 paths: './ReactCommon/hermes/executor/CMakeLists.txt', 99 find: /\bdebug (hermes-inspector_)/g, 100 replaceWith: '$1', 101 }, 102 { 103 paths: './ReactCommon/hermes/executor/CMakeLists.txt', 104 find: /if\(\${CMAKE_BUILD_TYPE} MATCHES Debug\)(\n\s*target_compile_options)/g, 105 replaceWith: 'if(true)$1', 106 }, 107 { 108 paths: [ 109 './ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/CMakeLists.txt', // remove this when we drop sdk 45 for sdk 48 110 './ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt', 111 ], 112 find: '$<$<CONFIG:Debug>:-DHERMES_ENABLE_DEBUGGER=1>', 113 replaceWith: '-DHERMES_ENABLE_DEBUGGER=1', 114 }, 115 ], 116 }; 117} 118 119export function codegenTransforms(abiVersion: string): FileTransforms { 120 return { 121 path: [], 122 content: [ 123 ...packagesToRename.map((pkg: string) => ({ 124 paths: ['**/*.{java,h,cpp}'], 125 find: new RegExp(`${escapeRegExp(pathFromPkg(pkg))}`, 'g'), 126 replaceWith: `${abiVersion}/${pathFromPkg(pkg)}`, 127 })), 128 ...reactNativeCmakeTransforms(abiVersion), 129 ], 130 }; 131} 132 133function reactNativeCmakeTransforms(abiVersion: string): FileTransform[] { 134 const libNames = JniLibNames.map((lib: string): string => 135 lib.startsWith('lib') ? lib.slice(3) : lib 136 ).filter((lib: string) => !['fbjni'].includes(lib)); 137 libNames.push('${HERMES_TARGET_NAME}'); // variable used in hermes-executor CMakeLists.txt 138 libNames.push('hermes-engine::libhermes'); 139 140 return [ 141 ...baseCmakeTransforms(abiVersion, libNames).map((transform: StringTransform) => ({ 142 paths: 'CMakeLists.txt', 143 ...transform, 144 })), 145 { 146 paths: 'CMakeLists.txt', 147 find: 'add_react_build_subdir(generated/source/codegen/jni)', 148 replaceWith: 'add_react_android_subdir(../codegen/jni)', 149 }, 150 { 151 paths: 'CMakeLists.txt', 152 find: /libhermes\.so/g, 153 replaceWith: `libhermes_${abiVersion}.so`, 154 }, 155 ]; 156} 157 158export function hermesTransforms(abiVersion: string): StringTransform[] { 159 return [ 160 { 161 find: /OUTPUT_NAME hermes/g, 162 replaceWith: `OUTPUT_NAME hermes_${abiVersion}`, 163 }, 164 { 165 find: /libhermes/g, 166 replaceWith: `libhermes_${abiVersion}`, 167 }, 168 { 169 find: /jsi/g, 170 replaceWith: `jsi_${abiVersion}`, 171 }, 172 ]; 173} 174