Revert back to using libsqlcipher0 for Debian & Ubuntu packages of Desktop (#367)

* Revert back to using libsqlcipher0 for Debian & Ubuntu packages of Element Desktop

Add option to static link for linux instead of forcing it

* Fix linux variants and add CI job

* Fix workflow syntax and add concurrency

* public all the things
This commit is contained in:
Michael Telatynski 2022-05-27 09:15:47 +01:00 committed by GitHub
parent f1f659b6a0
commit 8c3c190856
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 92 additions and 46 deletions

View file

@ -3,6 +3,9 @@ on:
pull_request: { } pull_request: { }
push: push:
branches: [ develop, master ] branches: [ develop, master ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
windows: windows:
strategy: strategy:
@ -67,7 +70,13 @@ jobs:
run: "yarn build --publish never -w ${{ matrix.build-args }}" run: "yarn build --publish never -w ${{ matrix.build-args }}"
linux: linux:
name: Linux strategy:
matrix:
include:
- sqlcipher: system
- sqlcipher: static
static: 1
name: 'Linux (sqlcipher: ${{ matrix.sqlcipher }})'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -84,6 +93,10 @@ jobs:
with: with:
toolchain: stable toolchain: stable
- name: Install libsqlcipher-dev
if: matrix.sqlcipher == 'system'
run: sudo apt-get install -y libsqlcipher-dev
- uses: actions/setup-node@v3 - uses: actions/setup-node@v3
with: with:
cache: "yarn" cache: "yarn"
@ -94,6 +107,8 @@ jobs:
- name: Build Natives - name: Build Natives
run: "yarn build:native" run: "yarn build:native"
env:
SQLCIPHER_STATIC: ${{ matrix.static }}
- name: Build App - name: Build App
run: "yarn build --publish never" run: "yarn build --publish never"

View file

@ -13,7 +13,9 @@ RUN apt-get -qq update && apt-get -qq dist-upgrade && \
# libsecret-1-dev and libgnome-keyring-dev are required even for prebuild keytar # libsecret-1-dev and libgnome-keyring-dev are required even for prebuild keytar
apt-get -qq install --no-install-recommends qtbase5-dev bsdtar build-essential autoconf libssl-dev gcc-multilib g++-multilib lzip rpm python libcurl4 git git-lfs ssh unzip tcl \ apt-get -qq install --no-install-recommends qtbase5-dev bsdtar build-essential autoconf libssl-dev gcc-multilib g++-multilib lzip rpm python libcurl4 git git-lfs ssh unzip tcl \
libsecret-1-dev libgnome-keyring-dev \ libsecret-1-dev libgnome-keyring-dev \
libopenjp2-tools && \ libopenjp2-tools \
# Used by seshat (when not SQLCIPHER_STATIC) \
libsqlcipher-dev && \
# git-lfs # git-lfs
git lfs install && \ git lfs install && \
apt-get purge -y --auto-remove && rm -rf /var/lib/apt/lists/* apt-get purge -y --auto-remove && rm -rf /var/lib/apt/lists/*

View file

@ -47,7 +47,7 @@ using yarn at the root of this project:
yarn add matrix-seshat yarn add matrix-seshat
You will have to rebuild the native libraries against electron's version of You will have to rebuild the native libraries against electron's version
of node rather than your system node, using the `electron-build-env` tool. of node rather than your system node, using the `electron-build-env` tool.
This is also needed to when pulling in changes to Seshat using `yarn link`. This is also needed to when pulling in changes to Seshat using `yarn link`.
@ -66,6 +66,17 @@ as usual using:
yarn start yarn start
### Statically linking libsqlcipher
On Windows & macOS we always statically link libsqlcipher for it is not generally available.
On Linux by default we will use a system package, on debian & ubuntu this is `libsqlcipher0`,
but this is problematic for some other packages.
By including `SQLCIPHER_STATIC=1` in the build environment, the build scripts will statically link sqlcipher,
note that this will want a `libcrypto1.1` shared library available in the system.
More info can be found at https://github.com/matrix-org/seshat/issues/102
and https://github.com/vector-im/element-web/issues/20926.
## Compiling for specific architectures ## Compiling for specific architectures
### macOS ### macOS

View file

@ -4,7 +4,7 @@ Vendor: support@element.io
Architecture: amd64 Architecture: amd64
Maintainer: support@element.io Maintainer: support@element.io
Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libsecret-1-0 Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libsecret-1-0
Recommends: libappindicator3-1 Recommends: libappindicator3-1, libsqlcipher0
Section: net Section: net
Priority: extra Priority: extra
Homepage: https://element.io/ Homepage: https://element.io/

View file

@ -4,7 +4,7 @@ Vendor: support@element.io
Architecture: amd64 Architecture: amd64
Maintainer: support@element.io Maintainer: support@element.io
Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libsecret-1-0 Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libsecret-1-0
Recommends: libappindicator3-1 Recommends: libappindicator3-1, libsqlcipher0
Replaces: riot-desktop (<< 1.7.0), riot-web (<< 1.7.0) Replaces: riot-desktop (<< 1.7.0), riot-web (<< 1.7.0)
Breaks: riot-desktop (<< 1.7.0), riot-web (<< 1.7.0) Breaks: riot-desktop (<< 1.7.0), riot-web (<< 1.7.0)
Section: net Section: net

View file

@ -26,7 +26,7 @@ export default async function(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promi
if (hakEnv.isWin()) { if (hakEnv.isWin()) {
await buildOpenSslWin(hakEnv, moduleInfo); await buildOpenSslWin(hakEnv, moduleInfo);
await buildSqlCipherWin(hakEnv, moduleInfo); await buildSqlCipherWin(hakEnv, moduleInfo);
} else { } else if (hakEnv.wantsStaticSqlCipherUnix()) {
await buildSqlCipherUnix(hakEnv, moduleInfo); await buildSqlCipherUnix(hakEnv, moduleInfo);
} }
await buildMatrixSeshat(hakEnv, moduleInfo); await buildMatrixSeshat(hakEnv, moduleInfo);
@ -186,9 +186,13 @@ async function buildSqlCipherUnix(hakEnv: HakEnv, moduleInfo: DependencyInfo) {
args.push('--with-crypto-lib=commoncrypto'); args.push('--with-crypto-lib=commoncrypto');
} }
if (hakEnv.wantsStaticSqlCipherUnix()) {
args.push('--enable-tcl=no');
if (hakEnv.isLinux()) { if (hakEnv.isLinux()) {
args.push('--with-pic=yes'); args.push('--with-pic=yes');
} }
}
if (!hakEnv.isHost()) { if (!hakEnv.isHost()) {
// In the nonsense world of `configure`, it is assumed you are building // In the nonsense world of `configure`, it is assumed you are building
@ -210,7 +214,7 @@ async function buildSqlCipherUnix(hakEnv: HakEnv, moduleInfo: DependencyInfo) {
args.push(`CFLAGS=${cflags.join(' ')}`); args.push(`CFLAGS=${cflags.join(' ')}`);
} }
const ldflags = []; const ldflags: string[] = [];
if (hakEnv.isMac()) { if (hakEnv.isMac()) {
ldflags.push('-framework Security'); ldflags.push('-framework Security');
@ -270,13 +274,15 @@ async function buildMatrixSeshat(hakEnv: HakEnv, moduleInfo: DependencyInfo) {
// it for now: we should confirm how much of this it still actually needs. // it for now: we should confirm how much of this it still actually needs.
const env = hakEnv.makeGypEnv(); const env = hakEnv.makeGypEnv();
if (!hakEnv.isLinux() || hakEnv.wantsStaticSqlCipherUnix()) {
Object.assign(env, { Object.assign(env, {
SQLCIPHER_STATIC: 1, SQLCIPHER_STATIC: 1,
SQLCIPHER_LIB_DIR: path.join(moduleInfo.depPrefix, 'lib'), SQLCIPHER_LIB_DIR: path.join(moduleInfo.depPrefix, 'lib'),
SQLCIPHER_INCLUDE_DIR: path.join(moduleInfo.depPrefix, 'include'), SQLCIPHER_INCLUDE_DIR: path.join(moduleInfo.depPrefix, 'include'),
}); });
}
if (hakEnv.isLinux()) { if (hakEnv.isLinux() && hakEnv.wantsStaticSqlCipherUnix()) {
// Ensure Element uses the statically-linked seshat build, and prevent other applications // Ensure Element uses the statically-linked seshat build, and prevent other applications
// from attempting to use this one. Detailed explanation: // from attempting to use this one. Detailed explanation:
// //

View file

@ -21,6 +21,7 @@ import HakEnv from '../../scripts/hak/hakEnv';
import { DependencyInfo } from '../../scripts/hak/dep'; import { DependencyInfo } from '../../scripts/hak/dep';
export default async function(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> { export default async function(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> {
if (hakEnv.wantsStaticSqlCipher()) {
// of course tcl doesn't have a --version // of course tcl doesn't have a --version
await new Promise<void>((resolve, reject) => { await new Promise<void>((resolve, reject) => {
const proc = childProcess.spawn('tclsh', [], { const proc = childProcess.spawn('tclsh', [], {
@ -35,6 +36,7 @@ export default async function(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promi
}); });
proc.stdin.end(); proc.stdin.end();
}); });
}
const tools = [ const tools = [
['rustc', '--version'], ['rustc', '--version'],

View file

@ -25,7 +25,9 @@ import HakEnv from '../../scripts/hak/hakEnv';
import { DependencyInfo } from '../../scripts/hak/dep'; import { DependencyInfo } from '../../scripts/hak/dep';
export default async function(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> { export default async function(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> {
if (hakEnv.wantsStaticSqlCipher()) {
await getSqlCipher(hakEnv, moduleInfo); await getSqlCipher(hakEnv, moduleInfo);
}
if (hakEnv.isWin()) { if (hakEnv.isWin()) {
await getOpenSsl(hakEnv, moduleInfo); await getOpenSsl(hakEnv, moduleInfo);
@ -36,7 +38,7 @@ async function getSqlCipher(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise
const version = moduleInfo.cfg.dependencies.sqlcipher; const version = moduleInfo.cfg.dependencies.sqlcipher;
const sqlCipherDir = path.join(moduleInfo.moduleTargetDotHakDir, `sqlcipher-${version}`); const sqlCipherDir = path.join(moduleInfo.moduleTargetDotHakDir, `sqlcipher-${version}`);
let haveSqlcipher; let haveSqlcipher: boolean;
try { try {
await fsProm.stat(sqlCipherDir); await fsProm.stat(sqlCipherDir);
haveSqlcipher = true; haveSqlcipher = true;
@ -47,7 +49,7 @@ async function getSqlCipher(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise
if (haveSqlcipher) return; if (haveSqlcipher) return;
const sqlCipherTarball = path.join(moduleInfo.moduleDotHakDir, `sqlcipher-${version}.tar.gz`); const sqlCipherTarball = path.join(moduleInfo.moduleDotHakDir, `sqlcipher-${version}.tar.gz`);
let haveSqlcipherTar; let haveSqlcipherTar: boolean;
try { try {
await fsProm.stat(sqlCipherTarball); await fsProm.stat(sqlCipherTarball);
haveSqlcipherTar = true; haveSqlcipherTar = true;
@ -97,7 +99,7 @@ async function getOpenSsl(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<v
const version = moduleInfo.cfg.dependencies.openssl; const version = moduleInfo.cfg.dependencies.openssl;
const openSslDir = path.join(moduleInfo.moduleTargetDotHakDir, `openssl-${version}`); const openSslDir = path.join(moduleInfo.moduleTargetDotHakDir, `openssl-${version}`);
let haveOpenSsl; let haveOpenSsl: boolean;
try { try {
await fsProm.stat(openSslDir); await fsProm.stat(openSslDir);
haveOpenSsl = true; haveOpenSsl = true;
@ -108,7 +110,7 @@ async function getOpenSsl(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<v
if (haveOpenSsl) return; if (haveOpenSsl) return;
const openSslTarball = path.join(moduleInfo.moduleDotHakDir, `openssl-${version}.tar.gz`); const openSslTarball = path.join(moduleInfo.moduleDotHakDir, `openssl-${version}.tar.gz`);
let haveOpenSslTar; let haveOpenSslTar: boolean;
try { try {
await fsProm.stat(openSslTarball); await fsProm.stat(openSslTarball);
haveOpenSslTar = true; haveOpenSslTar = true;

View file

@ -54,12 +54,12 @@ export default class HakEnv {
this.dotHakDir = path.join(this.projectRoot, '.hak'); this.dotHakDir = path.join(this.projectRoot, '.hak');
} }
async init() { public async init() {
this.runtime = await getRuntime(this.projectRoot); this.runtime = await getRuntime(this.projectRoot);
this.runtimeVersion = await getRuntimeVersion(this.projectRoot); this.runtimeVersion = await getRuntimeVersion(this.projectRoot);
} }
getRuntimeAbi(): string { public getRuntimeAbi(): string {
return nodePreGypVersioning.get_runtime_abi( return nodePreGypVersioning.get_runtime_abi(
this.runtime, this.runtime,
this.runtimeVersion, this.runtimeVersion,
@ -67,35 +67,35 @@ export default class HakEnv {
} }
// {node_abi}-{platform}-{arch} // {node_abi}-{platform}-{arch}
getNodeTriple(): string { public getNodeTriple(): string {
return this.getRuntimeAbi() + '-' + this.target.platform + '-' + this.target.arch; return this.getRuntimeAbi() + '-' + this.target.platform + '-' + this.target.arch;
} }
getTargetId(): TargetId { public getTargetId(): TargetId {
return this.target.id; return this.target.id;
} }
isWin(): boolean { public isWin(): boolean {
return this.target.platform === 'win32'; return this.target.platform === 'win32';
} }
isMac(): boolean { public isMac(): boolean {
return this.target.platform === 'darwin'; return this.target.platform === 'darwin';
} }
isLinux(): boolean { public isLinux(): boolean {
return this.target.platform === 'linux'; return this.target.platform === 'linux';
} }
getTargetArch(): Arch { public getTargetArch(): Arch {
return this.target.arch; return this.target.arch;
} }
isHost(): boolean { public isHost(): boolean {
return isHostId(this.target.id); return isHostId(this.target.id);
} }
makeGypEnv(): Record<string, string> { public makeGypEnv(): Record<string, string> {
return Object.assign({}, process.env, { return Object.assign({}, process.env, {
npm_config_arch: this.target.arch, npm_config_arch: this.target.arch,
npm_config_target_arch: this.target.arch, npm_config_target_arch: this.target.arch,
@ -107,7 +107,15 @@ export default class HakEnv {
}); });
} }
getNodeModuleBin(name: string): string { public getNodeModuleBin(name: string): string {
return path.join(this.projectRoot, 'node_modules', '.bin', name); return path.join(this.projectRoot, 'node_modules', '.bin', name);
} }
public wantsStaticSqlCipherUnix(): boolean {
return this.isMac() || process.env.SQLCIPHER_STATIC == '1';
}
public wantsStaticSqlCipher(): boolean {
return this.isWin() || this.wantsStaticSqlCipherUnix();
}
} }