Already defined symbol error when using Thrust in two separate static libraries

(I read all that related to the following problem in the Internet (some links points here, some on SO). Creation of this topic is the last resort.)
I use CUDA 10.1 with Visual Studio 2017 (MSVC v14.1). IDE is Qt Creator 4.9.0, build system is CMake 3.14.2.
The project consists of a half of dozen of static libraries and single executable depending on them. Two of the static libraries uses CUDA. Both use Thrust (in particular device_vector). When I build whole project I get an error:

kernels.lib(kernels.device-link.obj) : error LNK2005: __cudaRegisterLinkedBinary_38_cuda_device_runtime_compute_75_cpp1_ii_8b1a5d37 already defined in scene.lib(scene.device-link.obj) [C:\Users\Anatoly\Documents\Projects\build-cuda-raytracer-Desktop_Qt_5_12_3_MSVC2017_64bit-u0412u044bu043fu0443u0441u043a\src\renderer\renderer.vcxproj]

When I comment out all the occurences of thrust::device_vector and related code from either of the two libraries, then the error is ceased.
Both of the libraries compiled with the folowing tweaks:


CUDA_RESOLVE_DEVICE_SYMBOLS ON is essential on Windows/MSVC, because otherwise some needed symbols are missed on final linking step.

Seems I have to place all the code, which uses Thrust, into single *.cu file, is it the only fix possible?

I don’t think I understood your last comment, which seems to be your conclusion.
You have some source files that use Thrust. Placing all the code that uses Thrust in one .cu file is something you already did, and worked?

You say that you commented occurrences of device_vector, then changed some stuff in the CMake without mentioning how it was before the changes.
CUDA_RESOLVE_DEVICE_SYMBOLS ON “is essential”, was it off and you turned it on, or was it on and you had to turn it off?
It is confusing.

Second try:

  1. Problem CMake project consist of static libraries, two of them use thrust::device_vector. Let’s call these libraries “first library” and “second library”. Build of the project failed with cited error.
  2. If I comment out all thrust::* code in first library then project builds without the error.
  3. Then I uncomment back all the thrust::* code in the first library and comment thrust::* code in the second. In this case build is also successful (as in 2.).
  4. Then I uncomment back all the thrust::* code in the second library (now thrust::* code in both libraries are uncommented).
  5. Then (just to be ensured) I try to build the project. This try failed with the same error as in 1.
  6. After all I move all the thrust::* code from first library and second library into the separate library (say, third) and try to build the project. The build is successful.

Term “thrust::* code” here means, that corresponding code odr-uses some instantiations of template functions and class templates from headers of the Thrust library. These calls of methods of the classes and calls of functions of Thrust library are feaseble (i.e. can be called, and actually called in case of successful build and run) from main function.

Are you able to compile these 2 libraries separately, each to their own .o or shared library?
For example: nvcc -c -o lib_1.o, or nvcc --shared -o
And the same for lib_2. Does it work?

If it works, then Thrust is well resolved within each of these libraries, but when you put things together in a host application and things don’t link, without knowing anything else other than the description you provided I would say it is broken either in the compilation/linking process (I don’t use CMake, so I can’t comment further) or in the host application in how it is importing things.

Though nothing is perfect, Thrust has been stable for quite a while. From this description, where the library is not even put to use because the application didn’t link, personally I would start by checking the makefile in case the libraries compiled by hand (as suggested in the beginning), and then the main application to understand if all the includes are correct.

When project builded successfully, then with no doubt libraries are builded successfully. On the point 2. the second library builded successfully and has no modifiactions and first library has modifications but successfully builded too. On the point 3. first library builded successfully and has no modifications and second library has modifications but successfully builded. It is clear for me, that every of the two libraries is compiled successfully. Please tell me where see you the leak in the logic? I sure there is no way to avoid successful compilation of either of the libraries and simultaneously to get final executable with functionality that coming from both libraries together. It is nonsense otherwise.

If you didn’t familiar with meaning of CUDA_RESOLVE_DEVICE_SYMBOLS ON, CUDA_SEPARABLE_COMPILATION ON and other mentioned stuff (it is crucial to), especially in case of MSVC, then I think I need another specialist. Thank you for your efforts.