龍芯平臺的electron開發
一、環境
作業系統
筆者使用的為fedora28。
硬體需求
至少25GB硬碟和8GB記憶體。
檢視Python版本
python --version
需要Python版本 2.7.x
安裝python的一個HTTP客戶端庫requests
跟urllib,urllib2類似,那我們為什麼要用requests而不用urllib2呢?官方文件中是這樣說明的:python的標準庫urllib2提供了大部分需要的HTTP功能,但是API太逆天了,一個簡單的功能就需要一大堆程式碼。所以requests是比較簡單方便的庫。
sudo pip install requests
檢視Python 支援的 TLS 版本
python -c "import requests; print(requests.get('https://www.howsmyssl.com/a/check', verify=False).json()['tls_version'])"
至少為 1.2。
安裝clang
sudo dnf install clang
clang -v
版本至少為3.4。
安裝git
sudo dnf install git
GTK+標頭檔案及 libnotify
sudo dnf install dbus-devel gtk3-devel libnotify-devel libgonome-keyring-devel xorg-x11-server-utils libcap-devel cups-devel libXtst-devel alsa-lib-devel libXrandr-devel GConf2-devel nss-devel python-dbusmock
安裝Node.js
sudo dnf install node
檢視版本
node -v
npm -v
安裝eclipse
sudo dnf install eclipse
二、構建:
GN前提條件:
安裝 depot tools (the toolset used for fetching Chromium and its dependencies)
1)把 depot_tools 克隆到某個一個目錄下,假設為 ~/depot_tools :
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
2)把 export PATH=$PATH:~/depot_tools 這行語句加入到使用者目錄下的 .bashrc 或 .zshrc 的最後一行中。
快取式構建設定(可選步驟):
GIT_CACHE_PATH環境變數:
如果打算多次構建 Electron 的話,新增一個 git 的 cache 可以加速接下來對 gclient 的呼叫。可以通過設定環境變數 GIT_CACHE_PATH 的環境變數來實現這個效果:
$export GIT_CACHE_PATH="${HOME}/.git_cache"
$mkdir -p "${GIT_CACHE_PATH}" #快取的大約需要 16G 的硬碟空間
注意:git cache 會把 sr/electron 的 origin 設定為本地的 cache,而不是上游的 git 倉庫。恢復的方法:進入 src/electron 目錄,執行 git remote set-url origin https://github.com/electron/electron
使用sccache來重用已編譯的檔案:
詳見https://electronjs.org/docs/development/build-instructions-gn
獲取程式碼:
$mkdir electron-gn && cd electron-gn
$gclient config --name "src/electron" --unmanaged https://github.com/electron/electron
#shadowsocks連線不穩定導致:(gclient output) curl: Failed to connect to # chrome-infra-packages.appspot.com port 443: 連線超時
$gclient sync --with_branch_heads --with_tags
獲取程式碼後,把 src/electron 下的程式碼的版本 checkout 到 v4.0.6,然後到 src 目 錄下執行 gclient sync 來把其他專案參照 electron v4.0.6 的版本來同步到相應的 版本上:
在 src/electron 目錄下執行: $git checkout v4.0.6
在 src 目錄下執行:$gclient sync
構建:
進入 src 目錄,並設定 CHROMIUM_BUILDTOOLS_PATH 環境變數:
$cd src
$export CHROMIUM_BUILDTOOLS_PATH=`pwd`/buildtools
# this next line is needed only if building with sccache
# $export GN_EXTRA_ARGS="${GN_EXTRA_ARGS} cc_wrapper=\"${PWD}/electron/external_binaries/sccache\""
呼叫 gn 生成 ninja 所需的配置檔案:
Debug 版本(如果要使用系統自帶的 clang 請參見下面的“高階主題”):
$gn gen out/Debug --args="import(\"//electron/build/args/debug.gn\") $GN_EXTRA_ARGS"
Release 版本(如果要使用系統自帶的 clang 請參見下面的“高階主題”):
$gn gen out/Release --args="import(\"//electron/build/args/release.gn\") $GN_EXTRA_ARGS"
在 src 目錄中使用 ninja 以 electron 為目標進行實際的構建過程:
Debug 版本:
$ninja -C out/Debug electron
Release 版本:
$ninja -C out/Release electron
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
高階主題:不使用下載的 clang 編譯器,使用系統的 clang 編譯器
預設情況下 Electron 使用 Chromium project 提供的預編譯好的 clang 來進 行編譯。如果不想使用 Chromium project 提供的預編譯好的 clang 來進行編 譯,可以上面呼叫 gn 的步驟中提供 clang_base_path 的引數。例如,如果 clang 的路徑是 /usr/local/bin/clang 下,那麼呼叫 gn 的語句就可以寫成這樣:
Debug 版本:
$gn gen out/Debug --args='import("//electron/build/args/debug.gn") clang_base_path = "/usr/local/bin"'
Release 版本:
$gn gen out/Release --args='import("//electron/build/args/release.gn") clang_base_path = "/usr/local/bin"'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
打包:(詳見 https://electronjs.org/docs/development/build-instructions-gn)
交叉編譯:(詳見 https://electronjs.org/docs/development/build-instructions-gn)
測試:(詳見 https://electronjs.org/docs/development/build-instructions-gn)
在多個機器之間共享 git 快取:(詳見 https://electronjs.org/docs/development/build-instructions-gn)
編譯過程中遇到的問題:
1. src/buildtools/linux64/gn 的程式平臺不對,下載下來的是 x86-64的,需要替換成 MIPS64 的;
2. 在 src/electron/build/args/release.gn 檔案中的最後加上 use_sysroot = false (第14個問題的設定也可以放在這裡做)
3. depot_tools/ninja 的程式平臺不對,需要 MIPS64 平臺的 ninja;
4. /bin/sh 報錯:third_party/llvm-build/Release+Asserts/bin/clang++:沒有那個檔案或目錄(用 file 命令檢視clang發現平臺是 x86-64的,安裝 MIPS64 平臺的 clang,並把/usr/bin軟連結到 third_party/llvm-build/Release+Asserts下的bin上);
5. error:unable to find plugin 'find-bad-constructs' 的錯誤:原因是src/build下面的配置檔案中有 Xclang 選項,支掉此選項;
6. clang++: error: unknown argument: '-plugin-arg-find-bad-constructs' 的錯誤:在 src/build/config/clang/BUILD.gn 中去掉此選項;
7. clang++: error: no such file or directory: 'find-bad-constructs' 的錯誤:在 src/build/config/clang/BUILD.gn 中去掉此選項;
8. clang++: error: no such file or directory: 'check-ipc' 的錯誤:在 src/build/config/clang/BUILD.gn 中去掉此選項;
9. clang++: error: argument unused during compilation: '-add-plugin' [-Werror, -Wunused-command-line-argument] 的錯誤:在 src/build/config/clang/BUILD.gn 中去掉此選項;
10. fatal error: 'stddef.h' file not found: #include_next<stddef.h> 錯誤:參考 Electron 中編譯文件中的高階主題,使用系統的 clang,而不是按照第4)步的方法直接通過軟連結連結到系統中的 clang;
11. 檢視 clang 的預設搜尋路徑的相關資訊的命令: clang -E -xc++ - -v < /dev/null;
12. src/third_party/node/linux/node-linux-x64/bin/node 程式是 x86-64的,需要替換成 MIPS64的 node;
13. 作業系統的 NSS 的版本過低(static_assert((NSS_VMAJOR == 3 && NSS_VMINOR >= 26)||(NSS_VMAJOR > 3)): 更新 NSS 的版本(以不替換系統中的NSS的方法來處理這個問題,192.168.1.183/issues/608)
(0) NSS 釋出說明:https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_Releases
(1)nss3.43需要nspr4.21或以上版本,下載 nss-3.43-with-nspr-4.21.tar.gz(https://ftp.mozilla.org/pub/security/nss/releases/NSS_3_43_RTM/)編譯命令: make -C nss nss_build_all USE_64=1
(2)修改檔案 out/Release/obj/crypto/crypto.ninja,將原來的 cflags 中包含的 nss3 和 nspr4 的標頭檔案路徑改為相應正確的路徑,改為 ???/dist/Linux3.10_mips64_cc_glibc_PTH_64_OPT.OBJ/include ???/dist/public/nss
14. Failed: libVkICD_mock_icd.so libVkICD_mock_icd.so.TOC
python "../../build/toolchain/gcc_solink_wrapper.py" --readelf="readelf" --nm="nm" --sofile="./libVkICD_mock_icd.so" --tocfile="./libVkICD_mock_icd.so.TOC" --output="./libVkICD_mock_icd.so" ............ -fuse-ld=gold .............
clang-8: error: no such file or directory: 'obj/buildtools/third_party/libc++/libc++/algorithm.o'
clang-8: error: no such file or directory: 'obj/buildtools/third_party/libc++abi/libc++abi/private_typeinfo.o'
這種錯誤是由於 src/electron/build/args/release.gn 中預設是使用 gold 引數的,進而導致在生成的指令碼中包含了 -fuse-ld=gold 引數。去掉 -fuse-ld=gold 的解決辦法是在 src/electron/build/args/release.gn 檔案的最後加上 use_gold = false
15. Failed: libVkICD_mock_icd.so libVkICD_mock_icd.so.TOC
python "../../build/toolchain/gcc_solink_wrapper.py" --readelf="readelf" --nm="nm" --sofile="./libVkICD_mock_icd.so" --tocfile="./libVkICD_mock_icd.so.TOC" --output="./libVkICD_mock_icd.so" ............ --target=mips64el-linux-gnuabi64 ...........
............/usr/bin/ld: cannot find crtbeginS.o: No such file or directory
這種錯誤的原因是 gn 在生成指令碼時,根據 uname 獲取到的平臺引數生成了 --target=mips64el-linux-gnuabi64 的選項,而龍芯系統上的 gcc 的實際的目錄名稱為 /usr/lib/gcc/mips64el-redhat-linux/。 ld 去 mips64el-linux-gnuabi64 下找 crtbeginS.o,結果找不到。解決辦法:對 /usr/lib/gcc/mips64el-redhat-linux 做一個軟連結,連結為 mips64el-linux-gnuabi64
16. error: unable to load plugin '../../../../../../usr/lib/libBlinkGCPlugin.so': '../../../../../../usr/lib/libBlinkGCPlugin.so: cannot open shared object file: No such file or directory'
grep 到的含 blink-gc-plugin 的目錄:third_party/blink/renderer/BUILD.gn; tools/clang/blink_gc_plugin;
解決辦法:把 third_party/blink/renderer/BUILD.gn 中的 blink_gc_plugin = true 改為 = false
17. ../../third_party/fontconfig/src/src/fccache.c:42:10: fatal error: 'uuid/uuid.h' file not found
原因:缺少 libuuid;解決辦法:安裝 libuuid。安裝命令: yum install libuuid-devel.mips64el libuuid.mips64el
18. ./../../ui/views/widget/desktop_aura/desktop_screen_x11.cc:323:9: error: unknown type name 'XRRMonitorInfo'
原因:XRRMonitorInfo 型別定義在 libXrandr 1.5 以上的版本中,當前系統中 libXrandr 的版本為 1.4.2(參考http://192.168.1.183:3000/issues/608)
解決辦法:升級 libXrandr。
1)下載編譯libXrandr-1.5.1.tar.gz(https://www.x.org/releases/individual/lib/),configure失敗,需要 randrproto 的版本號 >=1.5;
2)下載編譯安裝 randrproto-1.5.0.tar.gz(https://www.x.org/releases/individual/proto/),configure失敗,包 'xorg-macros'未安裝;
3) 安裝 xorg-x11-util-macros: yum install xorg-x11-util-macros;
4) 編譯安裝 randrproto: make; make install
5) 編譯安裝 libXrandr: export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH; ./configure --prefix=/usr; make -j4; make install
19. FAILED: v8_context_snapshot_generator
Python "../../build/toolchain/gcc_link_wrapper.py" --output="./v8_context_snapshot_generator" ............
/usr/bin/ld: BFD version 2.24 assertion fail elf-strtab.c:200
clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
原因:ld 的版本有問題
解決辦法:把/usr/bin/ld 替換新版本的 ld
20. ACTION//tools/v8_context_snapshot:generate_v8_context_snapshot(//build/toolchain/linux:clang_mips64el)
FAILED: v8_context_snapshot.bin
python ../../build/gn_run_binary.py ./v8_context_snapshot_generator --output_file=v8_context_snapshot.bin ./v8_context_snapshot_generator failed with exit code -5
原因:可能與Loongson系統中編譯器的巨集 _MIPS_ARCH_LOONGSON 是否被定義有關
解決辦法:修改原始碼
1) src/third_party/tcmalloc/gperftools-2.0/chromium/src/common.h 中的第84到89行的程式碼,把 #else 的條件中兩個變數 kPageShift 和 kNumClasses 的值改為與 #if defined(_MIPS_ARCH_LOONGSON) 條件中的值一致;
2) src/base/allocator/partition_allocator/page_allocator_constants.h 中的第 15 到 19 行程式碼,把 #else 的條件中的變數 kPageAllocationGranularityShift 的值 改為與 #if defined(_MIPS_ARCH_LOONGSON) 條件中的值一致;對 27 到 31 行的程式碼作同樣的處理;
3) 對 src/bse/allocator/partition_allocator/partition_alloc_constants.h 檔案中的內容作相同的處理;
21. FAILED: electron
python "../../build/toolchain/gcc_link_wrapper.py" --output "./electron" -- ...................
obj/net/net/ssl_platform_key_nss.o: In function 'net::(anonymous namespace)::SSLPlatformKeyNSS::Sign(unsigned short, base::span<unsigned char const, 18446744073709551615ul>, std::__1::vector<unsigned char, std::__1::allocator<unsigned char>>*)':
src/out/Release/../../net/ssl/ssl_platform_key_nss.cc:130: undefined reference to 'PK11_SignWithMechanism'
src/out/Release/../../net/ssl/ssl_platform_key_nss.cc:130: undefined reference to 'PK11_SignWithMechanism'
clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
原因:新編譯的 nss-3.43+nspr-4.21 的庫檔案未安裝到系統當中,導致連結時出錯
解決辦法:在不改變系統本身環境的前提下,把下面這些庫 libsmime3.so, libnss3.so, libnssutils3.so, libplds4.so, libplc4.so, libnspr4.so 拷貝到 out/Release 下,並修改相對應的編譯的引數, 把涉及到這些庫的引數 -lnss3 等全部改為 ./lib*.so,然後再執行這條命