⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gcc-howto.txt

📁 linux-bible.rar linux-bible.rar
💻 TXT
📖 第 1 页 / 共 5 页
字号:
   在shell的提示符号下键入gcc -v,萤幕上就会显示出你目前正在使用的GCC的版   本。同时这也是一个相当可靠的方法,可以确定你现在所用的是ELF或是a.out。   在我的系统上,执行gcc -v的结果是:   $ gcc -vReading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specsgcc version 2.7.2   上面的讯息指出了几件重要的事情:     * i486 这是指明你现在正在用的gcc是为了486的微处理器而写的---你的电脑       可能是386或是586。这3种微处理器的晶片所编译而成的程式码,彼此间是可       以相容使用的。差别之处是486的程式码在某些地方有加上padding的功能,       所以可以在486上面跑得比较快。这对386的机器而言,执行程式的效能并不       会有什麽不良的影响,只不过真的会让程式码变得稍稍的大了一些。     * box 这可以说一点也不重要;不过也可能另有所指(像是slackware或者       是debian),或者根本什麽也不是(所以罗!完整的目录名称是i486-linux       )。假如你是实务派的佼佼者,亲自动手建立属於自己的gcc,那麽你可以在       建立的过程中设定这一项,以装点门面。就像我做的一样:-)。     * linux 其实这是指linuxelf或是linuxaout。这一项会令人引起不必要的困惑       ,究竟是指哪一种会根据你所用的版本而异。          + linux 意指ELF若版本序号是2.7.0.(或是更新的版本);否则的话,            就是a.out的了。          + linuxaout 意指a.out的格式。当linux的定义从a.out更换到ELF时            ,linuxaout就会顺水推舟,摇身一变,成了一个目标物。因此,你不            会看到任何版本新於2.7.0.的gcc有linuxaout的。          + linuxelf 已经过时了。通常这是指2.6.3版的gcc,而且这个版本也可            以用来产生ELF的可执行档。要注意的是,gcc 2.6.3版在产生ELF程式            码时会有bugs,所以如果你目前用的恰好是这个版本,建议你赶快升级     * 2.7.2 版本的序号。          所以,总结起来,我有2.7.2版的gcc,可以产生ELF格式的程式码。就这麽简单,   惊讶吧!eh?   3.2 东东装好後都到哪儿去了?   如果安装gcc时没有仔细的看著萤幕,或者你是从一个完整的发行系统里把gcc单   独抓出来安装的话,那麽也许你会想知道到底这些东东装好後是住在整个档案系   统的那些地方。几个重点如下:        * /usr/lib/gcc-lib/target/version/ (与子目录)大部份的编译器就是住在       这个地方的。在这儿有可执行的程式,实际在做编译的工作;另外,还有一       些特定版本的程式库与标头档等也会储存在此。     * /usr/bin/gcc 指的是编译器的驱动程式---也就是你实际在命令列(command       line)上执行的程式。这个目录可供各种版本的gcc使用,只要你用不同的编       译器目录(如上所述)来安装就可以了。要知道内定的版本是那一个,       在shell提示符号下打gcc -v。要是想强迫执行某个版本,就换打gcc -V       version。例如:       # gcc -vReading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specsgcc version 2.7.2# gcc -V 2.6.3 -vReading specs from /usr/lib/gcc-lib/i486-box-linux/2.6.3/specsgcc driver version 2.7.2 executing gcc version 2.6.3     * /usr/target/(bin|lib|include)/ 如果你装了数种的目标物件,例如a.out       与elf,或是某一种的交叉编译器(cross-compiler)等等,那些属於非主流目       标物件(non-native target(s))的程式库,binutils(as、ld等等)工具       与标头档等都可以在这儿找到。即使你只安装了一种gcc,还是可以在这儿找       到这些原本就是替它们准备的东东。如果不是在这儿,那麽就应该是       在/usr/(bin|lib|include)了。     * /lib/,/usr/lib 与其它的目录等都是主流系统(native-system)的程式馆       目录。许多的应用程式都会用到/lib/cpp,因此你也需要它---作法上,不是       从/usr/lib/gcc-lib/target/version/ 目录里拷贝,就是弄个符号连结       (symlink)指向那儿。 [译者注:所谓的native,是指目前你的系统是       以a.out或elf的格式为主,或者内定的gcc是哪一种版本等等。native的意思       是‘本土的’、‘本国的’与‘天生的’……等等;当你拿到一片CD-ROM重       头至尾将Linux安装完成,让Linux出生,成为你个人特色浓厚的作业平台後       ,如果再加装一些不一样的目标物件,自然就有‘本土’与‘外省’( 无关       政治),‘本国’与‘外国’、‘天生’与‘人为’等等的区别,同时也含       有内定(default)的意思在。假若再附加上你个人的价值观判断和喜好,我       想用主流(native)与非主流(non-native)来翻译应该还算恰当。]       3.3 标头档ㄋㄟ?标头档ㄋㄟ?   假如把你自行安装在/usr/local/include目录底下的标头档排除在外的话   ,Linux还有另外3种主要的标头档:        * /usr/include/与其子目录底下的标头档,大部份都是由H.J.Lu发展的libc套       件(libc binary package)所提供的。我会只说‘大部份’的原因,是因为你       可能有其它来源的标头档(像是curses与dbm程式库等等)摆在这儿;尤其是       ,如果你现在用的是最新的libc发行系统的话(新版本不像旧版那样,已经       不再支援curses或dbm了。),那东东之多是人人为之咋舌的! [译者       注:libc binary package意指以二进位形式(machine code)储存之套件,并       非原始码(text),若要以中文全称译出,则成‘libc二进位档套件’,似       有聱牙之嫌,故略去binary,以libc套件通称。]     * 在核心原始码的发行系统内(kernel source distribution)       ,/usr/include/linux 与 /usr/include/asm (里头有这些档案       :<linux/*.h> 与 <asm/*.h>)应该有符号连结(symbolic links)可以连       结至目录linux/include/linux 与 linux/include/asm。如果你有鸿鹄之志       的话,安装这些东东後,就不应该只是拿来编译核心(kernel)而已。 把原       始码解压缩(unpacking)後,可能你也会发现,需要在核心的目录       (kernel directory)底下做make config的动作。很多的档案都会依       赖<linux/autoconf.h>的帮忙,可是这个档案却有可能因版本不同而不存在       。若干核心版本里,asm就只是它自己的一个符号连结,仅仅是在make       config时才建立出来而已。 [译者注:原文提及autoconf.h时是‘Many       files depend on <linux/autoconf.h>,which otherwise may not exist,*       ’。此处之otherwise之词性应为形容词(adj),指‘另一情况’、‘另一种       ’、‘不同的’之意,将原文形容词子句拆开来应为:(i) Many files       depend on <linux/autoconf.h>. (ii)<linux/autoconf.h> of other       condition may not exist. 与下一句互相比对,此处应同指在不同版本之情       况下。] 所以,当你在目录/usr/src/linux底下,解开核心的程式码时,就       照著下面指示的做吧!       $ cd /usr/src/linux$ su# make config(回答接下来的问题。通常回答得正不正确并不重要,除非你打算继续□造核心。)# cd /usr/include# ln -s ../src/linux/include/linux .# ln -s ../src/linux/include/asm .     * 诸如<float.h>、<limits.h>、<varargs.h>、<stdarg.h> 与<stddef.h>之类       的档案,会随著不同的编译器版本而异,属於你‘个人的’档案,可以在       /usr/lib/gcc-lib/i486-box-linux/2.7.2/include/与其它相类似(相同)       的目录名称的地方找到。 11/11/97译 5/14/98修正       3.4 建立交叉编译器(Building cross compilers)  将Linux当作标的作业平台(target platform)     假设你已经拿到gcc的原始码,通常你只要依循INSTALL档的指示便可完成一切的   设定。 make後面再接configure --target=i486-linux --host=XXX on   platform XXX,就能帮你变把戏了。要注意的是,你会需要Linux还有核心的标头   档;同时也需要建立交叉组译器(cross assembler)与交叉连结器(cross   linker),来源是 [12]ftp://tsx-11.mit.edu/pub/linux/packages/GCC/。     Linux当成原始作业平台(source platform)而MSDOS作为标的作业平台     Ugh。很明显的,这个大概需要用到套件“emx”或是延伸套件“go”。请自行去   [13]ftp://sunsite.unc.edu/pub/Linux/devel/msdos看看。我并没有测试过这些   个东西,所以没有办法保证什麽。   4. 移植程式与编译程式4.1 gcc自行定义的符号   只要执行gcc时,附加 -v这个参数,就能找出你所用的这版gcc,自动帮你定义了   什麽符号。例如,我的机器看起来会像这样:   $ echo 'main(){printf("hello world\n");}' | gcc -E -v -Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specsgcc version 2.7.2 /usr/lib/gcc-lib/i486-box-linux/2.7.2/cpp -lang-c -v -undef-D__GNUC__=2 -D__GNUC_MINOR__=7 -D__ELF__ -Dunix -Di386 -Dlinux-D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__i386-D__linux -Asystem(unix) -Asystem(posix) -Acpu(i386)-Amachine(i386) -D__i486__ -   假若你正在写的程式码会用到一些Linux独有的特性,那麽把那些无法移植的程式   码,以条件式编译的前置命令封括起来,可是个不错的主意呢!如下所示∶   #ifdef __linux__/* ... funky stuff ... */#endif /* linux */   用__linux__就可以达成目的;看仔细一点,不是linux喔。尽管linux也有定义,   毕竟,这个仍然不是POSIX的标准。   4.2 线上求助说明   gcc编译器参数的说明文件是gcc info page(在Emacs内,按下C-h i,然後选   ‘gcc’的选项)。要是弄不出来,不是卖你CD-ROM的人没把这个东东压给你,不   然就是你现在用的是旧版的。遇到这种情况,最好的方法是移动尊臀到archive   [14]ftp://prep.ai.mit.edu/pub/gnu或是它的mirrors站台,去把gcc的原始档案   抓回家,重新烹饪一番。      gcc manual page(gcc.1) 可以说是已经过时了,要是你吃饱了撑著没事干硬是   想看,它就会告诉你说别无聊了。     旗正飘飘     在命令列上执行gcc时,只要在它的屁股後面加上-On的选项,就能让gcc乖乖的替   你生出最佳编码的机器码。这里的n是一个可有可无的小整数,不同版本的gcc   ,n的意义与其正确的功效都不一样,不过,典型的□围是从0(不要鸡婆,我不   要最佳编码。)变化到2(最佳编码要多一点。),再升级到3(最佳编码要再多   一点,多一点)。      gcc在其内部会将这些数字转译成一系列的-f与-m的选项。执行gcc时带上旗号-v   与-Q,你就能很清楚的看出每一种等级的-O是对应到那些选项。好比说,就-O2来   讲,我的gcc告诉会我说:   enabled: -fdefer-pop -fcse-follow-jumps -fcse-skip-blocks-fexpensive-optimizations         -fthread-jumps -fpeephole -fforce-mem -ffunction-cse -finline         -fcaller-saves -fpcc-struct-return -frerun-cse-after-loop         -fcommon -fgnu-linker -m80387 -mhard-float -mno-soft-float         -mno-386 -m486 -mieee-fp -mfp-ret-in-387   要是你用的最佳编码等级高於你的编译器所能支援的(e.g. -O6),那麽它的效   果就跟你用你的编译器所能提供的最高等级的效果是一样的。说实在的,发行出   去的gcc程式码,用在编译时竟是如此处理这等问题,真的不是什麽好的构想。日   後若是有更进步的最佳编码方法具体整合到新的版本里,而你(或是你的users)   还是试著这样做的话,可能就会发现gcc会中断你的程式了。      从gcc 2.7.0升级到2.7.2的users应该注意一点,使用-O2时会有一个bug。更糟糕   的是,强度折减参数(strength reduction)居然没有用!要是你喜欢重新编   译gcc的话,是有那麽一个修正的版本可以更正这项错误;不然的话,一定要确定   每次编译时都有加上-fno-strength-reduce喔!      11/12/97译     有个性的微处理器     有一些-m的旗号十分有用处,但是却无法藉由各种等级的-O打开来使用。这之中   最重要的有是-m386和-m486这两种,用来告诉gcc该把正在编译的程式码视作专   为386或是486机器所写的。不论是用哪一种-m来编译程式码,都可以在彼此的机   器上执行,-m486编译出来的码会比较大,不过拿来在386的机器上跑也不会比较   慢就是了。      目前尚无-mpentium或是-m586的旗号。Linus建议我们可以用-m486   -malign-loops=2 -malign-jumps=2 -malign-functions=2来得到最佳编码的486   程式码,这样做正好就可以避免alignment(Pentium并不需要)有过大的gaps发   生。Michael Meissner说:        我的第六感告诉我,-mno-strength-reduce(嘿!要晓得我可不是在谈强度折     减参数的bug呀,那已经是另外一个争论的战场了。)一样也可以在x86的机器     上产生较快的程式码,这是因为x86的机器对暂存器有著不可磨灭的□渴在,     而且GCC's method of grouping registers into spill registers vs.     other registers doesn't help either。传统上,强度折减的结果会使得编     译器去利用加法暂存器以加法运算来取代乘法运算。事实上,我在怀     疑-fcaller-saves可能也只是个漏洞也说不定。          而我的第七感则再度的告诉我说,-fomit-frame-pointer可能会也可能不会有     任何的赚头。从这点来看,就是意谓著有另一个暂存器可以用来处理记忆体分     配的问题。另方面,若纯粹从x86的机器在转换它的指令集成为机器码的方法     上来看,便意谓著堆叠所用到的记忆体空间要比frame所用到的还要来得多;     换句话说,Icache对程式码而言并没有实质上的帮助,若是阁下用     了-fomit-frame-pointer的话,同时也是告诉编译器在每次呼叫函数之後,就     必须修正堆叠的指标;然而,就frame来讲,若呼叫的次数不多的话,则允许     堆叠暂时堆积起来。        有关这方面主题的最後一段话仍是来自於Linus:        要注意的是,如果你想要得到最佳状况的执行效能,可千万别相信我的话。无     论如何,一定要进行测试。gcc编译器还有许多的参数可用,其中可能就有一     种最特别的组合,可以给你最佳编码的结果。        11/14/97译 5/15/98修正   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -