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

Build failing on DEP_QT_INCLUDE_PATH environment variable when building under bazel #298

Open
andrew-otiv opened this issue Aug 23, 2023 · 5 comments

Comments

@andrew-otiv
Copy link

When building a qmetaobject-rs based demo (which builds cleanly in cargo) in bazel (with rules_rust 0.25.0 and rust 1.70.0, using the crates_repository and crate_repositories mechanisms), I am hitting:

thread 'main' panicked at 'called Result::unwrap()on anErr value: NotPresent', external/otiv3__qmetaobject-0.2.9/build.rs:22:64

This is where build.rs reads the DEP_QT_INCLUDE_PATH environment variable. That variable isn't set in the environment where I am running cargo successfully.

In the qttypes crate README, it appears these environment variables it states this is set in that crate:

In addition, the build script of this crate expose some metadata to downstream crate that also
want to use Qt's C++ API:

  • DEP_QT_VERSION: The Qt version as given by qmake
  • DEP_QT_INCLUDE_PATH: The include directory to give to the cpp_build crate to locate the Qt headers
  • DEP_QT_LIBRARY_PATH: The path containing the Qt libraries.

So I suspect bazel is building qttypes and my crate in stricter isolation (compared to cargo) and will need additional configuration to pass on those variables.

I will keep studying and will update the ticket as I go along, but if someone already resolved this, let me know. Thanks!

@andrew-otiv
Copy link
Author

from qttype's lib.rs:

//! Note: It is important to depend directly on `qttype`, it is not enough to rely on the
//! dependency coming transitively from another dependencies, otherwise the `DEP_QT_*`
//! environment variables won't be defined.

Adding the explicit dependency on qttype in my project's Cargo.toml (which is in turn parsed by bazel to scrape dependencies), results in the same error.

@andrew-otiv
Copy link
Author

I believe the relevant paths can be scraped from the output of qttypes's build.rs file. Here is the relevant output from cargo clean -p qttypes; cargo build -vv:

[qttypes 0.2.9] cargo:VERSION=5.15.3
[qttypes 0.2.9] cargo:LIBRARY_PATH=/usr/lib/x86_64-linux-gnu
[qttypes 0.2.9] cargo:INCLUDE_PATH=/usr/include/x86_64-linux-gnu/qt5
[qttypes 0.2.9] cargo:FOUND=1
[qttypes 0.2.9] cargo:COMPILE_FLAGS=
[qttypes 0.2.9] cargo:rustc-cdylib-link-arg=-Wl,-rpath,/usr/lib/x86_64-linux-gnu
[qttypes 0.2.9] cargo:rustc-link-search=/usr/lib/x86_64-linux-gnu
[qttypes 0.2.9] cargo:rustc-link-lib=Qt5Core
[qttypes 0.2.9] cargo:rustc-link-lib=Qt5Gui
[qttypes 0.2.9] cargo:rustc-link-lib=Qt5Widgets

@andrew-otiv
Copy link
Author

So if I understand correctly, those line starting with "cargo:" in the stdout of qttypes' build.rs are the metadata that should get passed on... is it a bug that there aren't ~also lines starting with "DEP_QT_" as expected by crates building against qmetaobject?

@andrew-otiv
Copy link
Author

I am now able to build and run my small qmetaobject-rs demo project in bazel using a hacky workaround involving hard coding the paths to qt in another part of the build! Steps:

  1. Print the output of qttypes' build.rs as above using "cargo build -vv" in qttypes crate, and observe the values for
  2. Include an extra annotation in your WORKSPACE.bazel, with the values adjusted to match step 1, for the INCLUDE_PATH, QT_VERSION, and COMPILE_FLAGS variables, but with a "DEP_QT_" prefix:
crates_repository(
    ...
    annotations = {
        "qmetaobject": [ crate.annotation(build_script_env=
            {
                'DEP_QT_INCLUDE_PATH': '/usr/include/x86_64-linux-gnu/qt5',
                'DEP_QT_VERSION': '5.15.3',
                'DEP_QT_COMPILE_FLAGS': '',
            }
        ) ],
    }
)
  1. Don't forget to add dependencies to any .qml files you're embedding to the "compile_data" argument of rust_binary, i.e.:
rust_binary(
    ...
    compile_data = ["src/ui.qml"],
)

I am a bit baffled as to why cargo works but bazel didn't (without the above hack). It could be that qmetaobject isn't propagating the environment variables correctly, but qmetaobject is just getting lucky that cargo is sloppy an the environment is getting re-used.

@ogoffart
Copy link
Member

So if I understand correctly, those line starting with "cargo:" in the stdout of qttypes' build.rs are the metadata that should get passed on...

Yes: https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key

It looks like a bug in the bazel system

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants