MantisBT - CMake
View Issue Details
0015240CMakeCMakepublic2014-11-11 10:042016-06-10 14:31
James Bigler 
CMake 3.0.2 
0015240: When compiling CUDA *.cu code, NVCC uses CXX_FLAGS when it should be using C_FLAGS
When compiling cu files with cmake, it applies CXX_FLAGS to C compilation. See the attached and CMakeLists.txt for an example. This can lead to unnecessary warnings and errors as seen below:

$ make
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jeremy/optix/jaguar/tmp/build
[ 50%] Building NVCC (Device) object CMakeFiles/a_test.dir/
cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C [enabled by default]
cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C [enabled by default]
[100%] Building NVCC intermediate link file CMakeFiles/a_test.dir/a_test_intermediate_link.o
Linking CXX executable a_test
[100%] Built target a_test

if you use the -v option of nvcc, you can see that cmake is indeed applying the wrong arguments to "gcc -x c":

#$ "/usr/bin"/gcc-4.8 -D__CUDA_ARCH__=200 -E -x c -DCUDA_DOUBLE_MATH_FUNCTIONS -D__CUDACC__ -D__NVCC__ -D__CUDACC_RDC__ -D__CUDANVVM__ -std=c++11 -g -fPIC -g -fexceptions -fPIC -D__CUDA_PREC_DIV -D__CUDA_PREC_SQRT -I"/usr/local/cuda-6.5/include" -I"/usr/local/cuda-6.5/targets/x86_64-linux/include" -I"/usr/local/cuda-6.5/include" "-I/usr/local/cuda-6.5/bin/../targets/x86_64-linux/include" -m64 -g -gdwarf-2 -o "/tmp/tmpxft_00003aee_00000000-7_main.cpp2.i" "/tmp/tmpxft_00003aee_00000000-3_main.cudafe1.gpu"
cc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C [enabled by default]
cmake the attached files.
see [^]
zip (742) 2014-11-11 10:04
diff nvcc_patch.diff (636) 2014-11-12 09:26
diff nvcc_patch2.diff (1,787) 2014-11-12 13:03
diff nvcc_patch3.diff (1,783) 2014-11-12 13:06
diff nvcc_patch4.diff (2,431) 2014-11-14 06:50
patch 0001-FindCUDA-Optionally-prevent-host-flag-propagation.patch (2,883) 2015-08-04 09:02
Issue History
2014-11-11 10:04jeremyherbertNew Issue
2014-11-11 10:04jeremyherbertFile Added:
2014-11-11 10:07jeremyherbertNote Added: 0037178
2014-11-11 10:07jeremyherbertTag Attached: CUDA
2014-11-11 10:34Brad KingAssigned To => James Bigler
2014-11-11 10:34Brad KingStatusnew => assigned
2014-11-11 13:05James BiglerNote Added: 0037181
2014-11-11 14:33jeremyherbertNote Added: 0037186
2014-11-12 08:30jeremyherbertNote Added: 0037192
2014-11-12 08:32jeremyherbertNote Edited: 0037192bug_revision_view_page.php?bugnote_id=37192#r1618
2014-11-12 09:26jeremyherbertFile Added: nvcc_patch.diff
2014-11-12 09:26jeremyherbertNote Added: 0037194
2014-11-12 11:36James BiglerNote Added: 0037196
2014-11-12 11:37James BiglerNote Edited: 0037196bug_revision_view_page.php?bugnote_id=37196#r1620
2014-11-12 13:03jeremyherbertFile Added: nvcc_patch2.diff
2014-11-12 13:05jeremyherbertNote Added: 0037197
2014-11-12 13:06jeremyherbertFile Added: nvcc_patch3.diff
2014-11-12 13:07jeremyherbertNote Added: 0037198
2014-11-12 15:30James BiglerNote Added: 0037199
2014-11-12 15:55jeremyherbertNote Added: 0037200
2014-11-12 16:53James BiglerNote Added: 0037201
2014-11-14 06:50jeremyherbertFile Added: nvcc_patch4.diff
2014-11-14 06:52jeremyherbertNote Added: 0037220
2014-11-14 06:59jeremyherbertNote Edited: 0037220bug_revision_view_page.php?bugnote_id=37220#r1622
2014-11-14 11:51James BiglerAssigned ToJames Bigler => Brad King
2014-11-14 11:52James BiglerNote Added: 0037221
2015-08-01 21:43RolandSchulzNote Added: 0039215
2015-08-04 08:52Brad KingAssigned ToBrad King => James Bigler
2015-08-04 09:01Brad KingNote Added: 0039226
2015-08-04 09:02Brad KingFile Added: 0001-FindCUDA-Optionally-prevent-host-flag-propagation.patch
2015-08-04 09:02Brad KingNote Added: 0039227
2015-09-09 13:00RolandSchulzNote Added: 0039378
2015-09-09 13:04James BiglerNote Added: 0039379
2015-09-09 13:36RolandSchulzNote Added: 0039380
2015-09-09 13:48James BiglerNote Added: 0039381
2016-06-10 14:29Kitware RobotNote Added: 0042661
2016-06-10 14:29Kitware RobotStatusassigned => resolved
2016-06-10 14:29Kitware RobotResolutionopen => moved
2016-06-10 14:31Kitware RobotStatusresolved => closed

2014-11-11 10:07   
Also, compiling the file with just
$ nvcc -o out -std=c++11

does not cause any errors or warnings.
James Bigler   
2014-11-11 13:05   
This is an unfortunate thing that nvcc does. It treats all the CUDA source as C++ code, but yet it invokes the C compiler to do some of the preprocessing.

There are a couple of things you could do right now.

set CUDA_PROPAGATE_HOST_FLAGS to OFF or FALSE, and then set all the host flags you wish propagated via CUDA_NVCC_FLAGS.

Someone could add an option called CUDA_NON_PROPAGATED_HOST_FLAGS that is a list of flags specifically to ignore when propagating host flags. It could even have as a default the set of known flags to cause problems. There is already code in CUDA_WRAP_SRCS that does something like this for -g3. It could be extended to take a list.

I don't have the time to write it myself, but I can review patches.
2014-11-11 14:33   
Hi James,

I will give it a go over the next few days. My experience with cmake is limited, but I will try to add CUDA_NON_PROPAGATED_HOST_FLAGS.
2014-11-12 08:30   
(edited on: 2014-11-12 08:32)
Looks like there is something more sinister going on here. I added some code after the -g3 fix to remove -std=c++11 from _cuda_C_FLAGS but the problem still remains. I will try to dig a bit deeper.

FYI, I just checked. -std=c++11 is not in _cuda_C_FLAGS. doh

2014-11-12 09:26   
Fix uploaded. I await your comments.
James Bigler   
2014-11-12 11:36   
(edited on: 2014-11-12 11:37)
While this would work for this one case, I was hoping for a more general solution (CUDA_NON_PROPAGATED_HOST_FLAGS) that would allow others to add values to be ignored.

If you can't swing it, this should be fine until another argument comes in.

Here are some comments on the change itself.

1. I would move your code after the set(_cuda_host_flags "${_cuda_host_flags}\nset(CMAKE_HOST_FLAGS_${config_upper} ${_cuda_C_FLAGS})") in order to catch any arguments that were specified as part of a configuration specific flag.
2. The comment needs a bit of clarification

# You can't specify -std=c++11 as a host flag, since nvcc will try to pass it as an argument to the C host compiler during compilation. Instead -std=c++11 should be passed as a direct argument to nvcc which will handle passing the argument to the host compiler as needed.

2014-11-12 13:05   
Ok, I had a bit of time this evening so I reworked it to have the general solution. See nvcc_patch2.diff. I tried to incorporate your change to the comment as well.

Let me know if this is ok.
2014-11-12 13:07   
uploaded nvcc_patch3.diff which also fixes a small grammatical mistake on my part.
James Bigler   
2014-11-12 15:30   
Looks great. Documentation is present for the new variable (yeah!).

I would take it a step further and make CUDA_NON_PROPAGATED_HOST_FLAGS a cache variable. This allows it to be set via the GUI like all the other compiler flags.

I'm trying to decide what the value would be for adding -std=c++11 as a default as opposed to always adding it.

What do you think?
2014-11-12 15:55   
That makes sense. It shouldn't change between runs of course. I'll try to give it a shot tomorrow or the next day.

On your question: there are lots of bugs in nvcc (I know, I've reported some!) that prevent you from putting all of your code in .cu files. So in my experience, most complex CUDA projects involve using .cpp files as well, and then linking them with the .cu.o at a later stage. If you want to use c++11 for these c++ files, then without this fix, you will always get a warning. The trouble is, it is not obvious why this error shows up and the fix is not obvious either (because CMake shouldn't be using my C++ flags as C flags, right?). I would then worry that people would accidentally override the -std=c++11 in CUDA_NON_PROPAGATED_HOST_FLAGS to get rid of a warning like this and confusingly get a new warning that replaces the old one.

To put it another way, for all CUDA >=6.5 (where c++11 is possible) I believe it should be forced; there is no reason I can think of that it should ever be passed to the C compiler. For earlier CUDA versions, it won't matter because nvcc won't take that flag anyway.
James Bigler   
2014-11-12 16:53   
Yeah, ultimately nvcc needs to not invoke the C compiler ever (even to do some preprocessing). It should only invoke the C++ compiler. That's another story for another day, though.
2014-11-14 06:52   
(edited on: 2014-11-14 06:59)
Attached a patch that fixes the issue, adds CUDA_NON_PROPAGATED_HOST_FLAGS as a cache variable and fixes a spelling mistake in an adjacent line.

Is this acceptable?

Also, I have tested this on reasonably sized build (the one that caused my original problems) involving CUDA and the NVIDIA OptiX Prime ray tracing library and it now builds with zero warnings. Hooray!

James Bigler   
2014-11-14 11:52   
Looks great!

Brad can you integrate this?
2015-08-01 21:43   
What is the version of FindCUDA the patch is created against?
Are there plans to integrate this into the official version?
Brad King   
2015-08-04 09:01   
Since nvcc_patch4.diff was posted CMake has gained this change since 3.3:

 FindCUDA: Handle c++11 host flag;a=commitdiff;h=99abebde [^]

Are there other flags for which nvcc_patch4.diff is still needed? Should they be hard-coded like -std=c++11 instead of asking users to set a cache entry explicitly for them?
Brad King   
2015-08-04 09:02   
For reference, 0001-FindCUDA-Optionally-prevent-host-flag-propagation.patch is nvcc_patch4.diff with whitespace/doc tweaks and authorship information recorded.
2015-09-09 13:00   
The solution implemented in 3.3 doesn't work for CUDA < 6.5. CUDA 6.0 (and before) doesn't support C++11 and the "--std c++11" flag. Of course if the CUDA code requires C++11 than CUDA >= 6.5 is anyhow required and this is fine. But if C++11 is only required for the host code but not for the CUDA code then it would be nice to be able to propagate the flags without the host c++11 flag (--std=c++11) and without adding the nvcc flag (--std c++11).
James Bigler   
2015-09-09 13:04   
There is no way to get C++ only host flags to work with nvcc. This is because nvcc uses the C compiler during various phases and passes along the host compiler flags during these phases which chokes the C compiler. If you want c++-11 host code you must use a version of nvcc that supports the --std c++11 flag. There's no way around this.
2015-09-09 13:36   
I didn't mean host code in CUDA files. I meant standard C++ source files containing non-CUDA code. If the non-CUDA code requires C++11 but the CUDA code doesn't, then this works in theory with CUDA 6.0. But FindCUDA makes it impossible. Because it always passes "-stdd c++11" even if it isn't required (and not supported).
James Bigler   
2015-09-09 13:48   
I see. You need the CUDA_NON_PROPAGATED_HOST_FLAGS patch to filter out the c++11 flag from the host flags for older versions of CUDA.

I'm pretty sure you will have linking errors when you mix c++11 flags between different object files, though. I know I did.

Also, the workaround specified earlier in the post (turning off host flag propagation and specifying what flags you want manually with CUDA_NVCC_FLAGS) is also possible, though a bit annoying.
Kitware Robot   
2016-06-10 14:29   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.