note: Run with
RUST_BACKTRACE=1 for a backtrace.I'm on linux, and trying to compile the examples is failing because glslang_validator is not generating the output file it is supposed to. It turns out that my
...vulkano/examples/target/debug/build/glsl-to-spirv-11036aceadb12936/out/glslang_validator application is 0 bytes. It returns success when you run (apparently), but it doesn't do anything.
If I manually copy ...vulkano/examples/target/debug/build/glsl-to-spirv-11036aceadb12936/out/bin/glslangValidator to ...vulkano/examples/target/debug/build/glsl-to-spirv-11036aceadb12936/out/glslang_validator then it builds.
I assume that is what this code in glsl-to-spirv/build/build.rs is supposed to do:
if let Err(_) = fs::hard_link(&path, &out_file) {
fs::copy(&path, &out_file).expect("failed to copy executable");
}
However I was unable to figure out how to debug that code. (My attempts to print out paths didn't add any output to cargo build).
I noticed this problem as well, but don't really know what happens and haven't investigated much. It only happens when you update the library, and removing the target/debug/build/glsl* directory fixes it.
If you want to try debug this, you can see the output of the build script in target/debug/build/glsl-to-spirv-xxxxx/output.
Running cargo clean and cargo build works for me. Some state is getting screwed up by specifically building one example (in my case triangle).
I'm using rustc 1.8.0-dev on a 3.16.0-38-generic linux kernel using an Ext4 (version 1.0) file system.
I checked out another copy of the source at a different path, and tried to build it. After doing a cargo build in examples (which worked) I did a cargo build --bin=triangle which did some more building and failed the same way. vulkano2/examples/target/debug/build/glsl-to-spirv-23741bf12647e3c7/out/bin/glslangValidator is 0 bytes this time though. So maybe the copy/hard link did work, but the thing it was copying from was empty. Doing cargo build again fixed it and cargo build --bin=triangle broke it again. After that it seems to be in a fixed point and building either config no longer has any effect.
I think the creepy stateful thing may be build order related, with some part of the build invalidating some other part of the build. I think the build is palatalized, so may be non-deterministic.
Repro steps (this has worked for me at least twice):
in examples:
cargo clean
cargo build (works)
cargo build --bin triangle (this builds more things and fails)
cargo build (this fails now with same error)
output from cargo build --bin triangle:
vulkano2/examples $ cargo build --bin triangle
Compiling tempfile v2.1.3
Compiling glsl-to-spirv v0.1.1 (file:///mnt/DATA/Scratch/vulkano2/examples)
Compiling wayland-window v0.2.3
Compiling vulkano-shaders v0.1.0 (file:///mnt/DATA/Scratch/vulkano2/examples)
Compiling winit v0.5.0
... (lots of warnings)
Compiling examples v0.1.0 (file:///mnt/DATA/Scratch/vulkano2/examples)
Build failed, waiting for other jobs to finish...
failed to run custom build command forexamples v0.1.0 (file:///mnt/DATA/Scratch/vulkano2/examples)
Process didn't exit successfully:/mnt/DATA/Scratch/vulkano2/examples/target/debug/build/examples-dee7d6d1fef8a51c/build-script-build(exit code: 101)
--- stdout
cargo:rerun-if-changed=src/bin/triangle_vs.glsl--- stderr
thread '' panicked at 'failed to open SPIR-V output file: Error { repr: Os { code: 2, message: "No such file or directory" } }', src/libcore/result.rs:746
note: Run withRUST_BACKTRACE=1for a backtrace.
Ping @alexcrichton if you have some time? Since you wrote both Cargo and cmake-rs, maybe you have an idea?
Link to the problematic build script: https://github.com/tomaka/vulkano/blob/c9ccec44854dd95131314075bf9ac62cabd13099/glsl-to-spirv/build/build.rs
Unfortunately I may be missing some context here, could you summarize what's going on perhaps?
@alexcrichton Basically the glsl-to-spirv crate contains the source code of a C program named glslang.
The build script of that crate runs cmake on that source code, then links or copies the executable to OUT_DIR. The crate itself then invokes that executable. So far so good.
Everything works fine so far.
The problem is that if you do a small modification to the build script itself for example, then the executable that lands in OUT_DIR is of size 0. For some reason running it does not produce any error either. The executable in CMake's output directory looks correct however.
Ah it just struck me that maybe CMake rebuilds the executable anyway, which causes the link to become invalid? I'm not sure if that's true for hard links. I'm not familiar enough with Linux.
Someone on IRC suggested that CMake maybe does ftruncate the old executable.
Maybe we should just forget about linking and just copy.
Hm interesting! If you run cmake twice by hand does this reproduce?
Possibly related: I frequently get the following error when upating on Windows, but rerunning cargo build always fixes it:
error: failed to run custom build command for `glsl-to-spirv v0.1.2`
process didn't exit successfully: `C:\Users\Ralith\src\sg2-client\target\debug\build\glsl-to-spirv-4f198926f60b2e06\build-script-build` (exit code: 101)
--- stdout
cargo:rerun-if-changed=build/glslangValidator.exe
--- stderr
thread 'main' panicked at 'failed to copy executable: Error { repr: Os { code: 32, message: "The process cannot access the file because it is being used by another process." } }', src\libcore\result.rs:859
stack backtrace:
0: std::sys_common::backtrace::_print
at C:\projects\rust\src\libstd\sys_common\backtrace.rs:94
1: std::panicking::default_hook::{{closure}}
at C:\projects\rust\src\libstd\panicking.rs:354
2: std::panicking::default_hook
at C:\projects\rust\src\libstd\panicking.rs:371
3: std::panicking::rust_panic_with_hook
at C:\projects\rust\src\libstd\panicking.rs:549
4: std::panicking::begin_panic<collections::string::String>
at C:\projects\rust\src\libstd\panicking.rs:511
5: std::panicking::begin_panic_fmt
at C:\projects\rust\src\libstd\panicking.rs:495
6: std::panicking::rust_begin_panic
at C:\projects\rust\src\libstd\panicking.rs:471
7: core::panicking::panic_fmt
at C:\projects\rust\src\libcore\panicking.rs:69
8: core::result::unwrap_failed<std::io::error::Error>
at C:\projects\rust\src\libcore\macros.rs:29
9: core::result::Result<u64, std::io::error::Error>::expect<u64,std::io::error::Error>
at C:\projects\rust\src\libcore\result.rs:761
10: build_script_build::main
at .\build\build.rs:27
11: panic_unwind::__rust_maybe_catch_panic
at C:\projects\rust\src\libpanic_unwind\lib.rs:98
12: std::rt::lang_start
at C:\projects\rust\src\libstd\rt.rs:50
13: main
14: __scrt_common_main_seh
at f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:259
15: BaseThreadInitThunk
Build failed, waiting for other jobs to finish...
error: build failed
I've hit this a few times in the past couple weeks - I think there's enough context in this ticket for me to take a stab at it.
I think I've tracked this down. It's fun!
On an initial build, here's what happens:
cmakemake installbin/glslangValidator to glslang_validatorOn a rebuild, here's what happens
cmake (no-op)make install (no-op)bin/glslangValidator to glslang_validator :boom: The first thing Rust's copy routine does is truncate the destination... which in this case is also the source. (see https://github.com/rust-lang/rust/blob/master/src/libstd/sys/unix/fs.rs#L764-L778 and https://github.com/rust-lang/rust/blob/master/src/libstd/fs.rs#L261-L263 )
Getting rid of the hard link seems like the best solution here (and possibly also filing a bug about how rust's copy interacts with hard links!). If we're worried about the disk usage (about 20M) of a copy, would just renaming the executable be a sane option?
EDIT: Oh, the rename won't work on windows where we have a static file in the crate source. I'm just gonna open up a PR to remove the hardlinking code and use a copy unconditionally