交叉编译时间一般多久
㈠ cmake使用的编译器和交叉编译时候的一致么
一致的
下载cmake 然后解压缩,进入解压缩后的目录,依次执行
# ./bootstrap
# make && make install
安装过程需要几分钟。
二 构建交叉编译的CMakeLists.txt
说明:
设置交叉编译之前,必须在CMakeList.txt前面加上这样一句,这样CMake才会认为你是要交叉编译:
SET(CMAKE_SYSTEM_NAME linux)
在通知CMake要交叉编译以后,还要告诉CMake到哪个路径下去找库文件,因为在交叉编译的时候CMake是不会自动去系统默认的目录找库文件和头文件的:
SET(CMAKE_FIND_ROOT_PATH "编译器环境路径")
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
其中猜早的第一行,是告诉CMake查找的根目录是什么。后面分别是告诉CMake怎么查找编译时候的工具程序的位置、库的位置和头文件的位置。设置为NEVER表示不查找,设置为ONLY表示只在CMAKE_FIND_ROOT_PATH设定的目录下查找,设置为BOTH(这是默认选项)表示既可以在宽雹系统目录下查找,也可以在CMAKE_FIND_ROOT_PATH下查找。因为咱们是交叉编译,所以后两项的设置了ONLY,对于编译时调用工具,一般来说是需要在系统目录下查找的,不过我不需要所以设慎兆帆置为NEVER。
然后,设置编译器:
SET(CMAKE_C_COMPILER "编译器环境路径"
直接把编译器的路径设置过去就可以了,CMAKE_C_COMPILER是C语言编译器,CMAKE_CXX_COMPILE是C++语言编译器。
㈡ 北大青鸟设计培训:怎样才能提高python运行效率
python逐渐走入人们的视线,成为热门编程语言,随之而来,加入python培训的准程序员大军也成为社会热点。
Python具有许多其他编程语言不具备的优势,譬如能通过极少量代码完成许多操作,以及多进程,能够轻松支持多任务处理。
除了多种优势外,python也有不好的地方,运行较慢,下面电脑培训http://www.kmbdqn.cn/为大家介绍6个窍门,可以帮你提高python的运行效率。
1.在排序时使用键Python含有许多古老的排序规则,这些规则在你创建定制的排序方法时会占用很多时间,而这些排序方法运行时也会拖延程序实际的运行速度。
最佳的排序方法其实是尽可能多地使用键和内置的sort()方法。
2.交叉编译你的应用开发者有时会忘记计算机其实并不理解用来创建现代应用程序的编程语言。
计算机理解的是机器语言。
为了运行你的应用,你借助一个应用将你所编的人类可读的代码转换成机器可读的代码。
有时,你用一种诸如Python这样的语言编写应用,再以C++这样的语言运行你的应用,这在运行的角度来说,是可行的。
关键在于,你想你的应用完成什么事情,而你的主机系统能提供什么样的资源。
3.关键代码使用外部功能包Python简化了许多编程任务,但是对于一些时间敏感的任务,它的表现经常不尽人意。
使用C/C++或机器语言的外部功能包处理时间敏感任务,可以有效提高应用的运行效率。
这些功能包往往依附于特定的平台,因此你要根据自己所用的平台选择合适的功能包。
简而言之,这个窍门要你牺牲应用的可移植性以换取只有通过对底层主机的直接编程才能获得的运行效率。
4.针对循环的优化每一种编程语言都强调最优化的循环方案。
当使用Python时,你可以借助丰富的技巧让循环程序跑得更快。
然而,开发者们经常遗忘的一个技巧是:尽量避免在循环中访问变量的属性。
5.尝试多种编码方法每次创建应用时都使用同一种编码方法几乎无一例外会导致应用的运行效率不尽人意。
可以在程序分析时尝试一些试验性的办法。
譬如说,在处理字典中的数据项时,你既可以使用安全的方法,先确保数据项已经存在再进行更新,也可以直接对数据项进行更新,把不存在的数据项作为特例分开处理。
6.使用较新的Python版本你要保证自己的代码在新版本里还能运行。
你需要使用新的函数库才能体验新的Python版本,然后你需要在做出关键性的改动时检查自己的应用。
只有当你完成必要的修正之后,你才能体会新版本的不同。
㈢ 什么是交叉编译,为什么要采用交叉编译
在一个平台架构上,编译另一个平台架构的可执行代码,就是交叉编译。
例如在x86架构的PC上编译arm嵌入式设备的可执行程序。
交叉编译是不得不用,
首先在目标设备的系统还没引导起来的时候,编译目标平台的引导程序,显然只能交叉编译。
还有因为目标设备往往能力太低,没法安装编译器,或者勉强安装了,也慢得像蜗牛。
㈣ 什么是交叉编译,为什么要使用交叉编译
交叉编译的概念(来自网络):
简单地说,就是在一个平台上生成另一个平台上的可执行代码。同一个体系结构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系结构上运行。举例来说,我们常说的x86 Linux平台实际上是Intel x86体系结构和Linux for x86操作系统的统称;而x86 WinNT平台实际上是Intel x86体系结构和Windows NT for x86操作系统的简称。
举个例子:
我们在Linux系统比如Ubuntu上编写的C程序完全可以拿到Windows系统上正常运行。
㈤ 如何编译Android的kernel
1.准备工作: (ubuntu1110 32位)
ubuntu等linuxOS,下载好eclipse,安装好JDK, 安装好android的SDK, 在eclipse中成功打开android 手机模拟器即OK。
2.初始化编译环境 :
关注该网页上的“installing required packages”,其中有的软件包因为版本问题而安装不上,不用管它,之后遇到错误再单独解决。
3.下载内核源码:
android 2.3 内核 下载需要等待一段时间。
4.下载交叉编译器:
该步骤有可能耗费大量时间,依据网速不同,几个小时到几天不等,或许可以尝试git clone 后面的地址只下载prebuilt/linux-x86/toolchain
5.设置参数以及编译:
$ export ARCH=arm
$ export SUBARCH=arm
$ export CROSS_COMPILE=arm-eabi-
$ cd goldfish // 进入下载的源代码目录
$ git checkout <commit_from_first_step> //这个步骤我没有做,不知道干嘛用的
$ make goldfish_defconfig
$ make
6.报错信息:
若有报错说找不到 (arm-eabi-gcc command not found)等等,尝试使用采用另外一个交叉编译器。
7.测试:
最后,测试一下刚才编译的内核:emulator -avd myavd -kernel ~/goldfish/arch/arm/boot/zImageemulator若系统找不到,可以去android SDK中某文件夹找到,加入系统PATH即可。 -avd后面的参数 myavd即为模拟器的名字,这个我是在eclipse中的模拟器管理中新建的一个模拟器,用那个模拟器的名字即可。 -kernel后面的参数就找到刚才编译出的内核的路径。
若启动模拟器失败,可尝试关闭后再启动。第一次启动模拟器时可能需要等待比较长的时间。
㈥ 如何使用Docker构建运行时间较长的脚本
问题
让我们从这个我试图解决的问题开始。我开发了一个会运行很长时间的构建脚本,这个脚本中包含了很多的步骤。
这个脚本会运行1-2个小时。
它会从网络下载比较大的文件(超过300M)。
后面的构建步骤依赖前期构建的库。
但最最烦人的是,运行这个脚本真的需要花很长的时间。
文件系统是固有状态
我们一般是通过一种有状态的方式与文件系统进行交互的。我们可以添加、删除或移动文件。我们可以修改文件的 权限或者它的访问时间。大部分独立的操作都可以撤销,例如将文件移动到其它地方后,你可以将文件恢复到原来的位置。但我们不会通过快照的方式来将它恢复到 原始状态。这篇文章我将会介绍如何在耗时较长的脚本中充分利用快照这一特性。
使用联合文件系统的快照
Docker使用的是联合文件系统叫做AUFS(译者注:简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统)。联合文件系统实现了Union mount。顾名思义,也就是说不同的文件系统的文件和目录可以分层叠加在单个连贯文件系统之上。这是通过分层的方式完成的。如果一个文件出现在两个文件系统,那最高层级的文件才会显示(该文件其它版本也是存在于层级中的,不会改变,只是看不到的)。
在Docker中,每一个在Union mount转哦给你的文件系统都被称为layers(层)。使用这种技术可以轻松实现快照,每个快照都是所有层的一个Union mount。
生成脚本的快照
使用快照可以帮助构建一个长时运行的脚本。总的想法是,将一个大的脚本分解为许多小的脚本(我喜欢称之为 scriptlets),并单独运行这些小的脚本,脚本运行后为其文件系统打一个快照 (Docker会自动执行此操作)。如果你发现一个scriptlet运行失败,你可以快速回退到上次的快照,然后再试一次。一旦你完成脚本的构建,并且 可以保证脚本能正常工作,那你就可以将它分配给其它主机。
回过头来再对比下,如果你没有使用快照功能了?当你辛辛苦苦等待了一个半小时后,脚本却构建失败了,我想除了少部分有耐心的人外,很多人是不想再来一次了,当然,你也会尽最大努力把系统恢复到失败前的状态,比如可以删除一个目录或运行make clean。
但是,我们可能没有真正地理解我们正在构建的组件。它可能有复杂的Makefile,它会把把文件放到文件系统中我们不知道的地方,唯一真正确定的途径是恢复到快照。
使用快照构建脚本的Docker
在本节中,我将介绍我是如何使用Docker实现GHC7.8.3 ARM交叉编译器的构建脚本。Docker非常适合做这件事,但并非完美。我做了很多看起来没用的或者不雅的事情,但都是必要的,这都是为了保证将开发脚本的总时间降到最低限度。构建脚本可以在这里找到。
用Dockerfile构建
Docker通过读取Dockerfile来构建镜像。Dockerfile会通过一些命令来具体指定应该执行哪些动作。具体使用说明可以参考这篇文章。在我的脚本中主要用到WORKDIR、ADD和RUN。ADD命令非常有用因为它可以让你在运行之前将外部文件添加到当前Docker镜像中然后转换成镜像的文件系统。你可以在这里看到很多scriptlets构成的构建脚本。
设计
1. 在RUN之前ADD scriptlets
如果你很早就将所有的scriptletsADD在Dockerfile,您可能会遇到以下问题:如果你的脚本构建失败,你回去修改scriptlet并再次运行docker build。但是你发现,Docker开始在首次加入scriptlets的地方构建!这样做会浪费了大量的时间并且违背了使用快照的目的。
出现这种情况的原因是由于Docker处理它的中间镜像(快照)的方式。当Docker通过Dockerfile构建镜像时,它会与中间镜像比较当前命令是否一致。然而,在ADD命令的情况下被装进镜像的文件里的内容也会被检查。如果相对于现有的中间镜像,文件已经改变,那么Docker也别无选择,只能从这点开始建立一个新的镜像。因为Docker不知道这些变化会不会影响到构建。
此外,使用RUN命令要注意,每次运行时它都会导致文件系统有不同的更改。在这种情况下,Docker会发现中间镜像并使用它,但是这将是错误的。RUN命令每次运行时会造成文件系统相同的改变。举个例子,我确保在我的scriptlets我总是下载了一个已知版本的文件与一个特定MD5校验。
对Docker 构建缓存更详细的解释可以在这里找到。
2.不要使用ENV命令来设置环境变量,请使用scriptlet。
它似乎看起来很有诱惑力:使用ENV命令来设置所有构建脚本需要的环境变量。但是,它不支持变量替换的方式,例如 ENV BASE=$HOME/base 将设置BASE的值为$HOME/base着很可能不是你想要的。
相反,我用ADD命令添加一个名为set-env.sh文件。此文件会包含在后续的scriptlet中:
THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $THIS_DIR/set-env-1.sh
如果你没有在第一时间获取set-env.sh会怎么样呢?它很早就被加入Dockerfile并不意味着修改它将会使随后的快照无效?
是的,这会有问题。在开发脚本时,我发现,我已经错过了在set-env.sh添加一个有用的环境变量。解决方案是创建一个新的文件set-env-1.sh包含:
THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $THIS_DIR/set-env.sh
if ! [ -e "$CONFIG_SUB_SRC/config.sub" ] ; then
CONFIG_SUB_SRC=${CONFIG_SUB_SRC:-$NCURSES_SRC}
fi
然后,在所有后续的scriptlets文件中包含了此文件。现在,我已经完成了构建脚本,我可以回去解决这个问题了,但是,在某种意义上,它会破坏最初的目标。我将不得不从头开始运行构建脚本看看这种变化是否能成功。
缺点
一个主要缺点是这种方法是,所构建的镜像尺寸是大于它实际需求的尺寸。在我的情况下尤其如此,因为我在最后删除了大量文件的。然而,这些文件都仍然存在于联合挂载文件系统的底层文件系统内,所以整个镜像是大于它实际需要的大小至少多余的是删除文件的大小。
然而,有一个变通。我没有公布此镜像到Docker Hub Registry。相反,我:
使用docker export导出内容为tar文件。
创建一个新的Dockerfile简单地添加了这个tar文件的内容。
产生尺寸尽可能小的镜像。
结论
这种方法的优点是双重的:
它使开发时间降至最低,不再做那些已经构建成功的子组件。你可以专注于那些失败的组件。
这非常便于维护构建脚本。构建可能会失败,但只要你搞定Dockerfiel,至少你不必再从头开始。
此外,正如我前面提到的Docker不仅使写这些构建脚本更加容易,有了合适的工具同样可以在任何提供快照的文件系统实现。
㈦ 如何使用CMake进行交叉编译
cmake交叉编译配置
很多时候,我们在开发的时候是面对嵌入式平台,因此由于资源的限制需要用到相关的交叉编译。即在你host宿主机上要生成target目标机的程序。里面牵扯到相关头文件的切换和编译器的选择以及环境变量的改变等,我今天仅仅简单介绍下相关CMake在面对交叉编译的时候,需要做的一些准备工作。
CMake给交叉编译预留了一个很好的变量CMAKE_TOOLCHAIN_FILE,它定义了一个文件的路径,这个文件即toolChain,里面set了一系列你需要改变的变量和属性,包括C_COMPILER,CXX_COMPILER,如果用Qt的话需要更改QT_QMAKE_EXECUTABLE以及如果用BOOST的话需要更改的BOOST_ROOT(具体查看相关Findxxx.cmake里面指定的路径)。CMake为了不让用户每次交叉编译都要重新输入这些命令,因此它带来toolChain机制,简而言之就是一个cmake脚本,内嵌了你需要改变以及需要set的所有交叉环境的设置。
toolChain脚本中设置的几个重要变量
1.CMAKE_SYSTEM_NAME:
即你目标机target所在的操作系统名称,比如ARM或者Linux你就需要写"Linux",如果Windows平台你就写"Windows",如果你的嵌入式平台没有相关OS你即需要写成"Generic",只有当CMAKE_SYSTEM_NAME这个变量被设置了,CMake才认为此时正在交叉编译,它会额外设置一个变量CMAKE_CROSSCOMPILING为TRUE.
2. CMAKE_C_COMPILER:
顾名思义,即C语言编译器,这里可以将变量设置成完整路径或者文件名,设置成完整路径有一个好处就是CMake会去这个路径下去寻找编译相关的其他工具比如linker,binutils等,如果你写的文件名带有arm-elf等等前缀,CMake会识别到并且去寻找相关的交叉编译器。
3. CMAKE_CXX_COMPILER:
同上,此时代表的是C++编译器。
4. CMAKE_FIND_ROOT_PATH:
指定了一个或者多个优先于其他搜索路径的搜索路径。比如你设置了/opt/arm/,所有的Find_xxx.cmake都会优先根据这个路径下的/usr/lib,/lib等进行查找,然后才会去你自己的/usr/lib和/lib进行查找,如果你有一些库是不被包含在/opt/arm里面的,你也可以显示指定多个值给CMAKE_FIND_ROOT_PATH,比如
set(CMAKE_FIND_ROOT_PATH /opt/arm /opt/inst)
该变量能够有效地重新定位在给定位置下进行搜索的根路径。该变量默认为空。当使用交叉编译时,该变量十分有用:用该变量指向目标环境的根目录,然后CMake将会在那里查找。
5. CMAKE_FIND_ROOT_PATH_MODE_PROGRAM:
对FIND_PROGRAM()起作用,有三种取值,NEVER,ONLY,BOTH,第一个表示不在你CMAKE_FIND_ROOT_PATH下进行查找,第二个表示只在这个路径下查找,第三个表示先查找这个路径,再查找全局路径,对于这个变量来说,一般都是调用宿主机的程序,所以一般都设置成NEVER
6. CMAKE_FIND_ROOT_PATH_MODE_LIBRARY:
对FIND_LIBRARY()起作用,表示在链接的时候的库的相关选项,因此这里需要设置成ONLY来保证我们的库是在交叉环境中找的.
7. CMAKE_FIND_ROOT_PATH_MODE_INCLUDE:
对FIND_PATH()和FIND_FILE()起作用,一般来说也是ONLY,如果你想改变,一般也是在相关的FIND命令中增加option来改变局部设置,有NO_CMAKE_FIND_ROOT_PATH,ONLY_CMAKE_FIND_ROOT_PATH,BOTH_CMAKE_FIND_ROOT_PATH
8. BOOST_ROOT:
对于需要boost库的用户来说,相关的boost库路径配置也需要设置,因此这里的路径即ARM下的boost路径,里面有include和lib。
9. QT_QMAKE_EXECUTABLE:
对于Qt用户来说,需要更改相关的qmake命令切换成嵌入式版本,因此这里需要指定成相应的qmake路径(指定到qmake本身)
toolChain demo
# this is required
SET(CMAKE_SYSTEM_NAME Linux)
# specify the cross compiler
SET(CMAKE_C_COMPILER /opt/arm/usr/bin/ppc_74xx-gcc)
SET(CMAKE_CXX_COMPILER /opt/arm/usr/bin/ppc_74xx-g++)
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH /opt/arm/ppc_74xx /home/rickk/arm_inst)
# search for programs in the build host directories (not necessary)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# configure Boost and Qt
SET(QT_QMAKE_EXECUTABLE /opt/qt-embedded/qmake)
SET(BOOST_ROOT /opt/boost_arm)
这样就完成了相关toolChain的编写,之后,你可以灵活的选择到底采用宿主机版本还是开发机版本,之间的区别仅仅是一条-DCMAKE_TOOLCHAIN_FILE=./toolChain.cmake,更爽的是,如果你有很多程序需要做转移,但目标平台是同一个,你仅仅需要写一份toolChain放在一个地方,就可以给所有工程使用。
㈧ 关于交叉编译工具链的问题
核心转储是崩溃报告的一个过程,他只是把当前崩溃的信息转存出来方便差错。而且这个核心转储几个字也不过是个提示输出信息。这个提示不会给与任何与错误相关的内容,必须看其他的错误信息或者他转储出来的东西来分析。
不过核心转储,应该是程序运行出错而崩溃。这种问题出现在你正在运行的程序,而不是编译过程出现的编译错误(也就是说,出现核心转储应该就是 GCC 或者他调用的程序自己崩溃了)。出现这个问题的原因很多。
如果是因为没有找到某些 header 文件,不应该是核心转储错误,而是编译器或者某个过程提示错误信息后退出,他会输出错误信息告诉你问题所在。
至于你编译的这些东西版本都比较老,我建议还是尝试降级整个系统来编译、运行你现在的这些东西。或者升级你这个交叉编译工具链到当前主流的版本来用。
至于交叉工具连当中的 GCC 和你当前本机的 GCC,完全是两个互相独立的 GCC 。
只是他们编译输出的二进制程序针对的指令集不同而已。相对的 binutils 和 glibc 和 kernel-header 都是一样的意思,针对目标而输出的相关程序。当然 glibc 和 kernel-header 主要是以“数据”方式存在,gcc 和 binutils 主要是以可以运行的程序方式存在(当然不是绝对的,比如 gcc 还会提供几个 lib 相关的内容,不过大部分情况下你可以这么理解更直观了解他们的作用)。
一般说来 GCC 是编译器,binutils 是连接器,glibc 是标准 C 库(主要是连接时,连接器必须有目标的函数库文件,也就是 .so 文件,对应 Windows 是 .dll 文件。连接器把函数调用正确的挂接到对应的函数入口上)。linux header 就是 C 语言常见的 C header 文件和相关的开发数据。一般主要用来编译 glibc ,glibc 作为中间层来提供内核相关调用。当然程序有些时候也会直接调用内核函数,这样这些程序在编译时也需要 kernel 的 header 。
这两套东西一个输出你当前 PC 的程序,一个输出 ARM 的程序。两个 GCC 套装之间不能互相替换。只能自己输出属于自己的程序。
但是这两套程序虽然输出的程序不同,但可以运行的部分,却都是在你的计算机上运行。而且你本机的 GCC 因为可以输出本机的程序。所以你需要用他来输出在你本机运行,但是却输出 ARM 程序的 GCC 套装。
这就好比两个锤子,一个锤子用来打铁,一个锤子用来打锡。用途不同,但这两个锤子都是铁做的。
你作这个交叉编译工具链,就是用你手里已经有的打铁的锤子,打出一个用铁制作的用来打锡的锤子。这个打锡的锤子是不能打铁的,同样这个打铁的锤子是不能用来打锡的。