From 9383c9aa6819c87971b6fb1e1cf9c526df372fca Mon Sep 17 00:00:00 2001 From: Adrian Perez de Castro Date: Fri, 25 Nov 2016 02:21:57 +0200 Subject: [PATCH] Support building Flatpak bundles This adds support for building Flatpak application bundles, which should be runnable on any Linux distribution with Flatpak support. See the page at http://flatpak.org/getting.html New Gulp tasks are added to prepare a directory with the needed files (vscode-linux-${arch}-prepare-flatpak), assembling the Flatpak bundles (vscode-linux-${arch}-flatpak), and for cleaning the build directories (clean-vscode-linux-${arch}-flatpak). This mimics how the Debian and RPM package creation works. Hence, building an application bundle is done with: $ gulp vscode-linux-x64-flatpak [...] $ ls *.flatpak com.visualstudio.code.oss-x86_64.flatpak Installing and running the application is achieved with: $ flatpak --user install --bundle com.visualstudio.code.oss-x86_64.flatpak $ flatpak run com.visualstudio.code.oss (Removing "--user" would install the application system-wide. Also note that the "org.freedesktop.Platform" runtime needs to be installeed, check the Flatpak website for instructions.) The "flatpak-bundler" development dependency provides an asynchronous API to invoke "flatpak-builder". The "gulp-image-resize" module is used to incorporate scaling of the application icon to multiple sizes, and uses ImageMagick (or GraphicsMagick) under the hood, which is commonly available on most GNU/Linux distributions. Instead of building the Electron dependencies ourselves, this uses the io.atom.electron.BaseApp bundle as base application. Instead of building the Electron dependencies, this reuses the "io.atom.electron.BaseApp" bundle as base application. The contents of the base application are imported at build time, and then Electron and the prepared files added on top. The prebuilt base application will be fetched automatically using the URL specified in the "baseFlatpakref" attribute of the manifest, and it is kindly hosted at Amazon S3 by Endless Computers (https://endlessm.com). The sources for the base application can be found at: https://github.com/endlessm/electron-flatpak-base-app/ --- build/gulpfile.vscode.linux.js | 93 +++++++++++++++++++++++++++++++++- package.json | 2 + 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/build/gulpfile.vscode.linux.js b/build/gulpfile.vscode.linux.js index 3ea53bf035bc3..0a4850dfeb77e 100644 --- a/build/gulpfile.vscode.linux.js +++ b/build/gulpfile.vscode.linux.js @@ -16,12 +16,35 @@ const packageJson = require('../package.json'); const product = require('../product.json'); const rpmDependencies = require('../resources/linux/rpm/dependencies'); +const linuxPackageRevision = Math.floor(new Date().getTime() / 1000); + +const flatpakManifest = { + appId: product.darwinBundleIdentifier, // We need a reverse-url style identifier. + sdk: 'org.freedesktop.Sdk', + runtime: 'org.freedesktop.Sdk', + runtimeVersion: '1.4', + base: 'io.atom.electron.BaseApp', + baseFlatpakref: 'https://s3-us-west-2.amazonaws.com/electron-flatpak.endlessm.com/electron-base-app-master.flatpakref', + command: product.applicationName, + symlinks: [ + ['/share/' + product.applicationName + '/bin/' + product.applicationName, '/bin/' + product.applicationName], + ], + finishArgs: [ + '--share=ipc', '--socket=x11', // Allow showing X11 windows. + '--share=network', // Network access (e.g. for installing extension). + '--filesystem=host', // Allow access to the whole file system. + '--device=dri', // Allow OpenGL rendering. + '--filesystem=/tmp', // Needed for Chromium's single instance check. + '--socket=pulseaudio', // Some extensions may want to play sounds... + '--talk-name=org.freedesktop.Notifications', // ...or pop up notifications. + ], +}; + + function getDebPackageArch(arch) { return { x64: 'amd64', ia32: 'i386', arm: 'armhf' }[arch]; } -const linuxPackageRevision = Math.floor(new Date().getTime() / 1000); - function prepareDebPackage(arch) { const binaryDir = '../VSCode-linux-' + arch; const debArch = getDebPackageArch(arch); @@ -144,6 +167,60 @@ function buildRpmPackage(arch) { ]); } +function getFlatpakArch(arch) { + return { x64: 'x86_64', ia32: 'i386', arm: 'arm' }[arch]; +} + +function prepareFlatpak(arch) { + // This is not imported in the global scope to avoid requiring ImageMagick + // (or GraphicsMagick) when not building building Flatpak bundles. + const imgResize = require('gulp-image-resize'); + + const binaryDir = '../VSCode-linux-' + arch; + const flatpakArch = getFlatpakArch(arch); + const destination = '.build/linux/flatpak/' + flatpakArch; + + return function () { + const all = [16, 24, 32, 48, 64, 128, 192, 256, 512].map(function (size) { + return gulp.src('resources/linux/code.png', { base: '.' }) + .pipe(imgResize({ width: size, height: size, format: "png", noProfile: true })) + .pipe(rename('share/icons/hicolor/' + size + 'x' + size + '/apps/' + flatpakManifest.appId + '.png')); + }); + + all.push(gulp.src('resources/linux/code.desktop', { base: '.' }) + .pipe(replace('Exec=/usr/share/@@NAME@@/@@NAME@@', 'Exec=' + product.applicationName)) + .pipe(replace('@@NAME_LONG@@', product.nameLong)) + .pipe(replace('@@NAME_SHORT@@', product.nameShort)) + .pipe(replace('@@NAME@@', product.applicationName)) + .pipe(rename('share/applications/' + flatpakManifest.appId + '.desktop'))); + + all.push(gulp.src(binaryDir + '/**/*', { base:binaryDir }) + .pipe(rename(function (p) { + p.dirname = 'share/' + product.applicationName + '/' + p.dirname; + }))); + + return es.merge(all).pipe(vfs.dest(destination)); + } +} + +function buildFlatpak(arch) { + const flatpakArch = getFlatpakArch(arch); + const manifest = {}; + for (var k in flatpakManifest) { + manifest[k] = flatpakManifest[k]; + } + manifest.files = [ + ['.build/linux/flatpak/' + flatpakArch, '/'], + ]; + const buildOptions = { + arch: flatpakArch, + bundlePath: manifest.appId + '-' + flatpakArch + '.flatpak', + }; + return function (cb) { + require('flatpak-bundler').bundle(manifest, buildOptions, cb); + } +} + gulp.task('clean-vscode-linux-ia32-deb', util.rimraf('.build/linux/deb/i386')); gulp.task('clean-vscode-linux-x64-deb', util.rimraf('.build/linux/deb/amd64')); gulp.task('clean-vscode-linux-arm-deb', util.rimraf('.build/linux/deb/armhf')); @@ -164,3 +241,15 @@ gulp.task('vscode-linux-arm-prepare-rpm', ['clean-vscode-linux-arm-rpm', 'vscode gulp.task('vscode-linux-ia32-build-rpm', ['vscode-linux-ia32-prepare-rpm'], buildRpmPackage('ia32')); gulp.task('vscode-linux-x64-build-rpm', ['vscode-linux-x64-prepare-rpm'], buildRpmPackage('x64')); gulp.task('vscode-linux-arm-build-rpm', ['vscode-linux-arm-prepare-rpm'], buildRpmPackage('arm')); + +gulp.task('clean-vscode-linux-ia32-flatpak', util.rimraf('.build/linux/flatpak/i386')); +gulp.task('clean-vscode-linux-x64-flatpak', util.rimraf('.build/linux/flatpak/x86_64')); +gulp.task('clean-vscode-linux-arm-flatpak', util.rimraf('.build/linux/flatpak/arm')); + +gulp.task('vscode-linux-ia32-prepare-flatpak', ['clean-vscode-linux-ia32-flatpak', 'vscode-linux-ia32-min'], prepareFlatpak('ia32')); +gulp.task('vscode-linux-x64-prepare-flatpak', ['clean-vscode-linux-x64-flatpak', 'vscode-linux-x64-min'], prepareFlatpak('x64')); +gulp.task('vscode-linux-arm-prepare-flatpak', ['clean-vscode-linux-arm-flatpak', 'vscode-linux-arm-min'], prepareFlatpak('arm')); + +gulp.task('vscode-linux-ia32-flatpak', ['vscode-linux-ia32-prepare-flatpak'], buildFlatpak('ia32')); +gulp.task('vscode-linux-x64-flatpak', ['vscode-linux-x64-prepare-flatpak'], buildFlatpak('x64')); +gulp.task('vscode-linux-arm-flatpak', ['vscode-linux-arm-prepare-flatpak'], buildFlatpak('arm')); diff --git a/package.json b/package.json index b7795b35dfc85..c7fd9ff0d917f 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,8 @@ "gulp-uglify": "^2.0.0", "gulp-util": "^3.0.6", "gulp-vinyl-zip": "^1.2.2", + "gulp-image-resize": "^0.10.0", + "flatpak-bundler": "^0.1.1", "innosetup-compiler": "^5.5.60", "is": "^3.1.0", "istanbul": "^0.3.17",