在做大型工程的时候,除了有C++语法知识之外,还要有工程能力。
最先要具备的能力是:
理解C++文件的编译,链接过程。
明白C++头文件的搜索路径。
本文,介绍C++的文件搜索路径。
对于C++文件来说,主要有两种,一种是.h文件,一种是.cpp文件。
其中.h文件,相对来说,不那么重要。因为.cpp文件里会#include "a.h"一下,这样.h文件会在预编译阶段被加入到.cpp中,实质上,这是一种强制的替换。
谁来执行这个替换呢?是gcc,这个编译器。
gcc这个编译器会先对代码进行编译,甚至进行代码优化,再进行链接。
编译的过程也分为几个阶段,但不重要,主要是cpp文件会被编译成一个os文件。这是一个二进制文件。每一个cpp文件要变成程序,就需要一个os文件。这个编译的过程中,gcc会对C++代码进行代码优化,这个中间过程,可以看编译原理之类的书,我目前在搞这些,枯燥无味,却不得不做,因为性能要达标。
编译完了,就会进行链接:所谓的链接,就是把一些已经存在的库文件,链接到代码中。这个过程可以理解为:gcc有的时候只有一些库文件,也就是so文件。和它们的头文件,为啥只有so,因为头文件给接口,so就能保护源代码,从而使得程序可以以库的形式卖出价格。这些库文件的so要和我们自己写的cpp文件生成的.so链接起来。大概就是so中有一个表,表示自己身体里有哪些代码段对应的二进制,gcc就根据这个表,根据代码的需要,把二进制段拼凑起来。
最后链接完成的,就是exe文件,也就是可执行文件。
题外话:动态链接和静态链接的区别在于,静态链接是把库文件打包复制一份到exe,而动态链接是,可执行文件运行的时候,再去机子上的环境去寻找so,再构建起来。
那么,知道了gcc是怎么编译的了,问题就来了,一个cpp中会#include "a.h“,"a.h"中可能会有"b.h",也可能是"/tvm/b.h",那gcc怎么找b.h呢?
其实很简单,对于#include<iostream>这种:
gcc就会直奔gcc -l 这个路径指定的路径下去找。
如果gcc -l没有指定目录,它就会去usr/local下去找。
如果还是找不到,就会去local/bin里面去找。
路径可能是记错了,用的时候搜一下就好。
对于#include "hah.n"这种。
gcc就会在本目录下搜索,搜索不到,才会和<iostream>按照同样的逻辑去寻找。