The Comamba
The Comamba

Reputation: 63

How do I prevent build-scripts of dependencies to run?

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:

  1. Why is the build script of the dependency run in the github action, but not locally? This is primarily to sate my curiosity.
  2. How do I prevent the code generation of my dependency from running?
  3. (Bonus) Is there a smarter way to generate the schema.rs file than calling diesel_cli in build.rs?

Code

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

Answers (0)

Related Questions