Microsoft Visual Studio Not Linking My CUDA .obj Files Into My .lib
So, we recently upgraded our project to be using Microsoft Visual Studio 2010 and we are having some issues with our CUDA projects.
I do have 2008 installed, and I am using the vc90 toolkit, and the files appear to be compiling (their associate .obj files are created). This is in the a project which creates a .lib as its output. The .lib is then linked against in another project which produces linker errors because one of files in the library (Matrix.obj) can't find one of the symbols that should be in CUDAMatrix.obj.
I ran dumpbin /SYMBOLS on CUDAMatrix.obj, and the symbol is in there, is not UNDEF, and is External. I ran dumpbin on our .lib, and the symbol does not appear to be inside it. I turned up the verbosity of the build of the library and the list of .obj files after:
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\Lib.exe
Does not appear to contain CUDAMatrix.obj.
To sum up, how does the Visual Studio project 开发者_如何学运维know what .obj files to stick into the .lib that is being made? I couldn't find the actual list anywhere, and the librarian submenu didn't seem to help.
Or least conveniently, is there an external tool (similar to 'ar' on linux) that I can use to merge the .obj it produced with the library? I thought maybe the /MERGE switch on lib.exe would do it, but I kept getting a .dll not found error when I tried to run that from the command line.
P.S. The dumpbins also confirmed that both the .lib and the .objs were x86 targeted.
P.P.S. Adding them as "additional dependencies" in the librarian seems to work, but isn't there any good way to make this happen automatically? They are, after all, part of the project.
This seems harder, maybe some more competent/experienced people will answer too...
My first thought, however, is that maybe your CUDA build step does not "inform" the following building steps correctly what files it outputs and what they should do about it? Because VS2010 and VS2008 uses different build system, troubles may origin from that.
I must say, I do not really fully understand the new build system. I created my files through trial-and-error + some help with the buildin VS2008->VS2010 build-rule converter (which is still buggy and does not support everything).
In my CUDA build rule file I have (CUDA.targets)
<Target
Name="_SDF_CUDA"
...
Outputs="@(SDF_CUDA->Metadata('Outputs')->Distinct())"
...
> ...
<ItemGroup>
<SDF_CUDA
Condition="'%(SDF_CUDA.NvccCompilation)' == '0'">
<NvccCompilationLine>--compile -o "$(IntDir)%(OutputFile).cu.obj"</NvccCompilationLine>
</SDF_CUDA>
<SDF_CUDA
Condition="'%(SDF_CUDA.NvccCompilation)' == '1'">
<NvccCompilationLine>-cuda -o "$(IntDir)%(OutputFile).cu.c"</NvccCompilationLine>
</SDF_CUDA>
<SDF_CUDA
Condition="'%(SDF_CUDA.NvccCompilation)' == '2'">
<NvccCompilationLine>-gpu -o "$(IntDir)%(OutputFile).gpu"</NvccCompilationLine>
</SDF_CUDA>
<SDF_CUDA
Condition="'%(SDF_CUDA.NvccCompilation)' == '3'">
<NvccCompilationLine>-cubin -o "$(IntDir)%(OutputFile).cubin"</NvccCompilationLine>
</SDF_CUDA>
<SDF_CUDA
Condition="'%(SDF_CUDA.NvccCompilation)' == '4'">
<NvccCompilationLine>-ptx -o "$(IntDir)%(OutputFile).ptx"</NvccCompilationLine>
</SDF_CUDA>
</ItemGroup>
...
<SDF_CUDA
Condition="'@(SDF_CUDA)' != '' and '%(SDF_CUDA.ExcludedFromBuild)' != 'true'"
...
OutputFile="%(SDF_CUDA.OutputFile)"
... />
</Target>
...
<PropertyGroup>
<ComputeLinkInputsTargets>
$(ComputeLinkInputsTargets);
ComputeSDF_CUDAOutput;
</ComputeLinkInputsTargets>
<ComputeLibInputsTargets>
$(ComputeLibInputsTargets);
ComputeSDF_CUDAOutput;
</ComputeLibInputsTargets>
</PropertyGroup>
<Target
Name="ComputeSDF_CUDAOutput"
Condition="'@(SDF_CUDA)' != ''">
<ItemGroup>
<SDF_CUDA Condition="'%(SDF_CUDA.NvccCompilation)' == '0'">
<Outputs>$(IntDir)%(OutputFile).cu.obj</Outputs>
</SDF_CUDA>
<SDF_CUDA Condition="'%(SDF_CUDA.NvccCompilation)' == '1'">
<Outputs>$(IntDir)%(OutputFile).cu.c</Outputs>
</SDF_CUDA>
<SDF_CUDA Condition="'%(SDF_CUDA.NvccCompilation)' == '2'">
<Outputs>$(IntDir)%(OutputFile).gpu</Outputs>
</SDF_CUDA>
<SDF_CUDA Condition="'%(SDF_CUDA.NvccCompilation)' == '3'">
<Outputs>$(IntDir)%(OutputFile).cubin</Outputs>
</SDF_CUDA>
<SDF_CUDA Condition="'%(SDF_CUDA.NvccCompilation)' == '4'">
<Outputs>$(IntDir)%(OutputFile).ptx</Outputs>
</SDF_CUDA>
</ItemGroup>
<Message Text="Outputs file: %(SDF_CUDA.Outputs)" />
<ItemGroup>
<SDF_CUDADirsToMake
Condition="'@(SDF_CUDA)' != '' and '%(SDF_CUDA.ExcludedFromBuild)' != 'true'"
Include="%(SDF_CUDA.Outputs)" />
<Link
Include="%(SDF_CUDADirsToMake.Identity)"
Condition="'%(Extension)'=='.obj' or '%(Extension)'=='.res' or '%(Extension)'=='.rsc' or '%(Extension)'=='.lib'" />
<Lib
Include="%(SDF_CUDADirsToMake.Identity)"
Condition="'%(Extension)'=='.obj' or '%(Extension)'=='.res' or '%(Extension)'=='.rsc' or '%(Extension)'=='.lib'" />
<ImpLib
Include="%(SDF_CUDADirsToMake.Identity)"
Condition="'%(Extension)'=='.obj' or '%(Extension)'=='.res' or '%(Extension)'=='.rsc' or '%(Extension)'=='.lib'" />
</ItemGroup>
<MakeDir
Directories="@(SDF_CUDADirsToMake->'%(RootDir)%(Directory)')" />
</Target>
I believe the one of the last nodes actually guides the subsequent linking stage to include the generated .obj file. Which one exactly? I don't know :)
Hope it will help... somehow... good luck!
精彩评论