15815213711
2024-08-26 67b8b6731811983447e053d4396b3708c14dfe3c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
"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