CUDA与我的gcc版本不兼容。

151

我在编译CUDA SDK中的一些示例时遇到了问题。 我已经安装了开发者驱动程序(版本270.41.19)和CUDA工具包, 最后安装了SDK(4.0.17版本)。

最初它根本无法编译,会出现以下错误:

error -- unsupported GNU version! gcc 4.5 and up are not supported!

我在81行找到了负责的代码:/usr/local/cuda/include/host_config.h,然后将其修改为:

//#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)

从那个点开始,我只编译了几个示例,然后就停在了这里:

In file included from /usr/include/c++/4.6/x86_64-linux-gnu/bits/gthr.h:162:0,
             from /usr/include/c++/4.6/ext/atomicity.h:34,
             from /usr/include/c++/4.6/bits/ios_base.h:41,
             from /usr/include/c++/4.6/ios:43,
             from /usr/include/c++/4.6/ostream:40,
             from /usr/include/c++/4.6/iterator:64,
             from /usr/local/cuda/include/thrust/iterator/iterator_categories.h:38,
             from /usr/local/cuda/include/thrust/device_ptr.h:26,
             from /usr/local/cuda/include/thrust/device_malloc_allocator.h:27,
             from /usr/local/cuda/include/thrust/device_vector.h:26,
             from lineOfSight.cu:37:
/usr/include/c++/4.6/x86_64-linux-gnu/bits/gthr-default.h:251:1: error: pasting         "__gthrw_" and "/* Android's C library does not provide pthread_cancel, check for
`pthread_create' instead.  */" does not give a valid preprocessing token
make[1]: *** [obj/x86_64/release/lineOfSight.cu.o] Error 1

由于一些示例可以编译,我认为这不是驱动程序的问题,而是与不受支持的gcc版本有关。降级不是一个选项,因为此时gcc4.6作为整个系统的依赖关系...


4
未来读者请注意:确保使用最新版的CUDA(除非您必须使用早期版本)。NVIDIA几乎每次发布都会提高最大支持编译器版本。 - einpoklum
这可能对那些使用CUDA 10并遇到gnu编译器链版本过高错误的人有所帮助:https://dev59.com/6a_la4cB1Zd3GeqPzd7a#53828864 - Douglas Daseeco
在安装detectron2时,我收到了类似的消息,因此我传递了系统变量export TORCH_DONT_CHECK_COMPILER_ABI=1并重新运行了setup.py,一切都顺利安装。我使用的是CUDA 12.0 g++ 12.x。 - Muneeb Ahmad Khurram
所以这是在说gcc在对这个软件包至关重要的方面上不是向前兼容的?这真是令人惊讶和失望。 - undefined
22个回答

165
检查您的CUDA版本支持的最大GCC版本:
CUDA版本 最大支持的GCC版本 12.1, 12.2 12.2 12 12.1 11.4.1+, 11.5, 11.6, 11.7, 11.8 11 11.1, 11.2, 11.3, 11.4.0 10 11 9 10.1, 10.2 8 9.2, 10.0 7 9.0, 9.1 6 8 5.3 7 4.9 5.5, 6 4.8 4.2, 5 4.6 4.1 4.5 4.0 4.4
为该GCC版本设置环境变量。例如,对于CUDA 10.2:
MAX_GCC_VERSION=8
确保您已安装该版本:
sudo apt install gcc-$MAX_GCC_VERSION g++-$MAX_GCC_VERSION
在CUDA文件夹中添加符号链接:
sudo ln -s /usr/bin/gcc-$MAX_GCC_VERSION /usr/local/cuda/bin/gcc sudo ln -s /usr/bin/g++-$MAX_GCC_VERSION /usr/local/cuda/bin/g++
(如果CUDA安装路径不是/usr/local/cuda,请将其替换为相应路径)

请查看此GitHub Gist,了解有关CUDA-GCC兼容性表的更多信息


5
配置噩梦拯救了我的生命!!!!谢谢。我将此应用于带有gcc和g++ 7系统链接的cuda 10。对于任何遇到同样问题的人,请参考这个。 - thekevshow
2
我应该自己创建 /usr/bin/gcc/usr/bin/g++ 或者 /usr/local/cuda/bin/gcc 文件夹吗? - Josh Desmond
@JoshDesmond,你提到的文件的符号链接是在第4步创建的。 - bryant1410
2
当我运行第四步的命令时,我记得出现了一个类似于“错误:目录 /usr/local/cuda/bin/gcc 不存在,中止”之类的错误,或者类似的内容。现在我意识到(在阅读问题的细节之后),你的答案假定 OP 提到的步骤 0:“我已经安装了 CUDA 工具包,最后安装了 SDK”。我试图使用 NVIDIA 的 cuda_10.2.89_440.33.01_linux.run 向导进行安装,但它在运行时仅仅抱怨 gcc 的兼容性问题而失败了。最后我决定卸载 gcc 9 :P - Josh Desmond
1
如果您使用[ana|mini]conda(conda-forge包cudatoolkit-dev)安装了NVCC,则需要在环境内进行链接,例如 ln -s /usr/bin/gcc-8 /home/user/miniconda3/envs/your_env/bin/gccln -s /usr/bin/g++-8 /home/user/miniconda3/envs/your_env/bin/g++ - Diego Ferri
显示剩余6条评论

148

如前所述,nvcc依赖于gcc 4.4。可以通过在安装nvcc时创建的bin目录中添加软链接来配置nvcc以使用正确版本的gcc,而无需传递任何编译器参数。

默认的cuda二进制目录(安装默认)是/usr/local/cuda/bin,在该目录中添加指向正确版本的gcc的软链接即可:

sudo ln -s /usr/bin/gcc-4.4 /usr/local/cuda/bin/gcc


2
"update-alternatives" 命令也可能有所帮助,特别是在安装 CUDA 5.0 时。 - phoad
4
我也不得不添加一个符号链接到正确版本的g++。 - Auron
17
我还需要链接到 g++。否则,简单的 nvcc 命令可以工作,但是例如对 CUDA 示例应用 make 命令,会很快出现类似 nvcc -ccbin g++ 开头的命令。我使用了以下命令:sudo ln -s /usr/bin/gcc-4.9 /usr/local/cuda/bin/gccsudo ln -s /usr/bin/g++-4.9 /usr/local/cuda/bin/g++。注意,这些链接命令是为了使 CUDA 能够找到 g++ 编译器。 - user2023370
8
如果您使用 cmake .. && make 进行编译,您可以尝试使用 cmake -D CUDA_NVCC_FLAGS="-ccbin gcc-4.4" .. && make。如果您使用普通的 Makefile 进行编译,则可以尝试使用 make CXX=g++-4.4 CC=gcc-4.4 - patryk.beza
1
当我尝试运行这个命令时,它会显示“文件已存在”,并且不执行链接操作。有什么帮助吗? - Sentient07
显示剩余6条评论

65

gcc 4.5和4.6与CUDA不兼容 - 代码将无法编译,其余工具链(包括cuda-gdb)也无法正常工作。您不能使用它们,此限制不可协商。

您唯一的解决方案是安装gcc 4.4版本作为第二个编译器(大多数发行版都允许)。有一个选项nvcc --compiler-bindir可用于指向另一个编译器。创建本地目录,然后将符号链接到支持的gcc版本可执行文件。通过--compiler-bindir选项将该本地目录传递给nvcc,您应该能够编译CUDA代码而不影响系统的其他部分。


编辑:

请注意,此问题和答案涉及CUDA 4。

自编写以来,NVIDIA在较新的CUDA工具链版本中继续扩展对后续gcc版本的支持。

  • 从CUDA 4.1版本开始,支持gcc 4.5。 gcc 4.6和4.7不受支持。
  • 从CUDA 5.0版本开始,支持gcc 4.6。 gcc 4.7不受支持。
  • 从CUDA 6.0版本开始,支持gcc 4.7。
  • 从CUDA 7.0版本开始,完全支持gcc 4.8,在Ubuntu 14.04和Fedora 21上支持4.9。
  • 从CUDA 7.5版本开始,完全支持gcc 4.8,在Ubuntu 14.04和Fedora 21上支持4.9。
  • 从CUDA 8版本开始,完全支持Ubuntu 16.06和Fedora 23上的gcc 5.3。
  • 从CUDA 9版本开始,完全支持Ubuntu 16.04、Ubuntu 17.04和Fedora 25上的gcc 6。
  • CUDA 9.2版本添加了对gcc 7的支持
  • CUDA 10.1版本增加了对gcc 8的支持。
  • CUDA 10.2版本继续支持gcc 8。
  • CUDA 11.0版本在Ubuntu 20.04上增加了对gcc 9的支持。
  • CUDA 11.1版本扩展了对大多数发行版的gcc 9支持,并在Fedora linux上增加了对gcc 10的支持。
  • 截至CUDA 11.1版本,CUDA中除Fedora linux外,目前没有对gcc 10的支持。

    请注意,NVIDIA最近添加了一张非常有用的表格(点击此处),其中包含当前CUDA版本所支持的编译器和操作系统矩阵。


    CUDA 7.5 用于什么? - GuySoft
    2
    我在SLES 11 SP3上使用CUDA 7.5和gcc 4.9.3,没有任何问题。 - Peter VARGA
    3
    什么?一个代码怎么可能不与更高版本兼容(当然除了硬编码限制)?我能想到的唯一可能是某些版本默认启用了C11/C++11,但如果这导致旧代码出现问题,可以通过命令行开关轻松解决。 - Hi-Angel
    2
    支持@Hi-Angel的观点。 #talonmies,“限制是不可协商的”是什么意思?较新版本的gcc和gdb支持旧的二进制文件头用于目标文件,因为它们“总是”(有点)这样做,没有理由新的gcc版本不能工作。除了符号链接解决方案之外,任何其他问题最有可能是c预处理器版本标志设置,如果gcc版本测试在某个cuda头文件中作为定义或宏的一部分“硬编码”,那么很容易修复。例外可能是cuda gpu编译器本身。 - Beracah
    1
    这不是二进制兼容性问题。CUDA工具链要求nvcc和GPU前端解析器能够拦截和重载各种编译器和libc/libc++内部头文件,以编译主机和设备代码并将它们集成在一起。CUDA解析器需要能够正确解析gcc内部头文件,以及其他一些东西。未经测试的gcc版本可能会失败,而与内置于NVIDIA头文件中的预处理器保护无关。你可以相信我(作为一个从事CUDA工具链开发近10年的人),也可以不相信。目前为止,我真的不知道该怎么办了。 - talonmies
    显示剩余5条评论

    25

    在我的发行版(Ubuntu 11.10)上,Gearoid Murphy的解决方案效果更好,因为gcc-4.4和gcc-4.6在同一个目录下,所以--compiler-bindir无用。唯一的注意点是我还必须安装g++-4.4并创建符号链接:

    sudo ln -s /usr/bin/gcc-4.4 /usr/local/cuda/bin/gcc
    sudo ln -s /usr/bin/g++-4.4 /usr/local/cuda/bin/g++
    

    请您看一下这个链接 https://stackoverflow.com/questions/74596307/how-to-calculate-the-output-node-of-feed-forward-neural-network-in-cuda 的问题。 - Encipher

    12
    如果我使用cmake,那么编辑文件和链接的所有hack都不起作用,因此我使用指定gcc/g++版本的标志编译。
    cmake -DCMAKE_C_COMPILER=gcc-6 -DCMAKE_CXX_COMPILER=g++-6 ..
    非常顺利。

    哈哈,我本来想在这里链接你在另一个问题中的答案,因为我认为它需要放在这个帖子上。再次做得好!谢谢。 - MikeDoho
    一个人应该避免在SO上发布重复的答案,但我没有选择。 :) - markroxor

    11

    对于CUDA7.5,这些代码可以正常工作:

    sudo ln -s /usr/bin/gcc-4.9 /usr/local/cuda/bin/gcc 
    sudo ln -s /usr/bin/g++-4.9 /usr/local/cuda/bin/g++
    

    11

    请查看如何使用“update-alternatives”来解决这个问题:

    ... If you install gcc 4.6 you can also use the update-alternatives command to allow for easily switching between versions. This can be configured with:

    sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.6 
    sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.7 
    sudo update-alternatives --config gcc
    

    6

    在大多数发行版中,除了像gcc-4.7这样的最新编译器之外,您还可以安装另一个gcc和g ++版本。此外,大多数构建系统都知道CCCXX环境变量,它们分别指定其他C和C ++编译器。因此,我建议使用类似以下内容:

    CC=gcc-4.4 CXX=g++-4.4 cmake path/to/your/CMakeLists.txt
    

    对于Makefiles,应该有类似的方法。我不建议在/usr/local中设置自定义符号链接,除非你知道你在做什么。

    3

    这适用于Fedora 23。兼容的gcc存储库将根据您的Fedora版本略有不同。

    如果您安装以下存储库:

    sudo yum install compat-gcc-34-c++-3.4.6-37.fc23.x86_64 compat-gcc-34-3.4.6-37.fc23.x86_64 
    

    现在按照上述提到的方式建立软链接,假设您的cuda bin文件夹位于/usr/local/cuda/
    sudo ln -s /usr/bin/gcc-34 /usr/local/cuda/bin/gcc
    sudo ln -s /usr/bin/g++-34 /usr/local/cuda/bin/g++
    

    现在,您应该能够使用nvcc编译,而不出现gcc版本错误。


    2
    $CUDA_HOME/include/host_config.h中,查找类似以下内容的行(在不同版本的CUDA中可能会略有不同):
    //...
    #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 9)
    
    #error -- unsupported GNU version! gcc versions later than 4.9 are not supported!
    
    #endif [> __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 9) <]
    //...
    

    根据您的条件删除或更改它们。

    请注意,此方法可能存在潜在的不安全性,并可能破坏您的构建。例如,gcc 5将C++11用作默认设置,但CUDA 7.5当前不是这种情况。解决方法是添加

    --Xcompiler="--std=c++98" 用于CUDA<=6.5

    或者

    --std=c++11 用于CUDA>=7.0。


    我们在哪里添加 --std=c++ 选项? - asgs

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接