原交叉編譯詳解一概念篇
1. 為什麼交叉編譯的原生編譯器找不到/usr/include/limits.h
差別只在gcc提供的include-fixed的limits.h的內容
/usr/lib/gcc/i686-pc-linux-gnu/4.4.0-alpha20080926/include-fixed/limits.h
正常的這個文件里有
#ifdef _GCC_NEXT_LIMITS_H
#include_next /* recurse down to the real one */
#endif
有問題的文件里則沒有
2. 緊急求助QT程序交叉編譯
要將我們寫好的程序發布到開發板上,我們需要對Qt/Embedded 重新編譯,與前面在宿主機上編譯類似,步驟如下:
1. Build Qt/Embedded
tar –xzvf qt-embedded-2.3.10-free.tar.gz
mv qt-2.3.10 qt-2.3.10-target
export TMAKEDIR=$PWD/tmake-1.13
export QT2DIR=$PWD/qt-2.3.2
export QTEDIR=$PWD/qt-2.3.10-target
cd $QTEDIR
export TMAKEPATH=$TMAKEDIR/lib/qws/linux-arm-g++
export QTDIR=$QTEDIR
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
make clean
./configure -xplatform linux-arm-g++ -no-xft -no-qvfb -depths 4,8,16,32
make
出現
/public/qt/qt-2.3.10-target/lib/libqte.so: undefined reference to `operator new[](unsigned int)'
/public/qt/qt-2.3.10-target/lib/libqte.so: undefined reference to `operator delete(void*)'
/public/qt/qt-2.3.10-target/lib/libqte.so: undefined reference to `__cxa_pure_virtual'
/public/qt/qt-2.3.10-target/lib/libqte.so: undefined reference to `operator delete[](void*)'
/public/qt/qt-2.3.10-target/lib/libqte.so: undefined reference to `operator new(unsigned int)'
collect2: ld returned 1 exit status
make[4]: *** [t1]
暫時不管它,不影響的。下面的第2步: 「修改tmake 配置文件」 即可解決此類問題。
這步完成後,我們會在/$QTEDIR/lib/目錄下面看到libqte.so libqte.so.2 libqte.so.2.3 libqte.so.2.3.10 這四個文件,我們可以使用file 命令來查看這個庫文件是否是我們需要的在開發板上跑的庫。
file libqte.so.2.3.10
libqte.so.2.3.10: ELF 32-bit LSB shared object, ARM, version 1 (ARM), stripped
有了這個庫以後我們就可以把它拷貝到我們的開發板中相應的庫目錄下面,這里我們選擇了開發板上的/usr/lib 目錄,將/$QTEDIR/lib/下的libqte.so*復制到/usr/lib 目錄下。
首先要建立宿主機和開發板的通訊,假設本機的ip 地址為192.168.0.56 並且/root/share 為共享文件夾。
cp –arf /$QTEDIR/lib/libqte.so* /root/share
啟動minicom
mount –t nfs –o nolock 192.168.0.56:/root/share /mnt/nfs將文件復制到開發板上
cp –arf /mnt/nfs/libqte.so* /usr/lib
本篇文章來源於 黑軟基地-中國最大的黑客軟體安全教程QQ資源下載站! 原文鏈接:http://www.hackvip.com/article/sort0136/sort0186/Hackvip_184143.html
3. Linux嵌入式交叉編譯工具鏈問題 淺談
簡介
交叉編譯工具鏈是一個由編譯器、連接器和解釋器組成的綜合開發環境,交叉編譯工具鏈主要由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來生成試驗箱上的程序了!
4. linux嵌入式中的靜態交叉編譯是什麼意思
應該說是分為靜態和動態的
靜態就是把需要的庫文件也直接編譯進去
動態則是在需要的時候才去調用,本身不編譯進去
5. linux里opencv怎麼交叉編譯
一、交叉編譯opencv 構造: 下載:各個庫的下載可以直接搜名字到官網下載 幾個關鍵解釋: 「--prefix=」 後邊跟make install時的位置,本例中,libz在make install時將安裝到/usr/arm-linux-gnueabihf中 「--host=」 後邊跟arm-linux表明使用的是ARM環境 有configure的才能進行configure配置 4)所有的makefile修改類似 Libz的交叉編譯 第一步:# ./configure --prefix=/usr/arm-linux-gnueabihf --shared 第二步:修改makefile,主要有下邊幾個,修改的時候通篇參照即可 CC=arm-linux-gnueabihf-gcc AR=arm-linux-gnueabihf-ar rc RANLIB=arm-linux-gnueabihf-ranlib STRIP = arm-linux-gnueabihf-strip 如果有ARCH的話,ARCH=ARM 第三步:#sudo make #sudo make install Libjpeg的交叉編譯 第一步:#./configure --host=arm-linux --prefix=/usr/arm-linux-gnueabihf --enable-shared --enable-static CC=arm-linux-gnueabihf-gcc 第二步:參考1)中方法修改makefile 第三步:#sudo make #sudo make install Libpng的交叉編譯 第一步:#./configure --host=arm-linux --prefix=/usr/arm-linux-gnueabihf --enable-shared --enable-static CC=arm-linux-gnueabihf-gcc 第二步:參考1)中方法修改makefile 第三步:#sudo make #sudo make install Yasm的交叉編譯 第一步:#./configure --host=arm-linux --prefix=/usr/arm-linux-gnueabihf --enable-shared --enable-static 第二步:修改makefile 第三步:#sudo make #sudo make install Libx264的交叉編譯 第一步:#CC=arm-linux-gnueabihf-gcc ./configure --enable-shared --host=arm-linux --disable-asm --prefix=/usr/arm-linux-gnueabihf 第二步:修改config.mak里的參數,因為makefile要調用config.mak,所以修改方法同makefile 第三步:#sudo make #sudo make install Libxvid的交叉編譯 第一步:首先切換目錄 #cd build/generic 第二步:#./configure --prefix=/usr/arm-linux-gnueabihf --host=arm-linux --disable-assembly 第三步:#sudo make #sudo make install ffmpeg的交叉編譯 第一步: ./configure --enable-cross-compile --target-os=linux --cc=arm-linux-gnueabihf-gcc --arch=arm --enable-shared --disable-static --enable-gpl --enable-nonfree --enable-ffmpeg --disable-ffplay --enable-ffserver --enable-swscale --enable-pthreads --disable-yasm --disable-stripping --enable-libx264 --enable-libxvid --extra-cflags=-I/usr/arm-linux-gnueabihf/include --extra-ldflags=-L/usr/arm-linux-gnueabihf/lib --prefix=/usr/arm-linux-gnueabihf 第二步:修改makefile文件 第三步:#sudo make #sudo make install 第四步:將ffmpeg加入pkg-config 執行#sudo gedit /etc/bash.bashrc,在末尾加入 export LD_LIBRARY_PATH=/usr/arm-linux-gnueabihf/lib/ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/arm-linux-gnueabihf /lib/pkgconfig export PKG_CONFIG_LIBDIR=$PKG_CONFIG_LIBDIR:/usr/arm-linux-gnueabihf /lib/ 完畢後使用命令:#source /etc/bash.bashrc 或者單獨使用三個export,不過壽命只在一個終端中,終端關閉時就失效。 幾個關鍵解釋:--extra-flags指向xvid的安裝路徑,--extra-ldflags指向x264的路徑 安裝cmake-gui 執行:#sudo apt-get install cmake-qt-gui Opencv的交叉編譯 第一步:修改opencv/platflrms/linux/目錄下的arm-gnueabi.toolchain.cmake,將其所有刪掉,寫入: set( CMAKE_SYSTEM_NAME Linux ) set( CMAKE_SYSTEM_PROCESSOR arm ) set( CMAKE_C_COMPILER arm-linux-gnueabihf-gcc ) set( CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++ ) 第二步:在opencv目錄下新建build目錄,進入build目錄,執行命令: #cmake -DCMAKE_TOOLCHAIN_FILE=../platforms/linux/arm-gnueabi.toolchain.cmake ../ 這時,要保證出現: 第三步:使用cmake-gui打開CMakeCache.txt,去掉所有的無關項,修改CMAKE_INSTALL_PREFIX,來確定make install的目錄 第四步:#sudo make #sudo make install 可能出現的錯誤: opencv編譯不通過,出現skip之類的,說明ffmpeg沒編譯好,或者其編譯好了,但是pkg-config沒有設置好,一定要設置好其環境 前邊幾步不通過的話,看看命令有沒有少,或者有沒有修改好makefile 在arm上使用時,一種方法時直接將編譯好的opencv目錄下的lib文件拷貝到開發板對應的/lib目錄下,其他或者拷貝到自己指定的目錄,並設置好環境變數即可使用
6. 交叉編譯器的原理
編譯是從源代碼(通常為高級語言)到能直接被計算機或虛擬機執行的目標代碼(通常為低階語言或機器語言)的翻譯過程。然而,也存在從低階語言到高階語言的編譯器,這類編譯器中用來從由高階語言生成的低階語言代碼重新生成高階語言代碼的又被叫做反編譯器。也有從一種高階語言生成另一種高階語言的編譯器,或者生成一種需要進一步處理的的中間代碼的編譯器(又叫級聯)。
典型的編譯器輸出是由包含入口點的名字和地址, 以及外部調用(到不在這個目標文件中的函數調用)的機器代碼所組成的目標文件。一組目標文件,不必是同一編譯器產生,但使用的編譯器必需採用同樣的輸出格式,可以鏈接在一起並生成可以由用戶直接執行的可執行程序。
7. GCC能否運行於ARM-Linux環境下即GCC能否在ARM平台上運行
簡答:
gcc可以運行在arm-linux下。
gcc,可以在arm平台上運行。
詳解:
gcc,一般指的是,pc版,x86的平台,
用於嵌入式系統,比如arm的cpu,linux的系統下,是:
本來,一直就可以的,
而且有專門的屬於:
交叉編譯
簡答說就是:
在你的pc端,x86的cpu上,製作出一個交叉編譯器
一般叫做arm-linux-gcc
用此arm-linux-gcc去編譯你的程序
編譯出來的程序,可以運行在嵌入式開發板,比如arm的linux下
極其詳盡的解釋:
我剛寫個教程,你去看就知道了:
交叉編譯詳解
交叉編譯詳解
http://www.crifan.com/files/doc/docbook/cross_compile/release/html/cross_compile.html
此教程的主要內容包括:
了什麼是交叉編譯
為何要有交叉編譯
什麼是工具鏈
什麼是交叉工具鏈
交叉編譯器的名字的命名規則:包括你這里所說的arm-linux-gcc的含義
如何獲得交叉編譯器
製作交叉編譯器的各種工具:簡介了常見的crosstool-ng,buildroot,crosstool等等工具
使用已有的交叉編譯器和自己手動編譯交叉編譯器之間的對比
交叉編譯方面的心得和注意事項
等你看完了後,建議用crosstool-ng,或者是buildroot去自己編譯一個arm-linux的gcc。
8. 如何制定android交叉編譯工具鏈
經常搞嵌入式開發的朋友對於交叉編譯環境應該並不陌生,說白了,就是一組運行在x86 PC機的編譯工具,可以讓你在PC機上編譯出目標平台(例如ARM)可識別的二進制文件。Android平台也提供了這樣的交叉編譯工具鏈,就放在Android的NDK開發包的toolchains目錄下,因此,我們的Makefile文件中,只需給出相應的編譯工具即可。
廢話就先說到這,直接上例子,我們目標是把下面這個math.c文件編譯成一個靜態庫文件:
#include <stdio.h>
int add( int a , int b ) {
return a+b;
}
你需要編寫一個Makefile文件,這里假設你的Android ndk被安裝在 /opt/android/ndk 目錄下,當然,你可以根據自己的實際情況修改Makefile中相關路徑的定義,Makefile文件示例如下:
# Makefile Written by ticktick
# Show how to cross-compile c/c++ code for android platform
.PHONY: clean
NDKROOT=/opt/android/ndk
PLATFORM=$(NDKROOT)/platforms/android-14/arch-arm
CROSS_COMPILE=$(NDKROOT)/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-
CC=$(CROSS_COMPILE)gcc
AR=$(CROSS_COMPILE)ar
LD=$(CROSS_COMPILE)ld
CFLAGS = -I$(PWD) -I$(PLATFORM)/usr/include -Wall -O2 -fPIC -DANDROID -DHAVE_PTHREAD -mfpu=neon -mfloat-abi=softfp
LDFLAGS =
TARGET = libmath.a
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
all: $(OBJS)
$(AR) -rc $(TARGET) $(OBJS)
clean:
rm -f *.o *.a *.so
這里不講Makefile文件的基本原理,只說明一下針對Android環境的Makefile文件編寫的注意事項。
(1) CROSS_COMPILE
必須正確給出Android NDK編譯工具鏈的路徑,當在目錄中執行make命令的時候,編譯系統會根據 CROSS_COMPILE 前綴尋找對應的編譯命令。
(2) -I$(PLATFORM)/usr/include
由於Android平台沒有使用傳統的c語言庫libc,而是自己編寫了一套更加高效更適合嵌入式平台的c語言庫,所以系統頭文件目錄不能再使用默認的路徑,必須直到Android平台的頭文件目錄
(3) -Wall -O2 -fPIC -DANDROID -DHAVE_PTHREAD -mfpu=neon -mfloat-abi=softfp
這些參數的意義網上基本上都有介紹,我就不一一解釋了,並不都是必須添加的,但比較常用。
編譯方法:
寫好makefile文件,並且保存之後,就可以直接在當前目錄下執行make命令,編譯完成後,當前目錄下會生成 libmath.a ,即可直接拿到Android的jni工程中和使用了。