0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux程序的编写、编译、调试方法及make

C语言专家集中营 来源:未知 作者:李倩 2018-07-16 17:02 次阅读

1.建一个目录

2.写代码,建一个hello.c文件

代码:

< class="ViewSource" rel="nofollow" style="box-sizing: border-box;outline: 0px;color: rgb(103, 149, 181);background-image: url("https://mmbiz.qpic.cn/mmbiz_png/Yd5A7Cl21m4hiccZ4QpuUnPUuM8EQpfZdian4CriaHPzV0bXhbvnwoFkwHlKSoWRzRgxMERFP3oCtJxZz7icsLhIhQ/640?wx_fmt=gif");background-position: left top;background-size: initial;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: inherit;border-width: initial;border-style: none;border-color: initial;padding: 1px;margin-right: 10px;word-break: break-all;display: inline-block;width: 16px;height: 16px;text-indent: -2000px;" target="_self" title="view plain">view plain< class="CopyToClipboard" rel="nofollow" style="box-sizing: border-box;outline: 0px;color: rgb(103, 149, 181);background-image: url("https://mmbiz.qpic.cn/mmbiz_png/Yd5A7Cl21m4hiccZ4QpuUnPUuM8EQpfZdAbOXa8oicYJW4EAmgLUH0SNj4v9wju4KzA76TP9yPJhEgxr0uX4icBIg/640?wx_fmt=gif");background-position: left top;background-size: initial;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: inherit;border-width: initial;border-style: none;border-color: initial;padding: 1px;margin-right: 10px;word-break: break-all;display: inline-block;width: 16px;height: 16px;text-indent: -2000px;" target="_self" title="copy to clipboard">copy to clipboard

#include"stdio.h"

main()

{

printf("HelloLinux.\n")

}

#include"stdio.h"

main()

{

printf("Hello Linux.\n")

}

记得最后一定要换行

3.编译

gcc-ohellohello.c

使用gcc编译器就会为我们生成一个hello的可执行文件

4.输出

执行./hello就可以看到程序的输出结果了.

是不是很简单?

命令行中gcc表示我们是用gcc来编译我们的源程序,-o选项表示我们要求编译器给我们输出的可执行文件名为hello而hello.c是我们的源程序文件.gcc编译器有许多选项,一般来说我们只要知道其中的几个就够了.-o选项我们已经知道了,表示我们要求输出的可执行文件名.-c选项表示我们只要求编译器输出目标代码,而不必要输出可执行文件.-g选项表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息.知道了这三个选项,我们就可以编译我们自己所写的简单的源程序了,如果你想要知道更多的选项,可以查看gcc的帮助文档,那里有着许多对其它选项的详细说明.

下面我们来演示怎样用GDB来调试一个求0+1+2+3+…+99的程序:

/* Filename:hello.c */
#include "stdio.h"main(){int i, sum;sum = 0;for (i = 0; i < 100; i++){sum + = i;}printf("the sum of 1+2+...+ is %d", sum);}

执行如下命令编译hello.c(加-g选项产生debug信息):#gcc –g –ohello sum.c在命令行上键入gdb hello并按回车键就可以开始调试sum了,再运行run命令执行sum

#gdb hello

list命令用于列出源代码,对上述程序两次运行list,将出现如上画面(源代码被标行号)。

根据列出的源程序,如果我们将断点设置在第5行,只需在gdb 命令行提示符下键入如下命令设置断点:(gdb) break 5

设置断点的另一种语法是 break ,它在进入指定函数(function)时停住。相反的,clear用于清除所有的已定义的断点,clear 清除设置在函数上的断点, clear 则清除设置在指定行上的断点。watch命令:watch命令用于观查变量或表达式的值,我们观查sum变量只需要运行watch sum

watch 为表达式(变量)expr设置一个观察点,一量表达式值有变化时,程序会停止执行。要观查当前设置的watch,可以使用info watchpoints命令。next、step命令:next、step用于单步执行,在执行的过程中,被watch变量的变化情况将实时呈现(分别显示Old value和New value)

next、step命令的区别在于step遇到函数调用,会跳转到到该函数定义的开始行去执行,而next则不进入到函数内部,它把函数调用语句当作一条普通语句执行。

5.Make

make是所有想在Linux系统上编程的用户必须掌握的工具,对于任何稍具规模的程序,我们都会使用到make,几乎可以说不使用make的程序不具备任何实用价值。

在此,我们有必要解释编译和连接的区别。编译器使用源码文件来产生某种形式的目标文件(object files),在编译过程中,外部的符号参考并没有被解释或替换(即外部全局变量和函数并没有被找到)。因此,在编译阶段所报的错误一般都是语法错误。而连接器则用于连接目标文件和程序包,生成一个可执行程序。在连接阶段,一个目标文件中对别的文件中的符号的参考被解释,如果有符号不能找到,会报告连接错误。

编译和连接的一般步骤是:第一阶段把源文件一个一个的编译成目标文件,第二阶段把所有的目标文件加上需要的程序包连接成一个可执行文件。这样的过程很痛苦,我们需要使用大量的gcc命令。

而make则使我们从大量源文件的编译和连接工作中解放出来,综合为一步完成。GNU Make的主要工作是读进一个文本文件,称为makefile。这个文件记录了哪些文件(目的文件,目的文件不一定是最后的可执行程序,它可以是任何一种文件)由哪些文件(依靠文件)产生,用什么命令来产生。Make依靠此makefile中的信息检查磁盘上的文件,如果目的文件的创建或修改时间比它的一个依靠文件旧的话,make就执行相应的命令,以便更新目的文件。

假设我们写下如下的三个文件,add.h用于声明add函数,add.c提供两个整数相加的函数体,而main.c中调用add函数:

/* filename:add.h */extern int add(int i, int j);/* filename:add.c */int add(int i, int j){return i + j;}/* filename:main.c */#include "add.h"main(){int a, b;a = 2;b = 3;printf("the sum of a+b is %d", add(a + b));}

怎样为上述三个文件产生makefile呢?如下:

test : main.o add.ogcc main.o add.o -o testmain.o : main.c add.hgcc -c main.c -o main.oadd.o : add.c add.hgcc -c add.c -o add.o

上述makefile利用add.c和add.h文件执行gcc -c add.c -o add.o命令产生add.o目标代码,利用main.c和add.h文件执行gcc -c main.c -o main.o命令产生main.o目标代码,最后利用main.o和add.o文件(两个模块的目标代码)执行gcc main.o add.o -o test命令产生可执行文件test。我们可在makefile中加入变量,另外。环境变量在make过程中也被解释成make的变量。这些变量是大小写敏感的,一般使用大写字母。Make变量可以做很多事情,例如:i) 存储一个文件名列表;ii) 存储可执行文件名;iii) 存储编译器选项。要定义一个变量,只需要在一行的开始写下这个变量的名字,后面跟一个=号,再跟变量的值。引用变量的方法是写一个$符号,后面跟(变量名)。我们把前面的 makefile 利用变量重写一遍(并假设使用-Wall -O –g编译选项):

OBJS = main.o add.oCC = gccCFLAGS = -Wall -O -gtest : $(OBJS)$(CC) $(OBJS) -o testmain.o : main.c add.h$(CC) $(CFLAGS) -c main.c -o main.oadd.o : add.c add.h$(CC) $(CFLAGS) -c add.c -o add.o

makefile 中还可定义清除(clean)目标,可用来清除编译过程中产生的中间文件,例如在上述makefile文件中添加下列代码:

clean:rm -f *.o

运行make clean时,将执行rm -f *.o命令,删除所有编译过程中产生的中间文件。

不管怎么说,自己动手编写makefile仍然是很复杂和烦琐的,而且很容易出错。因此,GNU也为我们提供了Automake和Autoconf来辅助快速自动产生makefile,读者可以参阅相关资料

7.小结

本章主要阐述了Linux程序的编写、编译、调试方法及make,实际上就是引导读者学习怎样在Linux下编程,为后续章节做好准备。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7597

    浏览量

    136120
  • 函数
    +关注

    关注

    3

    文章

    4303

    浏览量

    62411
  • 编译器
    +关注

    关注

    1

    文章

    1618

    浏览量

    49043

原文标题:Linux下用C语言最基本的程序开发与调试

文章出处:【微信号:C_Expert,微信公众号:C语言专家集中营】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    嵌入式Linux编译调试

    【嵌入式Linux编译调试】VisualStdio+VisualGDB在嵌入式Linux开发中,常见的方式是通过sourceinsight编辑程序
    发表于 11-04 09:04

    Linux设备驱动程序调试方法

    由于设备驱动程序运行于内核空间,因此有着与用户空间程序不同的调试方法。 设备驱动程序调试需要内
    发表于 03-19 15:00 254次下载

    Linux系统网络驱动程序编写

    驱动程序编写 一.Linux系统设备驱动程序概述 1.1 Linux设备驱动程序分类 1.2
    发表于 11-07 10:40 0次下载

    Linux的GNU Make中文手册资料免费下载

    Linux 环境下的程序员如果不会使用 GNU make 来构建和管理自己的工程,应该不能算是一个合格的专业程序员,至少不能称得上是 Unix 程序
    发表于 06-03 08:00 9次下载
    <b class='flag-5'>Linux</b>的GNU <b class='flag-5'>Make</b>中文手册资料免费下载

    Linux下如何编译C程序

    少量文件时可以使用上面方法编译。源码文件较多时,可借用make工具。make通过解析Makefile文件来执行一些gcc命令进行编译
    的头像 发表于 09-20 10:56 4356次阅读
    <b class='flag-5'>Linux</b>下如何<b class='flag-5'>编译</b>C<b class='flag-5'>程序</b>?

    【嵌入式Linux编译调试---1---】VisualStdio+VisualGDB

    【嵌入式Linux编译调试】VisualStdio+VisualGDB 在嵌入式Linux开发中,常见的方式是通过sourceinsight编辑程序
    发表于 11-01 17:38 8次下载
    【嵌入式<b class='flag-5'>Linux</b><b class='flag-5'>编译</b><b class='flag-5'>调试</b>---1---】VisualStdio+VisualGDB

    嵌入式Linux--配置gdb调试环境

    一、获取arm-linux-gdbarm-linux-gdb属于调试程序,主机可以通过执行该程序开启在线调试。一开始照着网上的教程来操作,.configure、
    发表于 11-02 14:21 11次下载
    嵌入式<b class='flag-5'>Linux</b>--配置gdb<b class='flag-5'>调试</b>环境

    stm32cubeMX+vscode开发编译调试stm32程序

    stm32cubeMX+vscode开发编译调试stm32程序安装vscode安装make工具安装交叉编译工具链安装openocd安装cla
    发表于 12-24 19:31 6次下载
    stm32cubeMX+vscode开发<b class='flag-5'>编译</b><b class='flag-5'>调试</b>stm32<b class='flag-5'>程序</b>

    hypervisor的调试分析方法

    我们在编写裸机程序(baremetal)、虚拟化管理程序(hypervisor)和操作系统(OS)时,Debug分析程序是必不可少的。不像linux
    的头像 发表于 10-08 09:40 1400次阅读

    Linux使用gcc编译程序的语法

    01. 调试相关的宏 在Linux使用gcc编译程序的时候,对于调试的语句还具有一些特殊的语法。 gcc编译的过程中,会生成一些宏,可以使用
    的头像 发表于 06-22 10:51 671次阅读

    Linux交叉编译选项与源码与目标文件分离

    交叉编译选项 编译Linux,通常只需要运行 make menuconfig 配置要编译的模块,然后运行
    的头像 发表于 09-27 11:48 791次阅读

    Linux内核编译脚本

    获得编译命令及选项 编译linux时,默认不会显示编译的命令,如果你要获得编译命令及其选项,可以在mak
    的头像 发表于 09-27 11:52 606次阅读

    虚拟机linux怎么编写程序

    虚拟机Linux编写程序,包括设置虚拟机、选择编程工具、创建和编辑代码、编译和运行程序等等。让我们开始吧! 第一部分:设置虚拟机 在开始编写程序
    的头像 发表于 11-17 10:08 1675次阅读

    makemake all和make clean的使用方法

    刚接触Linux,认为直接make后就完成了编译,没想到编译出的结果存在很大问题,原来是makemak
    的头像 发表于 01-05 12:32 1837次阅读

    linux驱动程序编译方法是什么

    Linux驱动程序编译方法主要包括两种: 与内核一起编译编译成独立的内核模块 。以下是对
    的头像 发表于 08-30 14:46 406次阅读