Error when linking a shared library on Windows using Clang, CUDA and Ninja

I have recently worked on integrating CUDA in a project and have stumbled upon a couple of problems on Windows in combination with Clang (using the GNU-like command-line) and Ninja.

To demonstrate the problems there is a sample GitHub repository cmake_export_all_symbols.

There are two problems which occur - both are in the linking phase.

  1. The LLVM linker lld-link.exe cannot find the library include path for CUDA, and produces the following two error messages:
clang++: error: no such file or directory: 'cudadevrt.lib'
clang++: error: no such file or directory: 'cudart_static.lib'
  1. The WINDOWS_EXPORT_ALL_SYMBOLS property produces a exports.def (in CMakeFiles\lib.dir\.\exports.def) file, but it cannot be consumed by the linker. This seems to be somehow caused after enable_language(CUDA) call or when CUDA is one of the languages listed in the CMake project.
clang++: error: no such file or directory: '/DEF:CMakeFiles\lib.dir\.\exports.def'

The repository listed above works all fine when one changes Clang for MSVC.

Regarding the exact versions of the tools used:

  • CMake 3.23.2
  • Clang 13.0.0
  • CUDA 11.7
  • Ninja 1.10.2

I wanted to ask, whether these are known problems (as I couldn’t find any information here and in the issue tracker) and if there are ways to cleanly mitigate those problems.

So far, my teammates and I have found a workaround:

  1. The first one we solved was by placing the missing .lib files in the corresponding build directory in a pre-link step.
  2. Here we were lucky because all of our targets which use WINDOWS_EXPORT_ALL_SYMBOLS are independent of all our targets, which use CUDA. So we made sure that all targets using WINDOWS_EXPORT_ALL_SYMBOLS are compiled and linked before any enable_language(CUDA) call is encountered.

Thank you!

Cc: @robert.maynard

Hey guys, this is still a problem with CMake 3.28! I’m working on NiftyReg project, and it compiles without any problem when I do it with clang-cl. However, it fails if it’s done with clang.