deb包的control文件中添加Depends、Recommends字段,处理control的depends依赖包.
This commit is contained in:
parent
89ed698077
commit
95937a9a0d
|
@ -16,6 +16,9 @@ const task = require('./lib/task');
|
||||||
const packageJson = require('../package.json');
|
const packageJson = require('../package.json');
|
||||||
const product = require('../product.json');
|
const product = require('../product.json');
|
||||||
const rpmDependenciesGenerator = require('./linux/rpm/dependencies-generator');
|
const rpmDependenciesGenerator = require('./linux/rpm/dependencies-generator');
|
||||||
|
const debianDependenciesGenerator = require('./linux/debian/dependencies-generator');
|
||||||
|
const sysrootInstaller = require('./linux/debian/install-sysroot');
|
||||||
|
const debianRecommendedDependencies = require('./linux/debian/dep-lists').recommendedDeps;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const root = path.dirname(__dirname);
|
const root = path.dirname(__dirname);
|
||||||
const commit = util.getVersion(root);
|
const commit = util.getVersion(root);
|
||||||
|
@ -91,12 +94,16 @@ function prepareDebPackage(arch) {
|
||||||
let size = 0;
|
let size = 0;
|
||||||
const control = code.pipe(es.through(
|
const control = code.pipe(es.through(
|
||||||
function (f) { size += f.isDirectory() ? 4096 : f.contents.length; },
|
function (f) { size += f.isDirectory() ? 4096 : f.contents.length; },
|
||||||
function () {
|
async function () {
|
||||||
const that = this;
|
const that = this;
|
||||||
|
const sysroot = await sysrootInstaller.getSysroot(debArch);
|
||||||
|
const dependencies = debianDependenciesGenerator.getDependencies('deb', binaryDir, product.applicationName, debArch, sysroot);
|
||||||
gulp.src('resources/linux/debian/control.template', { base: '.' })
|
gulp.src('resources/linux/debian/control.template', { base: '.' })
|
||||||
.pipe(replace('@@NAME@@', product.applicationName))
|
.pipe(replace('@@NAME@@', product.applicationName))
|
||||||
.pipe(replace('@@VERSION@@', packageJson.IDEVersion + '-' + linuxPackageRevision))
|
.pipe(replace('@@VERSION@@', packageJson.IDEVersion + '-' + linuxPackageRevision))
|
||||||
.pipe(replace('@@ARCHITECTURE@@', debArch))
|
.pipe(replace('@@ARCHITECTURE@@', debArch))
|
||||||
|
.pipe(replace('@@DEPENDS@@', dependencies.join(', ')))
|
||||||
|
.pipe(replace('@@RECOMMENDS@@', debianRecommendedDependencies.join(', ')))
|
||||||
.pipe(replace('@@INSTALLEDSIZE@@', Math.ceil(size / 1024)))
|
.pipe(replace('@@INSTALLEDSIZE@@', Math.ceil(size / 1024)))
|
||||||
.pipe(rename('DEBIAN/control'))
|
.pipe(rename('DEBIAN/control'))
|
||||||
.pipe(es.through(function (f) { that.emit('data', f); }, function () { that.emit('end'); }));
|
.pipe(es.through(function (f) { that.emit('data', f); }, function () { that.emit('end'); }));
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
"use strict";
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.generatePackageDeps = void 0;
|
||||||
|
const child_process_1 = require("child_process");
|
||||||
|
const fs_1 = require("fs");
|
||||||
|
const os_1 = require("os");
|
||||||
|
const path = require("path");
|
||||||
|
const manifests = require("../../../cgmanifest.json");
|
||||||
|
const dep_lists_1 = require("./dep-lists");
|
||||||
|
function generatePackageDeps(files, arch, sysroot) {
|
||||||
|
const dependencies = files.map(file => calculatePackageDeps(file, arch, sysroot));
|
||||||
|
const additionalDepsSet = new Set(dep_lists_1.additionalDeps);
|
||||||
|
dependencies.push(additionalDepsSet);
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
exports.generatePackageDeps = generatePackageDeps;
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/calculate_package_deps.py.
|
||||||
|
function calculatePackageDeps(binaryPath, arch, sysroot) {
|
||||||
|
try {
|
||||||
|
if (!((0, fs_1.statSync)(binaryPath).mode & fs_1.constants.S_IXUSR)) {
|
||||||
|
throw new Error(`Binary ${binaryPath} needs to have an executable bit set.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// The package might not exist. Don't re-throw the error here.
|
||||||
|
console.error('Tried to stat ' + binaryPath + ' but failed.');
|
||||||
|
}
|
||||||
|
// Get the Chromium dpkg-shlibdeps file.
|
||||||
|
const chromiumManifest = manifests.registrations.filter(registration => {
|
||||||
|
return registration.component.type === 'git' && registration.component.git.name === 'chromium';
|
||||||
|
});
|
||||||
|
const dpkgShlibdepsUrl = `https://raw.githubusercontent.com/chromium/chromium/${chromiumManifest[0].version}/third_party/dpkg-shlibdeps/dpkg-shlibdeps.pl`;
|
||||||
|
const dpkgShlibdepsScriptLocation = `${(0, os_1.tmpdir)()}/dpkg-shlibdeps.pl`;
|
||||||
|
const result = (0, child_process_1.spawnSync)('curl', [dpkgShlibdepsUrl, '-o', dpkgShlibdepsScriptLocation]);
|
||||||
|
if (result.status !== 0) {
|
||||||
|
throw new Error('Cannot retrieve dpkg-shlibdeps. Stderr:\n' + result.stderr);
|
||||||
|
}
|
||||||
|
const cmd = [dpkgShlibdepsScriptLocation, '--ignore-weak-undefined'];
|
||||||
|
switch (arch) {
|
||||||
|
case 'amd64':
|
||||||
|
cmd.push(`-l${sysroot}/usr/lib/x86_64-linux-gnu`, `-l${sysroot}/lib/x86_64-linux-gnu`);
|
||||||
|
break;
|
||||||
|
case 'armhf':
|
||||||
|
cmd.push(`-l${sysroot}/usr/lib/arm-linux-gnueabihf`, `-l${sysroot}/lib/arm-linux-gnueabihf`);
|
||||||
|
break;
|
||||||
|
case 'arm64':
|
||||||
|
cmd.push(`-l${sysroot}/usr/lib/aarch64-linux-gnu`, `-l${sysroot}/lib/aarch64-linux-gnu`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cmd.push(`-l${sysroot}/usr/lib`);
|
||||||
|
cmd.push('-O', '-e', path.resolve(binaryPath));
|
||||||
|
const dpkgShlibdepsResult = (0, child_process_1.spawnSync)('perl', cmd, { cwd: sysroot });
|
||||||
|
if (dpkgShlibdepsResult.status !== 0) {
|
||||||
|
throw new Error(`dpkg-shlibdeps failed with exit code ${dpkgShlibdepsResult.status}. stderr:\n${dpkgShlibdepsResult.stderr} `);
|
||||||
|
}
|
||||||
|
const shlibsDependsPrefix = 'shlibs:Depends=';
|
||||||
|
const requiresList = dpkgShlibdepsResult.stdout.toString('utf-8').trimEnd().split('\n');
|
||||||
|
let depsStr = '';
|
||||||
|
for (const line of requiresList) {
|
||||||
|
if (line.startsWith(shlibsDependsPrefix)) {
|
||||||
|
depsStr = line.substring(shlibsDependsPrefix.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Refs https://chromium-review.googlesource.com/c/chromium/src/+/3572926
|
||||||
|
// Chromium depends on libgcc_s, is from the package libgcc1. However, in
|
||||||
|
// Bullseye, the package was renamed to libgcc-s1. To avoid adding a dep
|
||||||
|
// on the newer package, this hack skips the dep. This is safe because
|
||||||
|
// libgcc-s1 is a dependency of libc6. This hack can be removed once
|
||||||
|
// support for Debian Buster and Ubuntu Bionic are dropped.
|
||||||
|
//
|
||||||
|
// Remove kerberos native module related dependencies as the versions
|
||||||
|
// computed from sysroot will not satisfy the minimum supported distros
|
||||||
|
// Refs https://github.com/microsoft/vscode/issues/188881.
|
||||||
|
// TODO(deepak1556): remove this workaround in favor of computing the
|
||||||
|
// versions from build container for native modules.
|
||||||
|
const filteredDeps = depsStr.split(', ').filter(dependency => {
|
||||||
|
return !dependency.startsWith('libgcc-s1') &&
|
||||||
|
!dependency.startsWith('libgssapi-krb5-2') &&
|
||||||
|
!dependency.startsWith('libkrb5-3');
|
||||||
|
}).sort();
|
||||||
|
const requires = new Set(filteredDeps);
|
||||||
|
return requires;
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { spawnSync } from 'child_process';
|
||||||
|
import { constants, statSync } from 'fs';
|
||||||
|
import { tmpdir } from 'os';
|
||||||
|
import path = require('path');
|
||||||
|
import * as manifests from '../../../cgmanifest.json';
|
||||||
|
import { additionalDeps } from './dep-lists';
|
||||||
|
import { DebianArchString } from './types';
|
||||||
|
|
||||||
|
export function generatePackageDeps(files: string[], arch: DebianArchString, sysroot: string): Set<string>[] {
|
||||||
|
const dependencies: Set<string>[] = files.map(file => calculatePackageDeps(file, arch, sysroot));
|
||||||
|
const additionalDepsSet = new Set(additionalDeps);
|
||||||
|
dependencies.push(additionalDepsSet);
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/calculate_package_deps.py.
|
||||||
|
function calculatePackageDeps(binaryPath: string, arch: DebianArchString, sysroot: string): Set<string> {
|
||||||
|
try {
|
||||||
|
if (!(statSync(binaryPath).mode & constants.S_IXUSR)) {
|
||||||
|
throw new Error(`Binary ${binaryPath} needs to have an executable bit set.`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// The package might not exist. Don't re-throw the error here.
|
||||||
|
console.error('Tried to stat ' + binaryPath + ' but failed.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the Chromium dpkg-shlibdeps file.
|
||||||
|
const chromiumManifest = manifests.registrations.filter(registration => {
|
||||||
|
return registration.component.type === 'git' && registration.component.git!.name === 'chromium';
|
||||||
|
});
|
||||||
|
const dpkgShlibdepsUrl = `https://raw.githubusercontent.com/chromium/chromium/${chromiumManifest[0].version}/third_party/dpkg-shlibdeps/dpkg-shlibdeps.pl`;
|
||||||
|
const dpkgShlibdepsScriptLocation = `${tmpdir()}/dpkg-shlibdeps.pl`;
|
||||||
|
const result = spawnSync('curl', [dpkgShlibdepsUrl, '-o', dpkgShlibdepsScriptLocation]);
|
||||||
|
if (result.status !== 0) {
|
||||||
|
throw new Error('Cannot retrieve dpkg-shlibdeps. Stderr:\n' + result.stderr);
|
||||||
|
}
|
||||||
|
const cmd = [dpkgShlibdepsScriptLocation, '--ignore-weak-undefined'];
|
||||||
|
switch (arch) {
|
||||||
|
case 'amd64':
|
||||||
|
cmd.push(`-l${sysroot}/usr/lib/x86_64-linux-gnu`,
|
||||||
|
`-l${sysroot}/lib/x86_64-linux-gnu`);
|
||||||
|
break;
|
||||||
|
case 'armhf':
|
||||||
|
cmd.push(`-l${sysroot}/usr/lib/arm-linux-gnueabihf`,
|
||||||
|
`-l${sysroot}/lib/arm-linux-gnueabihf`);
|
||||||
|
break;
|
||||||
|
case 'arm64':
|
||||||
|
cmd.push(`-l${sysroot}/usr/lib/aarch64-linux-gnu`,
|
||||||
|
`-l${sysroot}/lib/aarch64-linux-gnu`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cmd.push(`-l${sysroot}/usr/lib`);
|
||||||
|
cmd.push('-O', '-e', path.resolve(binaryPath));
|
||||||
|
|
||||||
|
const dpkgShlibdepsResult = spawnSync('perl', cmd, { cwd: sysroot });
|
||||||
|
if (dpkgShlibdepsResult.status !== 0) {
|
||||||
|
throw new Error(`dpkg-shlibdeps failed with exit code ${dpkgShlibdepsResult.status}. stderr:\n${dpkgShlibdepsResult.stderr} `);
|
||||||
|
}
|
||||||
|
|
||||||
|
const shlibsDependsPrefix = 'shlibs:Depends=';
|
||||||
|
const requiresList = dpkgShlibdepsResult.stdout.toString('utf-8').trimEnd().split('\n');
|
||||||
|
let depsStr = '';
|
||||||
|
for (const line of requiresList) {
|
||||||
|
if (line.startsWith(shlibsDependsPrefix)) {
|
||||||
|
depsStr = line.substring(shlibsDependsPrefix.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Refs https://chromium-review.googlesource.com/c/chromium/src/+/3572926
|
||||||
|
// Chromium depends on libgcc_s, is from the package libgcc1. However, in
|
||||||
|
// Bullseye, the package was renamed to libgcc-s1. To avoid adding a dep
|
||||||
|
// on the newer package, this hack skips the dep. This is safe because
|
||||||
|
// libgcc-s1 is a dependency of libc6. This hack can be removed once
|
||||||
|
// support for Debian Buster and Ubuntu Bionic are dropped.
|
||||||
|
//
|
||||||
|
// Remove kerberos native module related dependencies as the versions
|
||||||
|
// computed from sysroot will not satisfy the minimum supported distros
|
||||||
|
// Refs https://github.com/microsoft/vscode/issues/188881.
|
||||||
|
// TODO(deepak1556): remove this workaround in favor of computing the
|
||||||
|
// versions from build container for native modules.
|
||||||
|
const filteredDeps = depsStr.split(', ').filter(dependency => {
|
||||||
|
return !dependency.startsWith('libgcc-s1') &&
|
||||||
|
!dependency.startsWith('libgssapi-krb5-2') &&
|
||||||
|
!dependency.startsWith('libkrb5-3');
|
||||||
|
}).sort();
|
||||||
|
const requires = new Set(filteredDeps);
|
||||||
|
return requires;
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
"use strict";
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.referenceGeneratedDepsByArch = exports.recommendedDeps = exports.additionalDeps = void 0;
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/additional_deps
|
||||||
|
// Additional dependencies not in the dpkg-shlibdeps output.
|
||||||
|
exports.additionalDeps = [
|
||||||
|
'ca-certificates', // Make sure users have SSL certificates.
|
||||||
|
'libgtk-3-0 (>= 3.9.10) | libgtk-4-1',
|
||||||
|
'libnss3 (>= 3.26)',
|
||||||
|
'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', // For Breakpad crash reports.
|
||||||
|
'xdg-utils (>= 1.0.2)', // OS integration
|
||||||
|
];
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/manual_recommends
|
||||||
|
// Dependencies that we can only recommend
|
||||||
|
// for now since some of the older distros don't support them.
|
||||||
|
exports.recommendedDeps = [
|
||||||
|
'libvulkan1' // Move to additionalDeps once support for Trusty and Jessie are dropped.
|
||||||
|
];
|
||||||
|
exports.referenceGeneratedDepsByArch = {
|
||||||
|
'amd64': [
|
||||||
|
'ca-certificates',
|
||||||
|
'libasound2 (>= 1.0.17)',
|
||||||
|
'libatk-bridge2.0-0 (>= 2.5.3)',
|
||||||
|
'libatk1.0-0 (>= 2.2.0)',
|
||||||
|
'libatspi2.0-0 (>= 2.9.90)',
|
||||||
|
'libc6 (>= 2.14)',
|
||||||
|
'libc6 (>= 2.15)',
|
||||||
|
'libc6 (>= 2.17)',
|
||||||
|
'libc6 (>= 2.28)',
|
||||||
|
'libc6 (>= 2.29)',
|
||||||
|
'libc6 (>= 2.4)',
|
||||||
|
'libcairo2 (>= 1.6.0)',
|
||||||
|
'libcups2 (>= 1.6.0)',
|
||||||
|
'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3',
|
||||||
|
'libdbus-1-3 (>= 1.5.12)',
|
||||||
|
'libdrm2 (>= 2.4.75)',
|
||||||
|
'libexpat1 (>= 2.0.1)',
|
||||||
|
'libgbm1 (>= 17.1.0~rc2)',
|
||||||
|
'libglib2.0-0 (>= 2.12.0)',
|
||||||
|
'libglib2.0-0 (>= 2.37.3)',
|
||||||
|
'libgtk-3-0 (>= 3.9.10)',
|
||||||
|
'libgtk-3-0 (>= 3.9.10) | libgtk-4-1',
|
||||||
|
'libnspr4 (>= 2:4.9-2~)',
|
||||||
|
'libnss3 (>= 2:3.30)',
|
||||||
|
'libnss3 (>= 3.26)',
|
||||||
|
'libpango-1.0-0 (>= 1.14.0)',
|
||||||
|
'libsecret-1-0 (>= 0.18)',
|
||||||
|
'libstdc++6 (>= 5)',
|
||||||
|
'libstdc++6 (>= 5.2)',
|
||||||
|
'libstdc++6 (>= 9)',
|
||||||
|
'libx11-6',
|
||||||
|
'libx11-6 (>= 2:1.4.99.1)',
|
||||||
|
'libxcb1 (>= 1.9.2)',
|
||||||
|
'libxcomposite1 (>= 1:0.4.4-1)',
|
||||||
|
'libxdamage1 (>= 1:1.1)',
|
||||||
|
'libxext6',
|
||||||
|
'libxfixes3',
|
||||||
|
'libxkbcommon0 (>= 0.4.1)',
|
||||||
|
'libxkbfile1 (>= 1:1.1.0)',
|
||||||
|
'libxrandr2',
|
||||||
|
'xdg-utils (>= 1.0.2)'
|
||||||
|
],
|
||||||
|
'armhf': [
|
||||||
|
'ca-certificates',
|
||||||
|
'libasound2 (>= 1.0.17)',
|
||||||
|
'libatk-bridge2.0-0 (>= 2.5.3)',
|
||||||
|
'libatk1.0-0 (>= 2.2.0)',
|
||||||
|
'libatspi2.0-0 (>= 2.9.90)',
|
||||||
|
'libc6 (>= 2.15)',
|
||||||
|
'libc6 (>= 2.16)',
|
||||||
|
'libc6 (>= 2.17)',
|
||||||
|
'libc6 (>= 2.4)',
|
||||||
|
'libc6 (>= 2.8)',
|
||||||
|
'libc6 (>= 2.9)',
|
||||||
|
'libcairo2 (>= 1.6.0)',
|
||||||
|
'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3',
|
||||||
|
'libdbus-1-3 (>= 1.5.12)',
|
||||||
|
'libdrm2 (>= 2.4.75)',
|
||||||
|
'libexpat1 (>= 2.0.1)',
|
||||||
|
'libgbm1 (>= 17.1.0~rc2)',
|
||||||
|
'libglib2.0-0 (>= 2.37.3)',
|
||||||
|
'libgssapi-krb5-2',
|
||||||
|
'libgtk-3-0 (>= 3.9.10)',
|
||||||
|
'libgtk-3-0 (>= 3.9.10) | libgtk-4-1',
|
||||||
|
'libkrb5-3',
|
||||||
|
'libnspr4 (>= 2:4.9-2~)',
|
||||||
|
'libnss3 (>= 2:3.30)',
|
||||||
|
'libnss3 (>= 3.26)',
|
||||||
|
'libpango-1.0-0 (>= 1.14.0)',
|
||||||
|
'libstdc++6 (>= 5)',
|
||||||
|
'libstdc++6 (>= 5.2)',
|
||||||
|
'libstdc++6 (>= 6)',
|
||||||
|
'libx11-6',
|
||||||
|
'libx11-6 (>= 2:1.4.99.1)',
|
||||||
|
'libxcb1 (>= 1.9.2)',
|
||||||
|
'libxcomposite1 (>= 1:0.4.4-1)',
|
||||||
|
'libxdamage1 (>= 1:1.1)',
|
||||||
|
'libxext6',
|
||||||
|
'libxfixes3',
|
||||||
|
'libxkbcommon0 (>= 0.4.1)',
|
||||||
|
'libxkbfile1',
|
||||||
|
'libxrandr2',
|
||||||
|
'xdg-utils (>= 1.0.2)'
|
||||||
|
],
|
||||||
|
'arm64': [
|
||||||
|
'ca-certificates',
|
||||||
|
'libasound2 (>= 1.0.17)',
|
||||||
|
'libatk-bridge2.0-0 (>= 2.5.3)',
|
||||||
|
'libatk1.0-0 (>= 2.2.0)',
|
||||||
|
'libatspi2.0-0 (>= 2.9.90)',
|
||||||
|
'libc6 (>= 2.17)',
|
||||||
|
'libcairo2 (>= 1.6.0)',
|
||||||
|
'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3',
|
||||||
|
'libdbus-1-3 (>= 1.0.2)',
|
||||||
|
'libdrm2 (>= 2.4.75)',
|
||||||
|
'libexpat1 (>= 2.0.1)',
|
||||||
|
'libgbm1 (>= 17.1.0~rc2)',
|
||||||
|
'libglib2.0-0 (>= 2.37.3)',
|
||||||
|
'libgssapi-krb5-2',
|
||||||
|
'libgtk-3-0 (>= 3.9.10)',
|
||||||
|
'libgtk-3-0 (>= 3.9.10) | libgtk-4-1',
|
||||||
|
'libkrb5-3',
|
||||||
|
'libnspr4 (>= 2:4.9-2~)',
|
||||||
|
'libnss3 (>= 2:3.30)',
|
||||||
|
'libnss3 (>= 3.26)',
|
||||||
|
'libpango-1.0-0 (>= 1.14.0)',
|
||||||
|
'libstdc++6 (>= 5)',
|
||||||
|
'libstdc++6 (>= 5.2)',
|
||||||
|
'libstdc++6 (>= 6)',
|
||||||
|
'libx11-6',
|
||||||
|
'libx11-6 (>= 2:1.4.99.1)',
|
||||||
|
'libxcb1 (>= 1.9.2)',
|
||||||
|
'libxcomposite1 (>= 1:0.4.4-1)',
|
||||||
|
'libxdamage1 (>= 1:1.1)',
|
||||||
|
'libxext6',
|
||||||
|
'libxfixes3',
|
||||||
|
'libxkbcommon0 (>= 0.4.1)',
|
||||||
|
'libxkbfile1',
|
||||||
|
'libxrandr2',
|
||||||
|
'xdg-utils (>= 1.0.2)'
|
||||||
|
]
|
||||||
|
};
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/additional_deps
|
||||||
|
// Additional dependencies not in the dpkg-shlibdeps output.
|
||||||
|
export const additionalDeps = [
|
||||||
|
'ca-certificates', // Make sure users have SSL certificates.
|
||||||
|
'libgtk-3-0 (>= 3.9.10) | libgtk-4-1',
|
||||||
|
'libnss3 (>= 3.26)',
|
||||||
|
'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', // For Breakpad crash reports.
|
||||||
|
'xdg-utils (>= 1.0.2)', // OS integration
|
||||||
|
];
|
||||||
|
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/manual_recommends
|
||||||
|
// Dependencies that we can only recommend
|
||||||
|
// for now since some of the older distros don't support them.
|
||||||
|
export const recommendedDeps = [
|
||||||
|
'libvulkan1' // Move to additionalDeps once support for Trusty and Jessie are dropped.
|
||||||
|
];
|
||||||
|
|
||||||
|
export const referenceGeneratedDepsByArch = {
|
||||||
|
'amd64': [
|
||||||
|
'ca-certificates',
|
||||||
|
'libasound2 (>= 1.0.17)',
|
||||||
|
'libatk-bridge2.0-0 (>= 2.5.3)',
|
||||||
|
'libatk1.0-0 (>= 2.2.0)',
|
||||||
|
'libatspi2.0-0 (>= 2.9.90)',
|
||||||
|
'libc6 (>= 2.14)',
|
||||||
|
'libc6 (>= 2.15)',
|
||||||
|
'libc6 (>= 2.17)',
|
||||||
|
'libc6 (>= 2.28)',
|
||||||
|
'libc6 (>= 2.29)',
|
||||||
|
'libc6 (>= 2.4)',
|
||||||
|
'libcairo2 (>= 1.6.0)',
|
||||||
|
'libcups2 (>= 1.6.0)',
|
||||||
|
'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3',
|
||||||
|
'libdbus-1-3 (>= 1.5.12)',
|
||||||
|
'libdrm2 (>= 2.4.75)',
|
||||||
|
'libexpat1 (>= 2.0.1)',
|
||||||
|
'libgbm1 (>= 17.1.0~rc2)',
|
||||||
|
'libglib2.0-0 (>= 2.12.0)',
|
||||||
|
'libglib2.0-0 (>= 2.37.3)',
|
||||||
|
'libgtk-3-0 (>= 3.9.10)',
|
||||||
|
'libgtk-3-0 (>= 3.9.10) | libgtk-4-1',
|
||||||
|
'libnspr4 (>= 2:4.9-2~)',
|
||||||
|
'libnss3 (>= 2:3.30)',
|
||||||
|
'libnss3 (>= 3.26)',
|
||||||
|
'libpango-1.0-0 (>= 1.14.0)',
|
||||||
|
'libsecret-1-0 (>= 0.18)',
|
||||||
|
'libstdc++6 (>= 5)',
|
||||||
|
'libstdc++6 (>= 5.2)',
|
||||||
|
'libstdc++6 (>= 9)',
|
||||||
|
'libx11-6',
|
||||||
|
'libx11-6 (>= 2:1.4.99.1)',
|
||||||
|
'libxcb1 (>= 1.9.2)',
|
||||||
|
'libxcomposite1 (>= 1:0.4.4-1)',
|
||||||
|
'libxdamage1 (>= 1:1.1)',
|
||||||
|
'libxext6',
|
||||||
|
'libxfixes3',
|
||||||
|
'libxkbcommon0 (>= 0.4.1)',
|
||||||
|
'libxkbfile1 (>= 1:1.1.0)',
|
||||||
|
'libxrandr2',
|
||||||
|
'xdg-utils (>= 1.0.2)'
|
||||||
|
],
|
||||||
|
'armhf': [
|
||||||
|
'ca-certificates',
|
||||||
|
'libasound2 (>= 1.0.17)',
|
||||||
|
'libatk-bridge2.0-0 (>= 2.5.3)',
|
||||||
|
'libatk1.0-0 (>= 2.2.0)',
|
||||||
|
'libatspi2.0-0 (>= 2.9.90)',
|
||||||
|
'libc6 (>= 2.15)',
|
||||||
|
'libc6 (>= 2.16)',
|
||||||
|
'libc6 (>= 2.17)',
|
||||||
|
'libc6 (>= 2.4)',
|
||||||
|
'libc6 (>= 2.8)',
|
||||||
|
'libc6 (>= 2.9)',
|
||||||
|
'libcairo2 (>= 1.6.0)',
|
||||||
|
'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3',
|
||||||
|
'libdbus-1-3 (>= 1.5.12)',
|
||||||
|
'libdrm2 (>= 2.4.75)',
|
||||||
|
'libexpat1 (>= 2.0.1)',
|
||||||
|
'libgbm1 (>= 17.1.0~rc2)',
|
||||||
|
'libglib2.0-0 (>= 2.37.3)',
|
||||||
|
'libgssapi-krb5-2',
|
||||||
|
'libgtk-3-0 (>= 3.9.10)',
|
||||||
|
'libgtk-3-0 (>= 3.9.10) | libgtk-4-1',
|
||||||
|
'libkrb5-3',
|
||||||
|
'libnspr4 (>= 2:4.9-2~)',
|
||||||
|
'libnss3 (>= 2:3.30)',
|
||||||
|
'libnss3 (>= 3.26)',
|
||||||
|
'libpango-1.0-0 (>= 1.14.0)',
|
||||||
|
'libstdc++6 (>= 5)',
|
||||||
|
'libstdc++6 (>= 5.2)',
|
||||||
|
'libstdc++6 (>= 6)',
|
||||||
|
'libx11-6',
|
||||||
|
'libx11-6 (>= 2:1.4.99.1)',
|
||||||
|
'libxcb1 (>= 1.9.2)',
|
||||||
|
'libxcomposite1 (>= 1:0.4.4-1)',
|
||||||
|
'libxdamage1 (>= 1:1.1)',
|
||||||
|
'libxext6',
|
||||||
|
'libxfixes3',
|
||||||
|
'libxkbcommon0 (>= 0.4.1)',
|
||||||
|
'libxkbfile1',
|
||||||
|
'libxrandr2',
|
||||||
|
'xdg-utils (>= 1.0.2)'
|
||||||
|
],
|
||||||
|
'arm64': [
|
||||||
|
'ca-certificates',
|
||||||
|
'libasound2 (>= 1.0.17)',
|
||||||
|
'libatk-bridge2.0-0 (>= 2.5.3)',
|
||||||
|
'libatk1.0-0 (>= 2.2.0)',
|
||||||
|
'libatspi2.0-0 (>= 2.9.90)',
|
||||||
|
'libc6 (>= 2.17)',
|
||||||
|
'libc6 (>= 2.28)',
|
||||||
|
'libc6 (>= 2.29)',
|
||||||
|
'libcairo2 (>= 1.6.0)',
|
||||||
|
'libcups2 (>= 1.6.0)',
|
||||||
|
'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3',
|
||||||
|
'libdbus-1-3 (>= 1.0.2)',
|
||||||
|
'libdrm2 (>= 2.4.75)',
|
||||||
|
'libexpat1 (>= 2.0.1)',
|
||||||
|
'libgbm1 (>= 17.1.0~rc2)',
|
||||||
|
'libglib2.0-0 (>= 2.12.0)',
|
||||||
|
'libglib2.0-0 (>= 2.37.3)',
|
||||||
|
'libgtk-3-0 (>= 3.9.10)',
|
||||||
|
'libgtk-3-0 (>= 3.9.10) | libgtk-4-1',
|
||||||
|
'libnspr4 (>= 2:4.9-2~)',
|
||||||
|
'libnss3 (>= 2:3.30)',
|
||||||
|
'libnss3 (>= 3.26)',
|
||||||
|
'libpango-1.0-0 (>= 1.14.0)',
|
||||||
|
'libsecret-1-0 (>= 0.18)',
|
||||||
|
'libstdc++6 (>= 5)',
|
||||||
|
'libstdc++6 (>= 5.2)',
|
||||||
|
'libstdc++6 (>= 9)',
|
||||||
|
'libx11-6',
|
||||||
|
'libx11-6 (>= 2:1.4.99.1)',
|
||||||
|
'libxcb1 (>= 1.9.2)',
|
||||||
|
'libxcomposite1 (>= 1:0.4.4-1)',
|
||||||
|
'libxdamage1 (>= 1:1.1)',
|
||||||
|
'libxext6',
|
||||||
|
'libxfixes3',
|
||||||
|
'libxkbcommon0 (>= 0.4.1)',
|
||||||
|
'libxkbfile1 (>= 1:1.1.0)',
|
||||||
|
'libxrandr2',
|
||||||
|
'xdg-utils (>= 1.0.2)'
|
||||||
|
]
|
||||||
|
};
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
'use strict';
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.getDependencies = void 0;
|
||||||
|
const child_process_1 = require("child_process");
|
||||||
|
const path = require("path");
|
||||||
|
const calculate_deps_1 = require("./calculate-deps");
|
||||||
|
const dep_lists_1 = require("./dep-lists");
|
||||||
|
const types_1 = require("./types");
|
||||||
|
// A flag that can easily be toggled.
|
||||||
|
// Make sure to compile the build directory after toggling the value.
|
||||||
|
// If false, we warn about new dependencies if they show up
|
||||||
|
// while running the prepare package tasks for a release.
|
||||||
|
// If true, we fail the build if there are new dependencies found during that task.
|
||||||
|
// The reference dependencies, which one has to update when the new dependencies
|
||||||
|
// are valid, are in dep-lists.ts
|
||||||
|
const FAIL_BUILD_FOR_NEW_DEPENDENCIES = true;
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/114.0.5735.199:chrome/installer/linux/BUILD.gn;l=64-80
|
||||||
|
// and the Linux Archive build
|
||||||
|
// Shared library dependencies that we already bundle.
|
||||||
|
const bundledDeps = [
|
||||||
|
'libEGL.so',
|
||||||
|
'libGLESv2.so',
|
||||||
|
'libvulkan.so.1',
|
||||||
|
'libvk_swiftshader.so',
|
||||||
|
'libffmpeg.so'
|
||||||
|
];
|
||||||
|
function getDependencies(packageType, buildDir, applicationName, arch, sysroot) {
|
||||||
|
if (packageType === 'deb') {
|
||||||
|
if (!(0, types_1.isDebianArchString)(arch)) {
|
||||||
|
throw new Error('Invalid Debian arch string ' + arch);
|
||||||
|
}
|
||||||
|
if (!sysroot) {
|
||||||
|
throw new Error('Missing sysroot parameter');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get the files for which we want to find dependencies.
|
||||||
|
const nativeModulesPath = path.join(buildDir, 'resources', 'app', 'node_modules.asar.unpacked');
|
||||||
|
const findResult = (0, child_process_1.spawnSync)('find', [nativeModulesPath, '-name', '*.node']);
|
||||||
|
if (findResult.status) {
|
||||||
|
console.error('Error finding files:');
|
||||||
|
console.error(findResult.stderr.toString());
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const files = findResult.stdout.toString().trimEnd().split('\n');
|
||||||
|
const appPath = path.join(buildDir, applicationName);
|
||||||
|
files.push(appPath);
|
||||||
|
// Add chrome sandbox and crashpad handler.
|
||||||
|
files.push(path.join(buildDir, 'chrome-sandbox'));
|
||||||
|
files.push(path.join(buildDir, 'chrome_crashpad_handler'));
|
||||||
|
// Generate the dependencies.
|
||||||
|
const dependencies = (0, calculate_deps_1.generatePackageDeps)(files, arch, sysroot);
|
||||||
|
// Merge all the dependencies.
|
||||||
|
const mergedDependencies = mergePackageDeps(dependencies);
|
||||||
|
// Exclude bundled dependencies and sort
|
||||||
|
const sortedDependencies = Array.from(mergedDependencies).filter(dependency => {
|
||||||
|
return !bundledDeps.some(bundledDep => dependency.startsWith(bundledDep));
|
||||||
|
}).sort();
|
||||||
|
const referenceGeneratedDeps = dep_lists_1.referenceGeneratedDepsByArch[arch];
|
||||||
|
if (JSON.stringify(sortedDependencies) !== JSON.stringify(referenceGeneratedDeps)) {
|
||||||
|
const failMessage = 'The dependencies list has changed.'
|
||||||
|
+ '\nOld:\n' + referenceGeneratedDeps.join('\n')
|
||||||
|
+ '\nNew:\n' + sortedDependencies.join('\n');
|
||||||
|
if (FAIL_BUILD_FOR_NEW_DEPENDENCIES) {
|
||||||
|
throw new Error(failMessage);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.warn(failMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sortedDependencies;
|
||||||
|
}
|
||||||
|
exports.getDependencies = getDependencies;
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/merge_package_deps.py.
|
||||||
|
function mergePackageDeps(inputDeps) {
|
||||||
|
const requires = new Set();
|
||||||
|
for (const depSet of inputDeps) {
|
||||||
|
for (const dep of depSet) {
|
||||||
|
const trimmedDependency = dep.trim();
|
||||||
|
if (trimmedDependency.length && !trimmedDependency.startsWith('#')) {
|
||||||
|
requires.add(trimmedDependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return requires;
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import { spawnSync } from 'child_process';
|
||||||
|
import path = require('path');
|
||||||
|
import { generatePackageDeps as generatePackageDepsDebian } from './calculate-deps';
|
||||||
|
import { referenceGeneratedDepsByArch as debianGeneratedDeps } from './dep-lists';
|
||||||
|
import { DebianArchString, isDebianArchString } from './types';
|
||||||
|
|
||||||
|
// A flag that can easily be toggled.
|
||||||
|
// Make sure to compile the build directory after toggling the value.
|
||||||
|
// If false, we warn about new dependencies if they show up
|
||||||
|
// while running the prepare package tasks for a release.
|
||||||
|
// If true, we fail the build if there are new dependencies found during that task.
|
||||||
|
// The reference dependencies, which one has to update when the new dependencies
|
||||||
|
// are valid, are in dep-lists.ts
|
||||||
|
const FAIL_BUILD_FOR_NEW_DEPENDENCIES: boolean = true;
|
||||||
|
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/114.0.5735.199:chrome/installer/linux/BUILD.gn;l=64-80
|
||||||
|
// and the Linux Archive build
|
||||||
|
// Shared library dependencies that we already bundle.
|
||||||
|
const bundledDeps = [
|
||||||
|
'libEGL.so',
|
||||||
|
'libGLESv2.so',
|
||||||
|
'libvulkan.so.1',
|
||||||
|
'libvk_swiftshader.so',
|
||||||
|
'libffmpeg.so'
|
||||||
|
];
|
||||||
|
|
||||||
|
export function getDependencies(packageType: 'deb' | 'rpm', buildDir: string, applicationName: string, arch: string, sysroot?: string): string[] {
|
||||||
|
if (packageType === 'deb') {
|
||||||
|
if (!isDebianArchString(arch)) {
|
||||||
|
throw new Error('Invalid Debian arch string ' + arch);
|
||||||
|
}
|
||||||
|
if (!sysroot) {
|
||||||
|
throw new Error('Missing sysroot parameter');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the files for which we want to find dependencies.
|
||||||
|
const nativeModulesPath = path.join(buildDir, 'resources', 'app', 'node_modules.asar.unpacked');
|
||||||
|
const findResult = spawnSync('find', [nativeModulesPath, '-name', '*.node']);
|
||||||
|
if (findResult.status) {
|
||||||
|
console.error('Error finding files:');
|
||||||
|
console.error(findResult.stderr.toString());
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = findResult.stdout.toString().trimEnd().split('\n');
|
||||||
|
|
||||||
|
const appPath = path.join(buildDir, applicationName);
|
||||||
|
files.push(appPath);
|
||||||
|
|
||||||
|
// Add chrome sandbox and crashpad handler.
|
||||||
|
files.push(path.join(buildDir, 'chrome-sandbox'));
|
||||||
|
files.push(path.join(buildDir, 'chrome_crashpad_handler'));
|
||||||
|
|
||||||
|
// Generate the dependencies.
|
||||||
|
const dependencies = generatePackageDepsDebian(files, arch as DebianArchString, sysroot!);
|
||||||
|
|
||||||
|
// Merge all the dependencies.
|
||||||
|
const mergedDependencies = mergePackageDeps(dependencies);
|
||||||
|
|
||||||
|
// Exclude bundled dependencies and sort
|
||||||
|
const sortedDependencies: string[] = Array.from(mergedDependencies).filter(dependency => {
|
||||||
|
return !bundledDeps.some(bundledDep => dependency.startsWith(bundledDep));
|
||||||
|
}).sort();
|
||||||
|
|
||||||
|
const referenceGeneratedDeps = debianGeneratedDeps[arch as DebianArchString];
|
||||||
|
if (JSON.stringify(sortedDependencies) !== JSON.stringify(referenceGeneratedDeps)) {
|
||||||
|
const failMessage = 'The dependencies list has changed.'
|
||||||
|
+ '\nOld:\n' + referenceGeneratedDeps.join('\n')
|
||||||
|
+ '\nNew:\n' + sortedDependencies.join('\n');
|
||||||
|
if (FAIL_BUILD_FOR_NEW_DEPENDENCIES) {
|
||||||
|
throw new Error(failMessage);
|
||||||
|
} else {
|
||||||
|
console.warn(failMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortedDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/merge_package_deps.py.
|
||||||
|
function mergePackageDeps(inputDeps: Set<string>[]): Set<string> {
|
||||||
|
const requires = new Set<string>();
|
||||||
|
for (const depSet of inputDeps) {
|
||||||
|
for (const dep of depSet) {
|
||||||
|
const trimmedDependency = dep.trim();
|
||||||
|
if (trimmedDependency.length && !trimmedDependency.startsWith('#')) {
|
||||||
|
requires.add(trimmedDependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return requires;
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
"use strict";
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.getSysroot = void 0;
|
||||||
|
const child_process_1 = require("child_process");
|
||||||
|
const crypto_1 = require("crypto");
|
||||||
|
const os_1 = require("os");
|
||||||
|
const fs = require("fs");
|
||||||
|
const https = require("https");
|
||||||
|
const path = require("path");
|
||||||
|
const util = require("../../lib/util");
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/install-sysroot.py.
|
||||||
|
const URL_PREFIX = 'https://msftelectron.blob.core.windows.net';
|
||||||
|
const URL_PATH = 'sysroots/toolchain';
|
||||||
|
function getSha(filename) {
|
||||||
|
const hash = (0, crypto_1.createHash)('sha1');
|
||||||
|
// Read file 1 MB at a time
|
||||||
|
const fd = fs.openSync(filename, 'r');
|
||||||
|
const buffer = Buffer.alloc(1024 * 1024);
|
||||||
|
let position = 0;
|
||||||
|
let bytesRead = 0;
|
||||||
|
while ((bytesRead = fs.readSync(fd, buffer, 0, buffer.length, position)) === buffer.length) {
|
||||||
|
hash.update(buffer);
|
||||||
|
position += bytesRead;
|
||||||
|
}
|
||||||
|
hash.update(buffer.slice(0, bytesRead));
|
||||||
|
return hash.digest('hex');
|
||||||
|
}
|
||||||
|
async function getSysroot(arch) {
|
||||||
|
const sysrootJSONUrl = `https://raw.githubusercontent.com/electron/electron/v${util.getElectronVersion()}/script/sysroots.json`;
|
||||||
|
const sysrootDictLocation = `${(0, os_1.tmpdir)()}/sysroots.json`;
|
||||||
|
const result = (0, child_process_1.spawnSync)('curl', [sysrootJSONUrl, '-o', sysrootDictLocation]);
|
||||||
|
if (result.status !== 0) {
|
||||||
|
throw new Error('Cannot retrieve sysroots.json. Stderr:\n' + result.stderr);
|
||||||
|
}
|
||||||
|
const sysrootInfo = require(sysrootDictLocation);
|
||||||
|
const sysrootArch = arch === 'armhf' ? 'bullseye_arm' : `bullseye_${arch}`;
|
||||||
|
const sysrootDict = sysrootInfo[sysrootArch];
|
||||||
|
const tarballFilename = sysrootDict['Tarball'];
|
||||||
|
const tarballSha = sysrootDict['Sha1Sum'];
|
||||||
|
const sysroot = path.join((0, os_1.tmpdir)(), sysrootDict['SysrootDir']);
|
||||||
|
const url = [URL_PREFIX, URL_PATH, tarballSha, tarballFilename].join('/');
|
||||||
|
const stamp = path.join(sysroot, '.stamp');
|
||||||
|
if (fs.existsSync(stamp) && fs.readFileSync(stamp).toString() === url) {
|
||||||
|
return sysroot;
|
||||||
|
}
|
||||||
|
console.log(`Installing Debian ${arch} root image: ${sysroot}`);
|
||||||
|
fs.rmSync(sysroot, { recursive: true, force: true });
|
||||||
|
fs.mkdirSync(sysroot);
|
||||||
|
const tarball = path.join(sysroot, tarballFilename);
|
||||||
|
console.log(`Downloading ${url}`);
|
||||||
|
let downloadSuccess = false;
|
||||||
|
for (let i = 0; i < 3 && !downloadSuccess; i++) {
|
||||||
|
fs.writeFileSync(tarball, '');
|
||||||
|
await new Promise((c) => {
|
||||||
|
https.get(url, (res) => {
|
||||||
|
res.on('data', (chunk) => {
|
||||||
|
fs.appendFileSync(tarball, chunk);
|
||||||
|
});
|
||||||
|
res.on('end', () => {
|
||||||
|
downloadSuccess = true;
|
||||||
|
c();
|
||||||
|
});
|
||||||
|
}).on('error', (err) => {
|
||||||
|
console.error('Encountered an error during the download attempt: ' + err.message);
|
||||||
|
c();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!downloadSuccess) {
|
||||||
|
fs.rmSync(tarball);
|
||||||
|
throw new Error('Failed to download ' + url);
|
||||||
|
}
|
||||||
|
const sha = getSha(tarball);
|
||||||
|
if (sha !== tarballSha) {
|
||||||
|
throw new Error(`Tarball sha1sum is wrong. Expected ${tarballSha}, actual ${sha}`);
|
||||||
|
}
|
||||||
|
const proc = (0, child_process_1.spawnSync)('tar', ['xf', tarball, '-C', sysroot]);
|
||||||
|
if (proc.status) {
|
||||||
|
throw new Error('Tarball extraction failed with code ' + proc.status);
|
||||||
|
}
|
||||||
|
fs.rmSync(tarball);
|
||||||
|
fs.writeFileSync(stamp, url);
|
||||||
|
return sysroot;
|
||||||
|
}
|
||||||
|
exports.getSysroot = getSysroot;
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { spawnSync } from 'child_process';
|
||||||
|
import { createHash } from 'crypto';
|
||||||
|
import { tmpdir } from 'os';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as https from 'https';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { DebianArchString } from './types';
|
||||||
|
import * as util from '../../lib/util';
|
||||||
|
|
||||||
|
// Based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/install-sysroot.py.
|
||||||
|
const URL_PREFIX = 'https://msftelectron.blob.core.windows.net';
|
||||||
|
const URL_PATH = 'sysroots/toolchain';
|
||||||
|
|
||||||
|
function getSha(filename: fs.PathLike): string {
|
||||||
|
const hash = createHash('sha1');
|
||||||
|
// Read file 1 MB at a time
|
||||||
|
const fd = fs.openSync(filename, 'r');
|
||||||
|
const buffer = Buffer.alloc(1024 * 1024);
|
||||||
|
let position = 0;
|
||||||
|
let bytesRead = 0;
|
||||||
|
while ((bytesRead = fs.readSync(fd, buffer, 0, buffer.length, position)) === buffer.length) {
|
||||||
|
hash.update(buffer);
|
||||||
|
position += bytesRead;
|
||||||
|
}
|
||||||
|
hash.update(buffer.slice(0, bytesRead));
|
||||||
|
return hash.digest('hex');
|
||||||
|
}
|
||||||
|
|
||||||
|
type SysrootDictEntry = {
|
||||||
|
Sha1Sum: string;
|
||||||
|
SysrootDir: string;
|
||||||
|
Tarball: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function getSysroot(arch: DebianArchString): Promise<string> {
|
||||||
|
const sysrootJSONUrl = `https://raw.githubusercontent.com/electron/electron/v${util.getElectronVersion()}/script/sysroots.json`;
|
||||||
|
const sysrootDictLocation = `${tmpdir()}/sysroots.json`;
|
||||||
|
const result = spawnSync('curl', [sysrootJSONUrl, '-o', sysrootDictLocation]);
|
||||||
|
if (result.status !== 0) {
|
||||||
|
throw new Error('Cannot retrieve sysroots.json. Stderr:\n' + result.stderr);
|
||||||
|
}
|
||||||
|
const sysrootInfo = require(sysrootDictLocation);
|
||||||
|
const sysrootArch = arch === 'armhf' ? 'bullseye_arm' : `bullseye_${arch}`;
|
||||||
|
const sysrootDict: SysrootDictEntry = sysrootInfo[sysrootArch];
|
||||||
|
const tarballFilename = sysrootDict['Tarball'];
|
||||||
|
const tarballSha = sysrootDict['Sha1Sum'];
|
||||||
|
const sysroot = path.join(tmpdir(), sysrootDict['SysrootDir']);
|
||||||
|
const url = [URL_PREFIX, URL_PATH, tarballSha, tarballFilename].join('/');
|
||||||
|
const stamp = path.join(sysroot, '.stamp');
|
||||||
|
if (fs.existsSync(stamp) && fs.readFileSync(stamp).toString() === url) {
|
||||||
|
return sysroot;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Installing Debian ${arch} root image: ${sysroot}`);
|
||||||
|
fs.rmSync(sysroot, { recursive: true, force: true });
|
||||||
|
fs.mkdirSync(sysroot);
|
||||||
|
const tarball = path.join(sysroot, tarballFilename);
|
||||||
|
console.log(`Downloading ${url}`);
|
||||||
|
let downloadSuccess = false;
|
||||||
|
for (let i = 0; i < 3 && !downloadSuccess; i++) {
|
||||||
|
fs.writeFileSync(tarball, '');
|
||||||
|
await new Promise<void>((c) => {
|
||||||
|
https.get(url, (res) => {
|
||||||
|
res.on('data', (chunk) => {
|
||||||
|
fs.appendFileSync(tarball, chunk);
|
||||||
|
});
|
||||||
|
res.on('end', () => {
|
||||||
|
downloadSuccess = true;
|
||||||
|
c();
|
||||||
|
});
|
||||||
|
}).on('error', (err) => {
|
||||||
|
console.error('Encountered an error during the download attempt: ' + err.message);
|
||||||
|
c();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!downloadSuccess) {
|
||||||
|
fs.rmSync(tarball);
|
||||||
|
throw new Error('Failed to download ' + url);
|
||||||
|
}
|
||||||
|
const sha = getSha(tarball);
|
||||||
|
if (sha !== tarballSha) {
|
||||||
|
throw new Error(`Tarball sha1sum is wrong. Expected ${tarballSha}, actual ${sha}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const proc = spawnSync('tar', ['xf', tarball, '-C', sysroot]);
|
||||||
|
if (proc.status) {
|
||||||
|
throw new Error('Tarball extraction failed with code ' + proc.status);
|
||||||
|
}
|
||||||
|
fs.rmSync(tarball);
|
||||||
|
fs.writeFileSync(stamp, url);
|
||||||
|
return sysroot;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
"use strict";
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.isDebianArchString = void 0;
|
||||||
|
function isDebianArchString(s) {
|
||||||
|
return ['amd64', 'armhf', 'arm64'].includes(s);
|
||||||
|
}
|
||||||
|
exports.isDebianArchString = isDebianArchString;
|
|
@ -0,0 +1,10 @@
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
export type DebianArchString = 'amd64' | 'armhf' | 'arm64';
|
||||||
|
|
||||||
|
export function isDebianArchString(s: string): s is DebianArchString {
|
||||||
|
return ['amd64', 'armhf', 'arm64'].includes(s);
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
Package: @@NAME@@
|
Package: @@NAME@@
|
||||||
Version: @@VERSION@@
|
Version: @@VERSION@@
|
||||||
Section: devel
|
Section: devel
|
||||||
Depends: libnss3 (>= 2:3.26), gnupg, apt, libxkbfile1, libsecret-1-0, libgtk-3-0 (>= 3.10.0), libxss1, libgbm1
|
Depends: @@DEPENDS@@
|
||||||
|
Recommends: @@RECOMMENDS@@
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Architecture: @@ARCHITECTURE@@
|
Architecture: @@ARCHITECTURE@@
|
||||||
Maintainer: KylinIdeTeam https://gitee.com/openkylin/kylin-code/contributors?ref=master
|
Maintainer: KylinIdeTeam https://gitee.com/openkylin/kylin-code/contributors?ref=master
|
||||||
|
|
Loading…
Reference in New Issue