Reputation: 63
My setup consists of a SQL database, a Rust library to access that database, and a Rust gui to display the data. The library contains a build.rs script that generates the schema.rs file for the SQL database. It does so using the diesel_cli (because I have not found a smarter way to do that). This means that having diesel_cli installed is a requirement to build the library. I recently decided to split gui and library into separate packages. The gui now refers to the library as a dependency via git URL.
Locally everything builds as expected. My github pipeline of the gui however fails with a panic in the build script of the library, because it does not have diesel_cli installed. I am pretty confident that the build script was not run when I built the gui locally.
In an attempt to fix this I checked the environment variable containing the package name, to only run the content of the build script when building the library, but to no avail.
From the Cargo book:
"If a manifest contains a links
key, then Cargo supports overriding the build script specified with a custom library. "
I think this refers to linking against a fully compiled binary. But I'm very happy to rebuild my library when building my gui. I just don't want to execute the code generation. So I do not think that this is a duplicate of this question.
To summarise:
My build.rs in the library looks like this ("lorecore" is the library name):
extern crate cbindgen;
use std::{env, process::Command};
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/api/c_api.rs");
println!("cargo:rerun-if-changed=migrations/");
if env!("CARGO_PKG_NAME") != "lorecore" {
return;
}
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
// Generate C header file
cbindgen::Builder::new()
.with_crate(crate_dir)
.with_no_includes()
.with_language(cbindgen::Language::C)
.generate()
.expect("Unable to generate C header file.")
.write_to_file("lorecore_api.h");
// Create dummy database
let mut cmd = Command::new("diesel");
cmd.arg("setup").arg("--database-url=dummy.db");
cmd.output().expect("Failed to execute diesel migrations");
// Create/Update schema.rs
let mut cmd = Command::new("diesel");
cmd.arg("print-schema").arg("--database-url=dummy.db");
let schema = cmd.output().expect("Failed to execute diesel migrations");
std::fs::write("src/sql/schema.rs", schema.stdout).expect("Failed to write schema.rs");
// Delete dummy.db
std::fs::remove_file("dummy.db").expect("Failed to delete dummy.db");
// Call cargo fmt
let mut cmd = Command::new("cargo");
cmd.arg("fmt");
cmd.output().expect("Failed to execute cargo fmt");
}
And here's my Cargo.toml from the gui, if that's of any importance:
[package]
name = "loregui"
version = "0.1.0"
edition = "2021"
[dependencies]
iced = { version = "0.10.0", features=["lazy"] }
iced_aw = { version = "0.7.0", default-features = false, features = ["card", "modal", "selection_list"] }
lorecore = { git = "https://github.com/TheComamba/LoreCore.git" }
preferences = {version = "1.1.0"}
rfd = "0.11.3" # file dialogs
The excerpt from my pipeline yaml file that gets executed is also pretty straightforward:
steps:
- uses: actions/checkout@v3
- name: Install dependencies for Linux
if: matrix.os == 'ubuntu-latest'
run: |
apt-get update
apt-get install -y sudo curl build-essential cmake pkg-config libfontconfig1-dev cargo
./scripts/install_build_dependencies_linux.sh
- uses: dtolnay/rust-toolchain@stable
- uses: clechasseur/rs-cargo@v1
if: ${{ !inputs.isRelease }}
with:
command: build
Upvotes: 3
Views: 280