2020-07-15 15:24:38 -07:00
|
|
|
/**
|
|
|
|
* Copyright (c) Microsoft Corporation.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
2021-07-01 16:17:59 -07:00
|
|
|
|
2021-02-11 06:36:15 -08:00
|
|
|
import fs from 'fs';
|
|
|
|
import path from 'path';
|
2020-07-15 15:24:38 -07:00
|
|
|
import * as os from 'os';
|
2021-07-01 17:14:04 -07:00
|
|
|
import childProcess from 'child_process';
|
2021-07-01 16:17:59 -07:00
|
|
|
import { getUbuntuVersion } from './ubuntuVersion';
|
|
|
|
import * as utils from './utils';
|
2021-10-27 18:58:13 +02:00
|
|
|
import { buildPlaywrightCLICommand } from './registry';
|
2020-07-15 15:24:38 -07:00
|
|
|
|
2021-10-29 20:12:46 +02:00
|
|
|
const BIN_DIRECTORY = path.join(__dirname, '..', '..', 'bin');
|
|
|
|
|
2021-06-03 09:55:33 -07:00
|
|
|
const checkExecutable = (filePath: string) => fs.promises.access(filePath, fs.constants.X_OK).then(() => true).catch(e => false);
|
2020-07-15 15:24:38 -07:00
|
|
|
|
2020-12-14 16:40:51 -08:00
|
|
|
function isSupportedWindowsVersion(): boolean {
|
|
|
|
if (os.platform() !== 'win32' || os.arch() !== 'x64')
|
|
|
|
return false;
|
|
|
|
const [major, minor] = os.release().split('.').map(token => parseInt(token, 10));
|
|
|
|
// This is based on: https://stackoverflow.com/questions/42524606/how-to-get-windows-version-using-node-js/44916050#44916050
|
|
|
|
// The table with versions is taken from: https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexw#remarks
|
|
|
|
// Windows 7 is not supported and is encoded as `6.1`.
|
|
|
|
return major > 6 || (major === 6 && minor > 1);
|
2020-07-30 17:15:46 -07:00
|
|
|
}
|
|
|
|
|
2021-07-13 19:03:49 -07:00
|
|
|
export type DependencyGroup = 'chromium' | 'firefox' | 'webkit' | 'tools';
|
|
|
|
|
|
|
|
export async function installDependenciesWindows(targets: Set<DependencyGroup>) {
|
2021-10-29 20:12:46 +02:00
|
|
|
if (targets.has('chromium')) {
|
|
|
|
const { code } = await utils.spawnAsync('powershell.exe', ['-File', path.join(BIN_DIRECTORY, 'install_media_pack.ps1')], { cwd: BIN_DIRECTORY, stdio: 'inherit' });
|
|
|
|
if (code !== 0)
|
|
|
|
throw new Error('Failed to install windows dependencies!');
|
2021-07-01 17:14:04 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-13 19:03:49 -07:00
|
|
|
export async function installDependenciesLinux(targets: Set<DependencyGroup>) {
|
2021-07-01 17:14:04 -07:00
|
|
|
const ubuntuVersion = await getUbuntuVersion();
|
|
|
|
if (ubuntuVersion !== '18.04' && ubuntuVersion !== '20.04' && ubuntuVersion !== '21.04') {
|
|
|
|
console.warn('Cannot install dependencies for this linux distribution!'); // eslint-disable-line no-console
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const libraries: string[] = [];
|
|
|
|
const { deps } = require('../nativeDeps');
|
|
|
|
for (const target of targets) {
|
|
|
|
if (ubuntuVersion === '18.04')
|
|
|
|
libraries.push(...deps['bionic'][target]);
|
|
|
|
else if (ubuntuVersion === '20.04')
|
|
|
|
libraries.push(...deps['focal'][target]);
|
|
|
|
else if (ubuntuVersion === '21.04')
|
|
|
|
libraries.push(...deps['hirsute'][target]);
|
|
|
|
}
|
|
|
|
const uniqueLibraries = Array.from(new Set(libraries));
|
|
|
|
console.log('Installing Ubuntu dependencies...'); // eslint-disable-line no-console
|
|
|
|
const commands: string[] = [];
|
|
|
|
commands.push('apt-get update');
|
|
|
|
commands.push(['apt-get', 'install', '-y', '--no-install-recommends',
|
|
|
|
...uniqueLibraries,
|
|
|
|
].join(' '));
|
2021-09-14 14:09:37 +02:00
|
|
|
const [command, args] = await buildAptProcessArgs(commands);
|
|
|
|
const child = childProcess.spawn(command, args, { stdio: 'inherit' });
|
|
|
|
await new Promise((resolve, reject) => {
|
|
|
|
child.on('exit', resolve);
|
|
|
|
child.on('error', reject);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
async function buildAptProcessArgs(commands: string[]): Promise<[string, string[]]> {
|
|
|
|
const isRoot = process.getuid() === 0;
|
|
|
|
if (isRoot)
|
|
|
|
return ['sh', ['-c', `${commands.join('&& ')}`]];
|
|
|
|
const sudoExists = await utils.spawnAsync('which', ['sudo']);
|
|
|
|
if (sudoExists.code === 0)
|
|
|
|
return ['sudo', ['--', 'sh', '-c', `${commands.join('&& ')}`]];
|
|
|
|
return ['su', ['root', '-c', `${commands.join('&& ')}`]];
|
2021-07-01 17:14:04 -07:00
|
|
|
}
|
|
|
|
|
2021-07-01 16:17:59 -07:00
|
|
|
export async function validateDependenciesWindows(windowsExeAndDllDirectories: string[]) {
|
|
|
|
const directoryPaths = windowsExeAndDllDirectories;
|
2020-07-30 17:15:46 -07:00
|
|
|
const lddPaths: string[] = [];
|
|
|
|
for (const directoryPath of directoryPaths)
|
|
|
|
lddPaths.push(...(await executablesOrSharedLibraries(directoryPath)));
|
|
|
|
const allMissingDeps = await Promise.all(lddPaths.map(lddPath => missingFileDependenciesWindows(lddPath)));
|
|
|
|
const missingDeps: Set<string> = new Set();
|
|
|
|
for (const deps of allMissingDeps) {
|
|
|
|
for (const dep of deps)
|
|
|
|
missingDeps.add(dep);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!missingDeps.size)
|
2020-07-15 15:24:38 -07:00
|
|
|
return;
|
2020-07-30 17:15:46 -07:00
|
|
|
|
|
|
|
let isCrtMissing = false;
|
|
|
|
let isMediaFoundationMissing = false;
|
|
|
|
for (const dep of missingDeps) {
|
2021-01-11 15:01:29 -08:00
|
|
|
if (dep.startsWith('api-ms-win-crt') || dep === 'vcruntime140.dll' || dep === 'vcruntime140_1.dll' || dep === 'msvcp140.dll')
|
2020-07-30 17:15:46 -07:00
|
|
|
isCrtMissing = true;
|
2020-07-31 14:11:11 -07:00
|
|
|
else if (dep === 'mf.dll' || dep === 'mfplat.dll' || dep === 'msmpeg2vdec.dll' || dep === 'evr.dll' || dep === 'avrt.dll')
|
2020-07-30 17:15:46 -07:00
|
|
|
isMediaFoundationMissing = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
const details = [];
|
|
|
|
|
|
|
|
if (isCrtMissing) {
|
|
|
|
details.push(
|
|
|
|
`Some of the Universal C Runtime files cannot be found on the system. You can fix`,
|
|
|
|
`that by installing Microsoft Visual C++ Redistributable for Visual Studio from:`,
|
|
|
|
`https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads`,
|
|
|
|
``);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isMediaFoundationMissing) {
|
|
|
|
details.push(
|
|
|
|
`Some of the Media Foundation files cannot be found on the system. If you are`,
|
|
|
|
`on Windows Server try fixing this by running the following command in PowerShell`,
|
|
|
|
`as Administrator:`,
|
|
|
|
``,
|
|
|
|
` Install-WindowsFeature Server-Media-Foundation`,
|
2020-09-11 01:36:08 +02:00
|
|
|
``,
|
|
|
|
`For Windows N editions visit:`,
|
|
|
|
`https://support.microsoft.com/en-us/help/3145500/media-feature-pack-list-for-windows-n-editions`,
|
2020-07-30 17:15:46 -07:00
|
|
|
``);
|
|
|
|
}
|
|
|
|
|
|
|
|
details.push(
|
|
|
|
`Full list of missing libraries:`,
|
|
|
|
` ${[...missingDeps].join('\n ')}`,
|
|
|
|
``);
|
|
|
|
|
2020-12-14 16:40:51 -08:00
|
|
|
const message = `Host system is missing dependencies!\n\n${details.join('\n')}`;
|
|
|
|
if (isSupportedWindowsVersion()) {
|
|
|
|
throw new Error(message);
|
|
|
|
} else {
|
|
|
|
console.warn(`WARNING: running on unsupported windows version!`);
|
|
|
|
console.warn(message);
|
|
|
|
}
|
2020-07-30 17:15:46 -07:00
|
|
|
}
|
|
|
|
|
2021-10-27 18:58:13 +02:00
|
|
|
export async function validateDependenciesLinux(sdkLanguage: string, linuxLddDirectories: string[], dlOpenLibraries: string[]) {
|
2021-07-01 16:17:59 -07:00
|
|
|
const directoryPaths = linuxLddDirectories;
|
2020-07-15 15:24:38 -07:00
|
|
|
const lddPaths: string[] = [];
|
|
|
|
for (const directoryPath of directoryPaths)
|
|
|
|
lddPaths.push(...(await executablesOrSharedLibraries(directoryPath)));
|
2020-11-09 16:47:15 -08:00
|
|
|
const allMissingDeps = await Promise.all(lddPaths.map(lddPath => missingFileDependencies(lddPath, directoryPaths)));
|
2020-07-17 16:50:20 -07:00
|
|
|
const missingDeps: Set<string> = new Set();
|
2020-07-15 15:24:38 -07:00
|
|
|
for (const deps of allMissingDeps) {
|
|
|
|
for (const dep of deps)
|
|
|
|
missingDeps.add(dep);
|
|
|
|
}
|
2021-07-01 16:17:59 -07:00
|
|
|
for (const dep of (await missingDLOPENLibraries(dlOpenLibraries)))
|
2020-07-29 09:58:45 -07:00
|
|
|
missingDeps.add(dep);
|
2020-07-15 15:24:38 -07:00
|
|
|
if (!missingDeps.size)
|
|
|
|
return;
|
2020-07-17 16:50:20 -07:00
|
|
|
// Check Ubuntu version.
|
|
|
|
const missingPackages = new Set();
|
|
|
|
|
|
|
|
const ubuntuVersion = await getUbuntuVersion();
|
2020-07-24 16:15:42 -07:00
|
|
|
let libraryToPackageNameMapping = null;
|
|
|
|
if (ubuntuVersion === '18.04')
|
|
|
|
libraryToPackageNameMapping = LIBRARY_TO_PACKAGE_NAME_UBUNTU_18_04;
|
|
|
|
else if (ubuntuVersion === '20.04')
|
|
|
|
libraryToPackageNameMapping = LIBRARY_TO_PACKAGE_NAME_UBUNTU_20_04;
|
2021-05-06 10:37:06 -07:00
|
|
|
else if (ubuntuVersion === '21.04')
|
|
|
|
libraryToPackageNameMapping = LIBRARY_TO_PACKAGE_NAME_UBUNTU_21_04;
|
2020-09-01 16:29:38 -07:00
|
|
|
libraryToPackageNameMapping = Object.assign({}, libraryToPackageNameMapping, MANUAL_LIBRARY_TO_PACKAGE_NAME_UBUNTU);
|
2020-07-24 16:15:42 -07:00
|
|
|
if (libraryToPackageNameMapping) {
|
2020-07-17 16:50:20 -07:00
|
|
|
// Translate missing dependencies to package names to install with apt.
|
|
|
|
for (const missingDep of missingDeps) {
|
2020-07-24 16:15:42 -07:00
|
|
|
const packageName = libraryToPackageNameMapping[missingDep];
|
2020-07-17 16:50:20 -07:00
|
|
|
if (packageName) {
|
|
|
|
missingPackages.add(packageName);
|
|
|
|
missingDeps.delete(missingDep);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-19 13:54:42 +03:00
|
|
|
const maybeSudo = (process.getuid() !== 0) && os.platform() !== 'win32' ? 'sudo ' : '';
|
|
|
|
// Happy path: known dependencies are missing for browsers.
|
|
|
|
// Suggest installation with a Playwright CLI.
|
|
|
|
if (missingPackages.size && !missingDeps.size) {
|
|
|
|
throw new Error('\n' + utils.wrapInASCIIBox([
|
|
|
|
`Host system is missing a few dependencies to run browsers.`,
|
|
|
|
`Please install them with the following command:`,
|
|
|
|
``,
|
2021-10-27 18:58:13 +02:00
|
|
|
` ${maybeSudo}${buildPlaywrightCLICommand(sdkLanguage, 'install-deps')}`,
|
2021-07-19 13:54:42 +03:00
|
|
|
``,
|
|
|
|
`<3 Playwright Team`,
|
|
|
|
].join('\n'), 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unhappy path - unusual distribution configuration.
|
2020-07-17 16:50:20 -07:00
|
|
|
let missingPackagesMessage = '';
|
|
|
|
if (missingPackages.size) {
|
|
|
|
missingPackagesMessage = [
|
|
|
|
` Install missing packages with:`,
|
2021-07-19 13:54:42 +03:00
|
|
|
` ${maybeSudo}apt-get install ${[...missingPackages].join('\\\n ')}`,
|
2020-07-17 16:50:20 -07:00
|
|
|
``,
|
|
|
|
``,
|
|
|
|
].join('\n');
|
|
|
|
}
|
|
|
|
|
|
|
|
let missingDependenciesMessage = '';
|
|
|
|
if (missingDeps.size) {
|
|
|
|
const header = missingPackages.size ? `Missing libraries we didn't find packages for:` : `Missing libraries are:`;
|
|
|
|
missingDependenciesMessage = [
|
|
|
|
` ${header}`,
|
|
|
|
` ${[...missingDeps].join('\n ')}`,
|
|
|
|
``,
|
|
|
|
].join('\n');
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error('Host system is missing dependencies!\n\n' + missingPackagesMessage + missingDependenciesMessage);
|
2020-07-15 15:24:38 -07:00
|
|
|
}
|
|
|
|
|
2020-07-30 17:15:46 -07:00
|
|
|
function isSharedLib(basename: string) {
|
|
|
|
switch (os.platform()) {
|
|
|
|
case 'linux':
|
|
|
|
return basename.endsWith('.so') || basename.includes('.so.');
|
|
|
|
case 'win32':
|
|
|
|
return basename.endsWith('.dll');
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-15 15:24:38 -07:00
|
|
|
async function executablesOrSharedLibraries(directoryPath: string): Promise<string[]> {
|
2021-06-03 09:55:33 -07:00
|
|
|
const allPaths = (await fs.promises.readdir(directoryPath)).map(file => path.resolve(directoryPath, file));
|
|
|
|
const allStats = await Promise.all(allPaths.map(aPath => fs.promises.stat(aPath)));
|
2021-02-09 09:00:00 -08:00
|
|
|
const filePaths = allPaths.filter((aPath, index) => (allStats[index] as any).isFile());
|
2020-07-15 15:24:38 -07:00
|
|
|
|
|
|
|
const executablersOrLibraries = (await Promise.all(filePaths.map(async filePath => {
|
|
|
|
const basename = path.basename(filePath).toLowerCase();
|
2020-07-30 17:15:46 -07:00
|
|
|
if (isSharedLib(basename))
|
2020-07-15 15:24:38 -07:00
|
|
|
return filePath;
|
|
|
|
if (await checkExecutable(filePath))
|
|
|
|
return filePath;
|
|
|
|
return false;
|
|
|
|
}))).filter(Boolean);
|
|
|
|
|
|
|
|
return executablersOrLibraries as string[];
|
|
|
|
}
|
|
|
|
|
2020-07-30 17:15:46 -07:00
|
|
|
async function missingFileDependenciesWindows(filePath: string): Promise<Array<string>> {
|
2021-07-01 16:17:59 -07:00
|
|
|
const executable = path.join(__dirname, '..', '..', 'bin', 'PrintDeps.exe');
|
2020-07-30 17:15:46 -07:00
|
|
|
const dirname = path.dirname(filePath);
|
2021-09-27 18:58:08 +02:00
|
|
|
const { stdout, code } = await utils.spawnAsync(executable, [filePath], {
|
2020-07-30 17:15:46 -07:00
|
|
|
cwd: dirname,
|
|
|
|
env: {
|
|
|
|
...process.env,
|
|
|
|
LD_LIBRARY_PATH: process.env.LD_LIBRARY_PATH ? `${process.env.LD_LIBRARY_PATH}:${dirname}` : dirname,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
if (code !== 0)
|
|
|
|
return [];
|
2020-09-11 01:36:08 +02:00
|
|
|
const missingDeps = stdout.split('\n').map(line => line.trim()).filter(line => line.endsWith('not found') && line.includes('=>')).map(line => line.split('=>')[0].trim().toLowerCase());
|
2020-07-30 17:15:46 -07:00
|
|
|
return missingDeps;
|
|
|
|
}
|
|
|
|
|
2020-11-09 16:47:15 -08:00
|
|
|
async function missingFileDependencies(filePath: string, extraLDPaths: string[]): Promise<Array<string>> {
|
2020-07-15 15:24:38 -07:00
|
|
|
const dirname = path.dirname(filePath);
|
2020-11-09 16:47:15 -08:00
|
|
|
let LD_LIBRARY_PATH = extraLDPaths.join(':');
|
|
|
|
if (process.env.LD_LIBRARY_PATH)
|
|
|
|
LD_LIBRARY_PATH = `${process.env.LD_LIBRARY_PATH}:${LD_LIBRARY_PATH}`;
|
2021-09-27 18:58:08 +02:00
|
|
|
const { stdout, code } = await utils.spawnAsync('ldd', [filePath], {
|
2020-07-15 15:24:38 -07:00
|
|
|
cwd: dirname,
|
|
|
|
env: {
|
|
|
|
...process.env,
|
2020-11-09 16:47:15 -08:00
|
|
|
LD_LIBRARY_PATH,
|
2020-07-15 15:24:38 -07:00
|
|
|
},
|
|
|
|
});
|
2020-07-29 09:58:45 -07:00
|
|
|
if (code !== 0)
|
|
|
|
return [];
|
2020-11-09 16:47:15 -08:00
|
|
|
const missingDeps = stdout.split('\n').map(line => line.trim()).filter(line => line.endsWith('not found') && line.includes('=>')).map(line => line.split('=>')[0].trim());
|
2020-07-29 09:58:45 -07:00
|
|
|
return missingDeps;
|
|
|
|
}
|
|
|
|
|
2021-07-01 16:17:59 -07:00
|
|
|
async function missingDLOPENLibraries(libraries: string[]): Promise<string[]> {
|
2020-07-29 09:58:45 -07:00
|
|
|
if (!libraries.length)
|
|
|
|
return [];
|
2020-08-13 11:39:50 -07:00
|
|
|
// NOTE: Using full-qualified path to `ldconfig` since `/sbin` is not part of the
|
|
|
|
// default PATH in CRON.
|
|
|
|
// @see https://github.com/microsoft/playwright/issues/3397
|
2021-09-27 18:58:08 +02:00
|
|
|
const { stdout, code, error } = await utils.spawnAsync('/sbin/ldconfig', ['-p'], {});
|
2020-08-12 08:47:41 -07:00
|
|
|
if (code !== 0 || error)
|
2020-07-29 09:58:45 -07:00
|
|
|
return [];
|
|
|
|
const isLibraryAvailable = (library: string) => stdout.toLowerCase().includes(library.toLowerCase());
|
|
|
|
return libraries.filter(library => !isLibraryAvailable(library));
|
|
|
|
}
|
|
|
|
|
2020-07-29 10:40:33 -07:00
|
|
|
// This list is generted with the following program:
|
|
|
|
// ./utils/linux-browser-dependencies/run.sh ubuntu:18.04
|
2020-07-17 16:50:20 -07:00
|
|
|
const LIBRARY_TO_PACKAGE_NAME_UBUNTU_18_04: { [s: string]: string} = {
|
|
|
|
'libasound.so.2': 'libasound2',
|
|
|
|
'libatk-1.0.so.0': 'libatk1.0-0',
|
|
|
|
'libatk-bridge-2.0.so.0': 'libatk-bridge2.0-0',
|
|
|
|
'libatspi.so.0': 'libatspi2.0-0',
|
|
|
|
'libbrotlidec.so.1': 'libbrotli1',
|
|
|
|
'libcairo-gobject.so.2': 'libcairo-gobject2',
|
|
|
|
'libcairo.so.2': 'libcairo2',
|
|
|
|
'libcups.so.2': 'libcups2',
|
|
|
|
'libdbus-1.so.3': 'libdbus-1-3',
|
|
|
|
'libdbus-glib-1.so.2': 'libdbus-glib-1-2',
|
|
|
|
'libdrm.so.2': 'libdrm2',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libEGL.so.1': 'libegl1',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libenchant.so.1': 'libenchant1c2a',
|
|
|
|
'libepoxy.so.0': 'libepoxy0',
|
2020-11-09 16:47:15 -08:00
|
|
|
'libevent-2.1.so.6': 'libevent-2.1-6',
|
2021-07-14 20:20:03 -07:00
|
|
|
'libevdev.so.2': 'libevdev2',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libfontconfig.so.1': 'libfontconfig1',
|
|
|
|
'libfreetype.so.6': 'libfreetype6',
|
|
|
|
'libgbm.so.1': 'libgbm1',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libgdk_pixbuf-2.0.so.0': 'libgdk-pixbuf2.0-0',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libgdk-3.so.0': 'libgtk-3-0',
|
|
|
|
'libgdk-x11-2.0.so.0': 'libgtk2.0-0',
|
|
|
|
'libgio-2.0.so.0': 'libglib2.0-0',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libGL.so.1': 'libgl1',
|
|
|
|
'libGLESv2.so.2': 'libgles2',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libglib-2.0.so.0': 'libglib2.0-0',
|
|
|
|
'libgmodule-2.0.so.0': 'libglib2.0-0',
|
|
|
|
'libgobject-2.0.so.0': 'libglib2.0-0',
|
2021-03-11 20:22:50 -08:00
|
|
|
'libgstapp-1.0.so.0': 'gstreamer1.0-plugins-base',
|
|
|
|
'libgstaudio-1.0.so.0': 'gstreamer1.0-plugins-base',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libgstbase-1.0.so.0': 'libgstreamer1.0-0',
|
2021-03-11 20:22:50 -08:00
|
|
|
'libgstcodecparsers-1.0.so.0': 'gstreamer1.0-plugins-bad',
|
|
|
|
'libgstfft-1.0.so.0': 'gstreamer1.0-plugins-base',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libgstgl-1.0.so.0': 'libgstreamer-gl1.0-0',
|
2021-03-11 20:22:50 -08:00
|
|
|
'libgstpbutils-1.0.so.0': 'gstreamer1.0-plugins-base',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libgstreamer-1.0.so.0': 'libgstreamer1.0-0',
|
2021-03-11 20:22:50 -08:00
|
|
|
'libgsttag-1.0.so.0': 'gstreamer1.0-plugins-base',
|
|
|
|
'libgstvideo-1.0.so.0': 'gstreamer1.0-plugins-base',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libgthread-2.0.so.0': 'libglib2.0-0',
|
|
|
|
'libgtk-3.so.0': 'libgtk-3-0',
|
|
|
|
'libgtk-x11-2.0.so.0': 'libgtk2.0-0',
|
|
|
|
'libharfbuzz-icu.so.0': 'libharfbuzz-icu0',
|
|
|
|
'libharfbuzz.so.0': 'libharfbuzz0b',
|
|
|
|
'libhyphen.so.0': 'libhyphen0',
|
2020-11-09 16:47:15 -08:00
|
|
|
'libicudata.so.60': 'libicu60',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libicui18n.so.60': 'libicu60',
|
|
|
|
'libicuuc.so.60': 'libicu60',
|
|
|
|
'libjpeg.so.8': 'libjpeg-turbo8',
|
|
|
|
'libnotify.so.4': 'libnotify4',
|
|
|
|
'libnspr4.so': 'libnspr4',
|
|
|
|
'libnss3.so': 'libnss3',
|
|
|
|
'libnssutil3.so': 'libnss3',
|
|
|
|
'libopenjp2.so.7': 'libopenjp2-7',
|
|
|
|
'libopus.so.0': 'libopus0',
|
|
|
|
'libpango-1.0.so.0': 'libpango-1.0-0',
|
|
|
|
'libpangocairo-1.0.so.0': 'libpangocairo-1.0-0',
|
|
|
|
'libpangoft2-1.0.so.0': 'libpangoft2-1.0-0',
|
|
|
|
'libpng16.so.16': 'libpng16-16',
|
|
|
|
'libsecret-1.so.0': 'libsecret-1-0',
|
|
|
|
'libsmime3.so': 'libnss3',
|
2020-07-27 10:39:45 -07:00
|
|
|
'libvpx.so.5': 'libvpx5',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libwayland-client.so.0': 'libwayland-client0',
|
|
|
|
'libwayland-egl.so.1': 'libwayland-egl1',
|
|
|
|
'libwayland-server.so.0': 'libwayland-server0',
|
|
|
|
'libwebp.so.6': 'libwebp6',
|
|
|
|
'libwebpdemux.so.2': 'libwebpdemux2',
|
|
|
|
'libwoff2dec.so.1.0.2': 'libwoff1',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libX11-xcb.so.1': 'libx11-xcb1',
|
|
|
|
'libX11.so.6': 'libx11-6',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libxcb-dri3.so.0': 'libxcb-dri3-0',
|
|
|
|
'libxcb-shm.so.0': 'libxcb-shm0',
|
|
|
|
'libxcb.so.1': 'libxcb1',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libXcomposite.so.1': 'libxcomposite1',
|
|
|
|
'libXcursor.so.1': 'libxcursor1',
|
|
|
|
'libXdamage.so.1': 'libxdamage1',
|
|
|
|
'libXext.so.6': 'libxext6',
|
|
|
|
'libXfixes.so.3': 'libxfixes3',
|
|
|
|
'libXi.so.6': 'libxi6',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libxkbcommon.so.0': 'libxkbcommon0',
|
|
|
|
'libxml2.so.2': 'libxml2',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libXrandr.so.2': 'libxrandr2',
|
|
|
|
'libXrender.so.1': 'libxrender1',
|
2020-07-17 16:50:20 -07:00
|
|
|
'libxslt.so.1': 'libxslt1.1',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libXt.so.6': 'libxt6',
|
|
|
|
'libXtst.so.6': 'libxtst6',
|
2020-07-17 16:50:20 -07:00
|
|
|
};
|
|
|
|
|
2020-07-29 10:40:33 -07:00
|
|
|
// This list is generted with the following program:
|
|
|
|
// ./utils/linux-browser-dependencies/run.sh ubuntu:20.04
|
2020-07-24 16:15:42 -07:00
|
|
|
const LIBRARY_TO_PACKAGE_NAME_UBUNTU_20_04: { [s: string]: string} = {
|
2020-07-29 10:40:33 -07:00
|
|
|
'libasound.so.2': 'libasound2',
|
|
|
|
'libatk-1.0.so.0': 'libatk1.0-0',
|
|
|
|
'libatk-bridge-2.0.so.0': 'libatk-bridge2.0-0',
|
|
|
|
'libatspi.so.0': 'libatspi2.0-0',
|
|
|
|
'libcairo-gobject.so.2': 'libcairo-gobject2',
|
|
|
|
'libcairo.so.2': 'libcairo2',
|
|
|
|
'libcups.so.2': 'libcups2',
|
|
|
|
'libdbus-1.so.3': 'libdbus-1-3',
|
|
|
|
'libdbus-glib-1.so.2': 'libdbus-glib-1-2',
|
|
|
|
'libdrm.so.2': 'libdrm2',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libEGL.so.1': 'libegl1',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libenchant.so.1': 'libenchant1c2a',
|
2021-08-04 23:36:27 +02:00
|
|
|
'libevdev.so.2': 'libevdev2',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libepoxy.so.0': 'libepoxy0',
|
|
|
|
'libfontconfig.so.1': 'libfontconfig1',
|
|
|
|
'libfreetype.so.6': 'libfreetype6',
|
|
|
|
'libgbm.so.1': 'libgbm1',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libgdk_pixbuf-2.0.so.0': 'libgdk-pixbuf2.0-0',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libgdk-3.so.0': 'libgtk-3-0',
|
|
|
|
'libgdk-x11-2.0.so.0': 'libgtk2.0-0',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libgio-2.0.so.0': 'libglib2.0-0',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libGL.so.1': 'libgl1',
|
|
|
|
'libGLESv2.so.2': 'libgles2',
|
|
|
|
'libglib-2.0.so.0': 'libglib2.0-0',
|
|
|
|
'libgmodule-2.0.so.0': 'libglib2.0-0',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libgobject-2.0.so.0': 'libglib2.0-0',
|
2021-03-11 20:22:50 -08:00
|
|
|
'libgstapp-1.0.so.0': 'gstreamer1.0-plugins-base',
|
|
|
|
'libgstaudio-1.0.so.0': 'gstreamer1.0-plugins-base',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libgstbase-1.0.so.0': 'libgstreamer1.0-0',
|
2021-03-11 20:22:50 -08:00
|
|
|
'libgstcodecparsers-1.0.so.0': 'gstreamer1.0-plugins-bad',
|
|
|
|
'libgstfft-1.0.so.0': 'gstreamer1.0-plugins-base',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libgstgl-1.0.so.0': 'libgstreamer-gl1.0-0',
|
2021-03-11 20:22:50 -08:00
|
|
|
'libgstpbutils-1.0.so.0': 'gstreamer1.0-plugins-base',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libgstreamer-1.0.so.0': 'libgstreamer1.0-0',
|
2021-03-11 20:22:50 -08:00
|
|
|
'libgsttag-1.0.so.0': 'gstreamer1.0-plugins-base',
|
|
|
|
'libgstvideo-1.0.so.0': 'gstreamer1.0-plugins-base',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libgthread-2.0.so.0': 'libglib2.0-0',
|
|
|
|
'libgtk-3.so.0': 'libgtk-3-0',
|
|
|
|
'libgtk-x11-2.0.so.0': 'libgtk2.0-0',
|
|
|
|
'libharfbuzz-icu.so.0': 'libharfbuzz-icu0',
|
|
|
|
'libharfbuzz.so.0': 'libharfbuzz0b',
|
|
|
|
'libhyphen.so.0': 'libhyphen0',
|
|
|
|
'libicui18n.so.66': 'libicu66',
|
|
|
|
'libicuuc.so.66': 'libicu66',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libjpeg.so.8': 'libjpeg-turbo8',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libnotify.so.4': 'libnotify4',
|
|
|
|
'libnspr4.so': 'libnspr4',
|
|
|
|
'libnss3.so': 'libnss3',
|
|
|
|
'libnssutil3.so': 'libnss3',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libopenjp2.so.7': 'libopenjp2-7',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libopus.so.0': 'libopus0',
|
|
|
|
'libpango-1.0.so.0': 'libpango-1.0-0',
|
|
|
|
'libpangocairo-1.0.so.0': 'libpangocairo-1.0-0',
|
|
|
|
'libpangoft2-1.0.so.0': 'libpangoft2-1.0-0',
|
|
|
|
'libpng16.so.16': 'libpng16-16',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libsecret-1.so.0': 'libsecret-1-0',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libsmime3.so': 'libnss3',
|
|
|
|
'libsoup-2.4.so.1': 'libsoup2.4-1',
|
|
|
|
'libvpx.so.6': 'libvpx6',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libwayland-client.so.0': 'libwayland-client0',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libwayland-egl.so.1': 'libwayland-egl1',
|
|
|
|
'libwayland-server.so.0': 'libwayland-server0',
|
|
|
|
'libwebp.so.6': 'libwebp6',
|
|
|
|
'libwebpdemux.so.2': 'libwebpdemux2',
|
|
|
|
'libwoff2dec.so.1.0.2': 'libwoff1',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libX11-xcb.so.1': 'libx11-xcb1',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libX11.so.6': 'libx11-6',
|
|
|
|
'libxcb-dri3.so.0': 'libxcb-dri3-0',
|
|
|
|
'libxcb-shm.so.0': 'libxcb-shm0',
|
|
|
|
'libxcb.so.1': 'libxcb1',
|
|
|
|
'libXcomposite.so.1': 'libxcomposite1',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libXcursor.so.1': 'libxcursor1',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libXdamage.so.1': 'libxdamage1',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libXext.so.6': 'libxext6',
|
|
|
|
'libXfixes.so.3': 'libxfixes3',
|
|
|
|
'libXi.so.6': 'libxi6',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libxkbcommon.so.0': 'libxkbcommon0',
|
|
|
|
'libxml2.so.2': 'libxml2',
|
|
|
|
'libXrandr.so.2': 'libxrandr2',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libXrender.so.1': 'libxrender1',
|
2020-07-29 10:40:33 -07:00
|
|
|
'libxslt.so.1': 'libxslt1.1',
|
2020-07-24 16:15:42 -07:00
|
|
|
'libXt.so.6': 'libxt6',
|
|
|
|
'libXtst.so.6': 'libxtst6',
|
2021-07-26 09:50:51 +01:00
|
|
|
'libxshmfence.so.1': 'libxshmfence1',
|
2020-07-24 16:15:42 -07:00
|
|
|
};
|
2020-09-01 16:29:38 -07:00
|
|
|
|
2021-05-06 10:37:06 -07:00
|
|
|
const LIBRARY_TO_PACKAGE_NAME_UBUNTU_21_04: { [s: string]: string} = {
|
|
|
|
'libasound.so.2': 'libasound2',
|
|
|
|
'libatk-1.0.so.0': 'libatk1.0-0',
|
|
|
|
'libatk-bridge-2.0.so.0': 'libatk-bridge2.0-0',
|
|
|
|
'libatspi.so.0': 'libatspi2.0-0',
|
|
|
|
'libcairo-gobject.so.2': 'libcairo-gobject2',
|
|
|
|
'libcairo.so.2': 'libcairo2',
|
|
|
|
'libcups.so.2': 'libcups2',
|
|
|
|
'libdbus-1.so.3': 'libdbus-1-3',
|
|
|
|
'libdbus-glib-1.so.2': 'libdbus-glib-1-2',
|
|
|
|
'libdrm.so.2': 'libdrm2',
|
|
|
|
'libEGL.so.1': 'libegl1',
|
|
|
|
'libepoxy.so.0': 'libepoxy0',
|
|
|
|
'libfontconfig.so.1': 'libfontconfig1',
|
|
|
|
'libfreetype.so.6': 'libfreetype6',
|
|
|
|
'libgbm.so.1': 'libgbm1',
|
|
|
|
'libgdk_pixbuf-2.0.so.0': 'libgdk-pixbuf-2.0-0',
|
|
|
|
'libgdk-3.so.0': 'libgtk-3-0',
|
|
|
|
'libgdk-x11-2.0.so.0': 'libgtk2.0-0',
|
|
|
|
'libgio-2.0.so.0': 'libglib2.0-0',
|
|
|
|
'libGL.so.1': 'libgl1',
|
|
|
|
'libGLESv2.so.2': 'libgles2',
|
|
|
|
'libglib-2.0.so.0': 'libglib2.0-0',
|
|
|
|
'libgmodule-2.0.so.0': 'libglib2.0-0',
|
|
|
|
'libgobject-2.0.so.0': 'libglib2.0-0',
|
|
|
|
'libgstapp-1.0.so.0': 'libgstreamer-plugins-base1.0-0',
|
|
|
|
'libgstaudio-1.0.so.0': 'libgstreamer-plugins-base1.0-0',
|
|
|
|
'libgstbase-1.0.so.0': 'libgstreamer1.0-0',
|
|
|
|
'libgstcodecparsers-1.0.so.0': 'libgstreamer-plugins-bad1.0-0',
|
|
|
|
'libgstfft-1.0.so.0': 'libgstreamer-plugins-base1.0-0',
|
|
|
|
'libgstgl-1.0.so.0': 'libgstreamer-gl1.0-0',
|
|
|
|
'libgstpbutils-1.0.so.0': 'libgstreamer-plugins-base1.0-0',
|
|
|
|
'libgstreamer-1.0.so.0': 'libgstreamer1.0-0',
|
|
|
|
'libgsttag-1.0.so.0': 'libgstreamer-plugins-base1.0-0',
|
|
|
|
'libgstvideo-1.0.so.0': 'libgstreamer-plugins-base1.0-0',
|
|
|
|
'libgthread-2.0.so.0': 'libglib2.0-0',
|
|
|
|
'libgtk-3.so.0': 'libgtk-3-0',
|
|
|
|
'libgtk-x11-2.0.so.0': 'libgtk2.0-0',
|
|
|
|
'libharfbuzz-icu.so.0': 'libharfbuzz-icu0',
|
|
|
|
'libharfbuzz.so.0': 'libharfbuzz0b',
|
|
|
|
'libhyphen.so.0': 'libhyphen0',
|
|
|
|
'libjavascriptcoregtk-4.0.so.18': 'libjavascriptcoregtk-4.0-18',
|
|
|
|
'libjpeg.so.8': 'libjpeg-turbo8',
|
|
|
|
'liblcms2.so.2': 'liblcms2-2',
|
|
|
|
'libnotify.so.4': 'libnotify4',
|
|
|
|
'libnspr4.so': 'libnspr4',
|
|
|
|
'libnss3.so': 'libnss3',
|
|
|
|
'libnssutil3.so': 'libnss3',
|
|
|
|
'libopenjp2.so.7': 'libopenjp2-7',
|
|
|
|
'libopus.so.0': 'libopus0',
|
|
|
|
'libpango-1.0.so.0': 'libpango-1.0-0',
|
|
|
|
'libpangocairo-1.0.so.0': 'libpangocairo-1.0-0',
|
|
|
|
'libpangoft2-1.0.so.0': 'libpangoft2-1.0-0',
|
|
|
|
'libpng16.so.16': 'libpng16-16',
|
|
|
|
'libsecret-1.so.0': 'libsecret-1-0',
|
|
|
|
'libsmime3.so': 'libnss3',
|
|
|
|
'libsoup-2.4.so.1': 'libsoup2.4-1',
|
|
|
|
'libvpx.so.6': 'libvpx6',
|
|
|
|
'libwayland-client.so.0': 'libwayland-client0',
|
|
|
|
'libwayland-egl.so.1': 'libwayland-egl1',
|
|
|
|
'libwayland-server.so.0': 'libwayland-server0',
|
|
|
|
'libwebkit2gtk-4.0.so.37': 'libwebkit2gtk-4.0-37',
|
|
|
|
'libwebp.so.6': 'libwebp6',
|
|
|
|
'libwebpdemux.so.2': 'libwebpdemux2',
|
|
|
|
'libwoff2dec.so.1.0.2': 'libwoff1',
|
|
|
|
'libwpe-1.0.so.1': 'libwpe-1.0-1',
|
|
|
|
'libWPEBackend-fdo-1.0.so.1': 'libwpebackend-fdo-1.0-1',
|
|
|
|
'libWPEWebKit-1.0.so.3': 'libwpewebkit-1.0-3',
|
|
|
|
'libX11-xcb.so.1': 'libx11-xcb1',
|
|
|
|
'libX11.so.6': 'libx11-6',
|
|
|
|
'libxcb-shm.so.0': 'libxcb-shm0',
|
|
|
|
'libxcb.so.1': 'libxcb1',
|
|
|
|
'libXcomposite.so.1': 'libxcomposite1',
|
|
|
|
'libXcursor.so.1': 'libxcursor1',
|
|
|
|
'libXdamage.so.1': 'libxdamage1',
|
|
|
|
'libXext.so.6': 'libxext6',
|
|
|
|
'libXfixes.so.3': 'libxfixes3',
|
|
|
|
'libXi.so.6': 'libxi6',
|
|
|
|
'libxkbcommon.so.0': 'libxkbcommon0',
|
|
|
|
'libxml2.so.2': 'libxml2',
|
|
|
|
'libXrandr.so.2': 'libxrandr2',
|
|
|
|
'libXrender.so.1': 'libxrender1',
|
|
|
|
'libxshmfence.so.1': 'libxshmfence1',
|
|
|
|
'libxslt.so.1': 'libxslt1.1',
|
|
|
|
'libXt.so.6': 'libxt6',
|
|
|
|
};
|
|
|
|
|
2020-09-01 16:29:38 -07:00
|
|
|
const MANUAL_LIBRARY_TO_PACKAGE_NAME_UBUNTU: { [s: string]: string} = {
|
|
|
|
// libgstlibav.so (the only actual library provided by gstreamer1.0-libav) is not
|
|
|
|
// in the ldconfig cache, so we detect the actual library required for playing h.264
|
|
|
|
// and if it's missing recommend installing missing gstreamer lib.
|
|
|
|
// gstreamer1.0-libav -> libavcodec57 -> libx264-152
|
2020-09-02 08:47:43 -07:00
|
|
|
'libx264.so': 'gstreamer1.0-libav',
|
2020-09-01 16:29:38 -07:00
|
|
|
};
|