guix: reproducible builds of the GUI

The GUI is using an insane MSRV so i had to patch my way through in
order to be able to build some dependencies.
This commit is contained in:
Antoine Poinsot 2022-12-01 17:21:06 +01:00
parent 8dda896e4b
commit 3906a1b5bc
No known key found for this signature in database
GPG Key ID: E13FC145CD3F4304
4 changed files with 561 additions and 39 deletions

View File

@ -1,21 +1,34 @@
set -ex
# Guix comes with Cargo 1.52 but --config was stabilized in 1.63, so we need
# to specify unstable-options.
# We use the --config to redirect cargo toward our vendored source directory
# for our dependencies.
# TODO: build in release mode
cargo -Z unstable-options -vvv \
# Instruct cargo to use our vendored sources
mkdir -p ~/.cargo
cat <<EOF >~/.cargo/config.toml
[source.vendored_sources]
directory = "$VENDOR_DIR"
[source.crates-io]
replace-with = "vendored_sources"
[source."https://github.com/darosior/rust-miniscript"]
git = "https://github.com/darosior/rust-miniscript"
branch = "multipath_descriptors_on_8.0"
replace-with = "vendored_sources"
[source."https://github.com/revault/liana"]
git = "https://github.com/revault/liana"
branch = "master"
replace-with = "vendored_sources"
EOF
# We need to set RUSTC_BOOTSTRAP=1 as a workaround to be able to use unstable
# features in the GUI dependencies
# FIXME: GUIX_LD_WRAPPER_DISABLE_RPATH=yes
RUSTC_BOOTSTRAP=1 cargo -vvv \
--color always \
--frozen \
--offline \
rustc \
--release \
--target-dir "$TARGET_DIR" \
--config source.vendored_sources.directory=\""$VENDOR_DIR"\" \
--config source.crates-io.replace-with=\"vendored_sources\" \
--config source.\"https://github.com/darosior/rust-miniscript\".replace-with=\"vendored_sources\" \
--config source.\"https://github.com/darosior/rust-miniscript\".git=\"https://github.com/darosior/rust-miniscript\" \
--config source.\"https://github.com/darosior/rust-miniscript\".branch=\"multipath_descriptors_on_8.0\"
--target-dir "$TARGET_DIR"
set +ex

View File

@ -21,15 +21,16 @@ VENDOR_DIR="$BUILD_ROOT/vendor"
OUT_DIR="${OUT_DIR:-"$BUILD_ROOT/out"}"
BIN_DIR="${BIN_DIR:-"$BUILD_ROOT/bin"}"
# Create the various folders if the root build directory is fresh.
for d in "$OUT_DIR" "$BIN_DIR"; do
if ! [ -d "$d" ]; then
mkdir -p "$d"
# Create the directory if it doesn't exist already
maybe_create_dir() {
if ! [ -d "$@" ]; then
mkdir -p "$@"
fi
done
}
maybe_create_dir "$BIN_DIR"
# That's what Guix comes with.
RUST_VERSION="1.52.0"
RUST_VERSION="1.60.0"
CARGO_BIN="$BIN_DIR/cargo"
# First off get the cargo binary to run on the host to vendor dependencies.
@ -37,17 +38,12 @@ CARGO_BIN="$BIN_DIR/cargo"
if ! [ -f "$CARGO_BIN" ]; then
ARCHIVE_PATH="$BIN_DIR/rust-for-cargo.tar.gz"
curl -o "$ARCHIVE_PATH" "https://static.rust-lang.org/dist/rust-$RUST_VERSION-x86_64-unknown-linux-gnu.tar.gz"
echo "c082b5eea81206ff207407b41a10348282362dd972e93c86b054952b66ca0e2b $ARCHIVE_PATH" | $SHASUM_BIN -c
echo "b8a4c3959367d053825e31f90a5eb86418eb0d80cacda52bfa80b078e18150d5 $ARCHIVE_PATH" | $SHASUM_BIN -c
# Path of the cargo binary within the archive
CARGO_BIN_PATH="rust-$RUST_VERSION-x86_64-unknown-linux-gnu/cargo/bin/cargo"
( cd $BIN_DIR && tar -xzf $ARCHIVE_PATH $CARGO_BIN_PATH && mv $CARGO_BIN_PATH $CARGO_BIN )
fi
# Pull the sources of our dependencies before building them in the container.
if ! [ -d "$VENDOR_DIR" ]; then
$CARGO_BIN vendor $VENDOR_DIR
fi
# Execute "$@" in a pinned, possibly older version of Guix, for reproducibility
# across time.
time_machine() {
@ -59,19 +55,67 @@ time_machine() {
-- "$@"
}
# Bootstrap a reproducible environment as specified by the manifest in an isolated
# container, and build the project.
time_machine shell --no-cwd \
--expose="$PWD/src=/liana/src" \
--expose="$PWD/Cargo.toml=/liana/Cargo.toml" \
--expose="$PWD/Cargo.lock=/liana/Cargo.lock" \
--expose="$PWD/contrib/guix/build.sh=/liana/build.sh" \
--expose="$VENDOR_DIR=$VENDOR_DIR" \
--share="$OUT_DIR=$OUT_DIR" \
--container \
-m $PWD/contrib/guix/manifest.scm \
-- env CC=clang VENDOR_DIR="$VENDOR_DIR" TARGET_DIR="$OUT_DIR" \
/bin/sh -c "cd /liana && ./build.sh"
# Build both the daemon (at the root of the repository) and the GUI (in gui/)
for project_folder in "" "gui"; do
PROJECT_ROOT="$PWD/$project_folder"
PROJECT_VENDOR_DIR="$VENDOR_DIR/$project_folder"
PROJECT_OUT_DIR="$OUT_DIR/$project_folder"
PROJECT_PATCHES_ROOT="$PWD/contrib/guix/patches/$project_folder"
project_needs_patches() {
test $(ls -A1q "$PROJECT_PATCHES_ROOT" |grep patch)
}
maybe_create_dir "$PROJECT_OUT_DIR"
# Pull the sources of our dependencies before building them in the container.
if ! [ -d "$PROJECT_VENDOR_DIR" ]; then
# Download the dependencies
( cd "$project_folder" && $CARGO_BIN vendor "$PROJECT_VENDOR_DIR" )
# Patch some dependencies sources if needed for this project
if project_needs_patches; then
(
cd "$PROJECT_VENDOR_DIR"
for patch_file in $(ls "$PROJECT_PATCHES_ROOT"); do
patch -p1 < "$PROJECT_PATCHES_ROOT/$patch_file"
done
)
# Some of the checksums will be incorrect. Instead of cherry-picking remove them
# altogether, since they aren't useful anyways (see comment below).
for dep in $(ls "$PROJECT_VENDOR_DIR"); do
echo "{\"files\":{}}" > "$PROJECT_VENDOR_DIR/$dep/.cargo-checksum.json"
done
fi
fi
cp "$PROJECT_ROOT/Cargo.lock" "$BUILD_ROOT/Cargo.lock"
if project_needs_patches; then
# Remove the checksums from the Cargo.lock. In the container `cargo rustc` would compare
# them against the .cargo-checksum.json to make sure they weren't tampered with since they
# where vendored. But we just removed the checksums from the .cargo-checksum.json.
# There is little point in checking integrity between the above vendor step and now anyways.
# What matters is checking integrity after downloading the crates from the internet and
# `cargo vendor` does that already.
sed -i '/checksum/d' "$BUILD_ROOT/Cargo.lock"
fi
# Bootstrap a reproducible environment as specified by the manifest in an isolated
# container, and build the project.
time_machine shell --no-cwd \
--expose="$PROJECT_ROOT/src=/liana/src" \
--expose="$PWD/gui/static=/liana/static" \
--expose="$PROJECT_ROOT/Cargo.toml=/liana/Cargo.toml" \
--expose="$BUILD_ROOT/Cargo.lock=/liana/Cargo.lock" \
--expose="$PWD/contrib/guix/build.sh=/liana/build.sh" \
--expose="$PROJECT_VENDOR_DIR=$PROJECT_VENDOR_DIR" \
--share="$PROJECT_OUT_DIR=$PROJECT_OUT_DIR" \
--container \
-m $PWD/contrib/guix/manifest.scm \
-- env CC=gcc VENDOR_DIR="$PROJECT_VENDOR_DIR" TARGET_DIR="$PROJECT_OUT_DIR" \
/bin/sh -c "cd /liana && ./build.sh"
done
set +ex

View File

@ -1,5 +1,11 @@
;; FIXME: Only pull the GUI dependencies when building it, not the daemon
(specifications->manifest
(list "rust"
"rust-cargo"
"rust:cargo"
"coreutils"
"clang-toolchain"))
"pkg-config" ;; For the GUI
"eudev" ;; For the GUI
"cmake" ;; For the GUI
"make" ;; For the GUI
"fontconfig" ;; For the GUI
"gcc-toolchain@10.3.0"))

View File

@ -0,0 +1,459 @@
commit f71bc71bf6724a1c5e2a3246dd8bd0a90fcf0e15
Author: Antoine Poinsot <darosior@protonmail.com>
Date: Thu Dec 1 15:38:32 2022 +0100
Do not use, or special-case them, unstable features as of 1.60.0
This is in order to make the GUI MSRV effectively 1.60.0.
Default derivation on enums is removed.
Usage of bool_to_option is removed.
Generic associated types is unfortunately special cased as enabled. This
forces use to set RUSTC_BOOTSTRAP=1 in the Guix container...
diff --git a/iced_glow/src/lib.rs b/iced_glow/src/lib.rs
index e3690a69..b5b9cc38 100644
--- a/iced_glow/src/lib.rs
+++ b/iced_glow/src/lib.rs
@@ -20,6 +20,7 @@
#![forbid(rust_2018_idioms)]
#![allow(clippy::inherent_to_string, clippy::type_complexity)]
#![cfg_attr(docsrs, feature(doc_cfg))]
+#![feature(generic_associated_types)]
pub use glow;
diff --git a/iced_graphics/src/lib.rs b/iced_graphics/src/lib.rs
index d39dd90c..876b478f 100644
--- a/iced_graphics/src/lib.rs
+++ b/iced_graphics/src/lib.rs
@@ -21,6 +21,7 @@
#![forbid(rust_2018_idioms)]
#![allow(clippy::inherent_to_string, clippy::type_complexity)]
#![cfg_attr(docsrs, feature(doc_cfg))]
+#![feature(generic_associated_types)]
mod antialiasing;
mod error;
mod primitive;
diff --git a/iced_native/src/program/state.rs b/iced_native/src/program/state.rs
index 8ae1cacb..25a3028b 100644
--- a/iced_native/src/program/state.rs
+++ b/iced_native/src/program/state.rs
@@ -120,7 +120,11 @@ where
.iter()
.zip(event_statuses)
.filter_map(|(event, status)| {
- matches!(status, event::Status::Ignored).then_some(event)
+ if matches!(status, event::Status::Ignored) {
+ Some(event)
+ } else {
+ None
+ }
})
.cloned()
.collect();
diff --git a/iced_style/src/theme.rs b/iced_style/src/theme.rs
index d7ebb827..224a04fc 100644
--- a/iced_style/src/theme.rs
+++ b/iced_style/src/theme.rs
@@ -25,10 +25,9 @@ use iced_core::{Background, Color, Vector};
use std::rc::Rc;
/// A built-in theme.
-#[derive(Debug, Clone, PartialEq, Default)]
+#[derive(Debug, Clone, PartialEq)]
pub enum Theme {
/// The built-in light variant.
- #[default]
Light,
/// The built-in dark variant.
Dark,
@@ -61,6 +60,12 @@ impl Theme {
}
}
+impl Default for Theme {
+ fn default() -> Self {
+ Self::Light
+ }
+}
+
/// A [`Theme`] with a customized [`Palette`].
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Custom {
@@ -79,15 +84,19 @@ impl Custom {
}
/// The style of an application.
-#[derive(Default)]
pub enum Application {
/// The default style.
- #[default]
Default,
/// A custom style.
Custom(Box<dyn application::StyleSheet<Style = Theme>>),
}
+impl Default for Application {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
impl application::StyleSheet for Theme {
type Style = Application;
@@ -119,10 +128,11 @@ impl From<fn(&Theme) -> application::Appearance> for Application {
}
/// The style of a button.
-#[derive(Default)]
+/*
+ * Button
+ */
pub enum Button {
/// The primary style.
- #[default]
Primary,
/// The secondary style.
Secondary,
@@ -138,6 +148,12 @@ pub enum Button {
Custom(Box<dyn button::StyleSheet<Style = Theme>>),
}
+impl Default for Button {
+ fn default() -> Self {
+ Self::Primary
+ }
+}
+
impl button::StyleSheet for Theme {
type Style = Button;
@@ -227,10 +243,11 @@ impl button::StyleSheet for Theme {
}
/// The style of a checkbox.
-#[derive(Default)]
+/*
+ * Checkbox
+ */
pub enum Checkbox {
/// The primary style.
- #[default]
Primary,
/// The secondary style.
Secondary,
@@ -242,6 +259,12 @@ pub enum Checkbox {
Custom(Box<dyn checkbox::StyleSheet<Style = Theme>>),
}
+impl Default for Checkbox {
+ fn default() -> Self {
+ Self::Primary
+ }
+}
+
impl checkbox::StyleSheet for Theme {
type Style = Checkbox;
@@ -339,10 +362,11 @@ fn checkbox_appearance(
}
/// The style of a container.
-#[derive(Default)]
+/*
+ * Container
+ */
pub enum Container {
/// No style.
- #[default]
Transparent,
/// A simple box.
Box,
@@ -350,6 +374,12 @@ pub enum Container {
Custom(Box<dyn container::StyleSheet<Style = Theme>>),
}
+impl Default for Container {
+ fn default() -> Self {
+ Self::Transparent
+ }
+}
+
impl From<fn(&Theme) -> container::Appearance> for Container {
fn from(f: fn(&Theme) -> container::Appearance) -> Self {
Self::Custom(Box::new(f))
@@ -387,15 +417,19 @@ impl container::StyleSheet for fn(&Theme) -> container::Appearance {
}
/// The style of a slider.
-#[derive(Default)]
pub enum Slider {
/// The default style.
- #[default]
Default,
/// A custom style.
Custom(Box<dyn slider::StyleSheet<Style = Theme>>),
}
+impl Default for Slider {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
impl slider::StyleSheet for Theme {
type Style = Slider;
@@ -468,15 +502,20 @@ impl slider::StyleSheet for Theme {
}
/// The style of a menu.
-#[derive(Clone, Default)]
+#[derive(Clone)]
pub enum Menu {
/// The default style.
- #[default]
Default,
/// A custom style.
Custom(Rc<dyn menu::StyleSheet<Style = Theme>>),
}
+impl Default for Menu {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
impl menu::StyleSheet for Theme {
type Style = Menu;
@@ -510,10 +549,9 @@ impl From<PickList> for Menu {
}
/// The style of a pick list.
-#[derive(Clone, Default)]
+#[derive(Clone)]
pub enum PickList {
/// The default style.
- #[default]
Default,
/// A custom style.
Custom(
@@ -522,6 +560,12 @@ pub enum PickList {
),
}
+impl Default for PickList {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
impl pick_list::StyleSheet for Theme {
type Style = PickList;
@@ -565,15 +609,19 @@ impl pick_list::StyleSheet for Theme {
}
/// The style of a radio button.
-#[derive(Default)]
pub enum Radio {
/// The default style.
- #[default]
Default,
/// A custom style.
Custom(Box<dyn radio::StyleSheet<Style = Theme>>),
}
+impl Default for Radio {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
impl radio::StyleSheet for Theme {
type Style = Radio;
@@ -620,15 +668,19 @@ impl radio::StyleSheet for Theme {
}
/// The style of a toggler.
-#[derive(Default)]
pub enum Toggler {
/// The default style.
- #[default]
Default,
/// A custom style.
Custom(Box<dyn toggler::StyleSheet<Style = Theme>>),
}
+impl Default for Toggler {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
impl toggler::StyleSheet for Theme {
type Style = Toggler;
@@ -687,15 +739,19 @@ impl toggler::StyleSheet for Theme {
}
/// The style of a pane grid.
-#[derive(Default)]
pub enum PaneGrid {
/// The default style.
- #[default]
Default,
/// A custom style.
Custom(Box<dyn pane_grid::StyleSheet<Style = Theme>>),
}
+impl Default for PaneGrid {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
impl pane_grid::StyleSheet for Theme {
type Style = PaneGrid;
@@ -729,10 +785,11 @@ impl pane_grid::StyleSheet for Theme {
}
/// The style of a progress bar.
-#[derive(Default)]
+/*
+ * Progress Bar
+ */
pub enum ProgressBar {
/// The primary style.
- #[default]
Primary,
/// The success style.
Success,
@@ -742,6 +799,12 @@ pub enum ProgressBar {
Custom(Box<dyn progress_bar::StyleSheet<Style = Theme>>),
}
+impl Default for ProgressBar {
+ fn default() -> Self {
+ Self::Primary
+ }
+}
+
impl From<fn(&Theme) -> progress_bar::Appearance> for ProgressBar {
fn from(f: fn(&Theme) -> progress_bar::Appearance) -> Self {
Self::Custom(Box::new(f))
@@ -782,15 +845,22 @@ impl progress_bar::StyleSheet for fn(&Theme) -> progress_bar::Appearance {
}
/// The style of a rule.
-#[derive(Default)]
+/*
+ * Rule
+ */
pub enum Rule {
/// The default style.
- #[default]
Default,
/// A custom style.
Custom(Box<dyn rule::StyleSheet<Style = Theme>>),
}
+impl Default for Rule {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
impl From<fn(&Theme) -> rule::Appearance> for Rule {
fn from(f: fn(&Theme) -> rule::Appearance) -> Self {
Self::Custom(Box::new(f))
@@ -824,15 +894,19 @@ impl rule::StyleSheet for fn(&Theme) -> rule::Appearance {
}
/// The style of a scrollable.
-#[derive(Default)]
pub enum Scrollable {
/// The default style.
- #[default]
Default,
/// A custom style.
Custom(Box<dyn scrollable::StyleSheet<Style = Theme>>),
}
+impl Default for Scrollable {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
impl scrollable::StyleSheet for Theme {
type Style = Scrollable;
@@ -889,15 +963,23 @@ impl scrollable::StyleSheet for Theme {
}
/// The style of text.
-#[derive(Clone, Copy, Default)]
+/*
+ * Text
+ */
+#[derive(Clone, Copy)]
pub enum Text {
/// The default style.
- #[default]
Default,
/// Colored text.
Color(Color),
}
+impl Default for Text {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
impl From<Color> for Text {
fn from(color: Color) -> Self {
Text::Color(color)
@@ -916,15 +998,19 @@ impl text::StyleSheet for Theme {
}
/// The style of a text input.
-#[derive(Default)]
pub enum TextInput {
/// The default style.
- #[default]
Default,
/// A custom style.
Custom(Box<dyn text_input::StyleSheet<Style = Theme>>),
}
+impl Default for TextInput {
+ fn default() -> Self {
+ Self::Default
+ }
+}
+
impl text_input::StyleSheet for Theme {
type Style = TextInput;
diff --git a/iced_wgpu/src/lib.rs b/iced_wgpu/src/lib.rs
index dcb699e8..5b3cda57 100644
--- a/iced_wgpu/src/lib.rs
+++ b/iced_wgpu/src/lib.rs
@@ -37,6 +37,7 @@
#![forbid(rust_2018_idioms)]
#![allow(clippy::inherent_to_string, clippy::type_complexity)]
#![cfg_attr(docsrs, feature(doc_cfg))]
+#![feature(generic_associated_types)]
pub mod settings;
pub mod triangle;