交叉编译

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

如:

  • 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 会用到

参考

linux-gcc简要知识点 **的更多相关文章

  1. linux gcc 编译动态类库(.so)和静态类库(.a)

    linux gcc 编译动态类库(.so)和静态类库(.a) 我的编译环境 ubuntu desktop 16.04 一:测试代码 测试有3个文件:AB.h,AB.c,test.c //AB.h vo ...

  2. linux gcc loudong

    五事九思 (大连Linux主机维护) 大连linux维护qq群:287800525 首页 日志 相册 音乐 收藏 博友 关于我     日志       spcark_0.0.3_i386.src.t ...

  3. linux gcc++漏洞:普通用户获得root权限

    linux gcc++漏洞:普通用户获得root权限 2012-02-06 10:22:38|  分类: linux安全|举报|字号 订阅       经我测试在RHEL5 / CentOS5 / F ...

  4. Ubuntu12.4 64位 安装 arm linux gcc 4.3.2

    一.下载arm linux gcc 4.3.2 http://pan.baidu.com/share/link?shareid=1575352696&uk=2754759285&fid ...

  5. linux gcc 区分32位或64位编译 && 请问arm存储,是以小端格式还是以大端格式?

    linux gcc 区分32位或64位编译   Linux系统下程序如何区分是64位系统还是32位系统 经过对include的翻查,最后确定gcc以__i386__来 进行32位编码,而以__x86_ ...

  6. 深入剖析 linux GCC 4.4 的 STL string

    转自: 深入剖析 linux GCC 4.4 的 STL string 本文通过研究STL源码来剖析C++中标准模板块库std::string运行机理,重点研究了其中的引用计数和Copy-On-Wri ...

  7. Linux gcc中的LIBRARY_PATH 和 LD_LIBRARY_PATH

    1. GNU 上关于LIBRARY_PATH的说明: LIBRARY_PATH The value of LIBRARY_PATH is a colon-separated list of direc ...

  8. Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别

    昨天在自己的CentOs7.1上写makefile的时候,发现在一个C程序在编译并链接一个已生成好的lib动态库的时候出错.链接命令大概是这样的: [root@typecodes tcpmsg]# g ...

  9. Linux GCC lib库相互引用,互相依赖(交叉引用)链接解决办法

    Linux GCC中,如果lib a依赖b,b又依赖a,链接的时候无论a放在前,还是b放在前,都会提示unrefrence. 解决办法就是: 链接的时候a链接两次,即: -la -lb -la

随机推荐

  1. 051 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 13 Eclipse下程序调试——debug入门1

    051 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 13 Eclipse下程序调试--debug入门1 本文知识点: 程序调试--debug入门1 程序 ...

  2. HTML & CSS & JavaScript 从一个表格到一个灰阶颜色表 02

    工具1:HBuilder X 1.9.9.20190522 工具2:火狐浏览器 67.0.4 (64 位) 其实,我想使用表格,做一个这样的颜色表,如下图所示: 例 3:我们参照上图,基于上一个例子, ...

  3. 持续更新——dp的一些技巧

    共菜鸡笔者看的--会慢慢更新,也请看到的大佬留意一眼,指出不足. 对于一些对部分点的二维\(dp\),状态从左上角继承而来时,对于一个点\((x,y)\),对它编号\(x*m+y\),按照这个顺序\( ...

  4. 101 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 05 通过方法实现学生类与专业类关联——方案二

    101 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 05 通过方法实现学生类与专业类关联--方案二 本文知识点:通过方法实现学生类与 ...

  5. K8S-ETCD数据库备份与恢复

    kubernetes使用etcd数据库实时存储集群中的数据,安全起见,一定要备份 需要指定使用etcdctl的版本 etcd数据库备份是使用数控快照的方式进行备份的,备份后的新数据不会保留,后面创建的 ...

  6. Rust之路(2)——数据类型 上篇

    [未经书面同意,严禁转载] -- 2020-10-13 -- Rust是系统编程语言.什么意思呢?其主要领域是编写贴近操作系统的软件,文件操作.办公工具.网络系统,日常用的各种客户端.浏览器.记事本. ...

  7. Java9系列第三篇-同一个Jar支持多JDK版本运行

    我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注.期待您能关注我,我将把java 9 ...

  8. Jmeter请求之cookie处理方式

    方法一:增加cookie管理器线程组->配置元件->HTTP Cookie管理器,放在最上方 但该方法不一定有效 方法二:http信息头&正则表达式提取器结合使用, 在登录的htt ...

  9. 落地Azure CosmosDb的一个项目分享

    我们遇到了什么? 我们有这么一个业务场景,就是某供应商会去爬取某些数据,爬到后会发到一个FTP上,然后我们定时去获取这些数据 这个数据有大有小,小的30多M数据量百万级,大的数据量能到数百M上千万数据 ...

  10. 2020-2021-1 20209313 《Linux内核原理与分析》第一周作业

    遇到的问题:安装ubuntu遇到问题 描述:在本机上虚拟机的安装包点开就闪退,无法安装VMware 解决方案: 清理VMware相关注册表,更改用户名为英文,查阅相关资料,重装系统. 更换linux安 ...