
首先是遇到了上述问题:cpp编译正确,但是nvcc报错无法继续编译;(补充讲解)。

回到我前面学习过的内容,大概是因为Runtime/Toolkit版本大于Driver。
故执行下列两命令得到对应版本分别为12.0<12.6感觉就没有问题。
bash
user@ao:/mnt/c/duiyou_cusignal/tests/utils$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Built on Fri_Jan__6_16:45:21_PST_2023
Cuda compilation tools, release 12.0, V12.0.140
Build cuda_12.0.r12.0/compiler.32267302_0
user@ao:/mnt/c/duiyou_cusignal/tests/utils$ nvidia-smi
Wed Apr 22 21:18:37 2026
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 560.35.02 Driver Version: 560.94 CUDA Version: 12.6 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce RTX 4050 ... On | 00000000:01:00.0 On | N/A |
| N/A 58C P8 2W / 125W | 610MiB / 6141MiB | 0% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
gaoziyang@Giao:/mnt/c/duiyou_cusignal/tests/utils$
向AI询问后得知可能是两种问题:1.环境变量迷路了 :CUDA 运行时找不到 Windows 穿透进来的专属驱动文件,而去读了一个系统里遗留的残缺替身;2.错误安装了 Linux 原生驱动 :如果你(或某些自动脚本)曾在 WSL 内部执行过类似 sudo apt install nvidia-driver-... 的命令,Linux 原生驱动覆盖了 Windows 的穿透驱动,导致 CUDA 运行时瞬间"精神分裂"。
第一步查出问题
故我只能清理潜在的假驱动nvidia driver.确保 WSL 内部没有安装干扰性的 Linux 原生显卡驱动:
bash
sudo apt-get purge -y nvidia-*
sudo apt-get autoremove -y
-
为什么要这么做(理由) : 在纯正的 Ubuntu 系统里,我们需要用
apt命令去下载 NVIDIA 驱动。但 WSL2 是寄生在 Windows 上的,它使用的是 Windows 投射过来的特殊驱动(存放于/usr/lib/wsl/lib)。如果你或者某些一键安装脚本,不小心在 WSL 里执行了原生的驱动安装命令,这个"假驱动"就会霸占系统,导致你的 CUDA 运行时(编译器)找不到真正的宿主机驱动,从而报错。 -
做完后的结果(你会看到什么):
-
终端会跑一段进度条,搜索所有带
nvidia-前缀的包。 -
情况 A :如果提示
0 upgraded, 0 newly installed, 0 to remove...,说明你的系统很干净,本来就没有错装假驱动。这非常好。 -
情况 B :如果列出了一大堆文件并提示
Removing...,说明抓到"内鬼"了,系统正在把它删掉。
-
-
下一步怎么操作: 无论情况 A 还是 B,只要命令执行完毕回到命令行输入提示符,就可以直接进入第二步。
而我在这里是第二种,且同时也把toolkit删了,所以要重新装toolkit.
这里又有两步:
1.删除残余文件
bash
sudo apt-get autoremove -y
2.重新装toolkit(这种方法会按照对应此系统默认版本的CUDA toolkit版本),但是我需要11.7版本,所以我按照第二种方式安装。
第一种:
bash
sudo apt-get install -y nvidia-cuda-toolkit
第二章:
bash
# 1. 下载 CUDA 11.7 官方离线安装包
wget https://developer.download.nvidia.com/compute/cuda/11.7.1/local_installers/cuda_11.7.1_515.65.01_linux.run
# 2. 赋予执行权限
chmod +x cuda_11.7.1_515.65.01_linux.run
# 3. 静默安装(只装 Toolkit,绝不覆盖驱动!)
sudo ./cuda_11.7.1_515.65.01_linux.run --silent --toolkit
但是我在这里执行第一步的步骤2.的最后一句话的时候有报错了:这里是因为我ubuntu24版本默认g++是13.3.0和CUDA11.7冲突了。
bash
Failed to verify gcc version. See log at /var/log/cuda-installer.log for details.
所以我直接打算把g++版本也降级变成赛题要求的9.3.0了下面见操作:
(1). **添加旧版工具链源并安装 GCC/G++ 9.**因为 Ubuntu 24.04 默认源里已经不提供这么老的版本了,我们需要添加一个专门维护编译器的官方 PPA 源
bash
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
sudo apt-get update
sudo apt-get install -y gcc-9 g++-9
(2). 将 GCC 9 设为系统默认编译器. 安装完后,系统里会同时存在 13 和 9 两个版本。我们用 update-alternatives 命令强行把 9 设置为第一顺位:
bash
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 100 --slave /usr/bin/g++ g++ /usr/bin/g++-9
执行完这句后,你可以敲一下 g++ --version,它现在应该已经乖乖变成 9.x.x 了!
此后跑出来就是:(赛题里写的 9.3.0 是 2020 年刚发布 Ubuntu 20.04 时原机自带的初始版本。后来官方陆续修复了一些编译器自身的底层崩溃 Bug,推出了 9.4.0,最后停更在了 9.5.0 。 所以,你现在拿到的是 GCC 9 系列的最强终极版。在 C++ 和 GCC 的规则里,只要大版本(大前缀)相同 (都是 GCC 9),它们的 ABI(应用程序二进制接口)、支持的 C++17 特性、以及底层的数据对齐方式就是完全一模一样的。所以不用担心影响比赛测评)
bash
g++ --version
g++ (Ubuntu 9.5.0-6ubuntu2.1) 9.5.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
(3).后面回到报错的地方也就是下面这句话:并重新执行(也可以在最后面加一个--override如下:二者选一个就行)
bash
# 3. 静默安装(只装 Toolkit,绝不覆盖驱动!)
sudo ./cuda_11.7.1_515.65.01_linux.run --silent --toolkit
bash
sudo ./cuda_11.7.1_515.65.01_linux.run --silent --toolkit --override
这一步要花很久,且我用了--silent所以屏幕不会打印进程,如果想要知道,可以重开一个wsl终端输入top即可.
注意此处安装好了之后,默认CUDA toolkit会安装在wsl路径下面:
bash
/usr/local/cuda-11.7
如果从windows路径里面找就如下:
第二步重新搭桥并指明 CUDA 路径(核心环境变量)
两件事:把 Windows 穿透进来的真驱动告诉系统,并且把刚才装好的 CUDA 11.7 编译器路径告诉系统。
bash
# 1. 配置当前终端
export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH
export PATH=/usr/local/cuda-11.7/bin:$PATH
# 2. 永久写入环境变量文件(以后重启都不用怕了)
echo 'export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH' >> ~/.bashrc
echo 'export PATH=/usr/local/cuda-11.7/bin:$PATH' >> ~/.bashrc
执行完后,你可以敲一下 nvcc --version,如果输出显示 Cuda compilation tools, release 11.7,恭喜你,完美对齐赛题!)
自此结束,后续验证即可!安装好了记得可以把.run安装包删了。
bash
user@ao:/mnt/c/duiyou_cusignal$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2022 NVIDIA Corporation
Built on Wed_Jun__8_16:49:14_PDT_2022
Cuda compilation tools, release 11.7, V11.7.99
Build cuda_11.7.r11.7/compiler.31442593_0
user@ao:/mnt/c/duiyou_cusignal$ g++ --version
g++ (Ubuntu 9.5.0-6ubuntu2.1) 9.5.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
第三步重新验证你的 C++ 程序
可是GPU 运行时仍然不通:依旧报错nvidia-smi 报 GPU access blocked by the operating system.我直接跑 test_windows 还是失败,报错落在 common.h,信息是 CUDA driver version is insufficient for CUDA runtime version报错和最初的基本一样说明终端会话里面虽然编译器版本对的,但是没有形成可用的CUDA编译环境,重要的是 GPU 运行权限/驱动仍然挡住了实际执行。
执行下面命令:(补充:结尾带冒号+路径的代表列表型变量,不带的是单值型变量)
bash
#export这个shell命令将变量导出为全局环境变量分别指定:
#1.找动态链接库路径.so和.dll等等;因为编译出的程序运行时候需要调用显卡的驱动,wsl需要显式指定,才能#借用显卡驱动才能运行,保证编译阶段后的运行阶段能够正常跑;
#2.CUDA (toolkit)11.7可执行文件目录添加进系统PATH变量;
#3.明确告诉系统nvcc绝对路径,防止CMake等代码构建工具找不到对应版本编译器;
#4.指定C编译器;
#5.指定C++编译器。
export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH
export PATH=/usr/local/cuda-11.7/bin:$PATH
export CUDACXX=/usr/local/cuda-11.7/bin/nvcc
export CC=/usr/bin/gcc-9
export CXX=/usr/bin/g++-9
#并打印出来看
nvcc --version
g++ --version
echo $CUDACXX
echo $CC
echo $CXX
#当然也可以在命令最后一句加一个>> ~/.bashrc如下:(~是用户家目录如/home/user名,)
#.bashrc隐藏的系统配置文件。它的神奇之处在于:每次你打开一个新的 Bash 终端窗口时,
##台静默运行一遍系统都会自动在后这个文件里的所有代码。
#所以每一次打开终端时候,我会自然运行单引号里面的命令!!!
echo 'export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH' >> ~/.bashrc
echo 'export PATH=/usr/local/cuda-11.7/bin:$PATH' >> ~/.bashrc
#如果我写入 ~/.bashrc后,需要运行下面命令才能在当前窗口生效
source ~/.bashrc
#补充是一个自动获取cpu核心,并行编译的指令
make -j$(nproc)
此后大家就可以正常的编译运行了。
但是我自己还是无法运行因为两个问题:我的CMakeList放在上上一级,找错了去找到了上一级的CMakeList;第二个问题是上上一级的CMakeList里面是队友写的,他的是高版本的CUDA,架构x89 40系显卡,但11.7无法使用所以我找到了对的CMakeList脚本也不行,但是改动队友代码也不太好,所以我在一键调用的py脚本里面多加了几个part用来.
所以对我来说有两种方法:
方法一运行时手动在终端敲命令:
1.先解决路径问题.
是不是必须把文件挪到上一级去",其实完全不用。CMake 提供了极其强大的路径指定参数:
-
-S <路径>(Source):显式告诉 CMake,源码和主CMakeLists.txt在哪里。 -
-B <路径>(Build):显式告诉 CMake,编译产生的垃圾文件和结果放在哪里。
不管你人现在在哪个目录下(哪怕你人在 ~ 家目录下),只要你敲出下面这句,CMake 就能精准找对地方,完全不用挪动任何文件:
bash
# 假设你当前在 /mnt/c/duiyou_cusignal
cmake -S . -B tests/build_gpu_naive
2.解决架构冲突问题.CMake 的 -D 外部注入参数
很多人遇到这种情况的第一反应就是:"我去把队友的 CMakeLists.txt 打开,把里面的 89 删掉,改成 75;80;86"。 在正规的软件工程里,这是非常错误的做法! 因为你改了之后一提交代码,队友那边的高级显卡可能就没法全速运行了。
CMake 提供了一个强大的"外部变量注入 "机制,也就是 -D 参数 。它允许你在敲命令的时候,强行把配置塞进去,这会覆盖 掉 CMakeLists.txt 里的默认行为,而不需要修改文件本身的代码。
即直接在命令里强行指定架构和编译器:
bash
cmake -S . -B tests/build_gpu_naive \
-DCMAKE_CUDA_ARCHITECTURES="75;80;86" \
-DCMAKE_CUDA_COMPILER="/usr/local/cuda-11.7/bin/nvcc"
总共如下:
bash
# 1. 回到项目根目录
cd /mnt/c/duiyou_cusignal
# 2. 用 -S, -B, -D 强行指定路径、编译器和架构,生成编译配置
cmake -S . -B tests/build_gpu_naive -DCMAKE_CUDA_ARCHITECTURES="75;80;86" -DCMAKE_CUDA_COMPILER="/usr/local/cuda-11.7/bin/nvcc" -DCMAKE_CXX_COMPILER="/usr/bin/g++-9"
# 3. 告诉 CMake 去刚才指定的目录里执行编译
cmake --build tests/build_gpu_naive -j$(nproc)