MantisBT - CMake
View Issue Details
0014550CMake(No Category)public2013-11-07 07:062015-04-23 03:57
Nils Gladitz 
James Bigler 
normalmajoralways
closedfixed 
CMake 2.8.12.1 
CMake 3.3 
0014550: FindCUDA: source files shared between multiple targets results in linker using objects from both targets
With the attached sample project consisting of CMakeLists.txt and test.cu two identical targets are being created.

With the Visual Studio 10 generator this results in each target using object files from the other target resulting in duplicate symbol errors.

With the NMake Makefiles generator there seems to be no issue.
No tags attached.
related to 0015434closed Nils Gladitz Multiple add_custom_command with the same MAIN_DEPENDENCY causes duplicate rule invokations 
related to 0015525closed Kitware Robot FindCUDA: Sporadic build failures in parallel make on OS X 
txt CMakeLists.txt (140) 2013-11-07 07:06
https://public.kitware.com/Bug/file/4939/CMakeLists.txt
? test.cu (120) 2013-11-07 07:08
https://public.kitware.com/Bug/file/4940/test.cu
Issue History
2013-11-07 07:06Nils GladitzNew Issue
2013-11-07 07:06Nils GladitzFile Added: CMakeLists.txt
2013-11-07 07:08Nils GladitzFile Added: test.cu
2013-11-07 08:04Brad KingNote Added: 0034408
2013-11-07 08:44Nils GladitzNote Added: 0034409
2013-11-07 08:50Brad KingNote Added: 0034410
2013-11-07 08:55Nils GladitzNote Added: 0034411
2013-11-07 09:09Nils GladitzNote Added: 0034412
2013-11-07 10:40Nils GladitzNote Added: 0034413
2013-11-07 11:06Nils GladitzNote Added: 0034414
2013-11-07 11:25Brad KingNote Added: 0034415
2013-11-07 11:26Brad KingNote Added: 0034416
2013-11-07 11:37Nils GladitzNote Added: 0034417
2013-11-07 11:52Brad KingNote Added: 0034418
2013-11-07 16:37Nils GladitzNote Added: 0034420
2013-11-07 16:45Brad KingAssigned To => James Bigler
2013-11-07 16:45Brad KingStatusnew => assigned
2013-11-08 12:20James BiglerNote Added: 0034422
2013-11-08 12:28Nils GladitzNote Added: 0034423
2013-11-08 15:12James BiglerNote Added: 0034424
2013-11-08 15:35Nils GladitzNote Added: 0034425
2015-03-06 11:47Nils GladitzRelationship addedrelated to 0015434
2015-03-27 09:37Nils GladitzNote Added: 0038348
2015-03-27 09:37Nils GladitzStatusassigned => closed
2015-03-27 09:37Nils GladitzResolutionopen => fixed
2015-03-27 09:37Nils GladitzFixed in Version => CMake 3.3
2015-04-23 03:57Nils GladitzRelationship addedrelated to 0015525

Notes
(0034408)
Brad King   
2013-11-07 08:04   
Does this happen with Visual Studio 11, or only 10?
(0034409)
Nils Gladitz   
2013-11-07 08:44   
Had to get a newer CUDA version to try it but apparently with "Visual Studio 11" the issue does not show.

Also reran a clean build with "Visual Studio 10" to make sure it wasn't an issue with the previous CUDA version but I can still reproduce the issue with it.
(0034410)
Brad King   
2013-11-07 08:50   
Re 0014550:0034409: Thanks. Are you reporting this as a newly discovered problem or as a regression from a previous version of CMake?
(0034411)
Nils Gladitz   
2013-11-07 08:55   
This showed up after updating from 2.8.8 to 2.8.12(.1).
I just tried 2.8.11.2 on the reduced test case and it did not reproduce the issue so the issue is probably a regression since 2.8.12.
(0034412)
Nils Gladitz   
2013-11-07 09:09   
To correct the initial report:
The first target builds fine.
Only the second target uses objects from the first target and fails due to duplicate symbols.
(0034413)
Nils Gladitz   
2013-11-07 10:40   
The issue seems to be in some way related to:
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ef27fa6760ddcfa0add1de956a68f59b134af836;hp=4c4bafdeabe868677a868dba416878c097c416b3 [^]

Reverting it gives me a successful build of the test case.
(0034414)
Nils Gladitz   
2013-11-07 11:06   
Looking at the linker command line it is now only using the object of the first target to build the second target which isn't really correct either (though apparently it happens to work in our case).
(0034415)
Brad King   
2013-11-07 11:25   
Commit http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ef27fa67 [^] was to correct a different regression:

 http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/7898 [^]
(0034416)
Brad King   
2013-11-07 11:26   
Is the module somehow accumulating the list of outputs and leaking it across targets?
(0034417)
Nils Gladitz   
2013-11-07 11:37   
I think it would be breaking with all generators then.
The deleted comment suggests that objects are being added to the linker command line implicitly by visual studio itself.
I don't quite understand why or how it could sensibly be doing that though.
(0034418)
Brad King   
2013-11-07 11:52   
Re 0014550:0034417: VS 10 checks the output of each custom command that is included in a target, and if it happens to be a ".obj" file, then links it. CMake wants to treat external object files as <Object> elements but if we do that with external objects that are also the output of custom commands then VS links the objects twice. Therefore we have a special hack for VS 10 that checks if an external object file is also the output of a custom command in the current target and if so uses <None> instead, depending on the VS behavior to link it.

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmVisualStudio10TargetGenerator.cxx;hb=v2.8.12.1#l1037 [^]

VS 11 provides an option to turn this off so CMake uses it there and there are no issues:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmVisualStudio10TargetGenerator.cxx;hb=v2.8.12.1#l660 [^]

We need to identify why the second target gets custom commands from the first target.
(0034420)
Nils Gladitz   
2013-11-07 16:37   
It was hiding in plain sight ... it is probably CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE that caused this.
It is specifically documented that this results in one rule per source file and hence breaks when you list source files in multiple targets.

The fact that it worked for us earlier was apparently accidental.
Sorry for the fuss.

I'd vote for having this OFF by default but I assume someone had a good reason to break this by default (I hope).
(0034422)
James Bigler   
2013-11-08 12:20   
I think the comment in the FindCUDA.cmake script about not being able to detect this could be ammended. I believe I can detect this case, I just can't fix it on the fly.

What if I were able to detect this case and provide an error to the user, telling them to disable CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE? Would that be sufficient?
(0034423)
Nils Gladitz   
2013-11-08 12:28   
That sounds good!

But what is the reason for having CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE enabled by default?
Is there some advantage to having it enabled?
Maybe whatever the reason is could be documented as well as to allow an informed decision.

Now that I have it disabled I might be missing out on something but I don't even know what that might be.
(0034424)
James Bigler   
2013-11-08 15:12   
Having the rule attached had two functions.

1. You didn't have to add the object to the project. This is no longer needed since I have to add it all the time. This is also mitigated by CMake's ability to create project folders (CMake couldn't do it when I first implemented this and having all the object files in the project next to the sources made the project a mess).
2. Having the rule attached allows you to compile the single .cu file using the 'Compile' menu option from the solution explorer or while it is open in the editor windows using CTRL-F7. Without the rule being attached you need to find the .rule rule in the project and right click that to compile. You can't use the CTRL-F7 option at all. This feature helps the .cu file feel more like a regular .cpp file.
(0034425)
Nils Gladitz   
2013-11-08 15:35   
Thank you James.
It all makes quite a bit more sense to me now.
(0038348)
Nils Gladitz   
2015-03-27 09:37   
Reusing the same MAIN_DEPENDENCY is now diagnosed by cmake in general and does not have to be diagnosed by FindCUDA.cmake:

http://www.cmake.org/gitweb?p=cmake.git;a=commit;h=242c396656783b1b3d542b14bc62710a46a87518 [^]