1. 程式人生 > >龍芯平臺的electron開發

龍芯平臺的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,然後再執行這條命