时间:2021-05-19
01、编译选项和内核编译
Linux内核(英语:linux kernel),是一种计算机操作系统内核,已C语言和汇编语言写成,匹配POSIX标准,以GNU通用公共许可证发布。从技术上说Linux只是一个内核。“内核”指的是一个提供硬件抽象层、磁盘及文件控制、多任务等功能的系统软件。
所以首先我们都知道,Linux内核如果用O0编译,是无法编译过的,Linux的内核编译,要么是O2,要么是Os,这点从Linux的Makefile里面可以看出:
当选择了
CONFIG_CC_OPTIMIZE_FOR_SIZE
它会是Os,否则就是O2。
其实O2和Os,都是一些优化选项的集合:
gcc -c -Q -O2 --help=optimizers > /tmp/O2-optsgcc -c -Q -Os --help=optimizers > /tmp/Os-opts前者倾向于基于速度的优化,后者倾向于基于size更小的优化。对比二者的开关选项:
meld /tmp/O2-opts /tmp/Os-opts发现差异小的可怜:
O2和Os都使能了inline small函数和called once的函数,但是O2里面-finline-functions是关闭的,而Os里面是开的。O2里面optimize-strlen是开的,Os里面这个选项是关闭的。相关选项的含义可以通过"man gcc"看出(有问题,找男人),譬如man gcc后检索inline-functions:
从O0到O1,O2,O3,是一个开启的优化选项逐步加大的过程:
kernel用O0编译不过,是因为kernel本身也没有想用O0能够编译过,它的设计里面包含了编译会优化的假想。下面我们用一个简单的例子来说明。
02、一个简单的例子
下面的代码:
O0编译会报如下错,说f()函数没有定义:
$ gcc -O0 cc.ccc.c:1:13: warning: ‘f' used but never defined [enabled by default] void f(void); ^/tmp/ccTwwtHG.o: In function `main':cc.c:(.text+0x19): undefined reference to `f'collect2: error: ld returned 1 exit status但是用O2编译,则没有问题:
$ gcc -O2 cc.c原因在于,O2编译,它意识到a==1,所以if(a>2),它不会成立,所以f()没有定义也没有关系。
把代码稍微改一下后:
O2这个时候也不行了:
$ gcc -O2 cc.c/tmp/ccXiyBHn.o: In function `main':cc.c:(.text.startup+0x7): undefined reference to `f'collect2: error: ld returned 1 exit status所以,通过这个例子,大家可以看出来为什么同样的代码,用O2就可以过,用O0就过不了。内核里面有许多类似设想编译器会进行优化的代码。
3.我们不想inline了
由于编译的优化,有些函数(比如小函数和全工程里面只被一个人调用的函数)虽然没有显示地写成inline,但是编译器优化为inline了,这给调试造成了一些麻烦,因为找不到这个函数对应的symbol了。
这个时候,我们可以显示地写明某些函数我们不想inline:
否则,上面2个函数,即便你代码里面没有写inline,由于O2和Os使能了相关的inline选项,也可能被编译器自动inline掉,如果我们想拒绝inline,可以通过noline来标识。
4.我不想被优化
在全局已经使能O1, O2, O3, Os的情况下,某个单独的函数我们不想做任何的优化,可以用__attribute__((optimize("O0")))来修饰这个函数,比如我们把上述用O2可以编译过的代码进行如下修改:
重新用O2编译:
$ gcc -O2 cc.c/tmp/cc8M338p.o: In function `main':cc.c:(.text+0x19): undefined reference to `f'collect2: error: ld returned 1 exit status5. 总结的话
下面给几条实践指南:
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
make:arm-linux-conmandnotfound错误处理的总结在超级用户权限下建立交叉编译环境成功,但编译是显示make:arm-linux-con
010203卖货有哪些正确姿势?开售、卖货,是每个主播必须经历的考验。不过,主播是一秒卖空还是几个小时才卖完,这个时间不重要。掌握卖货“黑话”,气势和氛围做足了
linux程序的段陆陆续续接触过一些,今天适当的总结一下,时间仓促,总结的比较零散。linux段:text:已编译程序的机器代码。.rodata:只读数据。pr
Golang交叉编译平台的二进制文件熟悉golang的人都知道,golang交叉编译很简单的,只要设置几个环境变量就可以了#mac上编译linux和window
安装g++Linux编译C++程序必须安装g++编译器。这里使用yum方式安装。首先切换到root账号,su-root然后输入密码。执行yuminstallgc