Microsoft Visual Studio не связывает мои файлы CUDA .obj в мою .lib - PullRequest
0 голосов
/ 17 марта 2011

Итак, мы недавно обновили наш проект, чтобы использовать Microsoft Visual Studio 2010, и у нас возникли некоторые проблемы с нашими проектами CUDA.

У меня установлен 2008, и я использую инструментарий vc90, и файлы, кажется, компилируются (создаются связанные с ними файлы .obj). Это в проекте, который создает .lib в качестве своего вывода. Затем .lib связывается с другим проектом, который выдает ошибки компоновщика, поскольку один из файлов в библиотеке (Matrix.obj) не может найти один из символов, который должен быть в CUDAMatrix.obj.

Я запустил dumpbin / SYMBOLS на CUDAMatrix.obj, и там есть символ, не UNDEF, а External. Я запустил мусорную корзину на нашем .lib, и символ, кажется, не находится внутри него. Я добавил подробности сборки библиотеки и список файлов .obj после:

c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\Lib.exe 

Не содержит CUDAMatrix.obj.

Подводя итог, как проект Visual Studio узнает, какие файлы .obj нужно вставить в создаваемый .lib? Я нигде не мог найти фактический список, и подменю библиотекаря, похоже, не помогло.

Или, по меньшей мере, удобно, есть ли какой-нибудь внешний инструмент (похожий на 'ar' в linux), который я могу использовать для объединения .obj, созданного им с библиотекой? Я подумал, что, возможно, ключ / MERGE на lib.exe сделает это, но я продолжал получать ошибку .dll не найден, когда пытался запустить ее из командной строки.

P.S. Кроме того, свалки подтвердили, что и .lib, и .objs были нацелены на x86.

P.P.S. Кажется, что добавление их в библиотеку как «дополнительных зависимостей» работает, но разве не существует хорошего способа сделать это автоматически? В конце концов, они являются частью проекта.

1 Ответ

2 голосов
/ 17 марта 2011

Это кажется сложнее, может быть, некоторые более компетентные / опытные люди тоже ответят ...

Моя первая мысль, однако, заключается в том, что, возможно, ваш шаг сборки 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. Какая именно? Я не знаю:)

Надеюсь, это поможет ... как-то ... удачи!

...