rust-lang / rust-lang/rust-bindgen

[user guide] [windows] 'could not emit library file'

Open
#2,632 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

The sample code provided in the user guide for Section 3.2 Bindings for non-system libraries does not work on Windows.

Actual Results
cargo build

Output:

...
--- stderr
  thread 'main' panicked at 'could not emit library file', build.rs:63:9

I tried to dig deeper into the issue by manually running the command that the script sets up and received the following error.

ar rcs \\?\C:\Users\...\bindgen-test\hello\libhello.a \\?\C:\Users\...\bindgen-test\hello\hello.o 

Output:

C:\msys64\mingw64\bin\ar.exe: \\?\C:\Users\...\bindgen-test\hello\libhello.a: Invalid argument

When running the same command without the "\?" prefixed to the absolute path, the program runs successfully. It seems the issue is due to our use of .canonicalize(). Here is the upstream issue for this: https://github.com/rust-lang/rust/issues/42869

Expected Results

The sample code provided in the user guide for Section 3.2 Bindings for non-system libraries should work on Windows. In particular, the path used as the input to the program ar should be digestable by ar.

Temporary workaround using dunce
Replace

extern crate bindgen;

use std::env;
use std::path::PathBuf;

use bindgen::CargoCallbacks;

fn main() {
    // This is the directory where the `c` library is located.
    let libdir_path = PathBuf::from("hello")
        // Canonicalize the path as `rustc-link-search` requires an absolute
        // path.
        .canonicalize()
        .expect("cannot canonicalize path");

with

extern crate bindgen;
extern crate dunce;

use std::env;
use std::path::PathBuf;

use bindgen::CargoCallbacks;

fn main() {
    // This is the directory where the `c` library is located.
    let libdir_path = PathBuf::from("hello");
    // Canonicalize the path as `rustc-link-search` requires an absolute
    // path.
    let libdir_path = dunce::canonicalize(libdir_path)
        .expect("cannot canonicalize path");

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Section 3.2 user-guide sample and its build.rs around line 63, then inspect how canonicalize() produces the path passed to ar on Windows. Confirm the change by running cargo build for the sample on Windows and checking that the library file is emitted successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
documentation
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.