Repository: automl/random_forest_run (language: python)

Issue:
Swig 4.0 nondynamic support causing Segmentation fault
# Problem Statement
Random Forest run requires nondynamic support in two places

- Interface to swig [here](https://github.com/automl/random_forest_run/blob/316c4d9f57f93710d306ec2e8235198c43deccf7/pyrfr/pyrfr/regression.i#L3).
- And in the setup.py [here](https://github.com/automl/random_forest_run/blob/316c4d9f57f93710d306ec2e8235198c43deccf7/pyrfr/setup.py#L37).

Which causes the following segmentation fault:
```
# To make this trace one can install apt install python3-dbg gdb
# Have this dummy file
# cat reproduce.py 
#     import pyrfr.regression as reg
#     data = reg.default_data_container(64)
# 
# and run gdb -ex r --args python3 reproduce.py
(gdb) backtrace 
#0  0x00000000005cec00 in PyDict_SetItem (op=op@entry=0x0, key='this', 
    value=value@entry=<SwigPyObject at remote 0x7f9bd68cd180>) at ../Objects/dictobject.c:1526
#1  0x00007f9bd66ecf6f in SWIG_Python_SetSwigThis (
    swig_this=<SwigPyObject at remote 0x7f9bd68cd180>, inst=<optimized out>)
    at pyrfr/regression_wrap.cpp:1979
#2  SWIG_Python_InitShadowInstance (args=<optimized out>) at pyrfr/regression_wrap.cpp:2309

```

# Next Steps
This appears to be a problem with our usage of nondynamic support as tracked [here](https://github.com/swig/swig/issues/1955).



Discussion / hints:

Fix patch:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 523f915..3ccc6ac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,6 +6,9 @@ set (RFR_VERSION_MAJOR 0)
 set (RFR_VERSION_MINOR 8)
 set (RFR_VERSION_RELEASE 1)
 
+# Print debug information about boost
+set(Boost_DEBUG 1)
+
 IF(NOT CMAKE_BUILD_TYPE)
  SET(CMAKE_BUILD_TYPE "DEBUG")
  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") # enabling coverage
diff --git a/build_tools/build_source.sh b/build_tools/build_source.sh
index 20a8977..51bedf9 100644
--- a/build_tools/build_source.sh
+++ b/build_tools/build_source.sh
@@ -15,8 +15,8 @@ cmake .. && make pyrfr_docstrings
 cd python_package
 
 # Also build the distribution
-python -m pip install twine
-python setup.py sdist -d ../../dist
+python3 -m pip install twine
+python3 setup.py sdist -d ../../dist
 
 # Check whether the source distribution will render correctly
 twine check ../../dist/*.tar.gz
diff --git a/build_tools/build_wheels.sh b/build_tools/build_wheels.sh
index 00f4fd6..29d3084 100755
--- a/build_tools/build_wheels.sh
+++ b/build_tools/build_wheels.sh
@@ -7,14 +7,14 @@ pip3 install cmake numpy==1.11.0 scipy==0.17.0
 echo 'echo "pyuic5 $@"' > /usr/local/bin/pyuic5
 chmod +x /usr/local/bin/pyuic5
 yum install -y curl gsl-devel pcre-devel
-curl -LO http://prdownloads.sourceforge.net/swig/swig-3.0.12.tar.gz
-tar xzvf swig-3.0.12.tar.gz
-cd swig-3.0.12
+curl -LO https://downloads.sourceforge.net/swig/swig-4.0.2.tar.gz
+tar xzvf swig-4.0.2.tar.gz
+cd swig-4.0.2
 ./configure
 make
 make install
 cd ..
-rm -rf swig-3.0.12*
+rm -rf swig-4.0.2*
 swig -version
 
 # Install the package building dependencies -- one line at
diff --git a/build_tools/env.sh b/build_tools/env.sh
index 63e36eb..36602b8 100755
--- a/build_tools/env.sh
+++ b/build_tools/env.sh
@@ -4,15 +4,17 @@ set -e
 set -x
 
 # Install the environment requirements
-sudo apt-get install -y build-essential
-python -m pip install --upgrade pip
-pip install "numpy<=1.19"
-sudo apt-get -qq update
-sudo apt-get install -y libboost-all-dev
-sudo apt-get remove swig
-sudo apt-get -y install swig3.0
-sudo ln -s /usr/bin/swig3.0 /usr/bin/swig
+# order is important so boost is properly recognized by cmake
+sudo apt update
+sudo apt upgrade -y
+sudo apt install -y build-essential libboost-all-dev swig doxygen git cmake
+sudo apt-get install -y swig
+
+# ctest related requirements
+sudo apt-get install -y ruby-dev
 sudo gem install coveralls-lcov
 sudo apt-get install -y lcov
-sudo apt-get install doxygen
+
+# python package requirements
+python3 -m pip install --upgrade pip
 pip3 install --user -U pip-tools
diff --git a/pyrfr/setup.py b/pyrfr/setup.py
index 043f307..0d60b27 100644
--- a/pyrfr/setup.py
+++ b/pyrfr/setup.py
@@ -27,14 +27,14 @@ def run(self):
 					name = 'pyrfr._regression',
 					sources=['pyrfr/regression.i'],
 					include_dirs = include_dirs,
-					swig_opts=['-c++', '-modern', '-features', 'nondynamic'] + ['-I{}'.format(s) for s in include_dirs],
+					swig_opts=['-c++', '-modern', '-py3', '-features', 'nondynamic'] + ['-I{}'.format(s) for s in include_dirs],
 					extra_compile_args = extra_compile_args
 				),
 				Extension(
 					name = 'pyrfr._util',
 					sources=['pyrfr/util.i'],
 					include_dirs = include_dirs,
-					swig_opts=['-c++', '-modern', '-features', 'nondynamic'] + ['-I{}'.format(s) for s in include_dirs],
+					swig_opts=['-c++', '-modern', '-py3', '-features', 'nondynamic'] + ['-I{}'.format(s) for s in include_dirs],
 					extra_compile_args = extra_compile_args
 				)
 			]


Test patch:
diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml
index 3afa850..7f98374 100644
--- a/.github/workflows/pytest.yml
+++ b/.github/workflows/pytest.yml
@@ -10,10 +10,11 @@ on:
 jobs:
   ubuntu:
 
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-latest
     strategy:
       matrix:
         python-version: [3.6, 3.7, 3.8, 3.9]
+        swig: ['3.0', '4.0']
       fail-fast:  false
 
     steps:
@@ -30,19 +31,26 @@ jobs:
         chmod u+x ./build_tools/env.sh
         ./build_tools/env.sh
         lcov --directory . --zerocounters
-    - name: Setup cmake
-      uses: jwlawson/actions-setup-cmake@v1.5
-      with:
-        cmake-version: '3.10.2'
+    - name: Overwrite Swig
+      if: ${{ matrix.swig == '3.0'}}
+      run: |
+        sudo apt-get update
+        sudo apt-get remove swig
+        sudo apt-get install swig3.0
+        sudo ln -s /usr/bin/swig3.0 /usr/bin/swig
+    - name: Use swig
+      run: /usr/bin/swig -version
     - name: Use cmake
       run: cmake --version
     - name: Use g++
       run: g++ --version
+    - name: Use boost
+      run: whereis boost && dpkg -s libboost-dev | grep 'Version'
     - name: Run Ctest
       run: |
         mkdir build
         cd build
-        cmake .. -DSWIG_EXECUTABLE=/usr/bin/swig3.0
+        cmake .. -DSWIG_EXECUTABLE=/usr/bin/swig
         make
         ctest --output-on-failure
     - name: Coverage