Installation

This was tested with Python3.7 to Python3.10 on Ubuntu 18.04 to 22.04, Fedora 36 and 37, WSL on Windows.

Install build dependencies

sudo apt -y install build-essential software-properties-common python3-software-properties
sudo apt -y install libboost-all-dev
sudo apt -y install libpng-dev libjpeg-dev libtiff-dev libglew-dev zlib1g-dev
sudo apt -y install libeigen3-dev
sudo apt -y install libcanberra-gtk-module libcanberra-gtk3-module
sudo apt -y install qt5-default

Note

For Ubuntu 22.04, replace sudo apt -y install qt5-default with sudo apt-get install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools.

Preparing python

You can either use a Conda environment, a virtualenv, or use the system’s python. We recommend using Conda.

  • Option A: Conda

    1. Install Conda

    wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
    bash Miniconda3*.sh
    conda init
    
    1. Create a Conda environment and install pybind11

    conda create -n sofa python=3.9
    conda activate sofa
    conda install -c conda-forge pybind11
    
  • Option B: VirtualEnv

    python3 -m venv $HOME/sofa/venv
    source $HOME/sofa/venv/bin/activate
    pip3 install pybind11
    
  • Option C: System

    sudo apt install python3-pybind11
    

Environment variables for building SOFA

  1. Set source and build paths

FOLDER_SRC=$HOME/sofa/src
FOLDER_TARGET=$HOME/sofa/build
FOLDER_SP3=$FOLDER_SRC/applications/plugins/SofaPython3
  1. Set variables for building SofaPython3

    • Option A: Conda

    PYTHON_PKG_PATH=$(python3 -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])')
    PYTHON_EXE=$(which python3)
    PYTHON_ROOT_DIR=$CONDA_PREFIX
    
    • Option B: VirtualEnv

    PYTHON_PKG_PATH=$(python3 -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])')
    PYTHON_EXE=$(which python3)
    PYTHON_ROOT_DIR=$VIRTUAL_ENV
    
    • Option C: System

    PYTHON_PKG_PATH=$(python3 -m site --user-site)
    PYTHON_EXE=$(which python3)
    PYTHON_ROOT_DIR=/usr/local
    

Clone the SOFA repository

mkdir -p $FOLDER_SRC
mkdir -p $FOLDER_TARGET
git clone https://github.com/sofa-framework/sofa.git $FOLDER_SRC
cd $FOLDER_SRC
git checkout v23.06
cd $FOLDER_SP3
git init
git remote add origin https://github.com/sofa-framework/SofaPython3.git
git pull origin master
git checkout 5a7371616fe8914530d44bf25ea6b724a6b1a08e

Run cmake

cmake -Wno-dev \
-S $FOLDER_SRC -B $FOLDER_TARGET \
-DCMAKE_BUILD_TYPE=Release \
-DSOFA_FETCH_SOFAPYTHON3=OFF \
-DPLUGIN_SOFAPYTHON3=ON \
-DPython_EXECUTABLE=$PYTHON_EXE \
-DPython_ROOT_DIR=$PYTHON_ROOT_DIR \
-DSP3_LINK_TO_USER_SITE=ON \
-DSP3_PYTHON_PACKAGES_LINK_DIRECTORY=$PYTHON_PKG_PATH \
-DPLUGIN_SOFACARVING=ON \
-DSP3_BUILD_TEST=OFF \
-DSOFA_BUILD_TESTS=OFF

For debugging the SOFA build itself, the following two CMake arguments are also helpful:

-DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1

Compile SOFA

  1. Build SOFA

cmake --build $FOLDER_TARGET -j --target install

Warning

Using the -j flag tells cmake to build multiple targets in parallel. If you run out of memory, the compilation will fail. You can either reduce the number of parallel processes by passing a number to cmake (e.g. -j 2) or by increasing the size of your swapfile.

  1. Add SofaPython3 to the list of default plugins so that SOFA loads it by default.

echo "" | tee -a $FOLDER_TARGET/install/lib/plugin_list.conf.default
echo "$FOLDER_TARGET/install/plugins/SofaPython3/lib/libSofaPython3.so 1.0" | tee -a $FOLDER_TARGET/install/lib/plugin_list.conf.default

Warning

Empty the build folder after every change in code / commit. You never know…

rm -rf $FOLDER_TARGET
mkdir -p $FOLDER_TARGET

After that you can run cmake to configure and build.

Setting environment variables

Setting environment variables for python to let SOFA and SofaPython3 know where to find the relevant stuff

Warning

On the last checked commit, SofaPython3 might have troubles finding the correct libpython3.9.so.1.0. If that happens, add the directory that holds the libpython3.9.so.1.0 that you used to compile to the LD_LIBRARY_PATH environment variable. E.g.:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PYTHON_ROOT_DIR/lib

We do not add this environment variable to conda, because conda will hard code the variable to whatever you set it to, not evaluating LD_LIBRARY_PATH=$LD_LIBRARY_PATH:... again. Furthermore this is a bug, introduced in recent commits and should hopefully be resolved soon.

  • Option A: Conda

conda env config vars set SOFA_ROOT=$FOLDER_TARGET/install
conda env config vars set SOFAPYTHON3_ROOT=$FOLDER_TARGET/install/plugins/SofaPython3

Note

For Ubuntu 22.04: If SOFA is missing GLIBCXX_3.4.30, install it with conda install -c conda-forge gcc=12.1.0

  • Option B: VirtualEnv

You can also do this stuff with the virtualenvwrapper https://virtualenvwrapper.readthedocs.io/en/latest/

  • Option C: System

Export the environment variables through your ~/.bashrc or ~/.zshrc

echo export SOFA_ROOT=$FOLDER_TARGET/install >> ~/.bashrc
echo export SOFAPYTHON3_ROOT=$FOLDER_TARGET/install/plugins/SofaPython3 >> ~/.bashrc

Adding additional SOFA Plugins

If you want to compile SOFA with additional plugins, such as BeamAdapter or Cosserat, you will have to do a few additional steps

  1. In step Environment variables for building SOFA export additional environment variables for each plugin

FOLDER_BEAM=$FOLDER_SRC/applications/plugins/BeamAdapter
FOLDER_COSSERAT=$FOLDER_SRC/applications/plugins/Cosserat
  1. In step Clone the SOFA repository clone the additional plugins

git clone git@github.com:sofa-framework/BeamAdapter.git $FOLDER_BEAM
git clone git@github.com:SofaDefrost/plugin.Cosserat.git $FOLDER_COSSERAT
  1. in step Run cmake add this flag to the cmake command

-DSOFA_EXTERNAL_DIRECTORIES="$FOLDER_BEAM;$FOLDER_COSSERAT" \
  1. After compiling, move the built libraries into the install directory

cp -r $FOLDER_TARGET/external_directories/BeamAdapter $FOLDER_TARGET/install/plugins
cp -r $FOLDER_TARGET/external_directories/Cosserat $FOLDER_TARGET/install/plugins

Manually Linking SofaPython3 to Python

If for some reason installing SofaPython3 does not work (cannot import Sofa in Python), you will probably just need to correctly link the modules compiled in SofaPython3 to your environment. To import a module, python will look for it in the site-packages dir. For Conda, that is most likely in $HOME/miniconda3/envs/<env_name>/lib/python3.9/site-packages. First, locate where the SofaPython3 modules were compiled to (e.g. $HOME/sofa/build/install/plugins/SofaPython3/lib/python3/site-packages) and then create soft links from all the modules into site-packages.

For example:

ln -s $HOME/sofa/build/install/plugins/SofaPython3/lib/python3/site-packages/Sofa $HOME/miniconda3/envs/<env_name>/lib/python3.9/site-packages/Sofa
ln -s $HOME/sofa/build/install/plugins/SofaPython3/lib/python3/site-packages/SofaRuntime $HOME/miniconda3/envs/<env_name>/lib/python3.9/site-packages/SofaRuntime
ln -s $HOME/sofa/build/install/plugins/SofaPython3/lib/python3/site-packages/SofaTypes $HOME/miniconda3/envs/<env_name>/lib/python3.9/site-packages/SofaTypes
ln -s $HOME/sofa/build/install/plugins/SofaPython3/lib/python3/site-packages/splib $HOME/miniconda3/envs/<env_name>/lib/python3.9/site-packages/splib