龙芯平台的electron开发

原创
2019/06/29 22:43
阅读数 6.7K

成品

electron-4.0.6-2.fc21.loongson.mips64el.rpm

http://ftp.loongnix.org/os/loongnix/1.0/os/Packages/e/electron-4.0.6-2.fc21.loongson.mips64el.rpm

其他版本,请在以下链接中搜索一下。

http://ftp.loongnix.org/os/loongnix/1.0/os/Packages/e/

一、环境

 操作系统

  本文基于fedora 28 for loongson完成。

 硬件需求

  至少25GB硬盘和8GB内存。

 依赖的软件

  查看Python版本

  python --version

  需要Python版本 2.7.x

  安装pip

   sudo dnf install python-pip

  安装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

  安装Node.js

  sudo dnf install node

  查看版本

  node -v

  npm -v

 GTK+头文件及 libnotify

  sudo dnf install dbus-devel gtk3-devel libnotify-devel libgnome-keyring-devel xorg-x11-server-utils libcap-devel cups-devel libXtst-devel alsa-lib-devel libXrandr-devel GConf2-devel nss-devel python-dbusmock

  如果是debian系统,请执行以下命令。

  sudo apt-get install build-essential libdbus-1-dev libgtk-3-dev libnotify-dev libgnome-keyring-dev libasound2-dev libcap-dev libcups2-dev libxtst-dev libxss1 libnss3-dev gcc-multilib g++-multilib curl gperf bison python-dbusmock openjdk-8-jre

 第一个electron app

  这一步在x86平台可以顺利完成。在龙芯平台请执行完后边的“构建”步骤之后再尝试。

  安装electron,这里选择了分支6.0.X作为克隆对象。

  git clone -b 6-0-x https://github.com/electron/electron.git

  获取electron官方的示例源码仓库

  git clone https://github.com/electron/electron-quick-start

  进入仓库
  cd electron-quick-start

  安装依赖库
  npm install

  运行应用
  npm start

二、构建

 GN前提条件 

  安装depot tools(获取Chromium及其依赖软件包的工具)

  1)把 depot_tools 克隆到某个一个目录下,假设为 ~/depot_tools :  
  git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

  2)设置环境变量。把export PATH=$PATH:/home/usr/dvp/depot_tools这行语句加入到全局变量/etc/profile(或用户目录下的 .bashrc 或 .zshrc)的最后一行中。“/home/usr/dvp/depot_tools”为安装路径。

  source /etc/profile

  验证一下
  gclient --version

 缓存式构建设置 

  虽然这是可选步骤,但是建议不要略过,尤其对于网络环境较差的场景。

  注意:缓存大约需要 20G 的硬盘空间。

  GIT_CACHE_PATH环境变量:

  如果打算多次构建 Electron 的话,添加一个 git 的 cache 可以加速接下来对 gclient 的调用。可以通过设置环境变量 GIT_CACHE_PATH 的环境变量来实现这个效果:

  export GIT_CACHE_PATH="${HOME}/.git_cache"

  mkdir -p "${GIT_CACHE_PATH}"

  注意:git cache 会把 sr/electron 的 origin 设置为本地的 cache,而不是上游的 git 仓库。

    恢复的方法:进入 src/electron 目录,运行

    git remote set-url origin https://github.com/electron/electron

  sccache

  构建Chromium和Electron必须编译成千上万个文件。您可以通过sccache复用Electron CI配置项的构建输出来避免大量等待。这需要一些可选步骤(如下所列)和这两个环境变量:

  export SCCACHE_BUCKET="electronjs-sccache"
  export SCCACHE_TWO_TIER=true

 获取代码

  mkdir electron-gn && cd electron-gn

  gclient config --name "src/electron" --unmanaged https://github.com/electron/electron

  常见问题:shadowsocks连接不稳定导致gclient输出:“curl: Failed to connect to chrome-infra-packages.appspot.com port 443: 连接超时“

  gclient sync --with_branch_heads --with_tags

  这一步会超级消耗时间,喝杯咖啡,睡会儿吧。大约20G。请根据网速推算所需的时长,建议至少保持5M/s以上的带宽,1-2小时左右能完成同步。

  你可以使用自己的复刻版本 (比如 https://github.com/<username>/electron),来代替官方版本https://github.com/electron/electron

  拉取或推送时的注意事项

  如果你打算将来从官方电子仓库中获取或推送,你现在需要更新各自文件夹的原始网址。

  $ cd src/electron
  $ git remote remove origin
  $ git remote add origin https://github.com/electron/electron
  $ git branch --set-upstream-to=origin/master
  $ cd -Copy

  gclient通过检查src/electron文件夹中一个名为DEPS的文件的依赖性来工作。运行 gclient sync -f 可确保构建电子版所需的所有依赖项都与该文件匹配。

  因此,为了拉取,您需要运行以下命令:

  $ cd src/electron
  $ git pull
  $ gclient sync -f

  获取代码后,把 src/electron 下的代码的版本 checkout 到 v5.0.6(这是当前的稳定版本,请根据您的需要进行设置),然后到 src 目录下运行 gclient sync 来把其他项目参照 electron v5.0.6 的版本来同步到相应的版本上:

  在src/electron目录下执行:

  git checkout v5.0.6

  返回上一级目录。

  cd ..

  在src目录下执行:

  gclient sync

 构建

  进入 src 目录,并设置 CHROMIUM_BUILDTOOLS_PATH 环境变量:
  cd src
  export CHROMIUM_BUILDTOOLS_PATH=`pwd`/buildtools

  下边这一行仅在使用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"

       这将在带有debug build configuration(调试生成配置)的目录src/下生成生成目录out/Debug。您可以用另一个名称替换“Debug”,但它应该是out的子目录。您也不要再运行gn gen。如果您想更改构建参数,您可以运行gn args out/Debug来调出一个编辑器。

  要查看可用的构建配置选项列表,请运行

  gn args out/Debug --list

 1、用于生成 Debug(又称“component组件”或“shared共享”)Electron的构建配置:

  $ gn gen out/Debug --args="import(\"//electron/build/args/debug.gn\") $GN_EXTRA_ARGS"

  如果要使用系统自带的 clang 请参见下面的“高级主题”。

 2、用于生成 Release(又称“non-component非组件”或“static静态”)Electron的构建配置:

  $ gn gen out/Release --args="import(\"//electron/build/args/release.gn\") $GN_EXTRA_ARGS"

  如果要使用系统自带的 clang 请参见下面的“高级主题”。

 3、使用 ninja 以 electron 为目标进行构建:注意事项:这也需要一段时间,可能会让你的膝盖发热。

  3.1、用于debug配置:

  $ ninja -C out/Debug electron

  3.2、用于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"'
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   

  这个过程会构建 'libchromiumcontent' 里的所有内容,(如chromium中的content,及其依赖(包括Webkit 和 V8))。因此,这个构建过程会比较费时。

  你可以使用sccache命令来提高后面的构建过程。 Add the GN arg cc_wrapper = "sccache" by running gn args out/Debug to bring up an editor and adding a line to the end of the file.

  The built executable will be under ./out/Debug:

  $ ./out/Debug/electron

三、打包

  在linux上,首先移除调试和符号信息:

  electron/script/strip-binaries.py -d out/Release

  要将electron打包为可分发的zip文件:

  ninja -C out/Release electron:electron_dist_zip

四、交叉编译和测试

  详见 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;

 clang

  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;    

 NSS

  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,然后再执行这条命令。

六、开发工具

 安装eclipse

  sudo dnf install eclipse

  安装JavaScript开发工具:依次选择help、install new software

  在“work with”中点击“manage”、“add”添加国内镜像软件源。自定义name,例如tuna(清华大学开源镜像站)。localtion填写“https://mirrors.tuna.tsinghua.edu.cn/eclipse/releases/2019-03“,其中“https://mirrors.tuna.tsinghua.edu.cn/eclipse/”为镜像地址,“2019-03”为eclipse的版本号,请根据个人喜好和eclipse版本信息配置。点击“add”完成添加,然后将列表中的其他软件源前面的勾都去掉,仅保留tuna(这一步很重要,不然镜像地址不能成为首选软件源,速度还会很慢)。

  其他国内镜像:
  大连东软信息学院:http://mirrors.neusoft.edu.cn/eclipse/
  中国科学技术大学:http://mirrors.ustc.edu.cn/eclipse/

  选择tuna作为软件源。在下方filter筛选文本框中输入javascript。勾选所有选项。点击“下一步”进行安装。

  安装完成后,重启eclipse。在file、new、project中已经可以看到JavaScript Project了。

 安装inteliJ IDEA

  https://www.jetbrains.com/idea/download/#section=linux

  解压缩后,启动程序

  ./idea.sh

七、参考文献

  https://electronjs.org/docs/development/build-instructions-linux#prerequisites

  https://electronjs.org/docs/development/build-instructions-gn

展开阅读全文
打赏
1
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
1
分享
返回顶部
顶部