Crosscompile from 64 to 32 bit

Hi!

I’ve installed the latest toolkit (2.2, 64bit) on a Vista 64bit box, I’m using VS2008. Now I’d like to compile a project both to 32 and 64 bit (latter is no problem). For 32 bit it seems that the object files of the .cu files are 64 bit: “fatal error LNK1112: module machine type ‘x64’ conflicts with target machine type ‘X86’”. Is there a way to make the nvcc from the 64bit toolset to compile to X86?

Thanks && kind regards

EDIT: I copied the libs and dlls from the 32-bit Toolkit (2.2), and everything works fine under 64 bit using the “–machine 32” switch (and naturally linking and executing against the 32bit files). Then I noticed that version 2.3 is already out, which makes it easier because the 64bit install also gives the 32bit flavored libs/dlls… → problem solved, thanks :)

I have just successfully compiled for both 32 and 64 bit from Windows 7 64.

Initially I had linker errors looking like yours.

For 64 bit, I had to:

  1. switch the platform/target from ‘Win32’ to ‘x64’ in the build tool bar.

For 32 bit, I had to:

  1. change environment variable CUDA_LIB_PATH from C:\CUDA\lib64 to C:\CUDA\lib. (Do NOT change the \bin path as you need to run the 64bit compiler always.)
  2. add ‘–machine 32’ to the Extra Options on Project Properties → CUDA Build Ruile 2.3 → General → Extra Options.
  3. add ‘C:\CUDA\bin’ to Path environment variable. (Thanks tmurray)

To build for both platforms together might be a bit more effort as you may need to hard code the CUDA_LIB_PATH value in each configuration. I have not done this myself yet. Probably the easiest solution is to add CUDA_LIB_PATH64 (or 32) and use the appropriate env var in each target platform configuration.

Edit: I spoke too soon. Although I can compile for 32bit, the build does not run. It exits with 'The application was unable to start correctly (0xc000007b). Click OK to close the application. ’ I will investigate further.
Edit: Thanks tmurray, that fixed it. Added step 3 for people reading this post.

add C:\CUDA\bin to your path, the 0xc0000007b error is caused by the wrong bitness of cudart.dll being found.

this will all be resolved at some point.

Hi Greg!

Thanks for that “–machine 32” option - the cross-compilation really works, however, I fear my version (2.2) of the CUDA Toolkit does not have libs for 32 and 64 bit (I only have a CUDA/lib directory, containing the 64bit libs). I assume you’re using some kind of beta/dev release (2.3)? I’ll try to install the missing libs/dlls from the 32bit Toolkit.

Thanks && Kind regards

Glad to hear you are getting somewhere. The v2.3 is final and available from here in the forum: http://forums.nvidia.com/index.php?showtopic=102548

Just want to say thanks. I was having the same issues on Windows XP x64 when compiling for x86, but following these instructions, things seem to work now. Somehow, having the 32-bit cudart.dll in the same directory as the exe, and the 64-bit cudart on the path allows the exe to run regardless of whether it is 32-bit or 64-bit. I don’t understand it, but it works.

Good to hear Gabriel.i.r, these instructions were helpful to me also. By the way, when a .exe is started, it locates its dependent .dlls. It first looks in the .exe folder, then the folders in the PATH environment variable, in the order they are listed.

Right, but the 32-bit and 64-bit cudart dlls have the same name. Isn’t the one that is found first always loaded? So why doesn’t the 64-bit exe find the 32-bit dll in it’s own folder, try to load it, and then crash because the bitness doesn’t match?

(I’ve had that problem before with other dlls, so I’m at a loss as to why things seem to work here.)

You are right. I’m not sure how that is arbitrated. At least it works :). I suppose building to separate folders and dropping in appropriate .dlls will remove any future confusion.

Yeah, in fact I just checked that things work fine if cudart is just on the path, not in the exe directory.

So, to summarize:

  1. Define the following environment variables:

CUDA_LIB_PATH32

CUDA_LIB_PATH64

CUDA_BIN_PATH32

CUDA_BIN_PATH64

pointing to the appropriate CUDA Toolkit directories.

  1. Add %CUDA_BIN_PATH32% and %CUDA_BIN_PATH64% to the PATH. The order doesn’t seem to matter, but I have the 64-bit one first.

  2. In Visual Studio project properties → Configuration Properties → Linker → General → Additional Library Directories, change CUDA_LIB_PATH to CUDA_LIB_PATH[32|64] as appropriate for the target platform. (If you have both “Debug” and “Release” configurations, don’t forget to make the change for both.)

That’s it. For me at least, this allows both Win32 and x64-targeted binaries to be built and run easily on Windows XP x64. I assume this works on Vista too.

Hope others find this helpful.

I have installed CUDA 2.3 on windows 7 x64. Now I tried to compile my old projects, but it always can’t find the cutil32.lib. Because the libs doesn’t exist I tried to use cutil64.lib, but this can’t be opended…

Is there away to get the cutil32.lib on a 64-Bit os? Maybe by installing the 32bit toolkit or so?

I just reinstalled and encountered the same issue.

I had to install the 32bit SDK along with the 64bit Toolkit.

For v2.3 that would be:

cudatoolkit_2.3_win_64.exe

cudasdk_2.3_win_32.exe

I am not sure that you can install both versions at the same time, they try to uninstall any existing version if present.

I was very happy to see this cross-compile topic. I need to develop a CUDA dll on my development machine (Win 7 64 bits), but I need to compile it for 32-bits since it needs to run on another Win 7 64-bit machine…but as a 32-bit mode dll. This is because another dll I’m using in my app (NAudio) will only run on a 64-bit system when compiled for 32-bits. Very ugly. Has anyone run their 32-bit cuda app on a 64-bit os?