-
Notifications
You must be signed in to change notification settings - Fork 8
Add opt-in static libphosh embedding for GTK3 #186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
3a2c52a
phosh: register resources for static embedding
samcday 3abe4f6
bindings: support explicit static libphosh builds
samcday bfd03d6
build: add vendored Phosh development commands
samcday 1570763
docs: record subtree update and export workflow
samcday File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| [alias] | ||
| xtask = "run --quiet --package xtask --" | ||
| vendored-phosh = "run --quiet --config .cargo/vendor.toml --package xtask -- vendored-phosh" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| #!/usr/bin/env bash | ||
| # Cargo invokes this for vendored test binaries and `cargo run --config ...`. | ||
| set -euo pipefail | ||
|
|
||
| # The dispatcher must start before libphosh (and its schemas) has been built. | ||
| if [[ $(basename "$1") == xtask ]]; then | ||
| exec "$@" | ||
| fi | ||
|
|
||
| profile_dir=$(dirname "$1") | ||
| if [[ $(basename "$profile_dir") == deps ]]; then | ||
| profile_dir=$(dirname "$profile_dir") | ||
| fi | ||
| schemas=("$profile_dir"/build/libphosh-sys-*/out/phosh/data/gschemas.compiled) | ||
| for schema in "${schemas[@]}"; do | ||
| if [[ ! -f "$schema" ]] || ! cmp -s "${schemas[0]}" "$schema"; then | ||
| echo 'Missing or inconsistent vendored Phosh schemas; clean libphosh-sys with the vendor configuration and rebuild.' >&2 | ||
| exit 1 | ||
| fi | ||
| done | ||
| export GSETTINGS_SCHEMA_DIR | ||
| GSETTINGS_SCHEMA_DIR=$(cd "$(dirname "${schemas[0]}")" && pwd) | ||
| exec "$@" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # Opt in from the repository root. Ordinary builds and publication use crates.io. | ||
| [patch.crates-io] | ||
| libphosh = { path = "libphosh-rs/libphosh" } | ||
| libphosh-sys = { path = "libphosh-rs/libphosh/sys" } | ||
|
|
||
| [env] | ||
| PHROG_LIBPHOSH_BUILD_INTERNAL = { value = "always", force = true } | ||
|
|
||
| [build] | ||
| target-dir = "target/vendor" | ||
|
|
||
| [target.'cfg(unix)'] | ||
| runner = ".cargo/vendor-runner.sh" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,184 @@ | ||
| // Generated by gir (https://github.com/gtk-rs/gir @ be9aa145267c) | ||
| // from ../.. (@ b4c1dbc27547+) | ||
| // from ../../gir-files (@ 6cd7b656acd6) | ||
| // DO NOT EDIT | ||
| #[cfg(not(docsrs))] | ||
| mod native_source; | ||
|
|
||
| #[cfg(not(docsrs))] | ||
| use std::process; | ||
| use std::{collections::HashSet, env, path::PathBuf, process::Command}; | ||
|
|
||
| #[cfg(docsrs)] | ||
| fn main() {} // prevent linking libraries to avoid documentation failure | ||
| fn main() {} | ||
|
|
||
| #[cfg(not(docsrs))] | ||
| fn main() { | ||
| if let Err(s) = system_deps::Config::new().probe() { | ||
| println!("cargo:warning={s}"); | ||
| process::exit(1); | ||
| println!("cargo:rerun-if-env-changed=PHOSH_SRC"); | ||
| println!("cargo:rerun-if-env-changed=PHROG_LIBPHOSH_BUILD_INTERNAL"); | ||
| match env::var("PHROG_LIBPHOSH_BUILD_INTERNAL").as_deref() { | ||
| Ok("always") => build_bundled(), | ||
| Err(env::VarError::NotPresent) | Ok("never") => { | ||
| system_deps::Config::new() | ||
| .probe() | ||
| .expect("system libphosh-0.45 is required (or set PHROG_LIBPHOSH_BUILD_INTERNAL=always)"); | ||
| } | ||
| _ => panic!("PHROG_LIBPHOSH_BUILD_INTERNAL must be always or never; implicit fallback is not supported"), | ||
| } | ||
| } | ||
|
|
||
| #[cfg(not(docsrs))] | ||
| fn run(command: &mut Command) { | ||
| let status = command | ||
| .status() | ||
| .unwrap_or_else(|err| panic!("{command:?}: {err}")); | ||
| assert!(status.success(), "{command:?} failed: {status}"); | ||
| } | ||
|
|
||
| #[cfg(not(docsrs))] | ||
| fn build_bundled() { | ||
| assert_eq!(env::var("HOST").unwrap(), env::var("TARGET").unwrap(), | ||
| "bundled libphosh currently supports native builds only; use system libphosh for cross builds"); | ||
| let manifest = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); | ||
| let source = env::var_os("PHOSH_SRC") | ||
| .map(PathBuf::from) | ||
| .unwrap_or_else(|| manifest.join("../../../phosh")); | ||
| let source = source | ||
| .canonicalize() | ||
| .expect("Phosh source tree not found; set PHOSH_SRC"); | ||
| assert!( | ||
| source.join("meson.build").is_file(), | ||
| "PHOSH_SRC must point to a Phosh source tree" | ||
| ); | ||
| println!("cargo:rerun-if-changed={}", source.display()); | ||
| let mut configuration = format!("source={source:?}\n"); | ||
| for name in [ | ||
| "CC", | ||
| "CFLAGS", | ||
| "CPPFLAGS", | ||
| "LDFLAGS", | ||
| "PKG_CONFIG_PATH", | ||
| "PKG_CONFIG_LIBDIR", | ||
| ] { | ||
| println!("cargo:rerun-if-env-changed={name}"); | ||
| configuration.push_str(&format!("{name}={:?}\n", env::var_os(name))); | ||
| } | ||
| let output = PathBuf::from(env::var_os("OUT_DIR").unwrap()); | ||
| let staged_source = output.join("phosh-source"); | ||
| native_source::stage(&source, &staged_source).expect("failed to stage Phosh sources"); | ||
| println!("cargo:rerun-if-env-changed=PHROG_VENDOR_OFFLINE"); | ||
| match env::var("PHROG_VENDOR_OFFLINE").as_deref() { | ||
| Ok("1") => (), | ||
| Err(env::VarError::NotPresent) | Ok("0") => { | ||
| run(Command::new("meson") | ||
| .args(["subprojects", "download", "--sourcedir"]) | ||
| .arg(&staged_source) | ||
| .args(["gvc", "libcall-ui"])); | ||
| } | ||
| _ => panic!("PHROG_VENDOR_OFFLINE must be 0 or 1"), | ||
| } | ||
| let build = output.join("phosh"); | ||
| let inputs = output.join("phosh-build-inputs"); | ||
| // Meson caches the source directory, compiler and environment flags at setup. | ||
| // Recreate only our generated build tree when those inputs change. | ||
| if build.exists() && std::fs::read_to_string(&inputs).ok().as_ref() != Some(&configuration) { | ||
| std::fs::remove_dir_all(&build).expect("failed to reset the native build directory"); | ||
| } | ||
| run(Command::new("meson") | ||
| .args([ | ||
| "setup", | ||
| "--reconfigure", | ||
| "--backend=ninja", | ||
| "--wrap-mode=nodownload", | ||
| "--prefix=/usr", | ||
| // Do not load plugins belonging to the system Phosh ABI. | ||
| "--libdir=lib/phrog", | ||
| "-Dbindings-lib=true", | ||
| "-Dtests=false", | ||
| "-Dphoc_tests=disabled", | ||
| "-Dlockscreen-plugins=false", | ||
| "-Dquick-setting-plugins=false", | ||
| ]) | ||
| .arg(&build) | ||
| .arg(&staged_source)); | ||
| run(Command::new("meson") | ||
| .args(["compile", "-C"]) | ||
| .arg(&build) | ||
| .args([ | ||
| "phosh-0.45:static_library", | ||
| "phosh-tool", | ||
| "glib-compile-schemas", | ||
| ])); | ||
|
|
||
| std::fs::write(inputs, configuration).expect("failed to record native build inputs"); | ||
|
|
||
| // Promote only libphosh's private dependencies. A recursive --static probe | ||
| // also exposes private dependencies of shared libraries (e.g. PulseAudio's | ||
| // libpulsecommon), which the executable must not link directly. | ||
| let metadata_dir = build.join("meson-uninstalled"); | ||
| let metadata = std::fs::read_to_string(metadata_dir.join("libphosh-0.45-uninstalled.pc")) | ||
| .expect("failed to read Meson's uninstalled libphosh metadata"); | ||
| let mut shared_metadata = metadata.clone(); | ||
| for field in ["Requires", "Libs"] { | ||
| let public = format!("{field}:"); | ||
| let private = format!("{field}.private:"); | ||
| let values: Vec<_> = metadata | ||
| .lines() | ||
| .filter_map(|line| { | ||
| line.strip_prefix(&public) | ||
| .or_else(|| line.strip_prefix(&private)) | ||
| }) | ||
| .collect(); | ||
| shared_metadata = shared_metadata | ||
| .lines() | ||
| .filter(|line| !line.starts_with(&public) && !line.starts_with(&private)) | ||
| .map(|line| format!("{line}\n")) | ||
| .collect(); | ||
| shared_metadata.push_str(&format!("{field}: {}\n", values.join(" "))); | ||
| } | ||
| std::fs::write(metadata_dir.join("phrog-libphosh.pc"), shared_metadata) | ||
| .expect("failed to write embedding metadata"); | ||
|
|
||
| // This build's metadata must win over any installed libphosh. | ||
| let mut paths = vec![metadata_dir]; | ||
| if let Some(existing) = env::var_os("PKG_CONFIG_PATH") { | ||
| paths.extend(env::split_paths(&existing)); | ||
| } | ||
| env::set_var("PKG_CONFIG_PATH", env::join_paths(paths).unwrap()); | ||
| let lib = pkg_config::Config::new() | ||
| .cargo_metadata(false) | ||
| .print_system_libs(false) | ||
| .statik(false) | ||
| .probe("phrog-libphosh") | ||
| .expect("failed to read bundled libphosh pkg-config metadata"); | ||
| // pkg-config can repeat transitive flags many times. Preserve their | ||
| // order while avoiding GCC's per-argument/environment size limit. | ||
| let mut seen_paths = HashSet::new(); | ||
| for path in &lib.link_paths { | ||
| if !seen_paths.insert(path) { | ||
| continue; | ||
| } | ||
| println!("cargo:rustc-link-search=native={}", path.display()); | ||
| } | ||
| let mut seen_libs = HashSet::new(); | ||
| for name in &lib.libs { | ||
| if !seen_libs.insert(name) { | ||
| continue; | ||
| } | ||
| let bundled = lib | ||
| .link_paths | ||
| .iter() | ||
| .any(|path| path.starts_with(&build) && path.join(format!("lib{name}.a")).is_file()); | ||
| assert!( | ||
| name != "phosh-0.45" || bundled, | ||
| "bundled libphosh archive not found" | ||
| ); | ||
| println!( | ||
| "cargo:rustc-link-lib={}{}", | ||
| if bundled { "static=" } else { "" }, | ||
| name | ||
| ); | ||
| } | ||
| let mut seen_args = HashSet::new(); | ||
| for args in &lib.ld_args { | ||
| if !seen_args.insert(args) { | ||
| continue; | ||
| } | ||
| println!("cargo:rustc-link-arg=-Wl,{}", args.join(",")); | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.