linux 编译错误详解

编译错误详解

头文件:

1.在编译时,我们可以用-I(i的大写)选项来指定头文件所在的目录
在-I后可以有空格也可以没有空格,另外也可以指定多个目录
gcc main.c -I ./ -I ./include/


2.设置gcc的环境变量C_INCLUDE_PATH、CPLUS_INCLUDE_PATH 、CPATH。
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include/xgytest


3.查找默认的路径/usr/include   /usr/local/include等



总结一下gcc在编译源码时是如何寻找所需要的头文件的:

   1.  首先gcc会从-Idir   -isystem dir   -Bprefix    -sysroot  dir     --sysroot=dir    -iquote dir选项指定的路径查找(这些选项先指定的会先搜索,有特例的情况请参考前面的链接)

   2. 然后找gcc的环境变量:C_INCLUDE_PATH、CPLUS_INCLUDE_PATH 、CPATH、GCC_EXEC_PREFIX等。(这些环境变量搜索的先后顺序不确定,有待确认)

   3. 然后查找GCC安装的目录(可以通过gcc  -print-search-dirs查询)

   4.  然后再按照下面列出的顺序查找系统默认的目录:/usr/include      /usr/local/include

库文件:

   用ldd命令可以查看一个可执行文件依懒于哪些库 @@@@@@@@@@@@@@@@@@@@@@@@
   编译时,编译器不会查找LD_LIBRARY_PATH,还有/etc/ld.so.conf文件中指定的路径 @@@@@@@@@@@@@@@@@@@@@@@@
  
   现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开,用户可以通过-L指定连接时库的路径,通过-R(或-rpath)指定程序运行时库的路径,大大提高了库应用的灵活性。
  
   Linux下 的库文件在命名时有一个约定,那就是库文件应该以lib三个字母开头,由于所有的库文件都遵循了同样的规范,因此在用-l(L的小写字母)选项指定链接的库文件名时可以省去 lib三个字母,也就是说GCC在对-lfoo进行处理时,会自动去链接名为libfoo.so的文件
   注意-lpos, 这里的-l是L的小写,另外也可以写成-l  pos即中间有一个空格,但有没有空格是有一点区别的,有空格的只搜索与POSIX兼容的库,一般建议使用没有空格的。
  
  
    程序在编译链接时,编译器是按照如下顺序来查找动态链接库(共享库)和静态链接库的:
   
    编译时,编译器不会查找LD_LIBRARY_PATH,还有/etc/ld.so.conf文件中指定的路径 @@@@@@@@@@@@@@@@@@@@@@@@

    1.  gcc会先按照-Ldir    -Bprefix选项指定的路径查找

    2. 再找gcc的环境变量GCC_EXEC_PREFIX

    3. 再找gcc的环境变量LIBRARY_PATH

    4. 然后查找GCC安装的目录(可以通过gcc  -print-search-dirs查询)

    5.  然后查找默认路径/lib

    6.  然后查找默认路径/usr/lib

    7.  最后查找默认路径/usr/local/lib

    8.  在同一个目录下,如果有相同文件名的库(只是后缀不同),那么默认链接的是动态链接库,可以用-static选项显示的指定链接静态库。
  
  
运行:
    在这里我没有提到头文件的查找,因为头文件只在编译的时候才会用到,编译完后就不需要头文件了!
   
    另外,这里的库指的是动态链接库,静态链接库在链接后是不需要了的,因为链接时链接器会把静态库中的代码插入到相应的函数的调用处,所以程序在运行时不再需要静态库
   
     程序运行时动态库的搜索路径搜索的先后顺序是:

    1.编译目标代码时指定的动态库搜索路径(指的是用-wl,rpath或-R选项而不是-L);

    example: gcc -Wl,-rpath,/home/arc/test,-rpath,/lib/,-rpath,/usr/lib/,-rpath,/usr/local/lib test.c

    2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

    3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;

    4.默认的动态库搜索路径/lib;

    5.默认的动态库搜索路径/usr/lib

有了这个再不会就是天才了。。。

你可能感兴趣的:(linux)