• 【linux】gcc简要知识点 **



    交叉编译

    使用不同的交叉编译工具链编译源码,能在不同框架的处理器上运行。
    如:

    • X86
    gcc -o hello hello.c
    

    上述命令编译出来的文件能在 X86 上运行,因为 gcc 编译工具链是给PC编译的。

    • ARM
    arm-linux-gnueabihf-gcc -o hello hello.c
    

    上述命令编译出来的文件能在 ARM 上运行。

    简要知识点 **

    1. 头文件的作用:
      1. 声明(declare)
    2. c文件的作用
      1. 定义、实现(define)
    3. 头文件寻址
      1. 默认路径:编译器中的 include 目录
      2. 可指定:
        1. #include "xx/xx.h" :由当前文件路径算起
        2. 编译时用 "-I" 选项指定
    4. c文件内的外部函数在哪里,如 printf 函数:
      1. 库:
        1. 默认路径:编译器中的 lib 目录
        2. 可指定:
          1. 编译时用 "-I" 指定库文件
          2. 编译时用 "-L"指定库目录
    5. 怎么确定交叉编译器中头文件的默认路径?
      1. 进入交叉编译器的目录,使用find命令直接查找,如
        • 执行"find -name "stdio.h""
    6. 怎么确定交叉编译器中库的默认路径?
      1. 进入交叉编译器的目录,执行"find -name lib",进去看看, 有很多 .so 文件的里面就是要找的路径。

    一些概念

    1. 交叉编译工具链中的 include 目录和lib 目录:
      1. include 存放头文件
        1. 这些头文件一般是函数声明,还有一些变量声明,名字空间,宏定义,typedef 等等
      2. lib 存放obj文件的(对gcc来说为.o)
        1. 也就是说,一些库文件,人家不想让你看见源代码,只是给了你中间生成的obj文件

    GCC编译器

     PC机上的编译工具链有 gcc、ld、objcopy、objdump等等,他们编译出来的程序能在 X86 平台上运行。
     要使编译出来的的程序能在 ARM 上运行,就必须使用交叉编译工具链 xxx-gcc、xxx-ld等(不同版本的编译器的前缀不一样,如 arm-linux-gcc)。

    GCC简要使用

    GCC编译过程 **

     一个C/C++文件要经过预处理、编译、汇编、链接等4个步骤才能变成一个可执行文件。(日常交流中用 编译 统称以上四大步骤

    1. 预处理,在预处理过程中,对源代码文件中的文件包含(include)、 预编译语句(如宏定义define等)进行展开,生成.i文件。 可理解为把头文件的代码、宏之类的内容转换成更纯粹的C代码,不过生成的文件以.i为后缀。
    2. 编译,把预处理后的.i文件通过编译成为汇编语言,生成.s文件,即把代码从C语言转换成汇编语言,这是GCC编译器完成的工作。
    3. 汇编,将汇编语言文件经过汇编,生成目标文件.o文件,每一个源文件都对应一个目标文件。即把汇编语言的代码转换成机器码,这是as汇编器完成的工作。
    4. 链接,最后将每个源文件对应的.o文件链接起来,就生成一个可执行程序文件,这是链接器ld完成的工作。
      • 链接分为两种
        • 动态链接
          • GCC编译时的默认选项。
          • 指应用程序运行时才去加载外部的代码库。
        • 静态链接
          • 链接时使用选项 –static
          • 它在编译阶段就会把所有用到的库打包到自己的可执行程序中。

    常用的编译选项

    选项 描述
    -E 预处理,开发过程中想快速确定某个宏可以使用 “-E -dM”
    -c 做了预处理、编译、汇编,但是没做链接
    -o 指定输出文件
    -I 指定头文件目录(大写 i)
    -l 指定链接到哪一个库文件(小写 L)
    -L 指定链接时库文件目录

    编译多个文件

    1. 一起编译、链接:
      如:
    gcc -o hello main.c hello.c
    
    1. 分开编译,统一链接:
      如:
    gcc -c -o main.o main.c
    gcc -c -o hello.o hello.c
    gcc -o hello main.o hello.o
    

    制作、使用动态库

    1. 制作、编译:
    gcc -c -o main.o main.c
    gcc -c -o hello.o hello.c
    gcc -shared -o libhello.so hello.o hello1.o // (*可以使用多个 .o 生成一个动态库*)
    gcc -o hello main.o -lhello -L <目录路径> // (*该路径为 libhello.so 文件所在目录*)
    
    1. 运行
      1. libhello.so 放到PC或板子的/lib目录下,然后运行test程序。
      2. 如果不想把 libhello.so 放到/lib, 也可以放到自己新建的某个目录,如 /mylib,然后执行:
    export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/a
    ./hello
    

    (其实就是修改 库的环境变量。)

    制作、使用静态库

    gcc -c -o main.o main.c
    gcc -c -o hello.o hello.c
    ar   crs   libhello.a hello.o hello1.o // (*可以使用多个 .o 生成一个静态库*) 
    gcc -o hello main.o libhello.a // (*如果 .a 不在当前目录下,需要指定它的绝对路径或相对路径*)
    

    注意:不需要把 hello.a 静态库文件拉到板子上

    很有用的选项

    gcc -E main.c // 查看预处理结果,比如头文件是哪个
    gcc -E -dM main.c > h.txt // 把所有的宏展开,保存到 h.txt 文件里
    gcc -Wp,-MD,yl.dep -c -c -o main.o main.c // 生成依赖文件 yl.dep,后面 Makefile 会用到
    

    参考

  • 相关阅读:
    解决The markup in the document following the root element must be well-formed.
    全排列算法:递归和非递归实现
    利用异或运算实现交换2个数据
    dojo 代码调试
    dogo 官方翻译 Ajax with dojo/request
    dojo 官方翻译 dojo/Deferred
    dojo 官方翻译 dojo/aspect
    get app id
    [转]解决eclipse无法设置NDK问题
    关于二级指针
  • 原文地址:https://www.cnblogs.com/lizhuming/p/13949385.html
Copyright © 2020-2023  润新知