"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getClangEnvironmentVars = void 0; const cp = __importStar(require("child_process")); const debug_1 = __importDefault(require("debug")); const fs = __importStar(require("fs-extra")); const path = __importStar(require("path")); const tar = __importStar(require("tar")); const zlib = __importStar(require("zlib")); const constants_1 = require("./constants"); const fetcher_1 = require("./fetcher"); const sysroot_fetcher_1 = require("./sysroot-fetcher"); const d = (0, debug_1.default)('electron-rebuild'); const CDS_URL = 'https://commondatastorage.googleapis.com/chromium-browser-clang'; function getPlatformUrlPrefix(hostOS, hostArch) { const prefixMap = { 'linux': 'Linux_x64', 'darwin': 'Mac', 'win32': 'Win', }; let prefix = prefixMap[hostOS]; if (prefix === 'Mac' && hostArch === 'arm64') { prefix = 'Mac_arm64'; } return CDS_URL + '/' + prefix + '/'; } function getClangDownloadURL(packageFile, packageVersion, hostOS, hostArch) { const cdsFile = `${packageFile}-${packageVersion}.tgz`; return getPlatformUrlPrefix(hostOS, hostArch) + cdsFile; } function getSDKRoot() { if (process.env.SDKROOT) return process.env.SDKROOT; const output = cp.execFileSync('xcrun', ['--sdk', 'macosx', '--show-sdk-path']); return output.toString().trim(); } async function getClangEnvironmentVars(electronVersion, targetArch) { const clangDownloadDir = await downloadClangVersion(electronVersion); const clangDir = path.resolve(clangDownloadDir, 'bin'); const clangArgs = []; if (process.platform === 'darwin') { clangArgs.push('-isysroot', getSDKRoot()); } const gypArgs = []; if (process.platform === 'win32') { console.log(fs.readdirSync(clangDir)); gypArgs.push(`/p:CLToolExe=clang-cl.exe`, `/p:CLToolPath=${clangDir}`); } if (process.platform === 'linux') { const sysrootPath = await (0, sysroot_fetcher_1.downloadLinuxSysroot)(electronVersion, targetArch); clangArgs.push('--sysroot', sysrootPath); } return { env: { CC: `"${path.resolve(clangDir, 'clang')}" ${clangArgs.join(' ')}`, CXX: `"${path.resolve(clangDir, 'clang++')}" ${clangArgs.join(' ')}`, }, args: gypArgs, }; } exports.getClangEnvironmentVars = getClangEnvironmentVars; function clangVersionFromRevision(update) { const regex = /CLANG_REVISION = '([^']+)'\nCLANG_SUB_REVISION = (\d+)\n/g; const clangVersionMatch = regex.exec(update); if (!clangVersionMatch) return null; const [, clangVersion, clangSubRevision] = clangVersionMatch; return `${clangVersion}-${clangSubRevision}`; } function clangVersionFromSVN(update) { const regex = /CLANG_REVISION = '([^']+)'\nCLANG_SVN_REVISION = '([^']+)'\nCLANG_SUB_REVISION = (\d+)\n/g; const clangVersionMatch = regex.exec(update); if (!clangVersionMatch) return null; const [, clangVersion, clangSvn, clangSubRevision] = clangVersionMatch; return `${clangSvn}-${clangVersion.substr(0, 8)}-${clangSubRevision}`; } async function downloadClangVersion(electronVersion) { d('fetching clang for Electron:', electronVersion); const clangDirPath = path.resolve(constants_1.ELECTRON_GYP_DIR, `${electronVersion}-clang`); if (await fs.pathExists(path.resolve(clangDirPath, 'bin', 'clang'))) return clangDirPath; if (!await fs.pathExists(constants_1.ELECTRON_GYP_DIR)) await fs.mkdirp(constants_1.ELECTRON_GYP_DIR); const electronDeps = await (0, fetcher_1.fetch)(`https://raw.githubusercontent.com/electron/electron/v${electronVersion}/DEPS`, 'text'); const chromiumRevisionExtractor = /'chromium_version':\n\s+'([^']+)/g; const chromiumRevisionMatch = chromiumRevisionExtractor.exec(electronDeps); if (!chromiumRevisionMatch) throw new Error('Failed to determine Chromium revision for given Electron version'); const chromiumRevision = chromiumRevisionMatch[1]; d('fetching clang for Chromium:', chromiumRevision); const base64ClangUpdate = await (0, fetcher_1.fetch)(`https://chromium.googlesource.com/chromium/src.git/+/${chromiumRevision}/tools/clang/scripts/update.py?format=TEXT`, 'text'); const clangUpdate = Buffer.from(base64ClangUpdate, 'base64').toString('utf8'); const clangVersionString = clangVersionFromRevision(clangUpdate) || clangVersionFromSVN(clangUpdate); if (!clangVersionString) throw new Error('Failed to determine Clang revision from Electron version'); d('fetching clang:', clangVersionString); const clangDownloadURL = getClangDownloadURL('clang', clangVersionString, process.platform, process.arch); const contents = await (0, fetcher_1.fetch)(clangDownloadURL, 'buffer'); d('deflating clang'); zlib.deflateSync(contents); const tarPath = path.resolve(constants_1.ELECTRON_GYP_DIR, `${electronVersion}-clang.tar`); if (await fs.pathExists(tarPath)) await fs.remove(tarPath); await fs.writeFile(tarPath, Buffer.from(contents)); await fs.mkdirp(clangDirPath); d('tar running on clang'); await tar.x({ file: tarPath, cwd: clangDirPath, }); await fs.remove(tarPath); d('cleaning up clang tar file'); return clangDirPath; } //# sourceMappingURL=clang-fetcher.js.map