Ubuntu 14.04安装使用GCC相关
准备工作:
- 已经安装好的Ubuntu 14.04系统
我用的ubuntukylin-14.04.5-enhanced-amd64
- 可以正常连接互联网的网络环境
- 脑子
1. 确认手上的工具
1.1 是否安装了vim
1.1.1 输入vim -v
查看vim版本
如果显示
程序 'vim' 已包含在下列软件包中:
* vim
* vim-gnome
* vim-tiny
* vim-athena
* vim-gtk
* vim-nox
请尝试:sudo apt-get install <选定的软件包>
说明vim尚未安装,输入以下命令安装vim(vim-gtk是自带语法高亮的版本)。
sudo apt-get install vim-gtk
或者直接使用大佬的配置
spf13
NeoVIM
exVIM
1.1.2 安装完成后再次输入vim -v
验证
出现上图才说明已经成功安装vim,ESC进入命令模式输入
:q
然后按回车退出vim。
1.2 配置vim
1.2.1 先测试语法高亮是否正常
touch一个c文件随便写点东西
回忆了半天c怎么写|д` )
可以看到即使没有任何额外配置,已经有语法高亮了√。
1.2.2 配置vim
然而只有语法高亮远远不够用,输入以下命令修改配置文件
sudo vim /etc/vim/vimrc
syntax on就是语法高亮,如果你的是off请改成on。
另外把光标移到 文件末尾,输入以下配置(根据自己需要选择)
colorscheme desert
" 设置配色为沙漠
" 其他可选: torte, solarized, molokai, phd, ron, evening等
set mouse=a " 设置可用鼠标点击移动光标
set nu " 显示行号
set nobackup " 覆盖文件时不备份
set autowrite " 自动保存
set cursorline " 高亮显示当前行
set tabstop=4 " 设置tab长度为4个空格
set softtabstop=4 " 设置软tab长度为4个空格
set shiftwidth=4 " 设置缩进为4个空格
set expandtab " 将tab替换为空格
set autoindent " 设置自动缩进(对齐上一行)
set smartindent " 设置智能缩进
set cindent " 设置c语言的缩进方式
set showmatch " 自动匹配
set ruler " 在右下角显示当前行信息
set incsearch " 搜索加强
set hlsearch " 搜索高亮
set ignorecase " 搜索忽略大小写
set whichwrap=b,s,<,>,[,] " 光标从行首和行末时可以跳到另一行去
set scrolloff=3 " 光标移动到上下两端时保持3行距离
set history=1000 " 历史记录条数从20到1000
最后:wq
保存并退出,像下面这样
配置后编辑文件效果
这里看起来似乎比起之前的图好像就多了左边的行号其他没什么区别,但是好处要自己写了才知道。
1.3 补充插件
安装自动完成插件
sudo apt-get install vim-youcompleteme
然后还要用插件管理器把插件安进vim才能生效
vam install youcompleteme
如果这里失败可能是因为插件管理器尚未安装。
尝试sudo apt-get install vim-addon-manager
。
2. 开始干活
理论上说ubuntu应该自带gcc,可能没安g++。
如果需要安装g++最好别单独安装g++。
为了能够编译Ubuntu的内核,Ubuntu提供了一个build-essential软件包。
查看依赖关系可以看到以下内容$ apt-cache depends build-essential build-essential 依赖: libc6-dev 依赖: libc6-dev 依赖: gcc 依赖: g++ 依赖: make 依赖: dpkg-dev
也就是说,安装了该软件包,编译c/c++所需要的软件包也都会被安装
apt-cache depends build-essential
然后
g++ --version
可以看到一步到位了。
gcc编译C文件一共分为四步:
- 预处理 (Preprocess) :生成.i文件
- 编译 (Compilation) :生成.s文件
- 汇编 (Assembly) :生成.o文件
- 链接 (Linking) :生成可执行文件
2.1 预处理 (Preprocess)
预处理会做两件事情:
第一,把除了函数之外的东西全部展开成指定的形式。
第二,删掉文件里的所有注释。
展开成指定形式是什么形式?
展开以#起始的行,包括#if
、#ifdef
、#ifndef
、#else
、#elif
、#endif
、#define
、#include
、#line
、#error
、#pragma
以及单独的#
。
另外还有加上行号等工作,并将头文件里包含的东西所对应的文件(包括子文件夹)也都写入进去以便调用。
至于为什么要删注释——
此时代码已经算进入底层了:
一方面是,对底层来说无用的注释留下来只会影响之后编译汇编等过程的效率;
另一方面是,这时候还不删注释是指着留到后面看能不能帮人家反编译吗。
执行以下命令可以得到仅预处理后的test.i文件(当然你要先写一个test.c)
gcc -E test.c -o test.i
用vim打开test.i后可以看到多加了成百上千行,都是预处理做的事情。
-E
是仅激活预处理程序,并将生成的信息放入test.i。
2.2 编译 (Compilation)
编译的作用就是把预处理完的文件进行一系列语法分析及优化后生成相应的汇编文件。
执行以下命令可以得到编译后的test.s汇编文件(同上,当然你要先有一个test.i)
gcc -S test.i -o test.s
用vim打开test.s后可以看到源代码已经面目全非了,变成了一条条的汇编指令。
2.3 汇编 (Assembly)
汇编就是把拿到的汇编指令逐条翻译成机器可以识别的形式,即机器码。
这一步会产生平台相关性,即决定了在何种平台下运行。
执行以下命令可以得到编译后的test.o文件(同上,当然你要先有一个test.s)
gcc -c test.s -o test.o
用vim打开是乱码,改成16进制显示可以看到是什么数字,但毕竟原本还是二进制,还要经过翻译才能变成机器码。
注意!
执行以下命令会生成onestep.ogcc test.c -o onestep.o
而「onestep.o」跟「test.o」区别是很大的,就算源代码test.c一模一样。
「test.o」不可以直接执行,而「onestep.o」可以直接执行。
这是因为test.o为可重定位文件,还需要经过最后一步链接才能变成可执行文件。
而一步到位的onestep.o已经完成了链接变成可执行文件了。
也就是说:
分步完成的「test.o」还要经过一道链接的工序才能变成「onestep.o」。
2.4 链接 (Linking)
将生成的目标文件和其所依赖的库文件进行连接,生成一个(包装好的)可执行文件。
(不是onestep.o那种半成品)
有兴趣可以试试按生成onestep.o的方式生成一个onestep.o,然后把后缀名 .o 改成 .out 看看是什么效果。
执行以下命令可以得到完成品「THE·可执行文件·test」
gcc test.o -o test
执行以下命令可以执行这个文件
./test
至此gcc从编译到执行就完成了。
2.5 代码含义及示例
-o:指定生成的输出文件。
-E:仅执行编译预处理。
-S:将C代码转换为汇编代码。
-wall:显示警告信息,把警告信息当作错误输出。
-c:仅执行编译操作,不进行连接操作。
//一般过程
gcc -o main main.c
./main
//一般过程的另一种写法
gcc main.c -o main
./main
//总之 -o 后面一定紧接的是 [生成的文件名]
//多个源文件的一般过程
gcc -o main main.c other.c
./main
//分步过程
gcc -c main.o main.c
gcc -o main main.o
./main
//多个源文件的分步过程
gcc -c main.o main.c
gcc -c other.o other.c
gcc -o main main.o other.o
./main
3. gdb的调试
摸了
明年再说
4. makefile的使用
摸了
后年再说
5. 其他
一串神秘的代码,用法:写在.vimrc里面
" 按F5一键编译并运行
map :call CompileRunGcc()
func! CompileRunGcc()
exec "w"
if &filetype == 'c'
exec "!g++ % -DLOCAL -o %<"
exec "!time ./%<"
elseif &filetype == 'cpp'
exec "!g++ % -std=c++11 -DLOCAL -Dxiaoai -o %<"
exec "!time ./%<"
elseif &filetype == 'java'
exec "!javac %"
exec "!time java %<"
elseif &filetype == 'sh'
:!time bash %
elseif &filetype == 'python'
exec "!time python3.5 %"
endif
endfunc