1. 问题重现那个让人头疼的“找不到文件”错误如果你和我一样在折腾AI绘画或者大模型想在Linux服务器上安装xFormers来给GPU加速那你大概率会碰到这个经典的拦路虎。错误信息通常长这样在你满怀期待地执行pip install xformers或者pip install -e .编译了十几二十分钟后它冷不丁地给你来一下cc1plus: fatal error: cuda_runtime.h: No such file or directory compilation terminated. error: command /usr/bin/g failed with exit code 1那一瞬间的感觉就像你辛辛苦苦搭了半天积木最后一块放上去的时候整个塔轰然倒塌。更气人的是你明明知道这个文件就在那里用find命令一搜cuda_runtime.h文件好端端地躺在/usr/local/cuda-11.x/include目录里为什么编译器就是“睁眼瞎”说找不到呢我当时的场景是在一个公司的计算服务器上为Stable Diffusion搭建环境。服务器本身装好了CUDA 11.2驱动也没问题。我创建了一个干净的conda虚拟环境按照官方指南装好了对应版本的PyTorch1.12.0CUDA 11.3。一切看起来都很完美直到开始安装xFormers这个“内存救星”。没有它我的P40显卡22G显存跑768x768的图都吃力动不动就显存爆炸。所以安装xFormers不是可选项而是必选项。这个错误的本质不是一个“文件真的丢失”的问题而是一个“编译器不知道去哪里找文件”的问题。这就好比你知道家里的钥匙放在进门鞋柜的第二个抽屉里但如果你没告诉一个陌生人这个具体位置他就算把鞋柜翻个底朝天在当前目录和默认目录找也找不到。在Linux的编译世界里这个“告诉编译器去哪里找”的关键角色就是环境变量尤其是那个容易被忽略的CPATH。2. 追根溯源为什么是CPATH而不是PATH或LD_LIBRARY_PATH很多朋友包括最初的我一看到CUDA相关的路径问题第一反应就是去折腾~/.bashrc文件里的PATH和LD_LIBRARY_PATH。我们会熟练地加上export PATH/usr/local/cuda-11.2/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-11.2/lib64:$LD_LIBRARY_PATH然后source ~/.bashrc满心欢喜地以为问题解决了。结果再次运行安装命令同样的错误“啪”地一下又糊在脸上。这时候就开始怀疑人生了路径明明加了为什么不行这里就需要理解这几个环境变量在编译过程中的不同职责PATH 这是给系统shell用的。当你输入nvcc或者python命令时系统会按照PATH变量里列出的目录顺序去查找这些可执行文件。它管的是“运行什么程序”。LD_LIBRARY_PATH 这是给程序运行时用的。当一个程序比如Python导入编译好的xFormers模块启动后系统加载器ld.so会按照这个变量里的路径去寻找程序依赖的动态链接库.so文件。它管的是“运行时找哪些库”。CPATH(或它的另一个常用别名C_INCLUDE_PATH/CPLUS_INCLUDE_PATH) 这是给编译器用的。当g或gcc进行编译时遇到#include cuda_runtime.h这样的语句它需要知道去哪些目录里搜索这个头文件.h文件。CPATH就是告诉编译器“嘿去这些目录里找头文件。” 它管的是“编译时找哪些头文件”。在我们安装xFormers的过程中执行pip install会触发源码编译。pip调用了setuptoolssetuptools又调用了g编译器来编译那些CUDA扩展.cu文件。g在编译时需要包含CUDA的头文件比如cuda_runtime.h。如果g自己的搜索路径系统默认的/usr/include等和CPATH环境变量里都没有包含CUDA头文件的实际路径它就会立刻报错“找不到文件”。所以核心矛盾就在于我们配置了运行环境PATH和运行时链接环境LD_LIBRARY_PATH却唯独漏掉了最关键的编译环境CPATH。编译器就像一个被蒙上眼睛的工人你给了它工具PATH也告诉它成品库房在哪LD_LIBRARY_PATH但没告诉它原材料头文件放在哪个仓库它当然没法开工。3. 手把手解决方案配置CPATH一劳永逸理解了原理解决起来就直击要害了。下面是我经过多次踩坑后总结出的可靠步骤请跟着一步一步来。3.1 第一步确认你的CUDA安装位置和版本在修改任何配置之前先搞清楚你的CUDA到底装在哪。打开终端执行which nvcc这条命令会返回nvcc编译器所在的路径通常是/usr/local/cuda/bin/nvcc。这里的/usr/local/cuda通常是一个指向具体版本如cuda-11.2的符号链接。更直接的方法是查看/usr/local目录ls -l /usr/local/ | grep cuda你会看到类似这样的输出lrwxrwxrwx 1 root root 20 Apr 10 2023 cuda - /usr/local/cuda-11.2 drwxr-xr-x 17 root root 4096 Apr 10 2023 cuda-11.2这表示系统默认的CUDA是11.2版本实际安装在/usr/local/cuda-11.2。请记下这个实际路径比如/usr/local/cuda-11.2。3.2 第二步定位关键的头文件目录我们需要的是包含cuda_runtime.h等头文件的目录。进入你的CUDA实际安装路径下的include目录查看ls /usr/local/cuda-11.2/include/ | grep cuda_runtime.h你应该能看到cuda_runtime.h这个文件。但请注意对于xFormers的编译仅仅指向/usr/local/cuda-11.2/include有时候可能还不够。更稳妥的做法是指向其子目录targets/x86_64-linux/include。你可以检查一下这个路径是否存在ls /usr/local/cuda-11.2/targets/x86_64-linux/include/cuda_runtime.h如果存在那么我们将使用这个更具体的路径作为CPATH的值。这个路径是CUDA工具链针对特定系统架构x86_64-linux的标准头文件位置兼容性最好。3.3 第三步永久修改环境变量配置文件我们不建议只在当前终端用export命令临时设置因为下次开新终端或者pip在非交互式环境下编译时又会失效。我们需要修改shell的配置文件通常是~/.bashrc如果你用的是Bash或者~/.zshrc如果你用的是Zsh。用你喜欢的文本编辑器打开它比如nanonano ~/.bashrc滚动到文件末尾添加以下三行请将/usr/local/cuda-11.2替换为你自己的实际路径# CUDA Development Environment export CPATH/usr/local/cuda-11.2/targets/x86_64-linux/include:$CPATH export LD_LIBRARY_PATH/usr/local/cuda-11.2/lib64:$LD_LIBRARY_PATH export PATH/usr/local/cuda-11.2/bin:$PATH重点解读一下这三行export CPATH... 这是解决cuda_runtime.h找不到的关键。它将CUDA的头文件目录添加到CPATH环境变量的最前面$CPATH代表原有的值。这样编译器在搜索头文件时会优先扫描这个目录。export LD_LIBRARY_PATH... 将CUDA的运行时库目录lib64添加进来确保编译出的程序在运行时能找到libcudart.so等动态库。export PATH... 将CUDA的可执行文件目录bin添加进来确保你能在终端直接运行nvcc、nvidia-smi等命令。保存文件在nano中是CtrlO然后回车再CtrlX退出。3.4 第四步让配置立即生效并验证修改完配置文件后需要让当前终端会话重新加载它source ~/.bashrc现在让我们验证一下环境变量是否设置正确echo $CPATH你应该能在输出中看到/usr/local/cuda-11.2/targets/x86_64-linux/include这个路径出现在前面。为了更彻底地测试我们可以写一个最简单的C测试程序。创建一个文件test_cuda_include.cu其实用.cpp也行但.cu更贴切cat EOF test_cuda_include.cu #include cstdio #include cuda_runtime.h int main() { printf(CUDA头文件包含测试成功\n); printf(CUDA运行时版本%d\n, CUDART_VERSION); return 0; } EOF尝试用g编译它不链接CUDA库只做预处理和编译检查g -I/usr/local/cuda-11.2/targets/x86_64-linux/include -c test_cuda_include.cu -o test_cuda_include.o 21如果这条命令没有报cuda_runtime.h: No such file or directory的错误只是提示一些关于未定义引用这是正常的因为我们没链接库的警告那就说明CPATH或者我们手动指定的-I参数生效了编译器能找到头文件了4. 重新安装xFormers见证成功环境变量配置妥当后就可以回到你的xFormers源码目录开始最终的安装了。我强烈建议在一个干净的虚拟环境下操作避免旧缓存干扰。# 激活你的conda环境例如名为sd conda activate sd # 进入xFormers源码目录如果你是用git clone的 cd path/to/xformers # 清除之前的构建缓存非常重要 pip uninstall -y xformers rm -rf build/ dist/ *.egg-info # 重新安装可以加上-v参数查看详细编译过程 pip install -v -e . # 或者直接安装最新稳定版 # pip install -v xformers这次你应该会看到编译过程顺利进行g命令不再抱怨找不到头文件而是开始愉快地编译一个个.cu文件。整个过程可能需要10-30分钟取决于你的机器性能。当最后出现Successfully installed xformers-0.0.xx的字样时恭喜你最艰难的一关已经过了安装成功后可以在Python中简单验证import torch import xformers print(fPyTorch版本: {torch.__version__}) print(fCUDA可用: {torch.cuda.is_available()}) print(fxFormers版本: {xformers.__version__})5. 进阶排查与替代方案虽然配置CPATH解决了90%的问题但现实世界总有意外。这里分享几个我遇到过的其他情况和备选方案。5.1 检查编译器兼容性有时候问题不在于找不到头文件而在于编译器版本不兼容。xFormers的CUDA扩展需要g编译器。你可以检查一下默认的g版本g --version确保你的g版本不是太老。在一些非常旧的系统上可能需要升级到较新的版本如 g-9, g-10。你可以通过包管理器安装多个版本并用update-alternatives进行切换。5.2 使用-I参数直接指定头文件路径临时方案如果你不想永久修改系统环境变量或者只是在某个特定项目中需要可以在安装xFormers时通过设置CFLAGS和CXXFLAGS环境变量来临时指定头文件路径export CFLAGS-I/usr/local/cuda-11.2/targets/x86_64-linux/include export CXXFLAGS-I/usr/local/cuda-11.2/targets/x86_64-linux/include pip install -e .这个方法的缺点是只对当前终端会话的这次pip安装有效。5.3 修改xFormers的setup.py硬编码方案如果你对源码编译流程比较熟悉可以直接修改xFormers源码目录下的setup.py文件。找到定义CUDAExtension的地方在include_dirs列表里显式地添加CUDA头文件路径。# 在setup.py中查找类似这样的部分 ext_modules [ CUDAExtension( xformers._C, sources[ # ... 一堆源文件 ], include_dirs[ # 在这里添加 /usr/local/cuda-11.2/targets/x86_64-linux/include, # ... 其他路径 ], libraries[cuda, cudart], # ... ), ]这种方法比较“硬核”但好处是配置直接写死在项目里不依赖用户的环境。不过每次更新xFormers源码后可能需要重新修改。5.4 考虑使用预编译的wheel包如果你实在被编译问题搞得焦头烂额不妨看看有没有对应你系统的预编译的xFormers wheel包。PyPI上官方发布的xFormers通常只针对有限的CUDA和Python版本组合提供预编译包。你可以去xFormers的GitHub Release页面看看或者在一些社区资源站上寻找。使用预编译包非常简单直接pip install对应的.whl文件即可完全跳过了编译步骤。这可以说是最省心的方案前提是你能找到匹配的版本。6. 成功之后享受GPU加速的快感当我按照上述方法配置好CPATH并成功安装xFormers后再次运行Stable Diffusion那种感觉真是豁然开朗。之前跑一张768x768的图片显存占用轻轻松松突破18G时刻在爆显存的边缘试探。启用xFormers的注意力优化后显存占用直接降到了10G以下并且生成速度还有可观的提升。运行命令也变得轻松愉快python scripts/txt2img.py --prompt “a best-quality photo of a cute cat” --ckpt v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --device cuda --xformers看着九宫格的可爱猫咪图片一张张快速生成之前折腾环境的所有烦躁都烟消云散了。这个踩坑经历让我深刻体会到在Linux下进行CUDA相关的开发环境变量的理解和管理是一项基本功。PATH、LD_LIBRARY_PATH和CPATH各司其职缺一不可。尤其是CPATH这个在普通应用开发中很少接触的变量在涉及C/C扩展编译时就成了决定成败的关键。下次再遇到类似的“找不到头文件”错误你应该能立刻反应过来问题很可能就出在CPATH这个“指路牌”没有设对地方。
【已解决】xFormers安装报错:CPATH环境变量缺失导致cuda_runtime.h找不到
1. 问题重现那个让人头疼的“找不到文件”错误如果你和我一样在折腾AI绘画或者大模型想在Linux服务器上安装xFormers来给GPU加速那你大概率会碰到这个经典的拦路虎。错误信息通常长这样在你满怀期待地执行pip install xformers或者pip install -e .编译了十几二十分钟后它冷不丁地给你来一下cc1plus: fatal error: cuda_runtime.h: No such file or directory compilation terminated. error: command /usr/bin/g failed with exit code 1那一瞬间的感觉就像你辛辛苦苦搭了半天积木最后一块放上去的时候整个塔轰然倒塌。更气人的是你明明知道这个文件就在那里用find命令一搜cuda_runtime.h文件好端端地躺在/usr/local/cuda-11.x/include目录里为什么编译器就是“睁眼瞎”说找不到呢我当时的场景是在一个公司的计算服务器上为Stable Diffusion搭建环境。服务器本身装好了CUDA 11.2驱动也没问题。我创建了一个干净的conda虚拟环境按照官方指南装好了对应版本的PyTorch1.12.0CUDA 11.3。一切看起来都很完美直到开始安装xFormers这个“内存救星”。没有它我的P40显卡22G显存跑768x768的图都吃力动不动就显存爆炸。所以安装xFormers不是可选项而是必选项。这个错误的本质不是一个“文件真的丢失”的问题而是一个“编译器不知道去哪里找文件”的问题。这就好比你知道家里的钥匙放在进门鞋柜的第二个抽屉里但如果你没告诉一个陌生人这个具体位置他就算把鞋柜翻个底朝天在当前目录和默认目录找也找不到。在Linux的编译世界里这个“告诉编译器去哪里找”的关键角色就是环境变量尤其是那个容易被忽略的CPATH。2. 追根溯源为什么是CPATH而不是PATH或LD_LIBRARY_PATH很多朋友包括最初的我一看到CUDA相关的路径问题第一反应就是去折腾~/.bashrc文件里的PATH和LD_LIBRARY_PATH。我们会熟练地加上export PATH/usr/local/cuda-11.2/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-11.2/lib64:$LD_LIBRARY_PATH然后source ~/.bashrc满心欢喜地以为问题解决了。结果再次运行安装命令同样的错误“啪”地一下又糊在脸上。这时候就开始怀疑人生了路径明明加了为什么不行这里就需要理解这几个环境变量在编译过程中的不同职责PATH 这是给系统shell用的。当你输入nvcc或者python命令时系统会按照PATH变量里列出的目录顺序去查找这些可执行文件。它管的是“运行什么程序”。LD_LIBRARY_PATH 这是给程序运行时用的。当一个程序比如Python导入编译好的xFormers模块启动后系统加载器ld.so会按照这个变量里的路径去寻找程序依赖的动态链接库.so文件。它管的是“运行时找哪些库”。CPATH(或它的另一个常用别名C_INCLUDE_PATH/CPLUS_INCLUDE_PATH) 这是给编译器用的。当g或gcc进行编译时遇到#include cuda_runtime.h这样的语句它需要知道去哪些目录里搜索这个头文件.h文件。CPATH就是告诉编译器“嘿去这些目录里找头文件。” 它管的是“编译时找哪些头文件”。在我们安装xFormers的过程中执行pip install会触发源码编译。pip调用了setuptoolssetuptools又调用了g编译器来编译那些CUDA扩展.cu文件。g在编译时需要包含CUDA的头文件比如cuda_runtime.h。如果g自己的搜索路径系统默认的/usr/include等和CPATH环境变量里都没有包含CUDA头文件的实际路径它就会立刻报错“找不到文件”。所以核心矛盾就在于我们配置了运行环境PATH和运行时链接环境LD_LIBRARY_PATH却唯独漏掉了最关键的编译环境CPATH。编译器就像一个被蒙上眼睛的工人你给了它工具PATH也告诉它成品库房在哪LD_LIBRARY_PATH但没告诉它原材料头文件放在哪个仓库它当然没法开工。3. 手把手解决方案配置CPATH一劳永逸理解了原理解决起来就直击要害了。下面是我经过多次踩坑后总结出的可靠步骤请跟着一步一步来。3.1 第一步确认你的CUDA安装位置和版本在修改任何配置之前先搞清楚你的CUDA到底装在哪。打开终端执行which nvcc这条命令会返回nvcc编译器所在的路径通常是/usr/local/cuda/bin/nvcc。这里的/usr/local/cuda通常是一个指向具体版本如cuda-11.2的符号链接。更直接的方法是查看/usr/local目录ls -l /usr/local/ | grep cuda你会看到类似这样的输出lrwxrwxrwx 1 root root 20 Apr 10 2023 cuda - /usr/local/cuda-11.2 drwxr-xr-x 17 root root 4096 Apr 10 2023 cuda-11.2这表示系统默认的CUDA是11.2版本实际安装在/usr/local/cuda-11.2。请记下这个实际路径比如/usr/local/cuda-11.2。3.2 第二步定位关键的头文件目录我们需要的是包含cuda_runtime.h等头文件的目录。进入你的CUDA实际安装路径下的include目录查看ls /usr/local/cuda-11.2/include/ | grep cuda_runtime.h你应该能看到cuda_runtime.h这个文件。但请注意对于xFormers的编译仅仅指向/usr/local/cuda-11.2/include有时候可能还不够。更稳妥的做法是指向其子目录targets/x86_64-linux/include。你可以检查一下这个路径是否存在ls /usr/local/cuda-11.2/targets/x86_64-linux/include/cuda_runtime.h如果存在那么我们将使用这个更具体的路径作为CPATH的值。这个路径是CUDA工具链针对特定系统架构x86_64-linux的标准头文件位置兼容性最好。3.3 第三步永久修改环境变量配置文件我们不建议只在当前终端用export命令临时设置因为下次开新终端或者pip在非交互式环境下编译时又会失效。我们需要修改shell的配置文件通常是~/.bashrc如果你用的是Bash或者~/.zshrc如果你用的是Zsh。用你喜欢的文本编辑器打开它比如nanonano ~/.bashrc滚动到文件末尾添加以下三行请将/usr/local/cuda-11.2替换为你自己的实际路径# CUDA Development Environment export CPATH/usr/local/cuda-11.2/targets/x86_64-linux/include:$CPATH export LD_LIBRARY_PATH/usr/local/cuda-11.2/lib64:$LD_LIBRARY_PATH export PATH/usr/local/cuda-11.2/bin:$PATH重点解读一下这三行export CPATH... 这是解决cuda_runtime.h找不到的关键。它将CUDA的头文件目录添加到CPATH环境变量的最前面$CPATH代表原有的值。这样编译器在搜索头文件时会优先扫描这个目录。export LD_LIBRARY_PATH... 将CUDA的运行时库目录lib64添加进来确保编译出的程序在运行时能找到libcudart.so等动态库。export PATH... 将CUDA的可执行文件目录bin添加进来确保你能在终端直接运行nvcc、nvidia-smi等命令。保存文件在nano中是CtrlO然后回车再CtrlX退出。3.4 第四步让配置立即生效并验证修改完配置文件后需要让当前终端会话重新加载它source ~/.bashrc现在让我们验证一下环境变量是否设置正确echo $CPATH你应该能在输出中看到/usr/local/cuda-11.2/targets/x86_64-linux/include这个路径出现在前面。为了更彻底地测试我们可以写一个最简单的C测试程序。创建一个文件test_cuda_include.cu其实用.cpp也行但.cu更贴切cat EOF test_cuda_include.cu #include cstdio #include cuda_runtime.h int main() { printf(CUDA头文件包含测试成功\n); printf(CUDA运行时版本%d\n, CUDART_VERSION); return 0; } EOF尝试用g编译它不链接CUDA库只做预处理和编译检查g -I/usr/local/cuda-11.2/targets/x86_64-linux/include -c test_cuda_include.cu -o test_cuda_include.o 21如果这条命令没有报cuda_runtime.h: No such file or directory的错误只是提示一些关于未定义引用这是正常的因为我们没链接库的警告那就说明CPATH或者我们手动指定的-I参数生效了编译器能找到头文件了4. 重新安装xFormers见证成功环境变量配置妥当后就可以回到你的xFormers源码目录开始最终的安装了。我强烈建议在一个干净的虚拟环境下操作避免旧缓存干扰。# 激活你的conda环境例如名为sd conda activate sd # 进入xFormers源码目录如果你是用git clone的 cd path/to/xformers # 清除之前的构建缓存非常重要 pip uninstall -y xformers rm -rf build/ dist/ *.egg-info # 重新安装可以加上-v参数查看详细编译过程 pip install -v -e . # 或者直接安装最新稳定版 # pip install -v xformers这次你应该会看到编译过程顺利进行g命令不再抱怨找不到头文件而是开始愉快地编译一个个.cu文件。整个过程可能需要10-30分钟取决于你的机器性能。当最后出现Successfully installed xformers-0.0.xx的字样时恭喜你最艰难的一关已经过了安装成功后可以在Python中简单验证import torch import xformers print(fPyTorch版本: {torch.__version__}) print(fCUDA可用: {torch.cuda.is_available()}) print(fxFormers版本: {xformers.__version__})5. 进阶排查与替代方案虽然配置CPATH解决了90%的问题但现实世界总有意外。这里分享几个我遇到过的其他情况和备选方案。5.1 检查编译器兼容性有时候问题不在于找不到头文件而在于编译器版本不兼容。xFormers的CUDA扩展需要g编译器。你可以检查一下默认的g版本g --version确保你的g版本不是太老。在一些非常旧的系统上可能需要升级到较新的版本如 g-9, g-10。你可以通过包管理器安装多个版本并用update-alternatives进行切换。5.2 使用-I参数直接指定头文件路径临时方案如果你不想永久修改系统环境变量或者只是在某个特定项目中需要可以在安装xFormers时通过设置CFLAGS和CXXFLAGS环境变量来临时指定头文件路径export CFLAGS-I/usr/local/cuda-11.2/targets/x86_64-linux/include export CXXFLAGS-I/usr/local/cuda-11.2/targets/x86_64-linux/include pip install -e .这个方法的缺点是只对当前终端会话的这次pip安装有效。5.3 修改xFormers的setup.py硬编码方案如果你对源码编译流程比较熟悉可以直接修改xFormers源码目录下的setup.py文件。找到定义CUDAExtension的地方在include_dirs列表里显式地添加CUDA头文件路径。# 在setup.py中查找类似这样的部分 ext_modules [ CUDAExtension( xformers._C, sources[ # ... 一堆源文件 ], include_dirs[ # 在这里添加 /usr/local/cuda-11.2/targets/x86_64-linux/include, # ... 其他路径 ], libraries[cuda, cudart], # ... ), ]这种方法比较“硬核”但好处是配置直接写死在项目里不依赖用户的环境。不过每次更新xFormers源码后可能需要重新修改。5.4 考虑使用预编译的wheel包如果你实在被编译问题搞得焦头烂额不妨看看有没有对应你系统的预编译的xFormers wheel包。PyPI上官方发布的xFormers通常只针对有限的CUDA和Python版本组合提供预编译包。你可以去xFormers的GitHub Release页面看看或者在一些社区资源站上寻找。使用预编译包非常简单直接pip install对应的.whl文件即可完全跳过了编译步骤。这可以说是最省心的方案前提是你能找到匹配的版本。6. 成功之后享受GPU加速的快感当我按照上述方法配置好CPATH并成功安装xFormers后再次运行Stable Diffusion那种感觉真是豁然开朗。之前跑一张768x768的图片显存占用轻轻松松突破18G时刻在爆显存的边缘试探。启用xFormers的注意力优化后显存占用直接降到了10G以下并且生成速度还有可观的提升。运行命令也变得轻松愉快python scripts/txt2img.py --prompt “a best-quality photo of a cute cat” --ckpt v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --device cuda --xformers看着九宫格的可爱猫咪图片一张张快速生成之前折腾环境的所有烦躁都烟消云散了。这个踩坑经历让我深刻体会到在Linux下进行CUDA相关的开发环境变量的理解和管理是一项基本功。PATH、LD_LIBRARY_PATH和CPATH各司其职缺一不可。尤其是CPATH这个在普通应用开发中很少接触的变量在涉及C/C扩展编译时就成了决定成败的关键。下次再遇到类似的“找不到头文件”错误你应该能立刻反应过来问题很可能就出在CPATH这个“指路牌”没有设对地方。