├── .gitignore ├── DEPS ├── LICENSE ├── README.md ├── create_env.sh ├── env.sh └── npm_install.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Tarball and compressed 32 | *.7z 33 | *.gz 34 | *.bz2 35 | *.iso 36 | *.jar 37 | *.rar 38 | *.tar 39 | *.zip 40 | 41 | # folders 42 | depot_tools/ 43 | linkit/ 44 | v8/ 45 | node-v0.12.7-mips/ 46 | mt7688sdk/ 47 | node_modules/ 48 | node_modules_mips/ 49 | etc/ 50 | _bad_scm/ 51 | 52 | # other files 53 | .gclient 54 | .gclient_entries 55 | 56 | # Debug files 57 | *.dSYM/ 58 | -------------------------------------------------------------------------------- /DEPS: -------------------------------------------------------------------------------- 1 | # Note: The buildbots evaluate this file with CWD set to the parent 2 | # directory and assume that the root of the checkout is in ./v8/, so 3 | # all paths in here must match this assumption. 4 | vars = { 5 | "git_url": "https://chromium.googlesource.com", 6 | } 7 | deps = { 8 | # Remember to keep the revision in sync with the Makefile. 9 | "v8/build/gyp": 10 | Var("git_url") + "/external/gyp.git@a3e2a5caf24a1e0a45401e09ad131210bf16b852", 11 | "v8/third_party/icu": 12 | Var("git_url") + "/chromium/deps/icu52.git@26d8859357ac0bfb86b939bf21c087b8eae22494", 13 | "v8/buildtools": 14 | Var("git_url") + "/chromium/buildtools.git@fb782d4369d5ae04f17a2fceef7de5a63e50f07b", 15 | "v8/testing/gtest": 16 | Var("git_url") + "/external/googletest.git@4650552ff637bb44ecf7784060091cbed3252211", 17 | "v8/testing/gmock": 18 | Var("git_url") + "/external/googlemock.git@896ba0e03f520fb9b6ed582bde2bd00847e3c3f2", 19 | } 20 | deps_os = { 21 | "android": { 22 | "v8/third_party/android_tools": 23 | Var("git_url") + "/android_tools.git@31869996507de16812bb53a3d0aaa15cd6194c16", 24 | }, 25 | "win": { 26 | "v8/third_party/cygwin": 27 | Var("git_url") + "/chromium/deps/cygwin.git@06a117a90c15174436bfa20ceebbfdf43b7eb820", 28 | "v8/third_party/python_26": 29 | Var("git_url") + "/chromium/deps/python_26.git@67d19f904470effe3122d27101cc5a8195abd157", 30 | } 31 | } 32 | include_rules = [ 33 | # Everybody can use some things. 34 | "+include", 35 | "+unicode", 36 | "+third_party/fdlibm", 37 | ] 38 | # checkdeps.py shouldn't check for includes in these directories: 39 | skip_child_includes = [ 40 | "build", 41 | "third_party", 42 | ] 43 | hooks = [ 44 | # Pull clang-format binaries using checked-in hashes. 45 | { 46 | "name": "clang_format_win", 47 | "pattern": ".", 48 | "action": [ "download_from_google_storage", 49 | "--no_resume", 50 | "--platform=win32", 51 | "--no_auth", 52 | "--bucket", "chromium-clang-format", 53 | "-s", "v8/buildtools/win/clang-format.exe.sha1", 54 | ], 55 | }, 56 | { 57 | "name": "clang_format_mac", 58 | "pattern": ".", 59 | "action": [ "download_from_google_storage", 60 | "--no_resume", 61 | "--platform=darwin", 62 | "--no_auth", 63 | "--bucket", "chromium-clang-format", 64 | "-s", "v8/buildtools/mac/clang-format.sha1", 65 | ], 66 | }, 67 | { 68 | "name": "clang_format_linux", 69 | "pattern": ".", 70 | "action": [ "download_from_google_storage", 71 | "--no_resume", 72 | "--platform=linux*", 73 | "--no_auth", 74 | "--bucket", "chromium-clang-format", 75 | "-s", "v8/buildtools/linux64/clang-format.sha1", 76 | ], 77 | }, 78 | { 79 | # A change to a .gyp, .gypi, or to GYP itself should run the generator. 80 | "pattern": ".", 81 | "action": ["python", "v8/build/gyp_v8"], 82 | }, 83 | ] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 simen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mt7688-cross 2 | 3 | The tool to create an environment on a Host for cross-compiling node.js native modules/add-ons for MT7688 mips platform. Once the environment is created, just use `./npm_install.sh` to install the cross-compiled version of node modules, it's easy. 4 | 5 | [**Note**] 6 | * Please **do not** use mt7688-cross **v1.0 release**, since Google has removed the gyp from svn to git repo. You will get an error of `svn: E160013: Unable to connect to...` when running `./create_env.sh`. mt7688-cross v1.1 already fixes this dependencies broken issue. 7 | 8 | 9 | ## 1. Information about the Host and Target 10 | 11 | * Host: Ubuntu/Debian x86_64 (Mine is Ubuntu 14.04 LTS running on a virtual machine) 12 | * Target: MT7688, MIPS24KEc (little endian) 13 | * node.js: 0.12.7 14 | * npm: 2.11.3 15 | * v8 engine: 3.28.71 (patch 19) 16 | 17 |
18 | 19 | ## 2. Preacquisition 20 | 21 |
22 | 23 | #### step 1: Install the following packages on your Host PC 24 | 25 | `$ sudo apt-get install subversion build-essential gcc-multilib g++-multilib` 26 | 27 | mt7688-cross requires **wget** to download the mt7688 SDK and node.js source, make sure you have wget on your Ubuntu. 28 | 29 | `$ sudo apt-get install wget` 30 | 31 |
32 | 33 | #### step 2: Make sure you are equipped with **node@0.12.7** and **npm@2.11.3** on your Host PC 34 | 35 | If you don't, try to install them: (I am using `n` as my node version manager. You can use `nvm` if you like.) 36 | 37 | `$ sudo n 0.12.7` 38 | `$ sudo npm install -g npm@2.11.3` 39 | 40 |
41 | 42 | #### step 3: Clone **mt7688-cross** to the Host PC 43 | 44 | `~$ git clone https://github.com/simenkid/mt7688-cross.git` 45 | `~$ cd mt7688-cross` 46 | `~/mt7688-cross$` 47 | 48 | mt7688-cross/ is the working directory for cross-compiling native node modules/add-ons. 49 | 50 |
51 | 52 | #### step 4: Build the environment 53 | 54 | Shoot `create_env.sh` to start the building process. This may take around 20 minutes depends on your PC performance. 55 | 56 | `~/mt7688-cross$ ./create_env.sh` 57 | 58 |
59 | 60 | As building accomplished, in`linkit/opt/`, there is the cross-compiled node.js that can run on MT7688 MIPS platform. In addition, `v8/`, `node-v0.12.7-mips/`, and `mt7688sdk/` are the sources of v8, node, and mt7688 SDK, respectively. 61 | 62 | Once this step is successfully done, the environment is ready for your later use. Every time you want to cross-compile a node native module, just come into the working directory `mt7688-cross/` and install a module with script `npm_install.sh`, there is no need to rebuild the environment again. 63 | 64 |
65 | 66 | ## 3. Install the cross-compiled node native module/add-on 67 | 68 | Assume that you like to install the `serialport` module on your MT7688. First install it with `npm_install.sh` on the Host: 69 | 70 | `~/mt7688-cross$ ./npm_install.sh serialport` 71 | 72 | You will get a compressed tarball in `node_modules_mips/`, in this example, it is `serialport-2.0.6_mips.tar.gz`. If you like to install other version, just specify the version with `@`: 73 | 74 | `~/mt7688-cross$ ./npm_install.sh serialport@2.0.4` 75 | 76 | Next step is push it to MT7688 via `scp` and decompress it to any place you want. In this example, I will put it to `~/app` with the root account and extract it to `~/app/node_modules/`. 77 | 78 | **At Host:** 79 | 80 | `~/mt7688-cross$ scp node_modules_mips/serialport-2.0.6_mips.tar.gz root@192.168.0.109:/root/app` 81 | 82 | **At Target:** 83 | 84 | `root@mylinkit:~/app# tar xvf serialport-2.0.6_mips.tar.gz -C node_modules/` 85 | 86 | Now, you are ready to write a script in `~/app` on your target. 87 | 88 |
89 | 90 | ## Note 91 | 92 | 1. Module cross-build may fail if the module is highly platform-dependent, e.g. module that operates SoC gpio/uart and other peripherals. 93 | 2. Module cross-build may fail if the module requires some libraries that SDK doesn't provide. 94 | 3. You are welcome to modify this script to fit your needs, e.g. automation of file transmission from Host to Target. 95 | 4. If you only like to have the environment variable settings for cross tools, it is in `env.sh`. 96 | 97 | This tool is inspired by [Build your own Node.js package with the linino toolchain](http://wiki.linino.org/doku.php?id=wiki:nodepackage). Thanks to linino! 98 | -------------------------------------------------------------------------------- /create_env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo " " 4 | echo "*********************************************************************" 5 | echo "* MT7688 Cross-environment for building native node modules/add-ons *" 6 | echo "* Tested on: *" 7 | echo "* Host: Ubuntu 14.04LTS x86_64 (MTK cross-tools) *" 8 | echo "* Target: MT7688 MIPS24KEc little endian, OpenWRT *" 9 | echo "* *" 10 | echo "* Author: Simen Li (simenkid@gmail.com) *" 11 | echo "* GitHub: https://github.com/simenkid/mt7688-cross *" 12 | echo "* License: MIT *" 13 | echo "*********************************************************************" 14 | echo " " 15 | echo " Please make sure you have installed the following packages on you host: " 16 | echo " >> subversion, build-essential, gcc-multilib, g++-multilib" 17 | echo " " 18 | read -n1 -p "Are you sure to create the cross environment? [Y/n]" sure 19 | echo " " 20 | 21 | sure=${sure:-y} 22 | if [ "${sure}" != "y" -a "${sure}" != "Y" ]; then 23 | exit 0 24 | fi 25 | 26 | node_ver=`node -v` 27 | npm_ver=`npm -v` 28 | 29 | # Check version of node and npm 30 | if [ ${node_ver} != 'v0.12.7' ]; then 31 | echo "Node version on host should be v0.12.7, yours is ${node_ver}." 32 | echo "If you are using n, run: " 33 | echo "$ sudo n 0.12.7" 34 | exit 0 35 | else 36 | echo "node version: ${node_ver}, ok!" 37 | fi 38 | 39 | if [ ${npm_ver} != '2.11.3' ]; then 40 | echo "Npm version on host should be 2.11.3, yours is ${npm_ver}." 41 | echo "To install the matched version, run: " 42 | echo "$ sudo npm install -g npm@2.11.3" 43 | exit 0 44 | else 45 | echo "npm version: ${npm_ver}, ok!" 46 | # if [ ! -d $(pwd)/node_modules ] || [ ! -d $(pwd)/node_modules/node-gyp ]; then 47 | # echo "Install node-gyp..." 48 | # sudo npm install --prefix $(pwd) node-gyp 49 | # fi 50 | fi 51 | 52 | echo " " 53 | echo "Create target folder..." 54 | if [ ! -d $(pwd)/linkit ]; then 55 | mkdir $(pwd)/linkit 56 | if [ ! -d $(pwd)/linkit/opt ]; then 57 | mkdir $(pwd)/linkit/opt 58 | fi 59 | fi 60 | 61 | echo " " 62 | echo "Get MT7688 OpenWrt SDK and decompress it into /mt7688sdk..." 63 | if [ ! -f OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar.bz2 ]; then 64 | wget http://download.labs.mediatek.com/MediaTek_LinkIt_Smart_7688_Openwrt_sdk_Linux -O OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar.bz2 65 | fi 66 | 67 | if [ ! -d mt7688sdk ]; then 68 | tar xjvf OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar.bz2 > /dev/null 69 | mv OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/ mt7688sdk 70 | fi 71 | 72 | echo " " 73 | echo "Get node source and decompress it into /node-v0.12.7-mips..." 74 | if [ ! -f node-v0.12.7.tar.gz ]; then 75 | wget https://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz 76 | fi 77 | 78 | if [ ! -d node-v0.12.7-mips ]; then 79 | tar xzvf node-v0.12.7.tar.gz > /dev/null 80 | mv node-v0.12.7/ node-v0.12.7-mips 81 | fi 82 | 83 | echo " " 84 | echo "Get depot tools for google chromium repository..." 85 | if [ ! -d depot_tools ]; then 86 | if [ -f .gclient ]; then 87 | rm .gclient 88 | fi 89 | if [ -f .gclient_entries ]; then 90 | rm .gclient_entries 91 | fi 92 | git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 93 | fi 94 | 95 | # source env.sh to export environment varaible for cross-toolchain 96 | . $(pwd)/env.sh 97 | 98 | echo " " 99 | echo "Get v8 source into /v8" 100 | echo "Takes few minutes, please wait..." 101 | echo " " 102 | # Fetch and build V8 103 | if [ ! -d v8 ]; then 104 | if [ -f .gclient ]; then 105 | rm .gclient 106 | fi 107 | if [ -f .gclient_entries ]; then 108 | rm .gclient_entries 109 | fi 110 | fetch v8 111 | cd v8 112 | git fetch origin 113 | # checkout to v8 version: 3.28.71 (patch 19) 114 | git checkout -b 3.28.71.19 4dbc223b1e4d 115 | git branch 116 | mv ../DEPS DEPS 117 | gclient sync 118 | cd .. 119 | fi 120 | 121 | echo " " 122 | echo "Build v8 for mips platform..." 123 | echo "Takes around 10 minutes, please wait..." 124 | echo " " 125 | 126 | cd v8/ 127 | make clean 128 | make distclean 129 | make dependencies 130 | 131 | make mipsel.release werror=no library=shared snapshot=off -j4 132 | cp ${BASEDIR}/v8/out/mipsel.release/lib.target/libicui18n.so ${LIBPATH} 133 | cp ${BASEDIR}/v8/out/mipsel.release/lib.target/libicuuc.so ${LIBPATH} 134 | cd .. 135 | 136 | # Build Node.js 137 | echo " " 138 | echo "Build node.js for mips platform..." 139 | echo "Takes few minutes, please wait..." 140 | echo " " 141 | 142 | cd node-v0.12.7-mips/ 143 | make clean 144 | make distclean 145 | 146 | ./configure --prefix=${TARGET_PATH} --dest-cpu=mipsel --dest-os=linux --without-snapshot --shared-v8 --shared-v8-includes=${V8SOURCE}/include/ --shared-v8-libpath=${V8SOURCE}/out/mipsel.release/lib.target/ 147 | make snapshot=off -j4 148 | make install 149 | 150 | echo " " 151 | echo "*********************************************" 152 | echo "* Cross-environment done! *" 153 | echo "* *" 154 | echo "* Use ./npm_install.sh module_name *" 155 | echo "* Or ./npm_install.sh module_name@version *" 156 | echo "* to compile the node module *" 157 | echo "*********************************************" 158 | -------------------------------------------------------------------------------- /env.sh: -------------------------------------------------------------------------------- 1 | # Setp up paths 2 | export PATH=`pwd`/depot_tools:"$PATH" 3 | export BASEDIR=$(pwd) 4 | export STAGING_DIR=${BASEDIR}/mt7688sdk/staging_dir 5 | export PREFIX=${STAGING_DIR}/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mipsel-openwrt-linux- 6 | 7 | # MIPS cross-compile exports 8 | export CC=${PREFIX}gcc 9 | export CXX=${PREFIX}g++ 10 | export AR=${PREFIX}ar 11 | export RANLIB=${PREFIX}ranlib 12 | export LINK=$CXX 13 | export CPP="${PREFIX}gcc -E" 14 | export STRIP=${PREFIX}strip 15 | export OBJCOPY=${PREFIX}objcopy 16 | #export LD=${PREFIX}g++ 17 | 18 | # extras for convenience. 19 | export OBJD=${PREFIX}objdump 20 | export GDB=${PREFIX}gdb 21 | export RDE=${PREFIX}readelf 22 | 23 | export NM=${PREFIX}nm 24 | export AS=${PREFIX}as 25 | export PS1="[${PREFIX}] \w$ " 26 | export LIBPATH=${STAGING_DIR}/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/lib/ 27 | export LDFLAGS='-Wl,-rpath-link '${LIBPATH} 28 | export GYPFLAGS="-Dv8_use_mips_abi_hardfloat=false -Dv8_can_use_fpu_instructions=false" 29 | 30 | export V8SOURCE=${BASEDIR}/v8 31 | export TARGET_PATH=${BASEDIR}/linkit/opt 32 | -------------------------------------------------------------------------------- /npm_install.sh: -------------------------------------------------------------------------------- 1 | # source the environment variables 2 | . $(pwd)/env.sh 3 | 4 | export npm_config_arch=mips 5 | export npm_config_nodedir=${BASEDIR}/node-v0.12.7-mips 6 | echo $npm_config_nodedir 7 | 8 | if [ ! -d $(pwd)/node_modules_mips ]; then 9 | mkdir $(pwd)/node_modules_mips 10 | fi 11 | 12 | cd node_modules_mips/ 13 | 14 | version=`npm view "$1" version` 15 | module_name=${1%%@*} 16 | echo "> module name: ${module_name}" 17 | echo "> version: ${version}" 18 | 19 | npm install --prefix ${BASEDIR} --target_arch=mipsel "$1" 20 | 21 | if [ $? -eq 1 ]; then 22 | echo " " 23 | echo "Building node module for MT7688(mipsel) failed!" 24 | echo " " 25 | exit 0 26 | else 27 | echo " " 28 | echo "Archiving "$1"...." 29 | echo " " 30 | 31 | if [ -f ${BASEDIR}/node_modules_mips/"${module_name}"-"${version}"_mips.tar.gz ]; then 32 | rm ${BASEDIR}/node_modules_mips/"${module_name}"-"${version}"_mips.tar.gz 33 | fi 34 | 35 | cd ${BASEDIR}/node_modules 36 | tar -cvf "${module_name}"-"${version}"_mips.tar.gz "${module_name}"/ > /dev/null 37 | 38 | mv "${module_name}"-"${version}"_mips.tar.gz ${BASEDIR}/node_modules_mips 39 | rm -rf * 40 | 41 | echo " " 42 | echo "Building node module for MT7688(mipsel) finished!" 43 | echo " " 44 | fi --------------------------------------------------------------------------------