Cross compile mongodb for 32 bit arm

I’d like to run a relatively modern mongodb server on my cubieboard which is powered by an ARMv7l chip. There was a good work but it was built against 2.6.3 thus a bit out-dated. The latest version of mongodb that supports 32 bit platform is 3.3.15. That’s what I’d like to try here.

  1. Prepare the build environment

    1
    2
    3
    $ sudo apt-get install build-essential wget scons
    $ sudo apt-get install libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev
    $ sudo apt-get install g++-5-arm-linux-gnueabihf g++-5-arm-linux-gnueabihf
  2. You might need to update the cross-compile toolchain accordingly to make arm-linux-gnueabihf-gcc point to the correct version, details see this post.

    1
    $ sudo update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /usr/bin/arm-linux-gnueabihf-gcc-5 100 --slave /usr/bin/arm-linux-gnueabihf-g++ arm-linux-gnueabihf-g++ /usr/bin/arm-linux-gnueabihf-g++-5
  3. Download and unpack mongodb source code

    1
    2
    3
    4
    5
    $ mkdir install
    $ cd install
    $ wget https://fastdl.mongodb.org/src/mongodb-src-r3.3.15.tar.gz
    $ tar xvf mongodb-src-r3.3.15.tar.gz
    $ cd mongodb-src-r3.3.15
  4. Generate additional sources. It’s suggested by this post.

    1
    2
    3
    4
    $ cd src/third_party/mozjs-45/
    $ ./get_sources.sh
    $ ./gen-config.sh arm linux
    $ cd -

    As I was doing it, an error raised saying a file missed.

    1
    fatal error: js-config.h: No such file or directory

    Therefore some extra parameters were added in the file gen-config.sh to fix it.

    1
    PYTHON=python ./configure --without-intl-api --enable-posix-nspr-emulation --disable-trace-logging --host=arm-linux --target=arm-linux-gnueabihf --build=x86_64-linux
  5. More modifications to move on.

    • No pause implementation.

      Error message:

      1
      2
      3
      4
      5
      6
      In file included from src/mongo/util/concurrency/spin_lock.cpp:34:0:
      src/mongo/platform/pause.h:71:2: error: #error "No processor pause implementation for this architecture."
      #error "No processor pause implementation for this architecture."
      src/mongo/util/concurrency/spin_lock.cpp: In member function 'void mongo::SpinLock::_lockSlowPath()':
      src/mongo/util/concurrency/spin_lock.cpp:57:34: error: 'MONGO_YIELD_CORE_FOR_SMT' was not declared in this scope
      MONGO_YIELD_CORE_FOR_SMT();

      Modification:

      mongo uses some processor pause signal to make CPU work more effectively, arm (armv7l) is out of support in this case, add it along with aarch64 in the file src/mongo/platform/pause.h.

      1
      2
      3
      #elif defined(__aarch64) || defined(__arm__)

      #define MONGO_YIELD_CORE_FOR_SMT() __asm__ volatile("yield" ::: "memory")
    • config.h missing for gperftools 2.5

      Error message:

      1
      src/third_party/gperftools-2.5/src/base/dynamic_annotations.c:38:20: fatal error: config.h: No such file or directory

      Modification:

      The missed file is generated by ./configure, download a gperftools source code.

      1
      2
      3
      4
      $ wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.5/gperftools-2.5.tar.gz
      $ tar xf gperftools-2.5.tar.gz
      $ cd gperftools-2.5
      $ ./configure --target=arm-linux-gnueabihf --host=arm-linux --build=x86_64-linux

      Find the file in the path src/config.h, copy it to the mongo third party directory src/third_party/gperftools-2.5/build_linux_arm.

    • --std=c++11 issue when compiling gperftools 2.5

      Error message:

      1
      2
      3
      src/base/linux_syscall_support.h: In function ‘pid_t sys_getpid()’:
      src/base/linux_syscall_support.h:1304:33: error: expected string-literal before ‘:’ token
      : "lr", "memory");

      Modification:

      It’s a problem reported here and fixed here. Use gnu++11 instead of c++11 in the top level SConstruct of mongodb.

      1
      2
      if not AddToCXXFLAGSIfSupported(myenv, '-std=gnu++11'):
      myenv.ConfError('Compiler does not honor -std=gnu++11')
    • call of overloaded appendNumber is ambitious

      Error message:

      1
      2
      3
      4
      5
      src/mongo/util/procparser.cpp: In function 'mongo::Status mongo::procparser::parseProcStat(const std::vector<mongo::StringData>&, mongo::StringData, int64_t, mongo::BSONObjBuilder*)':
      src/mongo/util/procparser.cpp:281:49: error: call of overloaded 'appendNumber(mongo::StringData&, uint64_t&)' is ambiguous
      builder->appendNumber(key, value);
      ^
      In file included from src/mongo/util/procparser.cpp:51:0:

      Modification:

      Change the argument type from uint64_t to long long for all calls of appendNumber, details see here.

  6. Compile and build.

    WiredTiger will not work on a 32 bit architecture so you will encounter some compilation challenges with it. It is recommended to simply exclude the WiredTiger storage engine altogether. That means you will run MongoDB with the MMAPv1 storage engine only.

    1
    $ scons mongo mongod --wiredtiger=off --mmapv1=on CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++
  7. Reduce binaries file size.

    1
    2
    $ strip -s build/opt/mongo
    $ strip -s build/opt/mongod
  8. Install binaries

    Copy all the binaries to the cubieboard.

    1
    $ sudo cp mongo mongod /usr/local/bin/

Binary Provided

I have compiled MongoDB 3.3.15 for ARM. You can DOWNLOAD it.


Credits: