Skip to content
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

Set the rpath to Qt for Rust binaries #797

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions api/sixtyfps-rs/sixtyfps-build/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,5 +269,25 @@ pub fn compile_with_config(
println!("cargo:rerun-if-env-changed=SIXTYFPS_STYLE");

println!("cargo:rustc-env=SIXTYFPS_INCLUDE_GENERATED={}", output_file_path.display());

apply_linker_flags();

Ok(())
}

// Backends such as Qt or the MCU might need special link flags. We don't want to require users to have to
// deal with those, so propagate them here.
fn apply_linker_flags() {
// Same logic as in sixtyfps-rendering-backend-default's build script to get the path
if let Some(path) = std::env::var_os("OUT_DIR").and_then(|path| {
Some(Path::new(&path).parent()?.parent()?.join("SIXTYFPS_BACKEND_LINK_FLAGS.txt"))
}) {
// unfortunately, if for some reason the file is changed, it is changed after cargo decide to re-run
// this build script or not. So that means one will need two build to settle the right thing.
println!("cargo:rerun-if-changed={}", path.display());

if let Ok(mut link_flags_file) = std::fs::File::open(path) {
std::io::copy(&mut link_flags_file, &mut std::io::stdout()).ok();
}
}
}
37 changes: 34 additions & 3 deletions sixtyfps_runtime/rendering_backends/default/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright © SixtyFPS GmbH <[email protected]>
// SPDX-License-Identifier: (GPL-3.0-only OR LicenseRef-SixtyFPS-commercial)

use std::fmt::Write;
use std::path::Path;

fn main() {
Expand Down Expand Up @@ -28,8 +29,38 @@ fn main() {
// out_dir is something like
// <target_dir>/build/sixtyfps-rendering-backend-default-1fe5c4ab61eb0584/out
// and we want to write to a common directory, so write in the build/ dir
let target_path =
let style_target_path =
Path::new(&out_dir).parent().unwrap().parent().unwrap().join("SIXTYFPS_DEFAULT_STYLE.txt");
std::fs::write(target_path, if has_native_style { b"native\n" as &[u8] } else { b"fluent\n" })
.unwrap();
std::fs::write(
style_target_path,
if has_native_style { b"native\n" as &[u8] } else { b"fluent\n" },
)
.unwrap();

let mut link_flags = String::new();

for backend in ["GL", "QT"] {
if let Ok(args) =
std::env::var(format!("DEP_SIXTYFPS_RENDERING_BACKEND_{}_LINK_ARGS", backend))
{
for arg in args.split('|') {
write!(&mut link_flags, "cargo:rustc-link-arg={}\n", arg).unwrap();
}
}
if let Ok(args) =
std::env::var(format!("DEP_SIXTYFPS_RENDERING_BACKEND_{}_LINK_SEARCH_PATHS", backend))
{
for arg in args.split('|') {
write!(&mut link_flags, "cargo:rustc-link-search={}\n", arg).unwrap();
}
}
}

let link_flags_target_path = std::path::Path::new(&out_dir)
.parent()
.unwrap()
.parent()
.unwrap()
.join("SIXTYFPS_BACKEND_LINK_FLAGS.txt");
std::fs::write(link_flags_target_path, link_flags).unwrap();
}
14 changes: 13 additions & 1 deletion sixtyfps_runtime/rendering_backends/qt/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ fn main() {
// Ref: https://docs.microsoft.com/en-us/cpp/build/reference/utf-8-set-source-and-executable-character-sets-to-utf-8
config.flag_if_supported("/utf-8");

let qt_library_path = std::env::var("DEP_QT_LIBRARY_PATH").unwrap();

if cfg!(target_os = "macos") {
config.flag("-F");
config.flag(&std::env::var("DEP_QT_LIBRARY_PATH").unwrap());
config.flag(&qt_library_path);
}
config.include(std::env::var("DEP_QT_INCLUDE_PATH").unwrap()).build("lib.rs");

Expand All @@ -58,4 +60,14 @@ fn main() {
println!("cargo:rerun-if-changed=qt_widgets/tabwidget.rs");
println!("cargo:rerun-if-changed=lib.rs");
println!("cargo:SUPPORTS_NATIVE_STYLE=1");

// Cargo doesn't support implicit transitive link flags for crates (https://github.com/rust-lang/cargo/issues/9554 | https://github.com/rust-lang/cargo/issues/9562 | https://github.com/sixtyfpsui/sixtyfps/issues/566).
// Instead of requiring Rust apps to have Qt backend specific code, propagate the needed rpath link options via a DEP_ variable to the default backend, which
// can write it to a file for use by sixtyfps-build.
// For C++ apps that's not an issue because we create a cdylib, qttypes emits `rustc-cdylib-link-arg` and that *is* propagated.
// This also means that the Qt backend cannot be combined with another backend that also writes to this file. The GL backend doesn't, but the MCU
// backend might/will.
if std::env::var("CARGO_CFG_TARGET_FAMILY").as_ref().map(|s| s.as_ref()) == Ok("unix") {
println!("cargo:LINK_ARGS=-Wl,-rpath,{}", &qt_library_path)
}
}