因此,我们最近将项目升级为使用Microsoft Visual Studio 2010,而我们的CUDA项目存在一些问题。
我安装了2008,我正在使用vc90工具包,文件似乎正在编译(它们的关联.obj文件已创建)。这是在一个创建.lib作为输出的项目中。然后在另一个产生链接器错误的项目中链接.lib,因为库中的一个文件(Matrix.obj)找不到应该在CUDAMatrix.obj中的符号之一。
我在CUDAMatrix.obj上运行了dumpbin / SYMBOLS,符号在那里,不是UNDEF,而是外部的。我在.lib上运行dumpbin,符号似乎不在其中。我发现了库的构建和.obj文件列表的详细程度:
c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\Lib.exe
似乎不包含CUDAMatrix.obj。
总而言之,Visual Studio项目如何知道要将哪些.obj文件粘贴到正在生成的.lib中?我无法在任何地方找到实际列表,图书管理员子菜单似乎没有帮助。
或者最不方便的是,是否有一个外部工具(类似于linux上的'ar'),我可以用它来合并它生成的.obj和库?我想也许lib.exe上的/ MERGE开关会这样做,但是当我试图从命令行运行时,我一直收到.dll找不到错误。
P.S。垃圾箱还确认.lib和.objs都是x86目标。
P.P.S。在库管理程序中将它们添加为“附加依赖项”似乎可行,但是没有任何好方法可以自动实现这一点吗?毕竟,它们是项目的一部分。
答案 0 :(得分:2)
这似乎更难,也许一些更有能力/有经验的人也会回答......
然而,我的第一个想法是,您的CUDA构建步骤可能无法正确地“通知”以下构建步骤它输出的文件以及它们应该如何处理它?由于VS2010和VS2008使用不同的构建系统,故障可能源于此。
我必须说,我并不完全了解新的构建系统。我通过试错法+对buildin VS2008-> VS2010构建规则转换器的一些帮助创建了我的文件(它仍然是错误的并且不支持所有内容)。
在我的CUDA构建规则文件中,我有(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>
我相信最后一个节点实际上引导后续链接阶段包含生成的.obj文件。究竟是哪一个?我不知道:))
希望它会有所帮助......不知何故......祝你好运!