LINUX下文件编译
body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;} th{border: 1px solid gray; padding: 4px; background-color: #DDD;} td{border: 1px solid gray; padding: 4px;} tr:nth-child(2n){background-color: #f8f8f8;}
Linux 下文件编译与调试
gcc/g++编译器
对于.c格式的 C文件,可以采用gcc或g++编译
对于 .cc、.cpp格式的C++文件,应该采用g++进行编译
|
常用的选项:
-c 表示编译源文件
-o 表示输出目标文件
-g 表示在目标文件中产生调试信息,用于gdb调试
-D <宏定义> 编译时将宏定义传入进去
-Wall 打开所有类型的警告。
|
|
1. gcc编译过程:预编译->编译->汇编->链接 |
(1)预处理:预处理器将对源文件中的宏进行展开。
(2)编译:gcc将c文件编译成 汇编文件。
(3)汇编:汇编器as将汇编文件编译成机器码。
(4)链接:将目标文件和外部符号进行连接,得到一个可执行二进制文件。
//test.c
|
|
(1)预处理: gcc –E test.c -o test.i
我们用 cat 查看 test.i 的内容如下:int main() int x=(1+2); return 0;我们可以看到,文件中宏定义NUMBER出现的位置被(1+2)替换掉了,其它的内容保持不变。
预处理阶段:对包含的头文件(#include)和宏定义(#define、#ifdef等)进行处理 |
(2)编译:gcc -S test.i –o test.s 通过 cat test.s 查看 test.s 的内容为代码。
编译阶段:检查代码规范性、语法错误等,在检查无误后把代码翻译成汇编语言
|
|
(3)汇编:as test.s -o test.o 利用as将汇编文件编译成机器码。得到输出文件为 test.o。test.o 中为目标机器上的二进制文件. 用 nm 查看文件中的符号: nm test.o 输出如下:0000000000000000 T main。既然已经是二进制目标文件了,能不能执行呢?试一下 ./test.o,提示 cannotexecute binary file.T表示这个符号属于代码。
//test.o 得先加一个执行权限
|
(4)链接: gcc test.o –o test ,将所有的.o文件链接起来生产可执行程序。 链接阶段:将.s的文件以及库文件整合起来链接为可执行程序 |
gcc所支持后缀名: | gcc常用选项: |
gcc库选项: |
gcc警告选项: |
file 文件名 看对应文件类型 |
//test1.c
#include<stdio.h>
int main()
{
#ifdef meihao
printf("define meihao\n");
#else
printf("not define meihao\n");
#endif
printf("main exit\n");
}
|
gcc -E test1.c -o test1.i |
静态库是目标文件.a 的归档文件(格式为libname.a)。如果在编译某个程序时链接静态库,则链接器将会搜索静态库并直接拷贝该程序的可执行二进制文件到当前文件中;
静态库将会整合到程序中,在程序执行时不用加载静态库。 因此,静态库会使你的程序臃肿并且难以升级,但比较容易部署。而动态库会使你的程序轻便易于升级但难以部署。
|
动态库(格式为 libname.so[.主版本号.次版本号.发行号])。在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入。
动态库只在执行时才被链接使用,不是直接编译为可执行文件,并且一个动态库可以被多个程序使用故可称为共享库。 |
|
创建静态库: >gcc -c add.c //编译add.c源文件生成add.o目标文件 >ar -crsv libadd.a add.o //对目标文件*.o进行归档,生成lib*.a,此处lib要写;命令参数: c 创建一个库。不管库是否存在,都将创建。 r 代替库中现有的文件或者插入新的文件 s 写入一个目标文件索引到库中,或者更新一个存在的目标文件索引 v 输出详细信息 a - add.o >su #cp ./libadd.a /lib //拷贝到标准程序设计库 >gcc main.c -w -o main -ladd >./main 1 2
sum=3
>gcc -c add.c
>ar -crsv libadd.a add.o
a - add.o >gcc main.c -w -o main -L./ -ladd //不要忘记-L后面的那个./ ;即在库文件的搜索路径中添加当前路径 -ladd表示链接库文件libadd.a/.so
>./main 1 2
sum=3 |
创建动态库:
>gcc -fPIC -Wall -c add.c //编译,允许发出警告,生成使用相对地址的位置无关的目标代码
>gcc -shared -o libadd.so add.o //生成库文件libadd.so
>su
#cp ./libadd.so /lib
#exit //拷贝到 /lib 库中
>gcc main.c -w -o main -ladd
>./main 1 2
sum=3
在运行main前,需要注册动态库的路径。
方法有3种:
▶修改/etc/ld.so.conf
▶修改LD_LIBRARY_PATH环境变量
▶将库文件拷贝到/lib或者/usr/lib下(系统默认搜索库路径)。 |
|
//add.c int add(int a,int b)
{
return a+b;
}
|
//main.c #include<stdio.h>
#include<stdlib.h>
void main(int argc,char* argv[])
{
if(argc!=3)
{
printf("error args\n");
return;
}
int i=atoi(argv[1]);
int j=atoi(argv[2]);
printf("sum=%d\n",add(i,j));
}
|
程序调试
gdb常用命令
Linux 包含了一个叫gdb的调试程序。gdb可以用来调试 C 和 C++ 程序。在程序编译时用 -g 选项可打开调试选项,表示在目标文件中产生调试信息,用于gdb调试;
>gcc test1.c -Wall -g -o test //(—g和—o要挨在一起)(—g和—c要挨在一起)
>gdb ./test
|
>ulimit -c unlimited |
>gcc test3.c -w -o test3
>gdb ./test3 core
//l 输出错误行代码,bt 打开调用栈查看自己错误行代码, q 退出;
|
//test3.c #include<stdio.h>
int add(int a,int b)
{
return a+b;
}
int main(int argc,char **argv)
{
int i,j,sum;
i=atoi(argv[1]);
j=atoi(argv[2]);
sum=add(i,j);
printf("sum=%d\n",sum);
}
|
gcc对代码进行优化通过选项“-On”来控制优化级别(n是整数)。不同的优化级别对应不同的优化处理工作。如使用优化选项“-O1”主要进行线程跳转和延迟退栈两种优化。使用优化选项“-O2”除了完成所有“-O1”级别的优化之外,还要进行一些额外的调整工作,如处理其指令调度等。选项“-O3”则还包括循环展开或其他一些与处理器特性相关的优化工作。虽然优化选项可以加速代码的运行速度,但对于调试而言将是一个很大的挑战。因为代码在经过优化之后,原先在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句也有可能因为循环展开而变得到处都有,所有这些对调试来讲都是不好的。所以在调试的时候最好不要使用任何的优化选项,只有当程序在最终发行的时候才考虑对其进行优化。
通常用的是-O2
|
LINUX下文件编译的更多相关文章
- 嵌入式之:Linux下文件编译过程
本文主要三个部分:1.GNU GCC简介 2.C/C++交叉编译器arm-elf-gcc 3.make文件,用于工程管理 部分一:GNU GCC简介: 该编译器基本功能: (1)输出预处理后的文件(展 ...
- dos2unix,去掉Linux下文件中的^M
Windows系统下使用VS2010编写好的CPP文件,想放到Linux上进行编译.发现Linux上文件中的每行代码末尾都跟着^M这个符号. 为什么同一份文件在windows上和Linux上显示的不一 ...
- ACE-6.1.0 linux 下的编译与安装步骤
ACE-6.1.0 linux 下的编译与安装步骤 引用至http://www.cnblogs.com/liangxiaxu/archive/2013/03/07/2948417.html 1.从 ...
- linux 下文件误删恢复
linux 下文件误删恢复 0x01 事件背景 某天晚上写代码的时候,本来想删除当前目录下一个叫xxx的文件夹 rm -rdf ./xxx/*, 结果光顾着和人说话,一不留神手贱把命令敲成了rm -r ...
- FFmpeg在Linux下安装编译过程
转载请把头部出处链接和尾部二维码一起转载,本文出自:http://blog.csdn.net/hejjunlin/article/details/52402759 今天介绍下FFmpeg在Linux下 ...
- Linux下nginx编译安装教程和编译参数详解
这篇文章主要介绍了Linux下nginx编译安装教程和编译参数详解,需要的朋友可以参考下 一.必要软件准备1.安装pcre 为了支持rewrite功能,我们需要安装pcre 复制代码代码如下: # y ...
- linux下将编译错误输出到一个文本文件
linux下将编译错误输出到一个文本文件 command > filename 把把标准输出重定向到一个新文件中 command > > filename 把把标准输出重定向到一个文 ...
- 从四个问题透析Linux下C++编译&链接
摘要:编译&链接对C&C++程序员既熟悉又陌生,熟悉在于每份代码都要经历编译&链接过程,陌生在于大部分人并不会刻意关注编译&链接的原理.本文通过开发过程中碰到的四个典型 ...
- Linux下文件的三种时间戳
Linux下文件的三种时间标记 三种时间对应关系表 column column column 访问时间 Access atime 修改时间 Modify mtime 状态改动时间 Change cti ...
随机推荐
- fastdfs集群
高可用的两大目的:数据备份,数据分片 1.FastDFS安装配置 先配置一台,将其中的配置文件打包,下载,然后配置其他机器时只需要解压即可, 打包命令 然后下载,上传到其他机器相对应的/etc目录下 ...
- 北漂的IT人
北京的互联网人,是工作日完全没有个人生活的一类人,也是整个北漂大队伍中,下班时间最晚的那一波人,如果赶上周末还要加班,那毫不夸张地说,你的整个人生都在互联网上奋斗着. 虽说十点上班让多少行内外的人羡慕 ...
- ERP中自定义报表制作流程
查询制作流程 新增单表查询--查询语句设置--表格设置(列信息)--参数设置--关联设置--着色设置 报表设计需求(以差旅报销单为例) 1.制作按部门统计每个月的 报销金额并且可以关联到明细进行比对 ...
- Elasticsearch Head插件实践
简介 Elasticsearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Ap ...
- 简易 bokeh 图像散景效果算法实现
bokeh百度百科的解释 摄影镜头光圈大小和拍摄距离决定了拍摄时的景深,相对于焦点位置,焦点前与焦点后的被拍摄物体会显得模糊,这个模糊区域被称为焦外.焦外具体的模糊程度还受到镜头中镜片单体和组合的物理 ...
- 合并 CentOS 6.8 的两个ISO镜像
合并 CentOS 6.8 的两个ISO镜像 1.创建相关目录: [root@local ~] mkdir -p /mnt/dvd1 /mnt/dvd2 /mnt/dvd3 /mnt/iso 说明: ...
- 用Vue中遇到的问题和处理方法
用Vue开发项目有一段时间,在实际项目中遇到一些问题,在里把问题记录下来,并附上解决方案,给遇到同样的问题的码友提供一个解决思路吧: 测试部抛出问题一:在Vue1.0路由vue-router中,当点击 ...
- Yii2.0源码阅读-一次请求的完整过程
Yii2.0框架源码阅读,从请求发起,到结束的运行步骤 其实最初阅读是从yii\web\UrlManager这个类开始看起,不断的寻找这个类中方法的调用者,最终回到了yii\web\Applicati ...
- Vue入门
一.引入vue 方法一:下载vue.js,然后像引用jquery一样,在HTML中使用script标签引入 <script src="https://unpkg.com/vue/dis ...
- MongoDB入门学习笔记之简介与安装配置
一.MongoDB简介 1.文档数据库 MongoDB是一款开源的文档型非关系数据库,具有高性能.高可靠性和自动扩展等特点.MongoDB中的每一条记录是一个文档,其数据存储结构为键/值对,类似JSO ...