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

发布于 2024-10-22 03:26:59 字数 843 浏览 5 评论 0原文

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

PS dumpbins 还确认 .lib 和 .obj 都是 x86 目标。

PPS 将它们添加为图书馆员中的“附加依赖项”似乎可行,但有没有什么好的方法可以自动实现这一点?毕竟,它们是该项目的一部分。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱&纷飞 2024-10-29 03:26:59

这看起来更难,也许一些更有能力/经验丰富的人也会回答...

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

我必须说,我并没有真正完全理解新的构建系统。我通过反复试验+使用内置 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 文件。到底是哪一个?我不知道:)

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

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文