CUDA 与我的 gcc 版本不兼容

我在编译 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在这一点上有一个完整的系统作为依赖..。

204601 次浏览

CUDA 不支持 gcc 4.5和4.6——代码不能编译,其他工具链,包括 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发布时,gcc 6在 Ubuntu 16.04、 Ubuntu 17.04和 Fedora 25上得到了完全支持。
  • 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)除了 Fedora linux 之外,CUDA 中没有对 gcc 10的支持

注意,NVIDIA 最近添加了一个非常有用的表 给你,其中包含了当前 CUDA 版本所支持的编译器和操作系统矩阵。

如前所述,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

Gearoid Murphy 的解决方案对我来说更好,因为在我的发行版(Ubuntu 11.10)中,gcc-4.4和 gcc-4.6在同一个目录中,所以编译器-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++

Gearoid Murphy 的解决方案非常有效。对我来说,我有两个 Cuda-的目录

/usr/local/cuda
/usr/local/cuda-5.0

软链接只能添加到下面提到的目录-

/usr/local/cuda

此外,如 SchighSchagh 所提到的,g + + 和 gcc 软链接都是必需的。

将 nvcc 配置为使用特定版本的 gcc (例如,gcc-4.4)的另一种方法是编辑 Nvcc.profile并修改 路径以包含首先要使用的 gcc 的路径。

例如(gcc-4.4.6安装在/opt 中) :

PATH += /opt/gcc-4.4.6/lib/gcc/x86_64-unknown-linux-gnu/4.4.6:/opt/gcc-4.4.6/bin:$(TOP)/open64/bin:$(TOP)/share/cuda/nvvm:$(_HERE_):

Nvcc.profile的位置不同,但是它应该与 Nvcc可执行文件本身在同一个目录中。

这是一个小技巧,因为根据 nvcc 手册,Nvcc.profile不是用于用户配置的,但它是最适合我的解决方案。

查看 如何使用「更新选择」来解决这个问题:

... 如果您安装 gcc 4.6,您也可以使用更新选项 命令,以便在不同版本之间轻松切换 配置有:

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

CUDA 经过了一些与 gcc4.7兼容的头部修改,可能还有更高的版本: Https://www.udacity.com/wiki/cs344/troubleshoot_gcc47

对于像我这样在使用 cmake时感到困惑的人来说,FindCUDA.cmake脚本覆盖了 nvcc.profile中的一些内容。可以通过按照 http://public.kitware.com/Bug/view.php?id=13674设置 CUDA_HOST_COMPILER来指定 nvcc主机编译器。

在大多数发行版中,您可以在最新的编译器(如 gcc-4.7)之外安装另一个 gcc 和 g + + 版本。此外,大多数构建系统都知道 CCCXX环境变量,它们可以分别指定其他 C 和 C + + 编译器。所以我的建议是:

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

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

我不得不安装 gcc,g + + 的旧版本。

    sudo apt-get install gcc-4.4
sudo apt-get install g++-4.4

检查 gcc-4.4是否在/usr/bin/中,g + + 也是如此 然后我可以使用上面的解决方案:

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

这适用于 Fedora 23。 compat 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 版本错误。

对于 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++

$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中 nvcc 不是这样。一个变通方法是添加

CUDA 的 --Xcompiler="--std=c++98" < = 6.5

或者

CUDA 的 --std=c++11 > = 7.0。

为了在 Ubuntu 16.10上编译 CUDA 8.0示例,我做了以下工作:

sudo apt-get install gcc-5 g++-5
cd /path/to/NVIDIA_CUDA-8.0_Samples
# Find the path to the library (this should be in NVIDIA's Makefiles)
LIBLOC=`find /usr/lib -name "libnvcuvid.so.*" | head -n1 | perl -pe 's[/usr/lib/(nvidia-\d+)/.*][$1]'`
# Substitute that path into the makefiles for the hard-coded, incorrect one
find . -name "*.mk" | xargs perl -pi -e "s/nvidia-\d+/$LIBLOC/g"
# Make using the supported compiler
HOST_COMPILER=g++-5 make

这样做的好处是不需要修改整个系统,也不需要仅对二进制文件建立符号链接(这可能会导致库链接问题)

  1. 检查您的 CUDA 版本最大支持的 GCC 版本:

    CUDA 版本 最大支持的 GCC 版本
    11.4.1 + ,11.5,11.6,11.7,11.8 11
    11.1,11.2,11.3,11.4 10
    11 9
    10.1,10.2 8
    9.2,10.0 7
    9.09.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
  2. 为该 GCC 版本设置 env var,例如,对于 CUDA 10.2:

    MAX_GCC_VERSION=8
    
  3. 确保您已经安装了该版本:

    sudo apt install gcc-$MAX_GCC_VERSION g++-$MAX_GCC_VERSION
    
  4. 在 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,如果没有的话)

有关 CUDA-GCC 兼容性表 的更多信息,请参见 GitHub 要点。

如果我使用 cmake没有任何编辑文件和链接的技巧,所以我使用指定 gcc/g + + 版本的标志进行编译。
cmake -DCMAKE_C_COMPILER=gcc-6 -DCMAKE_CXX_COMPILER=g++-6 ..

非常有效。

这解决了我的问题:

sudo rm /usr/local/cuda/bin/gcc
sudo rm /usr/local/cuda/bin/g++
sudo apt install gcc-4.4 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++

之所以会出现这种情况,是因为当前的 CUDA 版本不支持当前的 GCC 版本:

  1. 找到支持的 GCC 版本(在我的案例中是 CUDA 9的5)

    • CUDA 4.1: GCC 4.5
    • CUDA 5.0: GCC 4.6
    • CUDA 6.0: GCC 4.7
    • CUDA 7.0: GCC 4.8
    • CUDA 7.5: GCC 4.8
    • CUDA 8: GCC 5.3
    • CUDA 9: GCC 5.5
    • CUDA 9.2: GCC 7
    • CUDA 10.1: GCC 8
  2. 安装受支持的 GCC 版本

    sudo apt-get install gcc-5
    sudo apt-get install g++-5
    
  3. Change the softlinks for GCC in the /usr/bin directory

    cd /usr/bin
    sudo rm gcc
    sudo rm g++
    sudo ln -s /usr/bin/gcc-5 gcc
    sudo ln -s /usr/bin/g++-5 g++
    
  4. Change the softlinks for GCC in the /usr/local/cuda-9.0/bin directory

    cd /usr/local/cuda-9.0/bin
    sudo rm gcc
    sudo rm g++
    sudo ln -s /usr/bin/gcc-5 gcc
    sudo ln -s /usr/bin/g++-5 g++
    
  5. Add -DCUDA_HOST_COMPILER=/usr/bin/gcc-5 to your setup.py file, used for compilation

    if torch.cuda.is_available() and CUDA_HOME is not None:
    extension = CUDAExtension
    sources += source_cuda
    define_macros += [("WITH_CUDA", None)]
    extra_compile_args["nvcc"] = [
    "-DCUDA_HAS_FP16=1",
    "-D__CUDA_NO_HALF_OPERATORS__",
    "-D__CUDA_NO_HALF_CONVERSIONS__",
    "-D__CUDA_NO_HALF2_OPERATORS__",
    "-DCUDA_HOST_COMPILER=/usr/bin/gcc-5"
    ]
    
  6. Remove the old build directory

    rm -rd build/
    
  7. Compile again by setting CUDAHOSTCXX=/usr/bin/gcc-5

    CUDAHOSTCXX=/usr/bin/gcc-5 python setup.py build develop
    

Note: If you still get the gcc: error trying to exec 'cc1plus': execvp: no such file or directory error after following these steps, try reinstalling the GCC like this and then compiling again:

sudo apt-get install --reinstall gcc-5
sudo apt-get install --reinstall g++-5

来源: https://github.com/facebookresearch/maskrcnn-benchmark/issues/25#issuecomment-433382510

如果遇到此错误,请阅读日志文件:

$ cat /var/log/cuda-installer.log
[INFO]: Driver installation detected by command: apt list --installed | grep -e nvidia-driver-[0-9][0-9][0-9] -e nvidia-[0-9][0-9][0-9]
[INFO]: Cleaning up window
[INFO]: Complete
[INFO]: Checking compiler version...
[INFO]: gcc location: /usr/bin/gcc


[INFO]: gcc version: gcc version 9.2.1 20191008 (Ubuntu 9.2.1-9ubuntu2)


[ERROR]: unsupported compiler version: 9.2.1. Use --override to override this check.

只要按照日志文件中的建议:

sudo sh cuda_<version>_linux.run --override

任务完成:)

我刚刚使用 --override选项在 Kubuntu 19.10上安装了具有 gcc 9.2的 CUDA 10.2。

对于 CUDA 6.5(显然是7.0和7.5) ,我已经创建了一个版本的 GCC 4.8.5 RPM 包(在 Fedora Core 30下) ,它允许该版本的 GCC 与系统当前的 GCC 一起安装。

您可以找到所有这些信息 给你

在我的案例中,我已经从 Ubuntu 版本安装了 CUDA,cmake 会检测到使用 NVidia SDK Manager 安装了 CUDA 而不是新安装的版本。

我运行 dpkg -l | grep cuda,可以看到两个版本。

我必须做的是卸载旧的 CUDA (对我来说是9.1版本) ,而不去管新的版本(10.2版本)。我是这样使用 purge 命令的:

sudo apt-get purge libcudart9.1 nvidia-cuda-dev nvidia-cuda-doc \
nvidia-cuda-gdb nvidia-cuda-toolkit

请验证包名称是否与要从安装中删除的版本相匹配。

我必须从一个空白的 BUILD目录重新运行 cmake,将所有的 #include和库重定向到 SDK 版本(因为旧的路径是在现有的构建环境中生成的)。