Microsoft Visual Studio 未将我的 CUDA .obj 文件链接到我的 .lib

问题描述 投票:0回答:1

因此,我们最近将项目升级为使用 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 not find 错误。

附注dumpbin 还确认 .lib 和 .obj 都是 x86 目标。

P.P.S。将它们添加为图书馆员中的“附加依赖项”似乎可行,但是有没有什么好的方法可以自动发生这种情况?毕竟,它们是项目的一部分。

visual-studio-2010 cuda linker object-files .lib
1个回答
2
投票

这似乎更难,也许一些更有能力/有经验的人也会回答...

然而,我的第一个想法是,也许您的 CUDA 构建步骤没有正确“告知”以下构建步骤它输出哪些文件以及它们应该做什么?由于 VS2010 和 VS2008 使用不同的构建系统,因此可能会出现问题。

我必须说,我并没有真正完全理解新的构建系统。我通过反复试验+使用内置 VS2008->VS2010 构建规则转换器(仍然有问题并且不支持所有内容)的一些帮助创建了我的文件。

在我的 CUDA 构建规则文件中,我有 (CUDA.targets)

  <Target
    Name="_SDF_CUDA"
    ...
    Outputs="@(SDF_CUDA-&gt;Metadata('Outputs')-&gt;Distinct())"
    ...
  > ... 
      <ItemGroup>
      <SDF_CUDA
        Condition="'%(SDF_CUDA.NvccCompilation)' == '0'">
        <NvccCompilationLine>--compile -o &quot;$(IntDir)%(OutputFile).cu.obj&quot;</NvccCompilationLine>
      </SDF_CUDA>
      <SDF_CUDA
        Condition="'%(SDF_CUDA.NvccCompilation)' == '1'">
        <NvccCompilationLine>-cuda -o &quot;$(IntDir)%(OutputFile).cu.c&quot;</NvccCompilationLine>
      </SDF_CUDA>
      <SDF_CUDA
        Condition="'%(SDF_CUDA.NvccCompilation)' == '2'">
        <NvccCompilationLine>-gpu -o &quot;$(IntDir)%(OutputFile).gpu&quot;</NvccCompilationLine>
      </SDF_CUDA>
      <SDF_CUDA
        Condition="'%(SDF_CUDA.NvccCompilation)' == '3'">
        <NvccCompilationLine>-cubin -o &quot;$(IntDir)%(OutputFile).cubin&quot;</NvccCompilationLine>
      </SDF_CUDA>
      <SDF_CUDA
        Condition="'%(SDF_CUDA.NvccCompilation)' == '4'">
        <NvccCompilationLine>-ptx -o &quot;$(IntDir)%(OutputFile).ptx&quot;</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-&gt;'%(RootDir)%(Directory)')" />
  </Target>

我相信最后一个节点实际上指导后续链接阶段以包含生成的 .obj 文件。究竟是哪一个?我不知道:)

希望它能有所帮助...不知何故...祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.