使用交叉混合編譯從原始碼編譯龍芯上的llvm/clang-3.4
目標:
使用交叉混合編譯(hybrid cross-compiling)從原始碼編譯龍芯上的llvm/clang-3.4。之所以是混合交叉編譯而不是交叉編譯,是因為編譯的過程中,大部分程式碼是由效能較高的主體(Host)平臺編譯,而少部分程式碼是由效能較低的目標(Target)平臺編譯。混合交叉編譯採用了類似 COMET: Code Offload by Migrating Execution Transparently (OSDI’12) 的思想。其原理是,在目標平臺上配置,之後開始編譯時,將所有檔案同步到主體平臺上,並使用主體平臺的交叉編譯器編譯。當需要執行目標平臺命令(例如llvm-config
準備工作:
編譯環境:
主體平臺
- CPU:Intel Xeon(R) E5620 * 16
- OS:Ubuntu 14.04 + Linux 3.13.0
- 編譯器:mipsel-linux-gnu-gcc-4.4/mipsel-linux-gnu-g++-4.4
目標平臺
- CPU:loongson 3.2.0-4-loongson-2f, mipsel
- OS:Debian 3.2.51
- 編譯器: gcc-4.6.3/g++-4.6.3
預先準備
$ mkdir <common/path/prefix>/mips3/llvm
$ cp *-3.4 .src.tar.gz <common/path/prefix>/mips3/llvm
$ cd <common/path/prefix>/mips3/llvm
$ tar -xvf *-3.4.src.tar.gz
$ mv clang-3.4 llvm-3.4/tools/clang
$ rm *-3.4.src.tar.gz
以上指令碼同時在兩個平臺上執行。其中<common/path/prefix>
要求兩個平臺上的路徑名稱完全相同,這是因為./configure
後的makefile中包含了使用絕對路徑的變數,因此如果路徑名稱不同,會導致編譯出錯。
3. 建立編譯器符號連結
類似的,在兩個平臺上的編譯器名稱也需要一致。本文中使用mipsel-common-g++為兩者的c++編譯器,mipsel-common-gcc為兩者的c編譯器。在主體平臺上:
$ sudo ln -s /usr/bin/mipsel-common-g++ /usr/bin/mipsel-linux-gnu-g++
$ sudo ln -s /usr/bin/mipsel-common-gcc /usr/bin/mipsel-linux-gnu-gcc
在目標平臺上
$ sudo ln -s /usr/bin/mipsel-common-g++ /usr/bin/g++-4.6
$ sudo ln -s /usr/bin/mipsel-common-gcc /usr/bin/gcc-4.6
- 同步編譯時間
由於不同平臺的時間和時區可能都不同,而編譯時makefile會依賴檔案時間來確定生成檔案的新舊,因此需要同步兩者的系統時間。
- 同步時區
$ sudo dpkg-reconfigure tzdata
之後選擇asia
->Shanghai
,以便兩者平臺的時區一致。
2. 同步時間
只要使得兩個平臺的時間相同即可,本文中利用ntp協議使得目標平臺的時間和主體平臺的時間一致。在目標平臺執行以下程式碼:
$ sudo sntp -s <host-ip>
或者在安裝ntp之後
$ sudo service ntp stop
$ sudo ntpdate -s time.nist.gov
$ sudo service ntp start
- 同步編譯檔案
本文使用rsync同步主體平臺和目標平臺之間的檔案。
- 在主體平臺建立rsync配置檔案(因為主體平臺是同步伺服器)
address = <host-ip>
use chroot = yes
read only = no
pid file = /var/run/rsyncd.pid
log file = /var/log/rsync.log
[mips3]
uid = <host-user-name>
gid = <host-group-name>
path = <common/path/prefix>/mips3
hosts allow = <ip-mask> #例如192.168.0.0/8
auth users = mips3
secrets file = /etc/rsyncd.secrets
其中/etc/rsyncd.secrets
中儲存使用者名稱為mips3的密碼,內容如下
mips3:<host-password>
此外,為了保證rsyncd可以使用,需要將/etc/rsyncd.secrets
的許可權設定為600。
2. 啟動rsyncd:
rsyncd --daemon
- 建立同步命令
rsync-commit
和rsync-update
分別用於將目標平臺上的程式提交到主體平臺上,以及從主體平臺上更新目標平臺上的程式。此外,建立rsync.password
使用者存放密碼,以避免每次同步時輸入密碼。
$ cat <common/path/prefix>/mips3/rsync-commit
#!/bin/bash
rsync --password-file=<common/path/prefix>/mips3/rsync.password -azv <common/path/prefix>/mips3/llvm [email protected]<host-ip>::mips3
$ cat <common/path/prefix>/mips3/rsync-update
#!/bin/bash
rsync --password-file=<common/path/prefix>/mips3/rsync.password -azv [email protected]<host-ip>::mips3/llvm <common/path/prefix>/mips3
$ cat <common/path/prefix>/mips3/rsync.password
<host-password>
編譯
配置
在編譯前,需要在目標平臺上配置編譯環境:
$ cd <common/path/prefix>/mips3/llvm/llvm-3.4
$ CC=mipsel-common-gcc CXX=mipsel-common-g++ ./configure --enable-bindings=none --prefix=`pwd`/root --enable-targets=mips
開始編譯
配置完,即可開始編譯:
$ make
在出現開始編譯某個檔案時,CTRL+C
終止編譯,因為在目標平臺上編譯太慢了。此時執行<common/path/prefix>/mips3/rsync-commit
,將目標平臺上的編譯結果同步到主體平臺上。之後,在主體平臺上
$ make -j<n>
使用主體平臺上numa的並行性編譯。一旦主體平臺上的編譯過程中出現錯誤,立刻切換到目標平臺上
$ <common/path/prefix>/mips3/rsync-update
$ make
... # 開始編譯下一個檔案
CTRL+C
$ <common/path/prefix>/mips3/rsync-commit
來回切換50次以內,即可編譯完成。
優化編譯過程,提高編譯效率
由於頻繁CRTL+C
、切換、同步非常耗時,而且是在不同平臺上的切換(不同的物理機器),因此減少切換次數可以大大提高自動化程度。
- 只配置mips
clang預設會配置所有的目標平臺,而在配置每一種目標平臺時,都要呼叫當前目標平臺上的編譯結果。這也是需要頻繁切換的原因之一。因此在配置時加上--enable-targets=mips
,只配置當前的目標平臺,減少切換次數。 - 使用主體平臺上的編譯結果
clang在編譯可執行檔案和動態共享庫時,會呼叫llvm-config
獲得當前應該連結的靜態庫。這是需要頻繁切換的原因之二。因此,將llvm-config
替換成主體平臺也可以執行的、具有相同功能的llvm-config
可以顯著減少切換次數。
在主體平臺上,先使用相同的配置選項配置clang,之後會生成主體平臺上的mipsel交叉編譯clang。這裡我們用的不是交叉編譯clang,而是生成的副產品:llvm-config
。在將其重新命名為llvm-config-amd64
,將目標平臺上的對應檔案命名為llvm-config-mips3
。在主體平臺上執行以下命令,替換原有的llvm-config
,即可使用主體平臺上的編譯程式。
$ cp <path/to/llvm-config-amd64>/llvm-config-amd64 <common/path/prefix>/mips3/llvm/llvm-3.4/Release+Asserts/bin/llvm-config
- 刪去單元測試和其他測試
刪去clang中和test、unittest相關內容,刪去llvm中test目錄,這些在編譯時都不是必要的,並且會大大增加資料的傳輸量。
安裝
$ cd <common/path/prefix>/mips3/llvm/llvm-3.4
$ make install
$ <common/path/prefix>/mips3/rsync-commit
即可將編譯好的llvm/clang安裝到<common/path/prefix>/mips3/llvm/llvm-3.4/root
目錄下。
編譯完成
在目標平臺上我們來測試一個helloworld程式:
#include <iostream>
using namespace std;
int main() {
cout << "Hello World!" << endl;
return 0;
}
儲存並將其命名為test.cpp
。使用新安裝好的clang++編譯:
$ <common/path/prefix>/mips3/llvm/llvm-3.4/root/bin/clang++ test.cpp --target=mipsel-pc-linux
$ ./a.out
Hello World!
這裡需要加上--target=mipsel-pc-linux
選項。這是因為目標平臺的龍芯屬於 mipsel 體系結構,即little endianness。 而系統uname -a
的結果卻是mips64。因此,llvm的配置檔案會誤認為當前平臺是mipsel64,從而生成無法執行的程式碼。
相關推薦
使用交叉混合編譯從原始碼編譯龍芯上的llvm/clang-3.4
目標: 使用交叉混合編譯(hybrid cross-compiling)從原始碼編譯龍芯上的llvm/clang-3.4。之所以是混合交叉編譯而不是交叉編譯,是因為編譯的過程中,大部分程式碼是由效能較高的主體(Host)平臺編譯,而少部分程式碼是由效能較低的目
CentOS 從原始碼編譯並安裝 Nginx
Linux 系統要求 Nginx 在 Linux 作業系統下執行的時候,要想獲取高併發能力,要求 Linux 核心必須在 2.6 以上,可通過以下命令檢視 Linux 核心版本。 $ uname -r 2.6.18-128.e15 安裝 Nginx 的必備軟體 通過以下命令安裝使用
Linux從原始碼編譯安裝程式詳解
1.原始碼編譯概述 1.1 使用原始碼安裝軟體的優點: 獲得最新的軟體版本,及時修復bug 根據使用者需要,靈活定製軟體功能 1.2 應用場合舉例 安裝較新版本的應用程式時 當前安裝的程式無法滿足需要時 需要為應用程式新增新的功能時
golang 從原始碼編譯記錄
下載golang 原始碼 筆者寫此部落格的時候最新是go 1.10.1 版本。 原始碼目錄 /root/source_bk/go_source/go 基本編譯流程解釋 go 語言編譯器自1.5版本開始自舉 ( 使用go編譯器編譯go編譯器 ) 。所
Python3.7.1從原始碼編譯安裝
#!/bin/bash #確保shell 切換到當前shell 指令碼資料夾 current_file_path= ( c
linux下從原始碼編譯比特幣客戶端
下載原始碼 這個是master分支的,建議在tag裡選最新的穩定版,目前是v0.14.2 直接下載zip,別clone了,clone很慢。 編譯程式碼 不妨先看看官方的編譯說明 ps: 第一手的官方的資源一般都是最好的,有問題了最好
在win10裡從原始碼編譯nodejs的安裝包和學習原始碼
大家其實都是從網站上下載直接安裝檔案的,為什麼還要從原始碼安裝呢?可能原因就兩個,一個想自己優化,新增一個特定的東西;另一個想學習nodejs的實現,知道為什麼這樣實現的。我這裡主要為學習nodejs的實現,所以要到下面的網站下載原始碼:https://nodejs.org/
ARM64從原始碼編譯docker(v1.9.1)
在X86_64機器fedora系統下,不要使用官方編譯的rpm包,交叉編譯bootstrap會出現異常,使用原始碼編譯的go. 1.編譯X86_64的go binary cd /root git clone https://github.co
從零開始學習區塊鏈技術(一)--從原始碼編譯比特幣
寫在開始之前,為什麼你一定要學習區塊鏈技術? 技術的變革和迭代一直在飛速發展中,作為有著15年程式開發經驗的我,常常在思考現在的我們到底改如何做,到底應該學習些什麼,才能跟上新的時代變革,保持自身的競爭力,並且能為這個世界帶來更好的改變呢? 答案是,學習
OpenCV安裝流程及從原始碼編譯方法 + 配置VS
本篇文章記錄了安裝OpenCV 3.4.2及配置VS2017的方法,以及利用CMake從原始碼編譯適用於老版本VS2013的OpenCV 3.4.2的編譯及配置流程。本文也可以作為其他OpenCV及VS版本安裝配置方法的參考。 1 安裝OpenCV 3.4.2
從原始碼編譯TensorFlow CPU版本
1 安裝Python3 的依賴 sudo apt-get install python3-numpy python3-dev python3-pip python3-wheel 2從原始碼安裝Bazel sudo apt-get install ope
Linux 從原始碼編譯安裝 OpenSSH
https://blog.csdn.net/bytxl/article/details/46639073 Linux 從原始碼編譯安裝 OpenSSH以及各問題解決 2015年06月25日 17:37:49 by
Ubuntu16.04 從原始碼編譯LLVM+Clang
最近在安裝一個Vim自動補全外掛——YouCompleteMe,這個外掛可以根據語義補全,因此需要Clang這個庫,不過LLVM的官網並沒有提供Ubuntu的預編譯二進位制版本,所以需要自己從原始
從原始碼編譯cef-chromium的正確步驟
之前編譯過cef-chromium的原始碼,但是找不到之前的原始碼工程了。幸好壓縮原始碼還存在電腦裡。 現在又要編譯一下,因為需要定製自己需要的功能,這裡就把編譯過程記錄一下,以免以後還會遇到,也分享給需要的讀者。 下載cef-chromium的原始碼需要到google網站
Qt Creator在龍芯上編譯與安裝的方法
從QT官方網站上可以發現,提供的Qt Creator只有x86版的,不支援mips。下面這篇文章轉載自龍芯論壇,希望對大家有所幫助。他寫的還不是很具體,我也正在研究中。歡迎共同交流qtcreator1.1依賴於qt-4.5.1所以compile qtcreator1.1之前必須compile qt-4.5.1
Linux 從原始碼編譯安裝 OpenSSH以及各問題解決
簡單的說 OpenSSH 是一組安全遠端的連線工具,主要包括了幾個部份:ssh、sshd、scp、sftp、ssh-keygen、ssh-agent、ssh-add。OpenSSH 安裝配置比較複雜,難點在配置,特別是在 VPS 中,配置不當就完全無法連結 VPS 了。
從原始碼編譯OSG
Windows 下: 2。使用CMake工具編譯OSG。 1)把CMakeLists.txt 拖放到CMake軟體的GUI介面上,可以選擇更改安裝路徑:"Where to build the binaries"。該路徑是OSG的初始編譯路徑。 2)點選 '
從原始碼編譯docker (moby)
下面是從原始碼編譯最新(2018-03-27)的 docker/cli 和 moby 的詳細過程第1步 安裝 ubuntu 16.04下載最新的 ubuntu-16.04.4-desktop-amd64.iso 安裝後# cat /etc/os-release NAM
【指導】從原始碼編譯安裝Git-Ubuntu
1 下載原始碼包 2 編譯安裝Git 1)安裝編譯原始碼包的工具: $sudo apt-get installlibcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev 2)展開原始碼包,進入: $t
OpenWRT編譯——從原始碼到韌體
接觸OpenWRT一年時間,大部分都在編譯韌體、刷機,遇到過不少問題。這裡記錄下以前摸索的步驟。 op編譯過程的wiki:https://wiki.openwrt.org/zh-cn/doc/howto/buildroot.exigence 以下步驟的操作環境為64位的Ub