Linux编程环境简介

本文主要介绍Linux下编程Vim、GCC的使用和Makefile文件的编写。

1.Vim介绍

Vim是从 vi 发展出来的一个文本编辑器。代码补全、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用,和Emacs并列成为类Unix系统用户最喜欢的文本编辑器。

1.1Vim常用命令

i:在当前字符的左边插入
I:在当前行首插入
a:在当前字符的右边插入
A:在当前行尾插入
o:在当前行下面插入一个新行
O:在当前行上面插入一个新行
dd:剪切当前行。
yy:拷贝当前行。
cc:剪切当前行并且进入插入模式。
D:剪切从光标位置到行尾到剪贴板。
Y:拷贝当前行。
C:和 D 类似,最后进入插入模式。
x:剪切当前字符到剪贴板。
s:和x类似,不过最后进入插入模式

1.2Vim配置文件.vimrc

vim ~/.vimrc   #编辑配置文件命令

vim启动的时候会根据~/.vimrc文件配置vi的设置,可以修改.vimrc来制定vim风格。

:set number //显示行号(左边)
:syntax on   //关键字高亮
:split two.c //多文件编辑
:set showmatch //"设置匹配模式,输入左括号会出现右括号

2.GCC简介

GNU编译器套件(GNU Compiler Collection)包括C、C++、Objective-C、Fortran、Java、Ada和Go语言的前端,也包括了这些语言的库(如libstdc++、libgcj等等)。GCC的初衷是为GNU操作系统专门编写的一款编译器。GNU系统是彻底的自由软件。此处,“自由”的含义是它尊重用户的自由。

2.1 GCC基本用法

GCC最基本的用法是∶gcc [options] [filenames]
其中options就是编译器所需要的参数,filenames给出相关的文件名称。

-c,只编译,不链接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,文件名与.c文件名相同,通常用于编译不包含主程序的子程序文件。

-o output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。

-g,产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。

-O,对程序进行优化编译、链接,采用这个选项,整个源代码会在编译、链接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、链接的速度就相应地要慢一些。

-O2,比-O更好的优化编译、链接,当然整个编译、链接过程会更慢。
-Idirname,将dirname所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。C程序中的头文件包含两种情况∶

A)#include <myinc.h>
B)#include “myinc.h”

其中,A类使用尖括号(< >),B类使用双引号(“ ”)。对于A类,预处理程序cpp在系统预设包含文件目录(如/usr/include)中搜寻相应的文件,而B类,预处理程序在目标文件的文件夹内搜索相应文件。

2.2 GCC执行过程

虽然我们称GCC是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤∶预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和链接(Linking)。
命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。接着调用cc1进行编译,这个阶段根据输入文件生成以.i为后缀的目标文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的档案库中连到合适的地方。

2.3单文件编译生成执行文件

//method 1
Rosun# gcc hello.c  //自动生产名为a.out的可执行文件
Rosun# ./a.out      //执行a.out
//method 2
Rosun# gcc test hello.c //编译输出名为test的可执行程序
Rosun# ./test      //执行程序test

2.4多文件编译生成执行文件

两个源文件: main.c string.c

//method 1:将两个源文件直接编译生成可执行程序
Rosun# gcc -o test main.c string.c
Rosun# ./test    //执行可执行程序

//method 2:先生成.o目标文件,再连接成可执行程序
Rosun# gcc -c  main.c string.c
Rosun# gcc -o test main.o string.o
Rosun# ./test    //执行可执行程序

2.5编译成汇编语言、静态链接库

静态库是obj文件的一个集合,通常静态库以”.a”为后缀名。
静态库的两个优点:
(1):可以不用重新编译程序库代码的情况下,进行程序的重新链接,这种方法在编译大型程序的时候可以节省许多编译过程的时间。
(2):开发者可以提供库文件给使用人员,不用开放源代码。通常静态库的执行速度比共享库和动态库要快。

两个文件:main.c string.c

Rosun# gcc -S  main.c //将main.c编译生成main.s汇编程序,默认名字与源文件名相同

//生成和使用静态链接库
Rosun# ar -rcs libstr.a string.o  //将string.o打包成库文件libstr.a
Rosun# gcc -o test main.c libstr.a //使用库

3.Makefile文件编写

一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

所要完成的Makefile 文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文件、如何最后产生我们想要的可执行文件。尽管看起来可能是很复杂的事情,但是为工程编写Makefile 的好处是能够使用一行命令来完成“自动化编译”,一旦提供一个(通常对于一个工程来说会是多个)正确的 Makefile。编译整个工程你所要做的唯一的一件事就是在shell 提示符下输入make命令。整个工程完全自动编译,极大提高了效率。

make是一个命令工具,它解释Makefile 中的指令(应该说是规则)。在Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile 有自己的书写格式、关键字、函数。像C 语言有自己的格式、关键字和函数一样。而且在Makefile 中可以使用系统shell所提供的任何命令来完成想要的工作。Makefile(在其它的系统上可能是另外的文件名)在绝大多数的IDE 开发环境中都在使用,已经成为一种工程的编译方法。

3.1编写规则

让我们先来粗略地看一看Makefile的规则。[3]
target … : prerequisites …
command


目标:依赖
执行指令 …
target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。
① prerequisites就是,要生成那个target所需要的文件或是目标。
② command也就是make需要执行的命令。(任意的Shell命令)
这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行(command一定要以Tab键开始,否则编译器无法识别command),减少重复编译,提高了其软件工程管理效率。

3.2实际例子

5个.c文件,2个.h文件
这里写图片描述
这里写图片描述
Makefile

/***Makefile 1****/
CFLAGS = -Iadd -Isub -O2  #头文件搜索路径 add和sub -O2为优化
VPATH=add:sub
OBJS = add_int.o add_float.o sub_int.o sub_float.o main.o   #目标文件.o
TARGET = cacu    #最终生产目标程序
$(TARGET):$(OBJS)  #TARGET目标,需要先生产OBJS目标
    $(CC) -o $(TARGET) $(OBJS) $(CFLAGS)
clean:
    -$(RM) $(TARGET)   #删除可执行文件
    -$(RM) $(OBJS)     #删除目标文件.o

上面的Makefile文件,发现make后,发现目标文件都放在了当前目录下,这样对文件的规范化造成了维护,可以将输出的目标文件放到同一个目录下来解决此问题。

/***Makefile 2****/
 CFLAGS = -Iadd -Isub -O2
 OBJSDIR=.objs
 VPATH=add:sub   #搜索路径
 OBJS = add_int.o add_float.o sub_int.o sub_float.o main.o
 TARGET = cacu
 $(TARGET):$(OBJSDIR) $(OBJS)  #要执行TARGET的命令,先查看OBJSDIROBJS依赖项是否存在
     $(CC) -o $(TARGET) $(OBJSDIR)/*.o  $(CFLAGS)

 $(OBJS):%.o:%.c
     $(CC)  -c $(CFLAGS) $< -o $(OBJSDIR)/$@   #生产目标文件.o 存放在目录OBJSDIR$(OBJSDIR):
     mkdir -p ./$@
 clean:
     -$(RM) $(TARGET)   #delete cacu
     -$(RM) $(OBJSDIR)/*.o   #delete OBJSDIR/*.o

这里写代码片

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值