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

[Question] How to dllexport NvOptimusEnablement symbol to auto select dedicated Nvidia GPU? #582

Closed
panpang opened this issue Dec 30, 2016 · 3 comments
Labels

Comments

@panpang
Copy link

panpang commented Dec 30, 2016

This is rust related question with specifics for gpu usage in rust-sdl2.
In normal C/C++ SDL2 app I wrote, adding the following code
extern "C" {
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
causes the driver system with integrated and dedicated nvidia gpu, to auto select the dedicated nvidia gpu.

See here for some explanation of the mechanism->
urho3d/urho3d#139
http://stackoverflow.com/questions/16823372/forcing-machine-to-use-dedicated-graphics-card

I searched around rust documentation but things i found were about dllexport of pub methods of libs, not applications, and not just symbol values. I got confused about the best way to export this symbol from a rust-sdl2 app (using crate)

How can I make my rust sdl app (not a library) dllexport this symbol with this value ?

@panpang panpang changed the title How to dllexport NvOptimusEnablement symbol to auto select dedicated Nvidia GPU? [Question] How to dllexport NvOptimusEnablement symbol to auto select dedicated Nvidia GPU? Dec 30, 2016
@Cobrand
Copy link
Member

Cobrand commented Dec 30, 2016

I think this is more related to rust itself than rust-sdl2, and unfortunately I don't know anything about your issue.
You could try getting help from Mozilla's IRC in #rust, or maybe post an issue mentioning this one is the rust-lang/rust repository.

This might be useful for other rust-sdl2 users as well, so if you find a clue or a solution we could add this for both AMD and Nvidia GPUs, so please follow notify us if you do find something

@Cobrand
Copy link
Member

Cobrand commented Jan 11, 2017

Did you figure something out ?

@panpang
Copy link
Author

panpang commented Jan 12, 2017

I put the question in rust user forums here
https://users.rust-lang.org/t/question-how-to-dllexport-nvoptimusenablement-symbol-to-auto-select-dedicated-nvidia-gpu/8617

There are views but no replies...

I tried this in main.rs

#[no_mangle] pub static NvOptimusEnablement: i64 = 1;
#[link_args = "/EXPORT:NvOptimusEnablement,DATA"]
extern {}

which gives error ->

error: the `link_args` attribute is not portable across platforms, it is recommended to use `#[link(name = "foo")]` instead (see issue #29596)
 --> src\main.rs:6:1

but then got hit with this issue ->
rust-lang/rust#29596

I investigated ways to modify linking via cargo.toml via .cargo/config file
This file is put in the project root at ".cargo" folder with contents like this
[target.x86_64-pc-windows-msvc]
rustflags = [ "-C", "link-args=/EXPORT:NvOptimusEnablement,DATA"]

this works up to the linker but now, and I get this error:

error: linking with `link.exe` failed: exit code: 1120
  |
  = note: "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe" "/LIBPATH:C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\lib\\amd64" "/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.10240.0\\ucrt\\x64" "/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\8.1\\lib\\winv6.3\\um\\x64" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\hakanguleryuz\\xxxxxxxxxx\\target\\debug\\build\\sdl2-sys-6e3faa315e9c228a\\build_script_build.0.o" "/OUT:C:\\Users\\hakanguleryuz\\xxxxxxxxxxx\\target\\debug\\build\\sdl2-sys-6e3faa315e9c228a\\build_script_build.exe" "/OPT:REF,ICF" "/DEBUG" "/LIBPATH:C:\\Users\\xxxxxxxxxxxxxx\\target\\debug\\deps" "/LIBPATH:C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-f5a209a9.rlib" "C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libpanic_unwind-f5a209a9.rlib" "C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunwind-f5a209a9.rlib" "C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librand-f5a209a9.rlib" "C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcollections-f5a209a9.rlib" "C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_unicode-f5a209a9.rlib" "C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liblibc-f5a209a9.rlib" "C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-f5a209a9.rlib" "C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc_system-f5a209a9.rlib" "C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-f5a209a9.rlib" "C:\\Users\\hakanguleryuz\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-f5a209a9.rlib" "ws2_32.lib" "userenv.lib" "shell32.lib" "advapi32.lib" "msvcrt.lib" "/EXPORT:NvOptimusEnablement,DATA"
  = note: LINK : error LNK2001: unresolved external symbol NvOptimusEnablement
C:\xxxxxxxxxxxxxxxx\target\debug\build\sdl2-sys-6e3faa315e9c228a\build_script_build.lib : fatal error LNK1120: 1 unresolved externals

I guess the value (not function) export in main.rs did not work its way up to the build_script_build.lib

#[no_mangle] pub static NvOptimusEnablement: i64 = 1;
//#[link_args = "/EXPORT:NvOptimusEnablement,DATA"]
extern {}

Note: I am using visual studio tool "dumpbin" to check exports in the .exe and not seeing.
dumpbin usage as explained here (for some lib symbols) ->
http://stackoverflow.com/questions/40548334/rust-code-cannot-link-with-a-c-library-compiled-on-windows-because-there-is-an-u

This issue seems to be related
rust-lang/cargo#595
and there is an important comment in this issue by 'larsbergstrom':
"We have worked around this for now by instead setting the linker to be a shell script that manually invokes everything we need."

So we can totally replace the linker with our script
So if get custom built small .lib, say mynvoptimusvalueexport.lib that exports the value for linker to find, and append this in my custom linker shell script, then there may be some resolution into this.
but I did not, yet finalize this to solution.

Overall impression is that, according to some comments I read in issues related to this, the linker area in rust (and its integration with cargo) is yet to stabilize, and may still change in future. So a custom linker attachment may now be the only way forward.

On a related but different subject:
I am also having problems with static linking of the MSVC runtime, which I want to have,
due to portability issues of the final .exe. I think this is important to achieve.
There are some hints on how to do this as well, but I did not yet accomplish this.
Info here
rust-lang/libc#290
and here
https://github.com/rust-lang/rfcs/blob/master/text/1721-crt-static.md

@panpang panpang closed this as completed Jan 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants