import { spawnSync } from 'child_process';
import { constants, statSync } from 'fs';
import { tmpdir } from 'os';
import path from 'path';
import manifests from '../../../cgmanifest.json';
import { additionalDeps } from './dep-lists';
import { DebianArchString } from './types';
export function generatePackageDeps(files: string[], arch: DebianArchString, chromiumSysroot: string, vscodeSysroot: string): Set<string>[] {
const dependencies: Set<string>[] = files.map(file => calculatePackageDeps(file, arch, chromiumSysroot, vscodeSysroot));
const additionalDepsSet = new Set(additionalDeps);
dependencies.push(additionalDepsSet);
return dependencies;
}
function calculatePackageDeps(binaryPath: string, arch: DebianArchString, chromiumSysroot: string, vscodeSysroot: 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) {
console.error('Tried to stat ' + binaryPath + ' but failed.');
}
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${chromiumSysroot}/usr/lib/x86_64-linux-gnu`,
`-l${chromiumSysroot}/lib/x86_64-linux-gnu`,
`-l${vscodeSysroot}/usr/lib/x86_64-linux-gnu`,
`-l${vscodeSysroot}/lib/x86_64-linux-gnu`);
break;
case 'armhf':
cmd.push(`-l${chromiumSysroot}/usr/lib/arm-linux-gnueabihf`,
`-l${chromiumSysroot}/lib/arm-linux-gnueabihf`,
`-l${vscodeSysroot}/usr/lib/arm-linux-gnueabihf`,
`-l${vscodeSysroot}/lib/arm-linux-gnueabihf`);
break;
case 'arm64':
cmd.push(`-l${chromiumSysroot}/usr/lib/aarch64-linux-gnu`,
`-l${chromiumSysroot}/lib/aarch64-linux-gnu`,
`-l${vscodeSysroot}/usr/lib/aarch64-linux-gnu`,
`-l${vscodeSysroot}/lib/aarch64-linux-gnu`);
break;
}
cmd.push(`-l${chromiumSysroot}/usr/lib`);
cmd.push(`-L${vscodeSysroot}/debian/libxkbfile1/DEBIAN/shlibs`);
cmd.push('-O', '-e', path.resolve(binaryPath));
const dpkgShlibdepsResult = spawnSync('perl', cmd, { cwd: chromiumSysroot });
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);
}
}
const filteredDeps = depsStr.split(', ').filter(dependency => {
return !dependency.startsWith('libgcc-s1');
}).sort();
const requires = new Set(filteredDeps);
return requires;
}