1. .cc文件
.cc实质上就是Linux/Unix下C++源文件的默认扩展名。 而在Windows中通常为.cpp。(这和我认知可太不一样了……)
2. C++链接相关知识
首先要知道一个程序从源文件编译生成可执行文件的步骤:
预编译->编译->汇编->链接
(1)预编译,又叫做“预处理”,主要处理源文件中以“#”开头的预编译指,比如#define宏展开、条件编译指令(典型的是#ifndef、#endif)、#include(包含头文件)等。
(2)编译就是对预处理完的文件进行静态分析(包括词法、语法、语义)、优化(比如O2优化)后,生成汇编代码文件。需要注意的是这里还不是二进制文件。
(3)汇编是把汇编代码转二进制文件,这时计算机已经可以直接识别。
(4)链接其实就是打包成可执行文件。链接根据执行时机可以分为静态和动态(简单理解,在静态编译阶段一并打包就是静态,否则就是动态,动态又分为在程序加载到内存时和程序运行时),在Linux中典型的静态库是.a(Win中是.lib),动态库是.so(Win中是dll)。
在C++可执行文件生成过程中,需要对自定义的头文件和库进行指定,具体就是用到了GCC编译器中的-L、-I和-l选项。
undefined reference to ‘xxxxx’ 这种错误就是因为链接错误。根据生成可执行文件的步骤可以知道,到这一步为止,起码代码是不存在语法错误的。出现这种错误的大部分情况是由于没自行指定库。
下面是-L、-I和-l选项的简单用法。
一般来说,用.so就要引入与其配套的头文件(相当于一个是定义一个是实现)。
-I(大写的i):指定除程序当前目录、/usr/include
和/usr/local/include
目录外寻找头文件的路径。头文件引用搜索优先级为当前目录>-I自定义路径>/usr/local/include>/usr/include。
-L(大写的l):指定静态库和动态库的路径。这里缺省的和头文件目录一致,只不过是把include
替换成lib
。
-l(小写的l):指定具体库名。这里默认先搜索动态(.so),所以如果要引静态(.a),最好直接指定静态库路径。动态库文件一般命令是libxxx.so,这里指定的是要前去lib,后去.so。一个典型的例子,如果要用到数学相关的函数,那么就必须要加-lm
选项来链接数学库libm.so。
这里可以看出来,大写的一般就是指路径/目录,小写的是指具体的文件。
3. shell脚本执行陷阱
shell中下一句是否执行和上一句执行结果无关,也就是说和Python不同,并不是只有上一句执行成果,下一句才能得以执行。
例子:
cd 一个实际并不存在的路径
echo "1"
这时得到的结果是一句错误提示和一个打印出来的“1”。要避免这种情况出现,就必须用&&
连接。这样才能保证在上一句执行成功的情况下才执行下一句,常见的应用场景是编译时,mkdir 某路径&& cd 某路径
。