关于使用gcc在Linux系统中进行c语言程序的编译
目录
- 1.可执行文件的组装
- 学习使用gcc生成静态库和动态库
- 静态库生成
- 动态库生成
- 使用实例
- 静态库使用
- 动态库使用
- 2.gcc编译的各种工具
- 关于gcc编译器下的工具
- Binutils
- c运行库
- gcc的编译过程
- 用nasm汇编编译器编译生成执行程序
- 3.库函数的运用
- 从光标库(curses)的主要函数功能了解库函数的作用
- 在Ubuntu中安装curses库
- Linux 环境下C语言编译实现贪吃蛇游戏
- 4.参考资料
1.可执行文件的组装
学习使用gcc生成静态库和动态库
在平时工作中,我们通常把公有函数制作成函数库,供其他程序使用,函数库又分为静态库和动态库。静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。
静态库生成
这里使用最简单的Hello World程序来演示。
- 创建hello.c和main.c文件
使用touch命令创建
touch hello.c
touch main.c
使用vi对程序进行编译
vi hello.c
vi main.c
hello.c
#include <stdio.h>
void hello()
{printf("Hello World\n");
}
main.c
#include <stdio.h>
main()
{hello();return 0;
}
- 将hello.c编译成.o文件
输入以下命令,即可形成
gcc -c hello.c
- 由.o文件生成静态库
使用 ar 命令,即可生成.a文件
ar -crv libhello.a hello.o
注:静态库文件名的命名规范是以 lib 为前缀,紧接着跟静态库名,扩展名为.a。
- 在程序中使用静态库
使用命令
gcc main.c libhello.a -o hello
从静态库中将公用函数连接到目标文件中
生成目标文件hello
- 运行hello程序
动态库生成
- 由.o文件生成动态库
使用命令,生成.so文件
gcc -shared -fPIC -o libhello.so hello.o
- 在程序中使用动态库
使用命令
gcc main.c libhello.so -o hello
- 运行程序
使用实例
静态库使用
- 编辑x2x和x2y函数,实现计算两个数的加减运算
x2x
int x2x(int a, int b)
{return a+b;
}
x2y
int x2y(int a, int b)
{return a-b;
}
main
#include<stdio.h>
int main()
{int a=2;int b=3;printf("a+b=%d\n",x2x(a,b));printf("a-b=%d\n",x2y(a,b));
}
- 使用gcc命令生成3个.o文件
- 将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件
ar -crv libsub.a sub1.o sub2.o
- 用 gcc将 main函数的目标文件与静态库文件进行链接,生成最终的可执行程序
gcc main.c libsub.a -o main
- 运行程序
其文件大小为
动态库使用
- 由.o文件生成动态库
使用命令,生成.so文件
gcc -shared -fPIC -o libsub.so sub1.o sub2.o
- 用 gcc将 main函数的目标文件与动态库文件进行链接
gcc main.c libsub.so -o main2
- 运行程序
出现错误,找不到动态库文件
解决方法:将.so文件复制到lib文件夹里面
sudo cp libsub.so /usr/lib
重新运行
成功
文件大小为:
结论:使用静态库生成的目标程序比使用动态库生成的目标程序大
2.gcc编译的各种工具
关于gcc编译器下的工具
Binutils
Binutils是一组二进制程序处理工具,包括以下几种
(1) addr2line:用来将程序 地址转 换成其所 对应的程序源文件及所对应的代码行,也可以得到所对应的函数。该工具将帮助调试器在调试的过程中定位对应的源代码位置。
(2) as:主要用于汇编。
(3) ld:主要用于链接。
(4) ar:主要用于创建静态库。
(5) ldd:可以用于查看一个可执行程序依赖的共享库。
(6) objcopy:将一种对象文件翻译成另一种格式,譬如将.bin 转换成.elf、或
者将.elf 转换成.bin 等。
(7) objdump:主要的作用是反汇编。
(8) readelf:显示有关 ELF 文件的信息。
(9) size:列出可执行文件每个部分的尺寸和总尺寸,代码段、数据段、总大小
等。
c运行库
C 语言标准主要由两部分组成:一部分描述 C 的语法,另一部分描述 C 标准库。C 标准库定义了一组标准头文件,每个头文件中包含一些相关的函数、变量、类型声明和宏定义,譬如常见的 printf 函数便是一个 C 标准库函数,其原型定义在 stdio 头文件中。
C 语言标准仅仅定义了 C 标准库函数原型,并没有提供实现。因此,C 语言编译
器通常需要一个 C 运行时库(C Run Time Libray,CRT)的支持。C 运行时库又常简称为 C 运行库。与 C 语言类似,C++也定义了自己的标准,同时提供相关支持库,称为 C++运行时库。
gcc的编译过程
gcc的编译过程分为4步:预编译,编译,汇编,链接
这里使用一个简单的程序来演示这个过程
当使用gcc直接编译以下代码时
//hello.c
#include <stdio.h>
int main()
{printf("Hello World!\n");
return 0;
}
只需要使用
gcc hello.c -o hello
就能生成可执行文件
把编译过程分为四步
- 预编译
gcc -E hello.c -o hello.i
以输出 的hello.i 文件中存放着 hello.c 经预处理之后的代码
- 编译
gcc -S hello.i -o hello.s
预处理之后,直接对生成的 hello.i 文件编译,生成汇编代码
- 汇编
gcc -c hello.s -o hello.o
对生成的汇编代码文件 hello.s,gas 汇编器负责将其编译为目标文件
- 链接
gcc hello.o -o hello
将生成的 hello.o 与C标准输入输出库进行连接,最终生成程序 hello
运行程序
用nasm汇编编译器编译生成执行程序
nasm安装过程不在此赘述
- 创建hello.asm文件
touch hello.asm
- 编译hello.asm文件
将下列代码拷贝进hello.asm文件中
; hello.asm
section .data ; 数据段声明msg db "Hello, world!", 0xA ; 要输出的字符串len equ $ - msg ; 字串长度
section .text ; 代码段声明
global _start ; 指定入口函数
_start: ; 在屏幕上显示一个字符串mov edx, len ; 参数三:字符串长度mov ecx, msg ; 参数二:要显示的字符串mov ebx, 1 ; 参数一:文件描述符(stdout) mov eax, 4 ; 系统调用号(sys_write) int 0x80 ; 调用内核功能; 退出程序mov ebx, 0 ; 参数一:退出代码mov eax, 1 ; 系统调用号(sys_exit) int 0x80 ; 调用内核功能
- 编译文件
nasm -f elf64 hello.asm
- 链接文件
ld -s -o hello hello.o
- 运行程序
./hello
成功
可以看到由nasm生成的程序大小比C代码的编译生成的程序小的多
3.库函数的运用
从光标库(curses)的主要函数功能了解库函数的作用
curses是一个在Linux/Unix下广泛应用的图形函数库,作用是可以在终端内绘制简单的图形用户界面。
其基本函数名称和功能
1、move(y,x);将光标移动至(x,y)处。
2、refresh();我们写入的内容首先会在系统缓冲区中,经过refresh()函数刷新之后才能够显示到屏幕上。
3、echo()和noecho();输入的字符显示和不显示在终端上。可以用密码输入。
4、输出:
addch();显示一个字符
addstr();显示一串字符串
printw(“格式”,变量);显示指定格式的内容,类似于printf();
mvaddstr();移动到某个位置输出。
5、输入:
getch();输入一个字符
getstr();输入一串字符串
scanw("%s",s);;按指定格式输入内容,类似于scanf();
mvaddstr();移动到某个位置输入。
在Ubuntu中安装curses库
输入命令,安装
sudo apt-get install libncurses5-dev
Linux 环境下C语言编译实现贪吃蛇游戏
创建文件后将代码放进文件中
使用以下命令进行编译
c mysnake1.0.c -lcurses -o mysnake1.0
成功运行
4.参考资料
Linux 环境下C语言编译实现贪吃蛇游戏:
http://www.linuxidc.com/Linux/2011-08/41375.htm
关于使用gcc在Linux系统中进行c语言程序的编译相关推荐
- 在Linux系统中运行C语言程序
正式学习c语言的第一天 2022/1/10 在之前的学习中已经在Windows系统中用Microsoft VC++上实现了C语言程序的运行,现在将在Linux系统上运行C语言程序. 首先明确C语言 ...
- Linux系统中创建C语言程序文件并编译执行的方法
使用vim编辑器创建并编辑C语言源程序文件 执行命令"vim button_led.c"打开Button_Led目录下button_led.c源程序文件并进行编 ...
- linux系统如何卸载所有程序,Linux系统中完全卸载删除程序的命令
如果您在数据中心服务器或本地服务器中使用Ubuntu或任何其他基于debian的发行版系统,您可能会遇到需要卸载软件的情况.一般情况下,您会登录并运行命令:sudo apt-get remove pa ...
- linux系统卸载程序命令行,Linux系统中完全卸载删除程序的命令
如果您在数据中心服务器或本地服务器中使用Ubuntu或任何其他基于debian的发行版系统,您可能会遇到需要卸载软件的情况.一般情况下,您会登录并运行命令:sudo apt-get remove pa ...
- Ubuntu系统中编写c语言程序教程
目录 1.准备工作 1.1 安装GCC及必要软件包 2.使用GCC编写C语言程序 2.1 编写一个整型运算反回浮点型的程序 2.2 在windows系统下使用编译工具编译该程序 3.使用Makefil ...
- 在linux中运行c语言程序,linux环境中运行C语言程序
在linux环境下做运行C语言程序 [root@localhost ~]# cat a.c #include main() {int grade; char chgrade; printf(" ...
- Linux系统中利用C语言控制LED的方法
大家好, 今天主要和大家聊一聊,如何利用C语言控制LED灯的实验. 目录 第一:C语言板控制LED灯简介 第二:实验程序实现 第三:C语言实验控制程序 第一:C语言板控制LED灯简介 实际工作中 ...
- Linux系统中一些目录和文件的详细解释(参照RHEL5.4)
linux有四种基本文件系统类型: –普通文件:如文本文件.c语言源代码.shell脚本等,可以用cat.less.more.vi等来察看内容,用mv来改名: –目录文件:包括文件名.子目录名及其指针 ...
- linux使用什么dos系统安装,在Linux系统中安装DOSBox运行MS-DOS上游戏及程序的方法...
在 Linux 系统中可以借助安装 DOSBox 来运行 MS-DOS 游戏及程序,比如运行 C++ 编译器 Turbo C++,同时 DOSBox 还支持 Windows.MacOS.Unix 操作 ...
最新文章
- 我的Chrome常用快捷键
- GraphPad Prism 9.2 科学绘图 最新 可用
- python编程的条件语句_自学Python编程【第五节】if条件语句
- CodeForces - 546C Soldier and Cards(模拟)
- [跟我学UML] UML中的对象图
- 创建自己的Java批注
- Linux设置串口永久权限
- 在 Vs2013中查看类的内部布局
- ASP.NET MVC4中的异步控制器
- javascript 将时间戳格式化
- 基础01类与对象、封装、构造方法
- oracle 只有年和月怎么拼_oracle 两表关联时,年月条件的写法引起的巨大性能的差异...
- C# string转char数组 string转char[]
- LeetCode_125_Python_验证回文串
- ARM交叉编译工具链安装和使用教程【图文并茂】
- 10年老司机倾囊相授,贴片晶振的PCB layout需要注意哪些?
- 云计算与虚拟化技术【课堂笔记】
- 可任意改变背景颜色的万年历
- python控制键盘鼠标库pynput基本操作
- C++在屏幕中输出数字d0...while
热门文章
- 诸多源码,正是我想要的
- 专业现场媒体编辑工具:QLab Pro
- SQL查询有两门以上不及格的学生及查询出全部及格的学生
- 四个凡事:有章可循,有人负责,有据可查,有人监督
- 部门换届推文文字_【换届】遇见你们,真的很幸运了
- c语言建筑工地管理系统,建筑工地信息管理系统
- 使用 IFTTT 做 RSS 的邮件订阅服务
- 武侠界的最强原创,闯荡江湖的必备指南(1)
- 【云原生 | 29】Docker运行大数据经典分布式平台Hadoop
- SGC - Simplifying Graph Convolutional Networks 简化的图卷积网络 论文详解 ICML 2019