Problem
Cargo synthesizes several compile-time environment variables for test and bench targets. including:
- OUT_DIR
- CARGO_MANIFEST_DIR
- CARGO_BIN_EXE_
These values work well when tests are compiled and executed within Cargo’s normal build tree.
The problem I ran into is with Rust tests executed through Yocto ptest.
In that setup, test binaries are typically built in Cargo’s build tree, then installed later into a packaged test directory and executed from there. In that situation, the original compile-time paths embedded by Cargo may no longer match the runtime layout:
- OUT_DIR may point to a build directory that no longer exists on the target
- CARGO_MANIFEST_DIR may no longer be the right base path for fixtures or installed test resources
- CARGO_BIN_EXE_ may need to point to an installed binary location instead of a build-tree-derived path
As a result, some tests fail even though the tested code itself is correct.
I also do not appear to be the first one to run into this class of issue. For example, a PR was proposed in rpm-sequoia to work around the same kind of problem by introducing project-specific environment variables for tests in a Yocto / cross-compilation context:
What led me here is that this is not isolated to a single package. I am seeing multiple Rust packages that behave similarly, and I would like to avoid solving the same problem crate-by-crate when the affected values are already synthesized by Cargo itself.
Proposed Solution
Add opt-in overrides for these test/bench compile-time values in artifact.rs::get_env():
- __CARGO_TEST_OUT_DIR_OVERRIDE
- __CARGO_TEST_MANIFEST_DIR_OVERRIDE
- __CARGO_TEST_BIN_EXE_DIR_OVERRIDE
Behavior would be:
- only apply to test and bench units
- only apply when the corresponding
__CARGO_TEST_* variable is explicitly set
- preserve current Cargo behavior otherwise
- preserve the existing cargo check fallback behavior for CARGO_BIN_EXE_*
The idea is to let environments such as Yocto ptest adapt Cargo’s standard compile-time test paths directly, instead of requiring each affected crate to implement its own workaround.
For example, in the kind of Yocto setup that motivated this issue, this would make it possible to adapt the test environment directly in the recipe, for example:
do_compile_ptest_cargo:prepend() {
os.environ["__CARGO_TEST_OUT_DIR_OVERRIDE"] = d.getVar("libdir")
os.environ["__CARGO_TEST_MANIFEST_DIR_OVERRIDE"] = d.getVar("PTEST_PATH")
}
do_install_ptest:append () {
install -d ${D}${PTEST_PATH}/src
install -m 644 ${S}/src/symbols.txt ${D}${PTEST_PATH}/src/symbols.txt
}
Notes
I have already opened a PR for this change, but I moved it back to draft while waiting for feedback and agreement from reviewers on this issue and on the proposed direction.
Thanks in advance to the maintainers and reviewers for taking the time to look at this. Please feel free to share any feedback, questions, or suggestions.
Cc: @ycongal-smile
Problem
Cargo synthesizes several compile-time environment variables for test and bench targets. including:
These values work well when tests are compiled and executed within Cargo’s normal build tree.
The problem I ran into is with Rust tests executed through Yocto ptest.
In that setup, test binaries are typically built in Cargo’s build tree, then installed later into a packaged test directory and executed from there. In that situation, the original compile-time paths embedded by Cargo may no longer match the runtime layout:
As a result, some tests fail even though the tested code itself is correct.
I also do not appear to be the first one to run into this class of issue. For example, a PR was proposed in rpm-sequoia to work around the same kind of problem by introducing project-specific environment variables for tests in a Yocto / cross-compilation context:
What led me here is that this is not isolated to a single package. I am seeing multiple Rust packages that behave similarly, and I would like to avoid solving the same problem crate-by-crate when the affected values are already synthesized by Cargo itself.
Proposed Solution
Add opt-in overrides for these test/bench compile-time values in artifact.rs::get_env():
Behavior would be:
__CARGO_TEST_*variable is explicitly setThe idea is to let environments such as Yocto ptest adapt Cargo’s standard compile-time test paths directly, instead of requiring each affected crate to implement its own workaround.
For example, in the kind of Yocto setup that motivated this issue, this would make it possible to adapt the test environment directly in the recipe, for example:
Notes
I have already opened a PR for this change, but I moved it back to draft while waiting for feedback and agreement from reviewers on this issue and on the proposed direction.
Thanks in advance to the maintainers and reviewers for taking the time to look at this. Please feel free to share any feedback, questions, or suggestions.
Cc: @ycongal-smile