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

cdylib on Windows MSVC places .lib import library only under target/*/deps while the associated .dll is placed in both deps and its parent directory #4500

Closed
tatsuya6502 opened this issue Sep 17, 2017 · 6 comments · Fixed by #4570
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` O-windows OS: Windows

Comments

@tatsuya6502
Copy link
Contributor

tatsuya6502 commented Sep 17, 2017

On all Windows MSVC, Linux and macOS, cdylib places the dynamic library (such as .dll) under ./target/{debug,release}/. However, on Windows MSVC, the associated .lib import library is not placed in there, but in ./target/{debug,release}/deps/.

Is there any reason Cargo puts the .lib under deps? The .lib file is required by MSVC C/C++ compiler (cl.exe) when linking a C program against the .dll. It would make more sense if the .lib is placed under ./target{debt,release}/ together with .dll.

PS C:\Users\tatsuya\ffi> rustc --version --verbose
rustc 1.20.0 (f3d6973f4 2017-08-27)
binary: rustc
commit-hash: f3d6973f41a7d1fb83029c9c0ceaf0f5d4fd7208
commit-date: 2017-08-27
host: x86_64-pc-windows-msvc
release: 1.20.0
LLVM version: 4.0

PS C:\Users\tatsuya\ffi> cargo --version
cargo 0.21.0 (5b4b8b2ae 2017-08-12)
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS C:\Users\tatsuya> Import-VisualStudioVars 2017 amd64
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.0.26730.12
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'

PS C:\Users\tatsuya> cd .\ffi

PS C:\Users\tatsuya> cat Cargo.toml
[package]
name = "ffi"
version = "0.1.0"
authors = ["Tatsuya Kawano <...>"]

[lib]
crate-type = ["cdylib"]

[dependencies]

PS C:\Users\tatsuya\ffi> cargo clean

PS C:\Users\tatsuya\ffi> cargo build --release
   Compiling ffi v0.1.0 (file:///C:/Users/tatsuya/ffi)
    Finished release [optimized] target(s) in 6.58 secs

PS C:\Users\tatsuya\ffi> dir .\target\release\

    Directory: C:\Users\tatsuya\ffi\target\release

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2017/09/17     21:25                .fingerprint
d-----       2017/09/17     21:25                build
d-----       2017/09/17     21:25                deps
d-----       2017/09/17     21:25                examples
d-----       2017/09/17     21:25                incremental
d-----       2017/09/17     21:25                native
-a----       2017/09/17     21:25              0 .cargo-lock
-a----       2017/09/17     21:25             77 ffi.d
-a----       2017/09/17     21:25         111616 ffi.dll      <== .dll here

PS C:\Users\tatsuya\ffi> dir .\target\release\deps\

    Directory: C:\Users\tatsuya\ffi\target\release\deps

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2017/09/17     21:25         111616 ffi.dll        <== .dll here (again)
-a----       2017/09/17     21:25           2171 ffi.dll.exp
-a----       2017/09/17     21:25           3852 ffi.dll.lib    <== .lib here
-a----       2017/09/17     21:25        1069056 ffi.pdb
@tatsuya6502
Copy link
Contributor Author

tatsuya6502 commented Sep 18, 2017

Memo

During a build, cargo::opts::cargo_rustc::link_targets() creates a hard-link (or copies a file) from \target\{debug,release}\dep\<name>.dll to \target\{dobug,release}\<name>.dll. I would add <name>.lib to the file list if nobody complains.

PS C:\Users\tatsuya\ffi> $env:RUST_LOG = 'cargo=debug'
PS C:\Users\tatsuya\ffi> cargo build --release
...
DEBUG:cargo::ops::cargo_rustc: linking C:\Users\tatsuya\ffi\target\release\deps\ffi.dll to C:\Users\tatsuya\ffi\target\release\ffi.dll
...

@alexcrichton
Copy link
Member

Yeah this is an unfortunate case where neither rustc nor Cargo knows about this file. The artifacts are generated directly into the deps folder and the MSVC linker is what ends up generating this file. We'd have to either teach rustc or cargo about this file so Cargo could handle it.

@tatsuya6502
Copy link
Contributor Author

@alexcrichton Thanks for your reply. I just read your comment on a similar issue #4535. I will work on a PR to do this in Cargo for Windows MSVC target (when I have some spare time).

So up to this point we've avoided encoding anything target-specific in Cargo, it relies solely on rustc for this sort of information. That being said I think it's time to break that rule! If Cargo were to handle this then I believe yeah, that location is where the fix would go.

@tatsuya6502
Copy link
Contributor Author

Memo

It relies solely on rustc for this sort of information.

Cargo collects the target file name (e.g. ffi.dll) by running rustc like this:

# NOTE: I'm running this on Linux.
$ echo | \
  rustc - --crate-name ___ --print=file-names --target x86_64-pc-windows-msvc \
          --crate-type cdylib

This is done by cargo::opts::cargo_rustc::context::TargetInfo::discover_crate_type. rustc currently returns only one file name.

@tatsuya6502
Copy link
Contributor Author

#4535 (comment)

I think ideally rustc would inform Cargo about this as it tends to have more target-specific information, but for the time being I think we can go ahead and implement it in Cargo (in a conservative fashion) and we can move it around later if need be

OK. I will implement it in Cargo for now.

tatsuya6502 added a commit to tatsuya6502/cargo that referenced this issue Oct 3, 2017
Fixes rust-lang#4500, rust-lang#4535

Until now, Cargo does not have any knowledge about target-specific
output files. It relies solely on rustc for this sort of information
(`rustc --print=file-names ...`).

As a result, Cargo does not place some build artifacts (files) to
target/{debug,release} directory. These files include *.wasm
for wasm32-unknown-emscripten target and *.dll.lib for
*-pc-windows-msvc cdylib target.

This commit will add such knowledge to Cargo so that *.wasm and
*.dll.lib will be placed in target/{debug,release} directory.
@carols10cents carols10cents added C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` O-windows OS: Windows labels Oct 3, 2017
@alexcrichton
Copy link
Member

@tatsuya6502 yeah I was thinking we could solve this as well as with the wasm case, thanks for the PR! I'll try to take a look at the PR soon

bors added a commit that referenced this issue Oct 9, 2017
…ichton

Handle target specific outputs such as .wasm or .dll.lib

Fixes #4500, #4535

Until now, Cargo does not have any knowledge about target-specific output files. It relies solely on rustc for this sort of information (`rustc --print=file-names ...`).

As a result, Cargo does not place some build artifacts (files) to target/{debug,release} directory. These files include *.wasm for wasm32-unknown-emscripten target and *.dll.lib for *-pc-windows-msvc cdylib target.

This commit will add such knowledge to Cargo so that *.wasm and *.dll.lib will be placed in target/{debug,release} directory.

**EDIT**: I added [a summary of changes](#4570 (comment)). Please read it for more details of changes.

**IMPORTANT**
Although I added test cases for both wasm32-unknown-emscripten and *-pc-windows-msvc cdylib targets, ~I did not do manual testing on wasm32-unknown-emscripten target as I do not have an environment with emscripten installed. It will be appreciated if anybody tests this change for wasm32-unknown-emscripten target.~  **EDIT**: Tested for both wasm32-unknown-emscripten and x86_64-pc-windows-msvc. Thanks @Herschel for the help.
@bors bors closed this as completed in #4570 Oct 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` O-windows OS: Windows
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants