详解Linux下环境变量C_INCLUDE_PATH、CPLUS_INCLUDE_PATH。。。
C_INCLUDE_PATH、CPLUS_INCLUDE_PATH以及CPATH常被⽤于在全局性地添加预处理C/C++时的包含⽬录,其中C_INCLUDE_PATH仅对预处理C有效,CPLUS_INCLUDE_PATH仅对预处理C++有效,⽽CPATH对所有语⾔均有效。下⾯我们仅以C_INCLUDE_PATH为例来讨论。
常⽤的容易出错的设置⽅法是在~/.bashrc等⽂件中简单地使⽤递归式赋值:
环境变量path误删有影响吗export C_INCLUDE_PATH=$C_INCLUDE_PATH:/somewhere/include
这条语句的命令会将C_INCLUDE_PATH赋值为它原本的值之后再附加上:/somewhere/include⽽组成的值。
例如,如果原本$C_INCLUDE_PATH的值为/previous/include,那么执⾏过这⼀条shell语句后,$C_INCLUDE_PATH的值就会变
为/previous/include:/somewhere/include,⽽如果原本没有定义过环境变量C_INCLUDE_PATH或定义了但值为空,那么$C_INCLUDE_PATH的值就会变为:/somewhere/include.
可为什么说这样写是容易出错的呢?
我们知道在Linux中是使⽤冒号:分隔两个⽬录的(Windows下常⽤分号;),我们使⽤这条语句期望达成的效果应该是添
加/somewhere/include到预处理C时的包含⽬录。
GCC的官⽅⽂档中有这样⼀句:
In all these variables, an empty element instructs the compiler to search its current working directory. Empty elements can appear at the beginning or end of a path. For instance, if the value of CPATH is :/special/include, that has the same effect as -I. -I/special/include.
意思是:在所有这些变量中,⼀个空的元素会指⽰编译器搜索当前⼯作⽬录。空的元素可以出现在⼀个路径的开头或结尾。例如,如
果CPATH的值是:/special/include,这将会等效于-I. -I/special/include.
因此在之前的例⼦中,我们只想在预处理搜索路径中添加⼀个/somewhere/include,期望的C_INCLUDE_PATH的值是/somewhere/include,但实际上C_INCLUDE_PATH却被赋值为了:/somewhere/include,开头的冒号之前虽然为空,却会为预处理搜索路径添加上当前⼯作⽬录,也即Linux中的.,且优先级是所有⽬录中最⾼的!
⽽这往往并不是我们想要的结果,这会导致预处理的包含⽬录随着当前⼯作⽬录的改变⽽改变,如果当前⼯作⽬录中恰好有⼀个与源代码中包含的⽂件同名的⽂件,则会导致不可预期的错误。
不巧的是,在为我们⾃动⽣成的tasks.json中,默认的tasks.options.cwd恰好是/usr/bin,因此⼀旦错误地设置了C_INCLUDE_PATH的值,同时/usr/bin中恰好有⼀个同名的⽂件(要知道这⾥的⽂件⼤多都是可执⾏程序),那么在编译C程序时,就会错把这个同名⽂件当作源代码⽂件包含进来,接下来就可以欣赏海量的编译错误了。譬如⽬前最受欢迎的Linux发⾏版,在安装好后的/usr/bin中就会有⼀个名为array的可执⾏程序,与C++的<array>重名。
正确⽅法:
⾸先明确⼀点,这⼏个预处理包含⽬录的环境变量并不是Linux操作系统的⼀部分,因此⼀般情况下Linux是不会设置这些环境变量的。
所以在对某⼀个环境变量第⼀次设置时,应该直接将其赋值为所需的⽬录,在之后的设置中再使⽤递归式的赋值;或者直接⼀次性将所有⽬录⽤:分隔开,⼀起赋值;或者索性不使⽤这些环境变量,⽽是在编译时使⽤-I参数来添加包含⽬录。
其他:
查看gcc预处理C时的的搜索⽬录:
echo| gcc -x c -v -E -
查看gcc预处理C++时的的搜索⽬录:
echo| gcc -x c++ -v -E -
查看clang预处理C++时的搜索⽬录:
echo| clang -x c++ -v -E -
cwd : current working directory 当前⼯作⽬录

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。