我们将会学到以下内容:
源程序编译
Makefile的编写
程序库的链接
程序的调试
头文件和系统求助
--------------------------------------------------------------------------------
1.源程序的编译
在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器. 下面
我们以一个实例来说明如何使用gcc编译器.
假设我们有下面一个非常简单的源程序(hello.c):
int main(int argc,char **argv)
{
printf("Hello Linux/n");
}
要编译这个程序,我们只要在命令行下执行:
gcc -o hello hello.c
gcc 编译器就会为我们生成一个hello的可执行文件.执行./hello就可以看到程
序的输出结果了.命令行中 gcc表示我们是用gcc来编译我们的源程序,-o 选项表示
我们要求编译器给我们输出的可执行文件名为hello 而hello.c是我们的源程序文件.
gcc编译器有许多选项,一般来说我们只要知道其中的几个就够了. -o选项我们
已经知道了,表示我们要求输出的可执行文件名. -c选项表示我们只要求编译器输出
目标代码,而不必要输出可执行文件. -g选项表示我们要求编译器在编译的时候提
供我们以后对程序进行调试的信息.
知道了这三个选项,我们就可以编译我们自己所写的简单的源程序了,如果你
想要知道更多的选项,可以查看gcc的帮助文档,那里有着许多对其它选项的详细说
明.
2.Makefile的编写
假设我们有下面这样的一个程序,源代码如下:
/* main.c */
#include "mytool1.h"
#include "mytool2.h"
int main(int argc,char **argv)
{
mytool1_print("hello");
mytool2_print("hello");
}
/* mytool1.h */
#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
void mytool1_print(char *print_str);
#endif
/* mytool1.c */
#include "mytool1.h"
void mytool1_print(char *print_str)
{
printf("This is mytool1 print %s/n",print_str);
}
/* mytool2.h */
#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
void mytool2_print(char *print_str);
#endif
/* mytool2.c */
#include "mytool2.h"
void mytool2_print(char *print_str)
{
printf("This is mytool2 print %s/n",print_str);
}
当然由于这个程序是很短的我们可以这样来编译
gcc -c main.c
gcc -c mytool1.c
gcc -c mytool2.c
gcc -o main main.o mytool1.o mytool2.o
这样的话我们也可以产生main程序,而且也不时很麻烦.但是如果我们考虑一
下如果有一天我们修改了其中的一个文件(比如说mytool1.c)那么我们难道还要重
新输入上面的命令?也许你会说,这个很容易解决啊,我写一个SHELL脚本,让她帮我
去完成不就可以了.是的对于这个程序来说,是可以起到作用的.但是当我们把事情
想的更复杂一点,如果我们的程序有几百个源程序的时候,难道也要编译器重新一
个一个的去编译?
为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make.我们
只要执行以下make,就可以把上面的问题解决掉.在我们执行make之前,我们要先
编写一个非常重要的文件.--Makefile.对于上面的那个程序来说,可能的一个
Makefile的文件是:
# 这是上面那个程序的Makefile文件
main:main.o mytool1.o mytool2.o
gcc -o main main.o mytool1.o mytool2.o
main.o:main.c mytool1.h mytool2.h
gcc -c main.c
mytool1.o:mytool1.c mytool1.h
gcc -c mytool1.c
mytool2.o:mytool2.c mytool2.h
gcc -c mytool2.c
有了这个Makefile文件,不过我们什么时候修改了源程序当中的什么文件,我们
只要执行make命令,我们的编译器都只会去编译和我们修改的文件有关的文件,其
它的文件她连理都不想去理的.
下面我们学习Makefile是如何编写的.
在Makefile中也#开始的行都是注释行.Makefile中最重要的是描述文件的依赖
关系的说明.一般的格式是:
target: components
TAB rule
第一行表示的是依赖关系.第二行是规则.
比如说我们上面的那个Makefile文件的第二行
main:main.o mytool1.o mytool2.o
表示我们的目标(target)main的依赖对象(components)是main.o mytool1.o
mytool2.o 当倚赖的对象在目标修改后修改的话,就要去执行规则一行所指定的命
令.就象我们的上面那个Makefile第三行所说的一样要执行 gcc -o main main.o
mytool1.o mytool2.o 注意规则一行中的TAB表示那里是一个TAB键
Makefile有三个非常有用的变量.分别是$@,$^,$<代表的意义分别是:
$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件.
如果我们使用上面三个变量,那么我们可以简化我们的Makefile文件为:
# 这是简化后的Makefile
main:main.o mytool1.o mytool2.o
gcc -o $@ $^
main.o:main.c mytool1.h mytool2.h
gcc -c $<
mytool1.o:mytool1.c mytool1.h
gcc -c $<
mytool2.o:mytool2.c mytool2.h
gcc -c $<
经过简化后我们的Makefile是简单了一点,不过人们有时候还想简单一点.这里
我们学习一个Makefile的缺省规则
.c.o:
gcc -c $<
这个规则表示所有的 .o文件都是依赖与相应的.c文件的.例如mytool.o依赖于
mytool.c这样Makefile还可以变为:
# 这是再一次简化后的Makefile
main:main.o mytool1.o mytool2.o
gcc -o $@ $^
.c.o:
gcc -c $<
好了,我们的Makefile 也差不多了,如果想知道更多的关于Makefile规则可以查
看相应的文档.
3.程序库的链接
试着编译下面这个程序
/* temp.c */
#include
int main(int argc,char **argv)
{
double value;
printf("Value:%f/n",value);
}
这个程序相当简单,但是当我们用 gcc -o temp temp.c 编译时会出现下面所示
的错误.
/tmp/cc33Kydu.o: In function `main':
/tmp/cc33Kydu.o(.text+0xe): undefined reference to `log'
collect2: ld returned 1 exit status
出现这个错误是因为编译器找不到log的具体实现.虽然我们包括了正确的头
文件,但是我们在编译的时候还是要连接确定的库.在Linux下,为了使用数学函数,我
们必须和数学库连接,为此我们要加入 -lm 选项. gcc -o temp temp.c -lm这样才能够
正确的编译.也许有人要问,前面我们用printf函数的时候怎么没有连接库呢?是这样
的,对于一些常用的函数的实现,gcc编译器会自动去连接一些常用库,这样我们就没
有必要自己去指定了. 有时候我们在编译程序的时候还要指定库的路径,这个时候
我们要用到编译器的 -L选项指定路径.比如说我们有一个库在 /home/hoyt/mylib下
,这样我们编译的时候还要加上 -L/home/hoyt/mylib.对于一些标准库来说,我们没
有必要指出路径.只要它们在起缺省库的路径下就可以了.系统的缺省库的路径/lib
/usr/lib /usr/local/lib 在这三个路径下面的库,我们可以不指定路径.
还有一个问题,有时候我们使用了某个函数,但是我们不知道库的名字,这个时
候怎么办呢?很抱歉,对于这个问题我也不知道答案,我只有一个傻办法.首先,我到
标准库路径下面去找看看有没有和我用的函数相关的库,我就这样找到了线程
(thread)函数的库文件(libpthread.a). 当然,如果找不到,只有一个笨方法.比如我要找
sin这个函数所在的库. 就只好用 nm -o /lib/*.so|grep sin>~/sin 命令,然后看~/sin
文件,到那里面去找了. 在sin文件当中,我会找到这样的一行libm-2.1.2.so:00009fa0
W sin 这样我就知道了sin在 libm-2.1.2.so库里面,我用 -lm选项就可以了(去掉前面
的lib和后面的版本标志,就剩下m了所以是 -lm).
4.程序的调试
我们编写的程序不太可能一次性就会成功的,在我们的程序当中,会出现许许
多多我们想不到的错误,这个时候我们就要对我们的程序进行调试了.
最常用的调试软件是gdb.如果你想在图形界面下调试程序,那么你现在可以选
择xxgdb.记得要在编译的时候加入 -g选项.关于gdb的使用可以看gdb的帮助文件.由
于我没有用过这个软件,所以我也不能够说出如何使用. 不过我不喜欢用gdb.跟踪
一个程序是很烦的事情,我一般用在程序当中输出中间变量的值来调试程序的.当
然你可以选择自己的办法,没有必要去学别人的.现在有了许多IDE环境,里面已经自
己带了调试器了.你可以选择几个试一试找出自己喜欢的一个用.
5.头文件和系统求助
有时候我们只知道一个函数的大概形式,不记得确切的表达式,或者是不记得
着函数在那个头文件进行了说明.这个时候我们可以求助系统.
比如说我们想知道fread这个函数的确切形式,我们只要执行 man fread 系统就
会输出着函数的详细解释的.和这个函数所在的头文件说明了
相关推荐
智能客服系统知识库数据清洗
数据清洗(Data Cleaning)是确保智能客服知识库高效运行的重要环节,主要涉及。| 分类 & 标签优化 | 重新组织 FAQ,创建关键字索引 || 定期更新 | 结合用户反馈,每 1-3 个月优化 |才能提供更优质、正确的回答,提升客户满意度!、Zendesk、Intercom 等)中,: FAQ 或客服回答中可能存在。,会影响 AI 匹配的准确性。是一个持续优化的过程,
Linux系统下的GCC编译过程、使用命令详解(多文件编译、动态库、静态库)
以上是学习中大多数时候使用的gcc编译指令,上面代码是一步到位的得到链接后的文件,其本质是要经过预处理 编译 汇编 链接这四步。gcc -S -o hello.s hello.c,可直接将hello.c文件编译为汇编形式,并。通常编译hello.c 使用-o参数可命名文件,将hello.c编译后命名为hello,即gcc命令后的。数据段合并 将生成的.obj文件与库文件.lib等文件链接,生成可执行文件(.exe文件) ,地址回填。文件, 展开宏、头文件,替换条件编译,删除注释、空行、空白。
CANopen PDO 配置實戰:3步完成0x1800-0x1A00物件字典映射與事件觸發
本文详细解析CANopen PDO配置实战,通过3个关键步骤完成0x1800-0x1A00对象字典映射与事件触发设置。重点介绍COB-ID位域解析、映射参数配置及事件触发优化,帮助工程师实现工业自动化设备间毫秒级实时数据交换,提升系统通信效率。
Linux环境下GCC基本使用详解(含实例)
GCC(英文全拼:GNU Compiler Collection)是 GNU 工具链的主要组成部分,是一套以 GPL 和 LGPL 许可证发布的程序语言编译器自由软件。本文介绍了gcc的安装和基本使用命令,以及通过实例介绍了程序的预处理、编译、汇编、链接过程。
别怕,“卷积”其实很简单
首先给大家讲一个关于卷积的小故事:小明是杭州某互联网大厂的员工,每天996十分辛苦,但小明最近爱上了打台球,经常不在工位。这天,小明的主管让小明改一个需求,小明却到楼下找产品部小丽打台球去了,被主管发现,他非常气愤,扇了小明一巴掌(注意,这就是输入信号,脉冲)。于是小明脸上会渐渐地(贱贱地)鼓起来一个包,小明的脸就是一个系统,而鼓起来的包就是小明的脸对巴掌的响应。好,这样就和信号系统建立起来意义对应的联系。
PID详解
1、什么是PID及其作用 设定一个输出目标,反馈系统传回输出值,如与目标不一致,则存在一个误差,PID 根据此误差调整输入值,直至输出达到设定值. 为什么需要PID呢,比如控制温度,我们需要设置一个要达到的目标温度值,当将温度稳定在目标温度值 例如,我们希望水的目标温度值为70°,其希望无非就是可以快速而且无抖动的达到70°,并稳定在70° 如果我们使用普通的方式加热,当温度到达70°后就以及停止加热,岂不是简单快速,当然用在要求不高的场合也可以,但是如果要求更高的场合呢,会出现温度到达70°后......
Linux[一] 动态库与静态库的制作
Linux[一] 动态库与静态库的制作
馈电网络设计:通过Smith圆图工具完成微带线到同轴探针的阻抗匹配
Smith圆图通过图形化阻抗变换路径,显著简化微带线到同轴探针的匹配设计。设计需结合理论计算(微带线阻抗公式、探针等效模型)、圆图操作(串联/并联元件移动规则)及仿真验证,最终实现宽带低反射匹配。
轻松玩转Linux:GCC
GCC编译器是Linux系统下最常用的CIC++编译器,大部分Linux发行版中都会默认安装。GCC编译器通常以gcc指令的形式在终端中使用。
12、知识图谱数据处理与推理全解析
本文深入解析了知识图谱中的数据处理与推理技术,涵盖SHACL的多种约束类型(如值约束、范围约束、字符串约束、逻辑约束等)及其在数据质量控制中的应用,并介绍了常用的SHACL工具与实际案例。文章对比了SPARQL与SHACL的特点,探讨了RDF(S)的局限性,引出表达能力更强的OWL和OWL2语言及其在语义网和生物医学等领域的应用。此外,还阐述了规则在知识表示中的作用,包括产生式规则和Datalog规则,并总结了知识图谱中推理的重要性与典型流程,为构建高质量、可推理的知识图谱提供了全面的技术指导。
Android系统开发工程师面试指南与参考答案
本文整理了Android系统开发工程师面试常见问题与参考答案。核心内容涵盖:1)Framework层定制方法,如修改HAL和系统服务;2)ANR问题分析工具(systrace)与解决方案;3)性能优化实践,包括开机加速和功耗管理;4)四大组件工作机制与应用案例;5)Native崩溃调试技巧。文章强调通过AOSP源码研究、工具使用和项目案例准备来提升面试表现,重点考察应聘者的系统开发深度和实操能力。参考答案均基于实际开发经验,提供可量化的优化成果说明。
【Linux】内功篇:GCC基础知识
GCC作为一种编译器,在Linux内核的系统中经常被使用。因此,掌握GCC编译器的基础知识并理解GCC编译原理,能提高Linux环境下C编程的能力,为以后的服务器开发、嵌入式Linux开发奠定内功基础。本篇内容为学习笔记,来源于播布客---GCC编译器使用。若涉及版权问题,请联系删除。
5G/NR SSB学习总结
6.1 SSB概念 同步信号和PBCH块(Synchronization Signal and PBCH block, 简称SSB),它由主同步信号(Primary Synchronization Signals, 简称PSS)、辅同步信号(Secondary Synchronization Signals, 简称SSS)、PBCH三部分共同组成。 6.2 SSB特征 ...
Linux GCC编程
Linux:GCC编程 GCC可以对C/C++程序开发进行灵活控制。C/C++程序从喀什编码到生成可执行的二进制文件至少要经过4个步骤: 预处理 编译 汇编 链接 GCC的基本使用格式:$gcc [选项] <文件名> GCC编译.c源文件的过程(以hello.c文件为例): $gcc –E hello.c –o hello.i //预处理,生成预处理文件 $gcc –S...
IDEA的使用指南
IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.
霍尼韦尔SoftMaster使用说明
霍尼韦尔SoftMaster使用说明
linux编程——认识GCC编译器
GCC 是一套由 GNU 开发的编程语言编译器,它支持多种编程语言,包括 C、C++、Objective-C、Fortran、Ada 和 Go 等。GCC 以其高效、稳定和可移植性而闻名于世,被广泛应用于各种操作系统,尤其是 Linux 系统。
Devexpress16.2.6破解工具
Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具
Linux编程及GCC编译器
a.out 这个文件的命名是 GCC 编译器自动命名的,在使用 gcc 命令的时候加上-o 来指定生成的可执行文件名字,比如编译 main.c 以后生成名为“main”的可执行文件。当编译完成以后会生成一个 a.out 文件,这个 a.out 就是编译生成的可执行文件,执行此文件看看是否和我们代码的功能一样,执行的方法很简单使用命令:“./+可执行文件”,比如本例程就是命令: ./a.out。-c: 只编译不链接为可执行文件,编译器将输入的.c 文件编译为.o 的目标文件。
ssm框架搭建
这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载
linux系统下用GCC、JAVA和Python编程
一:linux系统下用GCC编程 方法一: 1.C语言文件建立 [root@localhost kang]# vim tang.c 2.编写代码 代码输入后,按下shift+;打出冒号输入wq按回车保存(或者insert键将写好的代码copy过来) 3.GCC编译 编译后生成可执行a.out文件 [root@localhost kang]# gcc tang.c 4.结果显示 [root@l...
虚拟机中Linux系统gcc代码编程及运行(超超超超级详细)基础篇
最近是不是要开始操作系统的实验部分了呢? 请运用虚拟机中的Linux系统进程GCC操作,连着蹦出来三个不认识的词是不是晕头转向呢? 好不容易下完了虚拟机,安完了Linux系统,结果,谁能告诉我GCC呢!
LINUX编程下GCC的宏
有些时候我们再编写代码或者阅读开源项目时经常会遇到一些陌生的宏定义,在找遍所有源代码都没发现其在哪里被定义过,这时,这些宏很可能是系统编译器自己定义的。 比如:在OneNet平台(http://open.iot.10086.cn/)提供的EDP协议C语言版的SDK中,common.h头文件中有这样的定义 #if defined(_LIN...
Linux GCC 64位编程技巧
Linux GCC 64位编程技巧,项目要用到,上网查了一下,资料虽多,但零零散散,干脆自己整理一份,共享给大家。 Windows和Linux类似,但有的细节还需要大家自己查了。
linux gcc c语言编程,linux 下c语言编程 GCC使用入门.doc
linux 下c语言编程 GCC使用入门关键字: linux 下c语言编程 gcc使用入门linux 下c语言编程 GCC使用入门2009年04月30日 星期四 13:24本文来自:ubuntu中文论坛本文是写给 gcc 新手的入门文章,所以内容比较简单。如果你知道下面3条命令都可以编译c++的话,就不用在本文浪费时间了代码:g++ -Wall hellocpp.cppgcc -Wall hell...
linux常用编程工具之gcc、make简介
引言 Linux在很多人眼中是非常好的操作系统,不仅因为它的内核和函数库的完整源代码都是公开的,而且因为它拥有许多好用的程序开发工具。下面就介绍几种常用的编程工具,熟悉这些工具对于开发Linux应用程序是很有必要的。当然了,像其它Linux程序一样,更详细的内容你能在man手册或info页中找到。 一.gcc编译器: gcc是GNU提供的优秀的软件之一,其性能不亚于任
linux GCC 64位编程技巧
linux GCC 64位编程技巧 64位系统的优势? 既然要采用64位系统,首先要知道64位系统的优势所在。对于技术人员来说,完全没有必要去看那些厂家拿出的厚厚的说明书、或者某个研究机构抛出的一堆的数字,64位系统的优势总结起来很简单:内存大、速度快! 内存大 与32位系统相比,64位系统的地址空间大大增大,达到了18PB,18PB究竟是多大呢?说出来有点吓人:4G内存的40亿倍!这么大
【Linux】Linux编程基础(vi、gcc、gdb)
编写一个程序,首先是程序的录入,然后是程序的编译,最后是程序的调试。本文介绍进行这三步工作的主要工具:vi、gcc、gdb。 编辑器介绍 Linux提供了一个完整的编辑器家族系列。按功能可以分为两大类:行编辑器(Ed、Ex)和全屏幕编辑器(vi、Emacs)。行编辑器每次只能队一行进行操作,而全屏幕编辑器可以对整个屏幕进行编辑。 vi介绍 vi是全屏幕编辑器中的一种,它有三种模式,分...
2098



被折叠的 条评论
为什么被折叠?



