1082815dcSEvan Baconimport { ExpoConfig } from '@expo/config-types'; 2082815dcSEvan Baconimport { XcodeProject } from 'xcode'; 3082815dcSEvan Bacon 4*8a424bebSJames Ideimport { isNotComment } from './utils/Xcodeproj'; 5082815dcSEvan Baconimport { ConfigPlugin } from '../Plugin.types'; 6082815dcSEvan Baconimport { withXcodeProject } from '../plugins/ios-plugins'; 7082815dcSEvan Baconimport { addWarningIOS } from '../utils/warnings'; 8082815dcSEvan Bacon 9082815dcSEvan Bacontype Bitcode = NonNullable<ExpoConfig['ios']>['bitcode']; 10082815dcSEvan Bacon 11082815dcSEvan Bacon/** 12082815dcSEvan Bacon * Plugin to set a bitcode preference for the Xcode project 13082815dcSEvan Bacon * based on the project's Expo config `ios.bitcode` value. 14082815dcSEvan Bacon */ 15082815dcSEvan Baconexport const withBitcode: ConfigPlugin = (config) => { 16082815dcSEvan Bacon return withXcodeProject(config, async (config) => { 17082815dcSEvan Bacon config.modResults = await setBitcodeWithConfig(config, { 18082815dcSEvan Bacon project: config.modResults, 19082815dcSEvan Bacon }); 20082815dcSEvan Bacon return config; 21082815dcSEvan Bacon }); 22082815dcSEvan Bacon}; 23082815dcSEvan Bacon 24082815dcSEvan Bacon/** 25082815dcSEvan Bacon * Plugin to set a custom bitcode preference for the Xcode project. 26082815dcSEvan Bacon * Does not read from the Expo config `ios.bitcode`. 27082815dcSEvan Bacon * 28082815dcSEvan Bacon * @param bitcode custom bitcode setting. 29082815dcSEvan Bacon */ 30082815dcSEvan Baconexport const withCustomBitcode: ConfigPlugin<Bitcode> = (config, bitcode) => { 31082815dcSEvan Bacon return withXcodeProject(config, async (config) => { 32082815dcSEvan Bacon config.modResults = await setBitcode(bitcode, { 33082815dcSEvan Bacon project: config.modResults, 34082815dcSEvan Bacon }); 35082815dcSEvan Bacon return config; 36082815dcSEvan Bacon }); 37082815dcSEvan Bacon}; 38082815dcSEvan Bacon 39082815dcSEvan Bacon/** 40082815dcSEvan Bacon * Get the bitcode preference from the Expo config. 41082815dcSEvan Bacon */ 42082815dcSEvan Baconexport function getBitcode(config: Pick<ExpoConfig, 'ios'>): Bitcode { 43082815dcSEvan Bacon return config.ios?.bitcode; 44082815dcSEvan Bacon} 45082815dcSEvan Bacon 46082815dcSEvan Bacon/** 47082815dcSEvan Bacon * Enable or disable the `ENABLE_BITCODE` property of the project configurations. 48082815dcSEvan Bacon */ 49082815dcSEvan Baconexport function setBitcodeWithConfig( 50082815dcSEvan Bacon config: Pick<ExpoConfig, 'ios'>, 51082815dcSEvan Bacon { project }: { project: XcodeProject } 52082815dcSEvan Bacon): XcodeProject { 53082815dcSEvan Bacon const bitcode = getBitcode(config); 54082815dcSEvan Bacon return setBitcode(bitcode, { project }); 55082815dcSEvan Bacon} 56082815dcSEvan Bacon 57082815dcSEvan Bacon/** 58082815dcSEvan Bacon * Enable or disable the `ENABLE_BITCODE` property. 59082815dcSEvan Bacon */ 60082815dcSEvan Baconexport function setBitcode(bitcode: Bitcode, { project }: { project: XcodeProject }): XcodeProject { 61082815dcSEvan Bacon const isDefaultBehavior = bitcode == null; 62082815dcSEvan Bacon // If the value is undefined, then do nothing. 63082815dcSEvan Bacon if (isDefaultBehavior) { 64082815dcSEvan Bacon return project; 65082815dcSEvan Bacon } 66082815dcSEvan Bacon 67082815dcSEvan Bacon const targetName = typeof bitcode === 'string' ? bitcode : undefined; 68082815dcSEvan Bacon const isBitcodeEnabled = !!bitcode; 69082815dcSEvan Bacon if (targetName) { 70082815dcSEvan Bacon // Assert if missing 71082815dcSEvan Bacon const configs = Object.entries(project.pbxXCBuildConfigurationSection()).filter(isNotComment); 72082815dcSEvan Bacon const hasConfiguration = configs.find(([, configuration]) => configuration.name === targetName); 73082815dcSEvan Bacon if (hasConfiguration) { 74082815dcSEvan Bacon // If targetName is defined then disable bitcode everywhere. 75082815dcSEvan Bacon project.addBuildProperty('ENABLE_BITCODE', 'NO'); 76082815dcSEvan Bacon } else { 77082815dcSEvan Bacon const names = [ 78082815dcSEvan Bacon // Remove duplicates, wrap in double quotes, and sort alphabetically. 79082815dcSEvan Bacon ...new Set(configs.map(([, configuration]) => `"${configuration.name}"`)), 80082815dcSEvan Bacon ].sort(); 81082815dcSEvan Bacon addWarningIOS( 82082815dcSEvan Bacon 'ios.bitcode', 83082815dcSEvan Bacon `No configuration named "${targetName}". Expected one of: ${names.join(', ')}.` 84082815dcSEvan Bacon ); 85082815dcSEvan Bacon } 86082815dcSEvan Bacon } 87082815dcSEvan Bacon 88082815dcSEvan Bacon project.addBuildProperty('ENABLE_BITCODE', isBitcodeEnabled ? 'YES' : 'NO', targetName); 89082815dcSEvan Bacon 90082815dcSEvan Bacon return project; 91082815dcSEvan Bacon} 92