当前位置: 首页 > news >正文

GCC 编译器 详细总结

前言:

源文件需要经过编译才能生成可执行文件。

在 Windows 下进行开发时,只需要点几个按钮即可编译,集成开发环境(比如 Visual studio)已经将各种编译 工具的使用封装好了。

Linux 下也有很优秀的集成开发工具,但是更多的时候是 直接使用编译工具;即使使用集成开发工具,也需要掌握一些编译选项。

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

目录

GCC 编译过程(精简版)

常用编译选项​编辑

怎么编译多个文件

制作、使用动态库

制作、使用静态库


GCC 编译过程(精简版)

一个 C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇 编(assembly)和链接(linking)等 4 步才能变成可执行文件。

通过不同的 gcc 选项可以控制这些过程:

gcc 使用示例:执行“gcc -o hello hello.c -v”时,可以查看到这些步骤:

可以手工执行以下命令体验一下:

常用编译选项

1.-c

        预处理、编译和汇编源文件,但是不作链接,编译器根据源文件生成 OBJ 文 件。缺省情况下,GCC 通过用`.o'替换源文件名的后缀`.c',`.i',`.s'等, 产生 OBJ 文件名。可以使用-o 选项选择其他名字。GCC 忽略-c 选项后面任何无 法识别的输入文件。

2.-S

        编译后即停止,不进行汇编。对于每个输入的非汇编语言文件,输出结果是 汇编语言文件。缺省情况下,GCC 通过用`.s'替换源文件名后缀`.c',`.i'等 147 / 566 等,产生汇编文件名。可以使用-o 选项选择其他名字。GCC 忽略任何不需要汇编 的输入文件。

3.-E

        预处理后即停止,不进行编译。预处理后的代码送往标准输出。

4.-o file

        指定输出文件为 file。无论是预处理、编译、汇编还是链接,这个选项都可 以使用。如果没有使用`-o'选项,默认的输出结果是:可执行文件为`a.out'; 修改输入文件的名称是`source.suffix',则它的 OBJ 文件是`source.o',汇 编文件是 `source.s',而预处理后的 C 源代码送往标准输出。

5.-v

        显示制作 GCC 工具自身时的配置命令;同时显示编译器驱动程序、预处理器、 编译器的版本号。

示例1:找不到头文件目录,使用-I 指定头文件目录

示例2:libsub.so通常写为lsub,找不到库文件目录,使用-L 指定库文件目录

怎么编译多个文件

1.一起编译、链接:

gcc -o test main.c sub.c

2.分开编译,统一链接:

gcc -c -o main.o main.c

gcc -c -o sub.o sub.c

gcc -o test main.o sub.o

制作、使用动态库

1.制作、编译动态库:

gcc -c -o main.o main.c

gcc -c -o sub.o sub.c

gcc -shared -o libsub.so sub.o sub2.o sub3.o(可以使用多个.o 生成动态库)

gcc -o test main.o libsub.so

gcc -o test main.o libsub.so也可被替换:使用-L 指定库文件目录

2.运行:

1.先把 libsub.so 放到 Ubuntu 的/lib 目录,然后就可以运行 test 程序。

2.如果不想把 libsub.so 放到/lib,也可以放在某个目录比如/a,然后如下执行:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/a

./test

制作、使用静态库

1.制作、编译静态库:

gcc -c -o main.o main.c

gcc -c -o sub.o sub.c

ar crs libsub.a sub.o 

gcc -o test main.o libsub.a (如果.a 不在当前目录下,需要指定它的绝对或相对路径)

2.运行:

不需要把静态库 libsub.a 放到板子上,直接运行

注意:

执行 arm-buildroot-linux-gnueabihf-gcc -c -o sub.o sub.c 交叉编译需要在最后面加上-fPIC 参数。

相关文章:

  • 刷题笔记day08-字符串01
  • 编译支持GPU的opencv,并供python的import cv2调用
  • 程序员想要网上接单却看花了眼?那这几个平台你可得收藏好了!
  • C++之初始化列表详细剖析
  • 【Algorithm】最容易理解的蒙特卡洛树搜索(Monte Carlo Tree Search,MCTS)算法
  • 华纳云:centos系统中怎么查看cpu信息?
  • 【智能座舱系列】- 深度解密小米Hyper OS,华为HarmonyOS区别
  • 【从0到1设计一个网关】过滤器链的实现---实现负载均衡过滤器
  • postgresql|数据库|SQL语句冲突的解决
  • 2023年CCF中国开源大会“大模型时代的智能化软件工程新范式”分论坛成功举行...
  • zookeeper安装配置
  • 基于nodejs+vue客户管理管理系统
  • 天拓四方分享:企业安全生产管控系统的构建、实施与优化
  • ip划分与私公网ip、ip的传递
  • 供应链ERP之合同:创建、修订与模板
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 11111111
  • ERLANG 网工修炼笔记 ---- UDP
  • HashMap剖析之内部结构
  • pdf文件如何在线转换为jpg图片
  • php ci框架整合银盛支付
  • rc-form之最单纯情况
  • React 快速上手 - 07 前端路由 react-router
  • React-redux的原理以及使用
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • Shell编程
  • spring-boot List转Page
  • SQLServer之索引简介
  • use Google search engine
  • yii2中session跨域名的问题
  • 观察者模式实现非直接耦合
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • puppet连载22:define用法
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • # 计算机视觉入门
  • #define与typedef区别
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (floyd+补集) poj 3275
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (第一天)包装对象、作用域、创建对象
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (一)80c52学习之旅-起始篇
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .NET 8.0 中有哪些新的变化?
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .Net程序帮助文档制作
  • .Net中的设计模式——Factory Method模式
  • .NET中两种OCR方式对比
  • .NET中使用Protobuffer 实现序列化和反序列化