build mongodb from source code on armhf raspberry pi

# first of all

you may encounter several issues such as following on build mongodb:

sorry that this is intermediate memo...

```
      running build_ext
      running build_rust
      
          =============================DEBUG ASSISTANCE=============================
          If you are seeing a compilation error please try the following steps to
          successfully install cryptography:
          1) Upgrade to the latest pip and try again. This will fix errors for most
             users. See: https://pip.pypa.io/en/stable/installing/#upgrading-pip
          2) Read https://cryptography.io/en/latest/installation/ for specific
             instructions for your platform.
          3) Check our frequently asked questions for more information:
             https://cryptography.io/en/latest/faq/
          4) Ensure you have a recent Rust toolchain installed:
             https://cryptography.io/en/latest/installation/#rust
      
          Python: 3.10.6
          platform: Linux-5.15.0-1026-raspi-armv7l-with-glibc2.35
          pip: n/a
          setuptools: 67.6.1
          setuptools_rust: 1.5.2
          =============================DEBUG ASSISTANCE=============================
      
      error: can't find Rust compiler
```

If you tried to build from source code especially on armhf (aarch32), you should be encountering a lot of errors.

This article helps you to make it buildable on armhf Ubuntu such as Raspberry Pi Ubuntu 22.04 armhf (32bit).

And some of essences should be helpful on your different situation.

# how to build

## get source code

```
git clone https://github.com/mongodb/mongo.git -b r4.4.18
```

## ensure build essentials

```
sudo apt-get install build-essential libssl-dev libffi-dev python3-dev
```

```
pip3 install cryptography
```

## ensure rust...

```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

or

```
apt install rustc cargo
```

and do following if you didn't restart.

```
source $HOME/.cargo/env
```

```
pip3 install -r etc/pip/compile-requirements.txt
```
```
sudo apt-get install libcurl4-openssl-dev
```

## patch work

```
~/work/mongo/src/third_party/mozjs-60/platform$ cp aarch64 arm -rf
```

```
~/work/mongo/src/third_party/gperftools-2.7/platform$ cp linux_aarch64/ linux_arm -rf
```

### ```SConstruct```

```./SConstruct -L 2584
#AddToCXXFLAGSIfSupported(myenv, "-Wredundant-move")
```

```./SConstruct -L 2610
#AddToCCFLAGSIfSupported(myenv, "-Wno-exceptions")
```

```./SConstruct -L 2580
        # Warn about moves of prvalues, which can inhibit copy elision.
        #AddToCXXFLAGSIfSupported(myenv, "-Wpessimizing-move")
```

```./SConstruct
-        AddToCXXFLAGSIfSupported(myenv, "-Wunused-exception-parameter")
+
+        AddToCXXFLAGSIfSupported(myenv, "-Wno-range-loop-construct")
```

Add the ```"-Wno-range-loop-construct"```
Note that the indent level is important.

```./SConstruct -L2164
    # -Winvalid-pch Warn if a precompiled header (see Precompiled Headers) is found in the search path but can't be used.
    env.Append( CCFLAGS=["-fno-omit-frame-pointer",
                         "-fno-strict-aliasing",
                         "-fasynchronous-unwind-tables",
                         "-ggdb" if not env.TargetOSIs('emscripten') else "-g",
                         "-pthread",
                         #"-Wall",
                         #"-Wsign-compare",
                         "-Wno-unknown-pragmas",
                         "-Winvalid-pch"] )
```

Comment out ```-Wall``` and ```-Wsign-compare```

### wiredtiger

```src/third_party/wiredtiger/src/include/verify_build.h -L33
#define WT_STATIC_ASSERT(cond)
//#define WT_STATIC_ASSERT(cond) (void)sizeof(char[1 - 2 * !(cond)])

#define WT_SIZE_CHECK(type, e)
//#define WT_SIZE_CHECK(type, e)                               \
//    do {                                                     \
//        char __check_##type[1 - 2 * !(sizeof(type) == (e))]; \
//        (void)__check_##type;                                \
//    } while (0)
```

### wiredtiger

```src/third_party/wiredtiger/src/include/btree_inline.h
#define WT_KV_ENCODE_VALUE_OFFSET(v) ((uint64_t)(v) << 45)
```

```./src/third_party/wiredtiger/src/include/gcc.h
#define WT_WRITE_BARRIER()                 \
    do {                                   \
        __asm__ volatile("" ::: "memory"); \
    } while (0)

#else
//#error "No write barrier implementation for this hardware"
    #define WT_WRITE_BARRIER() do{}while(0);                 \
    do {                                   \
        __asm__ volatile("" ::: "memory"); \
    } while (0)
#endif
```


### boost

```
cd ~/work/mongo/src/third_party/boost-1.70.0
wget https://raw.githubusercontent.com/NixOS/nixpkgs/master/pkgs/development/libraries/boost/pthread-stack-min-fix.patch
patch -p1 < pthread-stack-min-fix.patch
```

By the way, the file itself is

```pthread-stack-min-fix.patch
Taken from https://github.com/conan-io/conan-center-index/pull/361/files

diff --git a/include/boost/thread/pthread/thread_data.hpp b/include/boost/thread/pthread/thread_data.hpp
index aefbeb4..bc9b136 100644
--- a/boost/thread/pthread/thread_data.hpp
+++ b/boost/thread/pthread/thread_data.hpp
@@ -57,7 +57,7 @@ namespace boost
 #else
           std::size_t page_size = ::sysconf( _SC_PAGESIZE);
 #endif
-#if PTHREAD_STACK_MIN > 0
+#ifdef PTHREAD_STACK_MIN
           if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN;
 #endif
           size = ((size+page_size-1)/page_size)*page_size;
```

### mozjs

```~/work/mongo/src/third_party/mozjs-60/extract/js/src/gc/Heap.h
#define static_assert(...) do{}while(0);
```

```src/third_party/mozjs-60/extract/js/src/gc/Heap.h
#define static_assert(...) do{}while(0);
```

```src/third_party/mozjs-60/extract/js/src/vm/JSScript.h
#define static_assert(...) do{}while(0);
```

```src/third_party/mozjs-60/include/js/UbiNode.h
#define static_assert(...) do{}while(0);
```

```src/third_party/mozjs-60/include/mozilla/Assertions.h
#define MOZ_CRASH_UNSAFE_PRINTF(format, ...) \
   do { \
/*     static_assert( \
       MOZ_ARG_COUNT(__VA_ARGS__) > 0, \
       "Did you forget arguments to MOZ_CRASH_UNSAFE_PRINTF? " \
       "Or maybe you want MOZ_CRASH instead?"); \
     static_assert( \
       MOZ_ARG_COUNT(__VA_ARGS__) <= sPrintfMaxArgs, \
       "Only up to 4 additional arguments are allowed!"); \
     static_assert(sizeof(format) <= sPrintfCrashReasonSize, \
       "The supplied format string is too long!"); \
     MOZ_CALL_CRASH_PRINTF("" format, __VA_ARGS__); \
 */  } while (false)

template<typename T>
struct AssertionConditionType
{
  typedef typename RemoveReference<T>::Type ValueT;
/*  static_assert(!IsArray<ValueT>::value,
                "Expected boolean assertion condition, got an array or a "
                "string!");
  static_assert(!IsFunction<ValueT>::value,
                "Expected boolean assertion condition, got a function! Did "
                "you intend to call that function?");
  static_assert(!IsFloatingPoint<ValueT>::value,
                "It's often a bad idea to assert that a floating-point number "
                "is nonzero, because such assertions tend to intermittently "
                "fail. Shouldn't your code gracefully handle this case instead "
                "of asserting? Anyway, if you really want to do that, write an "
                "explicit boolean condition, like !!x or x!=0.");
*/
  static const bool isValid = true;
};
```

```src/third_party/mozjs-60/extract/js/src/vm/Shape.h
#define static_assert(...) do{}while(0);
```

```src/third_party/mozjs-60/extract/js/src/vm/JSScript.h
#define static_assert(...) do{}while(0);
```

```src/third_party/mozjs-60/extract/js/src/jit/JitAllocPolicy.h
#define static_assert(...) do{}while(0);
```

```./src/third_party/mozjs-60/include/mozilla/Attributes.h
#define static_assert(...) do{}while(0);
```

### db

```src/mongo/db/exec/plan_stats.h
#include <optional>
```

# temporary swap enable

```
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
```

## build

```
cd ~/work/mongo
python3 buildscripts/scons.py -j 2
```

## finalizing...

```
sudo swapoff /swapfile
```