From 283927d23ac83b3b16a6685999a133b80b6cb176 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Wed, 23 Feb 2022 15:51:53 +0100 Subject: [PATCH] feat: allow specifying XCode version to load --- src/e-build.js | 4 +- src/e-load-xcode.js | 146 +++++++++++++++++++++++++------------------- src/utils/xcode.js | 9 ++- 3 files changed, 92 insertions(+), 67 deletions(-) diff --git a/src/e-build.js b/src/e-build.js index 78dd472..a16a03c 100644 --- a/src/e-build.js +++ b/src/e-build.js @@ -92,6 +92,7 @@ program .option('--gen', 'Force a re-run of `gn gen` before building', false) .option('-t|--target [target]', 'Forces a specific ninja target') .option('--no-goma', 'Build without goma', false) + .option('--no-load-xcode', 'Do not load Xcode prior to building', false) .parse(process.argv); try { @@ -109,7 +110,8 @@ try { const isChromium = program.target ? program.target === targets.chromium : targets.default === targets.chromium; - if (process.platform === 'darwin' && !isChromium) { + + if (process.platform === 'darwin' && !isChromium && program.loadXcode) { const result = depot.spawnSync( config, process.execPath, diff --git a/src/e-load-xcode.js b/src/e-load-xcode.js index 496c59f..bbd84d4 100644 --- a/src/e-load-xcode.js +++ b/src/e-load-xcode.js @@ -3,71 +3,89 @@ const childProcess = require('child_process'); const fs = require('fs'); const path = require('path'); +const program = require('commander'); -const { color } = require('./utils/logging'); +const { color, fatal } = require('./utils/logging'); const Xcode = require('./utils/xcode'); -if (process.platform !== 'darwin') { - console.error('Should only configure Xcode on darwin platform'); - process.exit(1); +program + .description('Load and link a specific version of XCode') + .option('--list-targets', 'Show all supported patch targets', false) + .option('--version [version]', 'Forces a specific Xcode version', null) + .option('--quiet', 'Run without verbose output', false) + .action(loadXCode) + .parse(process.argv); + +function loadXCode() { + try { + if (process.platform !== 'darwin') { + console.error('Should only configure Xcode on darwin platform'); + process.exit(1); + } + + if (Xcode.ensureXcode(program.version) === false) { + process.exit(0); + } + + // Select our new xcode + const output = childProcess.execFileSync('xcode-select', ['-p']).toString(); + if (!output.trim().startsWith(Xcode.XcodePath)) { + console.info( + `Setting your Xcode installation to ${color.path(Xcode.XcodePath)}, this will require sudo`, + ); + childProcess.execFileSync('sudo', ['xcode-select', '-s', Xcode.XcodePath], { + stdio: 'inherit', + }); + } + + // Ensure that we have accepted the Xcode license agreement + const out = childProcess.spawnSync('lldb', ['--help']); + if (out.status !== 0 && out.stderr.toString().includes('xcodebuild')) { + console.info('You need to accept the Xcode license agreement, this will require sudo'); + childProcess.execFileSync('sudo', ['xcodebuild', '-license', 'accept']); + } + + const SDK_TO_UNLINK = ['10.12', '10.13', '10.14', '10.15']; + + const xCodeSDKDir = path.resolve( + Xcode.XcodePath, + 'Contents', + 'Developer', + 'Platforms', + 'MacOSX.platform', + 'Developer', + 'SDKs', + ); + + if (!fs.existsSync(xCodeSDKDir)) { + console.error('Could not find Xcode SDK directory. Please ensure you have installed Xcode'); + process.exit(1); + } + + // Unlink unnecessary macOS SDKs that we have linked in the past + for (const sdk of SDK_TO_UNLINK) { + // Check that target exists. + const targetDirectory = path.resolve(xCodeSDKDir, `MacOSX${sdk}.sdk`); + if (!fs.existsSync(targetDirectory)) continue; + + // Check that target is a valid symbolic link. + const stats = fs.lstatSync(targetDirectory); + if (!stats.isSymbolicLink()) return; + + // Check if the link is to the default SDK that we should have + if ( + fs.realpathSync(targetDirectory) === + fs.realpathSync(path.resolve(xCodeSDKDir, 'MacOSX.sdk')) + ) + return; + + console.warn(`${color.info} Removing symbolic link ${color.path(targetDirectory)}`); + + childProcess.execFileSync('unlink', [targetDirectory]); + } + + if (!program.quiet) console.log(color.success); + } catch (e) { + fatal(e); + } } - -if (Xcode.ensureXcode() === false) { - process.exit(0); -} - -// Select our new xcode -const output = childProcess.execFileSync('xcode-select', ['-p']).toString(); -if (!output.trim().startsWith(Xcode.XcodePath)) { - console.info( - `Setting your Xcode installation to ${color.path(Xcode.XcodePath)}, this will require sudo`, - ); - childProcess.execFileSync('sudo', ['xcode-select', '-s', Xcode.XcodePath], { - stdio: 'inherit', - }); -} - -// Ensure that we have accepted the Xcode license agreement -const out = childProcess.spawnSync('lldb', ['--help']); -if (out.status !== 0 && out.stderr.toString().includes('xcodebuild')) { - console.info('You need to accept the Xcode license agreement, this will require sudo'); - childProcess.execFileSync('sudo', ['xcodebuild', '-license', 'accept']); -} - -const SDK_TO_UNLINK = ['10.12', '10.13', '10.14', '10.15']; - -const xCodeSDKDir = path.resolve( - Xcode.XcodePath, - 'Contents', - 'Developer', - 'Platforms', - 'MacOSX.platform', - 'Developer', - 'SDKs', -); - -if (!fs.existsSync(xCodeSDKDir)) { - console.error('Could not find Xcode SDK directory. Please ensure you have installed Xcode'); - process.exit(1); -} - -// Unlink unnecessary macOS SDKs that we have linked in the past -for (const sdk of SDK_TO_UNLINK) { - // Check that target exists. - const targetDirectory = path.resolve(xCodeSDKDir, `MacOSX${sdk}.sdk`); - if (!fs.existsSync(targetDirectory)) continue; - - // Check that target is a valid symbolic link. - const stats = fs.lstatSync(targetDirectory); - if (!stats.isSymbolicLink()) return; - - // Check if the link is to the default SDK that we should have - if (fs.realpathSync(targetDirectory) === fs.realpathSync(path.resolve(xCodeSDKDir, 'MacOSX.sdk'))) - return; - - console.warn(`${color.info} Removing symbolic link ${color.path(targetDirectory)}`); - - childProcess.execFileSync('unlink', [targetDirectory]); -} - -if (!process.argv.includes('--quiet')) console.log(color.success); diff --git a/src/utils/xcode.js b/src/utils/xcode.js index 1fc1391..3dc5e52 100644 --- a/src/utils/xcode.js +++ b/src/utils/xcode.js @@ -115,8 +115,13 @@ function fixBadVersioned103() { } } -function ensureXcode() { - const expected = expectedXcodeVersion(); +function ensureXcode(version) { + if (version && !Object.keys(XcodeVersions).includes(version)) { + console.error(`Invalid XCode version ${version}`); + process.exit(1); + } + + const expected = version || expectedXcodeVersion(); fixBadVersioned103(); const shouldEnsureXcode = !fs.existsSync(XcodePath) || getXcodeVersion() !== expected;