编译器局限
简介
交叉编译工具链是一个由编译器、连接器和解释器组成的综合开发环境,交叉编译工具链主要由binutils、gcc和glibc 3个部分组成。有时出于减小libc库大小的考虑,也可以用别的c库来代替glibc,例如uClibc、dietlibc和newlib。交叉编译工具链主要包括针对目标系统的编译器gcc、目标系统的二进制工具binutils、目标系统的标准c库glibc和目标系统的Linux内核头文件。第一个步骤就是确定目标平台。每个目标平台都有一个明确的格式,这些信息用于在构建过程中识别要使用的不同工具的正确版本。因此,当在一个特定目标机下运行GCC时,GCC便在目录路径中查找包含该目标规范的应用程序路径。GNU的目标规范格式为CPU-PLATFORM-OS。例如,建立基于ARM平台的交叉工具链,目标平台名为arm-linux-gnu。
交叉编译工具链的制作方法
分步编译和安装交叉编译工具链所需要的库和源代码,最终生成交叉编译工具链。
通过Crosstool脚本工具来实现一次编译生成交叉编译工具链。
直接通过网上(ftp.arm.kernel.org.uk)下载已经制作好的交叉编译工具链。
方法1相对比较困难,适合想深入学习构建交叉工具链的读者。如果只是想使用交叉工具链,建议使用方法2或方法3构建交叉工具链。方法3的优点不用多说,当然是简单省事,但与此同时该方法有一定的弊端就是局限性太大,因为毕竟是别人构建好的,也就是固定的没有灵活性,所以构建所用的库以及编译器的版本也许并不适合你要编译的程序,同时也许会在使用时出现许多莫名的错误,建议你慎用此方法。
方法1:分步构建交叉编译工具链
下载所需的源代码包
建立工作目录
建立环境变量
编译、安装Binutils
获取内核头文件
编译gcc的辅助编译器
编译生成glibc库
编译生成完整的gcc
由于在问答中的篇幅,我不能细述具体的步骤,兴趣的同学请自行阅读开源共创协议的《Linux from scratch》,网址是:linuxfromscratch dot org
。
方法2:用Crosstool工具构建交叉工具链(推荐)
Crosstool是一组脚本工具集,可构建和测试不同版本的gcc和glibc,用于那些支持glibc的体系结构。它也是一个开源项目,下载地址是kegel dot com/crosstool。用Crosstool构建交叉工具链要比上述的分步编译容易得多,并且也方便许多,对于仅仅为了工作需要构建交叉编译工具链的你,建议使用此方法。
运行which makeinfo,如果不能找见该命令,在解压texinfo-4.11.tar.bz2,进入texinfo-4.11目录,执行./configure&&make&&make install完成makeinfo工具的安装
准备文件:
下载所需资源文件linux-2.4.20.tar.gz、binutils-2.19.tar.bz2、gcc-3.3.6.tar.gz、glibc- 2.3.2.tar.gz、glibc-linuxthreads-2.3.2.tar.gz和gdb-6.5.tar.bz2。然后将这些工具包文件放在新建的$HOME/downloads目录下,最后在$HOME/目录下解压crosstool-0.43.tar.gz,命
令如下:
#cd$HOME/
#tar–xvzfcrosstool-0.43.tar.gz
建立脚本文件
接着需要建立自己的编译脚本,起名为arm.sh,为了简化编写arm.sh,寻找一个最接近的脚本文件demo-arm.sh作为模板,然后将该脚本的内容复制到arm.sh,修改arm.sh脚本,具体操作如下:
# cd crosstool-0.43
# cp demo-arm.sh arm.sh
# vi arm.sh
修改后的arm.sh脚本内容如下:
#!/bin/sh
set-ex
TARBALLS_DIR=$HOME/downloads#定义工具链源码所存放位置。
RESULT_TOP=$HOME/arm-bin#定义工具链的安装目录
exportTARBALLS_DIRRESULT_TOP
GCC_LANGUAGES="c,c++"#定义支持C,C++语言
exportGCC_LANGUAGES
#创建/opt/crosstool目录
mkdir-p$RESULT_TOP
#编译工具链,该过程需要数小时完成。
eval'catarm.datgcc-3.3.6-glibc-2.3.2.dat'shall.sh--notest
echoDone.
建立配置文件
在arm.sh脚本文件中需要注意arm-xscale.dat和gcc-3.3.6-glibc-2.3.2.dat两个文件,这两个文件是作为Crosstool的编译的配置文件。其中arm.dat文件内容如下,主要用于定义配置文件、定义生成编译工具链的名称以及定义编译选项等。
KERNELCONFIG='pwd'/arm.config#内核的配置
TARGET=arm-linux#编译生成的工具链名称
TARGET_CFLAGS="-O"#编译选项
gcc-3.3.6-glibc-2.3.2.dat文件内容如下,该文件主要定义编译过程中所需要的库以及它定义的版本,如果在编译过程中发现有些库不存在时,Crosstool会自动在相关网站上下载,该工具在这点上相对比较智能,也非常有用。
BINUTILS_DIR=binutils-2.19
GCC_DIR=gcc-3.3.6
GLIBC_DIR=glibc-2.3.2
LINUX_DIR=linux-2.6.10-8(根据实际情况填写)
GDB_DIR=gdb-6.5
执行脚本
将Crosstool的脚本文件和配置文件准备好之后,开始执行arm.sh脚本来编译交叉编译工具。具体执行命令如下:
#cdcrosstool-0.43
#./arm.sh
经过数小时的漫长编译之后,会在/opt/crosstool目录下生成新的交叉编译工具,其中包括以下内容:
arm-linux-addr2linearm-linux-g++arm-linux-ldarm-linux-size
arm-linux-ararm-linux-gccarm-linux-nmarm-linux-strings
arm-linux-asarm-linux-gcc-3.3.6arm-linux-objarm-linux-strip
arm-linux-c++arm-linux-gccbugarm-linux-objmpfix-embedded-paths
arm-linux-c++filtarm-linux-gcovarm-linux-ranlib
arm-linux-cpparm-linux-gprofarm-linux-readelf
添加环境变量
然后将生成的编译工具链路径添加到环境变量PATH上去,添加的方法是在系统/etc/ bashrc文件的最后添加下面一行,在bashrc文件中添加环境变量
export PATH=/home/jiabing/gcc-3.3.6-glibc-2.3.2/arm-linux-bin/bin:$PATH
至此,arm-linux下的交叉编译工具链已经完成,现在就可以使用arm-linux-gcc来生成试验箱上的程序了!
Ⅱ 编译器本身是如何进行测试的
编译器最重要的性质就是保证语义的正确。比如,从高级语言翻译到机器指令之后,指令必须正确的表达原来程序的意思。所以一般编译器测试都包含一些源程序,用来覆盖可能出现的各种情况。基本的原则是:原来程序的结果 = 编译后机器指令运行的结果。机器指令运行的结果很容易知道,运行一下就知道了。可是原来程序的结果你怎么知道呢?
为了解决这个“原来程序语义”的问题,最好是写一个解释器,准确无误的表达原来的代码的语义。所以我们的要求就是:
高级语言解释器(源程序) = 机器执行(机器代码)
由于处理器其实就是一个用来执行机器代码的解释器,这里有一个很美好的对称关系:
interp1(L1) = interp2(L2)
另外还有一个问题,就是编译器一般需要经过多个转化步骤(叫做 pass)才能最后编译为机器指令。比如,
L2 = pass1(source)
L3 = pass2(L2)
L4 = pass3(L3)
Ln = passN(Ln-1)
machine_code = codegen(Ln)
由于源程序经过了很多步骤猜得到最后的机器指令,如果你使用上面的公式,就会出现以下一些情况:
1. 知道结果错了,但是却不知道到底是哪一个 pass 错了。
2. 结果没有错,但是中间却有 pass 实际上是错的。但是由于之前的 pass 把输入程序的一些结构给“优化”掉了,所以错的那个 pass 其实没能得到触发错误的那个数据结构。所以测试没能发现错误。如果以后前面的那个 pass 被修改,错误就会暴露出来。这是非常难以发现的潜伏的危险。
为了防止这些情况出现,一些编译器(比如 Chez Scheme 和 Kent Dybvig 的课程编译器)使用了对每一个 pass 进行测试的做法。具体的方法就是为每一个中间语言都写一个解释器,把这语言的语义完全的表示出来。这样我们就需要检查一组等式:
L2 = pass1(source)
高级语言编译器(源程序) = interp2(L2) // 测试 pass1 的正确性
L3 = pass2(L2)
interp2(L2) = interp3(L3) // 测试 pass2 的正确性
这样一来我们就能独立的判断每一个 pass 的正确性了。
这些是基本的语义测试原理。另外除了语义,可能还有一些“表面”一些的测试,它们看代码本身,而不只看它的语义。比如尾递归优化的测试应该确保输出程序的尾递归得到正确的处理,等等。这些是语义测试检查不到的,因为尾递归没有正确处理的程序大部分也能输出正确的结果。
普通的单元测试方法也可以用来测试一些编译器里的辅助函数,但那些不是编译器特有的,所以就不讲了。
另外,就像所有测试的局限性一样,你没法枚举所有可能出现的输入,所以以上的测试方法其实也不能保证编译器的完全正确。
Ⅲ 编译器优化方法和局限性有什么_ 急!
Ⅳ 既然大部分语言都具有移植性,为什么现在的应用程序依然有很大的平台局限性
比较上层的语言(通常是脚本语言)不太受系统环境的影响,这也就是为什么同一款浏览器插件可以在不同系统的浏览器上运行的原因。
相反,比较底层的语言(C,汇编语言等)受制于硬件接口,如果你认真学习过硬件方面的知识的话你就会知道不同的系统对同一个硬件IO的命令是不一样的,而这个不一样不只是二进制机器语言上的不同,而是源代码就有很大的区别。例如UNIX环境下网络编程使用套接字通常调用<sys/socket.h>下的函数,而windows环境下根本没有这个头文件。 如果一款底层编写的程序不需要任何处理就可以移植到另一个平台上,那么说明它几乎没有怎么使用高级硬件IO,也就是说它基本没什么用。。。。
Ⅳ java这门语言编程时有哪些限制或局限
Java语言局限性及其解决对策
2.1 执行速度慢
事实上,Java比c语言写的程序执行起来慢很多。执行慢的原因主要是在主机操作系统上加了虚拟机层,比本地编译码慢。
解决的方法主要有:
(1)“及时(Just in Time, JIT)编译器”
(2)研究新的编译理论和技术
(3)使用JavaStation及JavaOS
(4)采用Java芯片
将Java做成芯片,用来解释Java语句,把Java语句作为一条指令来执行,加快Java语言编写程序的执行。Java芯片可直接执行Java字节码。
2.2 Java标准问题
目前还没有Java系列国际标准。有关Java的核心技术:Java虚拟机、Java语法、Java类库和Java应用程序接口(API)等。这些都变成国际标准还需要一段时间。
Java在实现跨平台性和可移植性的同时,自己也渐渐走上了Unix发展的老路。这样发展下去是很危险的。
解决的方法主要有:
(1)尽快制定出Java国际标准;
(2)Sun公司提出了100%纯Java倡议,这是纯化Java的良好开端。
2.3 安全性问题
Java已实现了几种安全性机制。但还存在的问题:对applets有许多限制。
Java现有的安全模型并不完善,有些开发人员能生成嵌入Web的Java小程序,即不友好的小程序。这种程序可能给Web用户带来麻烦。
安全性问题需要进一步的研究,包括提出新的Java安全模型。
2.4 已有软件产品的充分利用
如果程序必须与遗留下来的老代码和数据打交道,则传统的工具或语言能工作得更好。
Java语言提供了本地方法调用,可调用其它语言编写的程序。但这样系统就不能保证运行在其它Java平台上。要能运行在任何Java平台上,就要求100%的纯Java。
Sun公司提出了100%纯Java倡议,要求满足下列所有条件:100%用Java编程,没有本地方法调用,遵守Java核心API规范,通过100%纯Java测试。
解决的方法主要有:
(1)将C, C++等语言直接编译成Java的字节码。美国已将Ada语言编译成了Java字节码。
(2) IBM正在研制的通用虚拟机(UVM),它允许开发人员使用Java,Basic和Smalltalk等语言,建立各种与平台无关的软件。UVM的设计目标是翻译Smalltalk、Basic和Java编码。
2.5 Java语言的基本类库简单
与微软(Microsoft)的基本类库相比,Java语言的基本类库简单。
解决的方法主要有: Java语言基本类库的扩充。
2.6 跨平台问题
跨平台是Java语言最大的优点。但保证跨平台兼容性的条件下,Java不能全部使用本机操作系统具有的各种功能。
由于一种操作系统特有的功能和特征并不能准确的转移到另一种操作系统上,因此Java的跨平台适配性也许是不可能实现的。
从理论上讲,可以创建一个能在任何处理器和操作系统上运行的Java虚拟机,但不同的处理器和操作系统支持的功能不同,所有这些差异要靠Java虚拟机来解决。
跨平台计算的实现较之于单平台来说成本高,难度大,而且为此必须开发能够运行于多种硬件平台和软件平台的应用程序。
2.7 软件开发费用问题
软件开发商对另外的语言也许有更好的工具,使用熟悉的工具或语言有更高的生产率。
如果要另外花钱和增加客户负担,软件开发商也许不愿意改变。
2.8 广泛的应用实例
用一种语言满足所有用户的需求,是很难地,也不大可能。Java语言还很年轻,不够稳定和成熟。
这还要经过实际应用的检验。
3 结束语
本文分析了Java语言存在的问题,目前解决这些问题的研究方法。这些为Java语言的进一步研究提供了参考,为广大用户选择Java语言作为开发工具提出了可能遇到的问题。
总之,随着计算机网络的广泛普及,越来越多的用户进入Internet,Java计算模式会是一种非常重要的计算模式,Java语言的研究和应用,也会变得更加深入和广泛。
Ⅵ c语言编程在功能上有哪些局限性
环境就是你用来进行编程的编程平台,最简单的环境就是TXT文本文件了(不过这个不支持编译,一般的编译环境是支持编译的)。就C语言系列来说,主流的编译环境有C-FREE系列、VC系列、VS(Visual Studio)系列 Emacs是一种强大的文本编辑器,在程序员和其他以技术工作为主的计算机用户中广受欢迎。EMACS,即Editor MACroS(编辑器宏)的缩写,最初由Richard Stallman(理乍得·马修·斯托曼)于1975年在MIT协同Guy Steele共同完成。这一创意的灵感来源于TECMAC和TMACS,它们是由Guy Steele、Dave Moon、Richard Greenblatt、Charles Frankston等人编写的宏文本编辑器。 Visual C++ 6.0,简称VC或者VC6.0,是微软推出的一款C++编译器,将“高级语言”翻译为“机器语言(低级语言)”的程序。Visual C++是一个功能强大的可视化软件开发工具。自1993年Microsoft公司推出Visual C++1.0后,随着其新版本的不断问世,Visual C++已成为专业程序员进行软件开发的首选工具。虽然微软公司推出了 Visual C++.NET(Visual C++7.0),但它的应用有很大的局限性,只适用于Windows 2000、Windows XP和Windows NT4.0。所以实际中,更多的是以Visual C++6.0为平台。
Ⅶ 用dev-c++编译器对C语言程序进行编译有什么局限性
首先,Dev-C++不是编译器,仅仅是编译环境。
其次,Dev-C++用的编译器是在Windows环境下模拟Linux G++的MinGW,据说G++是完全标准的C++编译器。
但模拟后因为系统不完全兼容,编译出的结果在Windows环境下不如VC++编译结果快。写C的话,因为是C++兼容C,速度达不到最优。如果对程序结果质量有高要求的话,建议换Turbo C这款经典的C编译器。(用C++编译器影响不大,基本上1000000以内语句执行次数,或者说1000行代码以内看不出明显区别)
Ⅷ 解释器与编译器的区别
编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快;而解释器则是只在执行程序时,才一条一条的解释成机器语言给计算机来执行,所以运行速度是不如编译后的程序运行的快的.这是因为计算机不能直接认识并执行我们写的语句,它只能认识机器语言(是二进制的形式)
Ⅸ 【编译器】有宁愿用VC++6.0也不用codeblocks的吗为什么
Code::Blocks 是一个开放源码的全功能的跨平台C/C++集成开发环境。 Code::Blocks是开放源码软件。Code::Blocks由纯粹的C++语言开发完成,它使用了蓍名的图形界面库wxWidgets(2.6.2 unicode)版。对于追求完美的C++程序员,再也不必忍受Eclipse的缓慢,再也不必忍受VS.NET的庞大和高昂的价格。 Visual C++ 6.0,简称VC或者VC6.0,是微软推出的一款C++编译器,将“高级语言”翻译为“机器语言(低级语言)”的程序。Visual C++是一个功能强大的可视化软件开发工具。自1993年Microsoft公司推出Visual C++1.0后,随着其新版本的不断问世,Visual C++已成为专业程序员进行软件开发的首选工具。虽然微软公司推出了 Visual C++.NET(Visual C++7.0),但它的应用有很大的局限性,只适用于Windows 2000、Windows XP和Windows NT4.0。所以实际中,更多的是以Visual C++6.0为平台。
Ⅹ 我的机器上面没有java或者c的编译器,能否远程编程
我想你要的是这个。
http://events.csdn.net/solaris/unix-center/
这里有很多机器你可以用终端连上去,里面有自带的C/C++/Java等编译器,但是这样受到的局限很大,毕竟没有在本机上来得方便,如果是网站我想应该是没有的,因为浏览器的负载很有限,根本达不到那种效率。其实现在一般的机器装个JDK、VC完全没问题,为什么要如此麻烦。