diff --git a/README.md b/README.md index 9093b07e..5ea5adea 100644 --- a/README.md +++ b/README.md @@ -197,20 +197,44 @@ If you have installed to a different directory by changing the `--import` comman You can run ODM natively on Ubuntu 21.04 (although we don't recommend it): -1. Download the source from [here](https://github.com/OpenDroneMap/ODM/archive/master.zip) -2. Run `bash configure.sh install` -3. Download a sample dataset from [here](https://github.com/OpenDroneMap/odm_data_aukerman/archive/master.zip) (about 550MB) and extract it in `/datasets/aukerman` -4. Run `./run.sh --project-path /datasets odm_data_aukerman` +```bash +git clone https://github.com/OpenDroneMap/ODM +cd ODM +bash configure.sh install +``` + +You can then process datasets with `./run.sh /datasets/odm_data_aukerman` + +## Native Install (MacOS) + +You can run ODM natively on Intel/ARM MacOS. + +First install: + + * Xcode 13 (not 14, there's currently a bug) + * [Homebrew](https://docs.brew.sh/Installation) + +Then Run: + +```bash +git clone https://github.com/OpenDroneMap/ODM +cd ODM +bash configure_macos.sh install +``` + +You can then process datasets with `./run.sh /datasets/odm_data_aukerman` + +This could be improved in the future. [Helps us create a Homebrew formula](https://github.com/OpenDroneMap/ODM/issues/1531). ### Updating a native installation -When updating to a newer version of ODM, it is recommended that you run +When updating to a newer version of native ODM, it is recommended that you run: - bash configure.sh reinstall +`bash configure.sh reinstall` to ensure all the dependent packages and modules get updated. -### Build From Source +### Build Docker Images From Source If you want to rebuild your own docker image (if you have changed the source code, for example), from the ODM folder you can type: diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt index d87649ca..862c42f5 100644 --- a/SuperBuild/CMakeLists.txt +++ b/SuperBuild/CMakeLists.txt @@ -2,13 +2,41 @@ cmake_minimum_required(VERSION 3.1) project(ODM-SuperBuild) +# Setup SuperBuild root location +set(SB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + if (NOT CMAKE_BUILD_TYPE) message(STATUS "No build type selected, default to Release") set(CMAKE_BUILD_TYPE "Release") endif() -# Setup SuperBuild root location -set(SB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +if (APPLE) + find_program(HOMEBREW_EXECUTABLE brew) + mark_as_advanced(FORCE HOMEBREW_EXECUTABLE) + if (HOMEBREW_EXECUTABLE) + # Detected a Homebrew install, query for its install prefix. + execute_process(COMMAND ${HOMEBREW_EXECUTABLE} --prefix + OUTPUT_VARIABLE HOMEBREW_INSTALL_PREFIX + OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "Detected Homebrew with install prefix: " + "${HOMEBREW_INSTALL_PREFIX}, adding to CMake search paths.") + list(APPEND CMAKE_PREFIX_PATH "${HOMEBREW_INSTALL_PREFIX}") + endif() + + # Use homebrew's clang compiler since Apple + # does not allow us to link to libomp + set(CXX_PATH ${HOMEBREW_INSTALL_PREFIX}/bin/c++-12) + message("Checking for ${CXX_PATH}...") + if(EXISTS "${CXX_PATH}") + message("Found Homebrew's compiler: ${CXX_PATH}") + set(CMAKE_CXX_COMPILER ${CXX_PATH}) + set(APPLE_CMAKE_ARGS "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}") + endif() + + if (NOT APPLE_CMAKE_ARGS) + message(WARNING "Cannot find Homebrew's compiler, compilation might fail...") + endif() +endif() ################################ # Setup SuperBuild directories # @@ -75,6 +103,9 @@ if (WIN32) file(COPY ${CUDA_DLLS} DESTINATION "${SB_INSTALL_DIR}/bin") set(WIN32_GDAL_ARGS -DGDAL_FOUND=TRUE -DGDAL_LIBRARY=${GDAL_LIBRARY} -DGDAL_INCLUDE_DIR=${GDAL_INCLUDE_DIR}) +elseif(APPLE) + set(PYTHON_HOME "${SB_ROOT_DIR}/../venv") + set(PYTHON_EXE_PATH "${PYTHON_HOME}/bin/python") else() set(PYTHON_EXE_PATH "/usr/bin/python3") endif() @@ -139,10 +170,10 @@ set(custom_libs OpenSfM externalproject_add(mve GIT_REPOSITORY https://github.com/OpenDroneMap/mve.git - GIT_TAG 262 + GIT_TAG 290 UPDATE_COMMAND "" SOURCE_DIR ${SB_SOURCE_DIR}/mve - CMAKE_ARGS ${WIN32_CMAKE_ARGS} + CMAKE_ARGS ${WIN32_CMAKE_ARGS} ${APPLE_CMAKE_ARGS} BUILD_IN_SOURCE 1 INSTALL_COMMAND "" ) @@ -160,10 +191,13 @@ if (WIN32) else() set (POISSON_BUILD_CMD make -j${nproc} poissonrecon) set (POISSON_BIN_PATH "Linux/PoissonRecon") + if (APPLE) + set(POISSON_BUILD_CMD COMPILER=${CMAKE_CXX_COMPILER} make -j${nproc} -f Makefile.macos poissonrecon) + endif() endif() externalproject_add(poissonrecon GIT_REPOSITORY https://github.com/OpenDroneMap/PoissonRecon.git - GIT_TAG 272 + GIT_TAG 290 PREFIX ${SB_BINARY_DIR}/PoissonRecon SOURCE_DIR ${SB_SOURCE_DIR}/PoissonRecon UPDATE_COMMAND "" @@ -180,6 +214,7 @@ externalproject_add(dem2mesh SOURCE_DIR ${SB_SOURCE_DIR}/dem2mesh CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} ${WIN32_GDAL_ARGS} + ${APPLE_CMAKE_ARGS} ) externalproject_add(dem2points @@ -189,12 +224,13 @@ externalproject_add(dem2points SOURCE_DIR ${SB_SOURCE_DIR}/dem2points CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} ${WIN32_GDAL_ARGS} + ${APPLE_CMAKE_ARGS} ) externalproject_add(odm_orthophoto DEPENDS opencv GIT_REPOSITORY https://github.com/OpenDroneMap/odm_orthophoto.git - GIT_TAG 288b + GIT_TAG 290 PREFIX ${SB_BINARY_DIR}/odm_orthophoto SOURCE_DIR ${SB_SOURCE_DIR}/odm_orthophoto CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} diff --git a/SuperBuild/cmake/External-Entwine.cmake b/SuperBuild/cmake/External-Entwine.cmake index 5d52e879..6319212f 100644 --- a/SuperBuild/cmake/External-Entwine.cmake +++ b/SuperBuild/cmake/External-Entwine.cmake @@ -13,7 +13,7 @@ ExternalProject_Add(${_proj_name} #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} GIT_REPOSITORY https://github.com/OpenDroneMap/entwine/ - GIT_TAG 285 + GIT_TAG 290 #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- @@ -33,4 +33,4 @@ ExternalProject_Add(${_proj_name} LOG_DOWNLOAD OFF LOG_CONFIGURE OFF LOG_BUILD OFF -) +) \ No newline at end of file diff --git a/SuperBuild/cmake/External-MvsTexturing.cmake b/SuperBuild/cmake/External-MvsTexturing.cmake index 4f8828f3..dd2d7c68 100644 --- a/SuperBuild/cmake/External-MvsTexturing.cmake +++ b/SuperBuild/cmake/External-MvsTexturing.cmake @@ -9,7 +9,7 @@ ExternalProject_Add(${_proj_name} #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}/${_proj_name} GIT_REPOSITORY https://github.com/OpenDroneMap/mvs-texturing - GIT_TAG 287 + GIT_TAG 290 #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- @@ -19,6 +19,7 @@ ExternalProject_Add(${_proj_name} -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} ${WIN32_CMAKE_ARGS} + ${APPLE_CMAKE_ARGS} #--Build step----------------- BINARY_DIR ${_SB_BINARY_DIR} #--Install step--------------- diff --git a/SuperBuild/cmake/External-Obj2Tiles.cmake b/SuperBuild/cmake/External-Obj2Tiles.cmake index 53b86913..cb83bf91 100644 --- a/SuperBuild/cmake/External-Obj2Tiles.cmake +++ b/SuperBuild/cmake/External-Obj2Tiles.cmake @@ -10,6 +10,8 @@ if (WIN32) set(OBJ2TILES_EXT ".exe") elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64") set(OBJ2TILES_ARCH "LinuxArm") +elseif(APPLE) + set(OBJ2TILES_ARCH "Osx64") endif() diff --git a/SuperBuild/cmake/External-OpenCV.cmake b/SuperBuild/cmake/External-OpenCV.cmake index d40d0b42..812d4873 100644 --- a/SuperBuild/cmake/External-OpenCV.cmake +++ b/SuperBuild/cmake/External-OpenCV.cmake @@ -2,12 +2,32 @@ set(_proj_name opencv) set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}") if (WIN32) - set(WIN32_CMAKE_EXTRA_ARGS -DPYTHON3_NUMPY_INCLUDE_DIRS=${PYTHON_HOME}/lib/site-packages/numpy/core/include + set(OCV_CMAKE_EXTRA_ARGS -DPYTHON3_NUMPY_INCLUDE_DIRS=${PYTHON_HOME}/lib/site-packages/numpy/core/include -DPYTHON3_PACKAGES_PATH=${PYTHON_HOME}/lib/site-packages -DPYTHON3_EXECUTABLE=${PYTHON_EXE_PATH} -DWITH_MSMF=OFF -DOPENCV_LIB_INSTALL_PATH=${SB_INSTALL_DIR}/lib -DOPENCV_BIN_INSTALL_PATH=${SB_INSTALL_DIR}/bin) +elseif(APPLE) + # macOS is unable to automatically detect our Python libs + set(OCV_CMAKE_EXTRA_ARGS -DPYTHON3_NUMPY_INCLUDE_DIRS=${PYTHON_HOME}/lib/python3.8/site-packages/numpy/core/include + -DPYTHON3_PACKAGES_PATH=${PYTHON_HOME}/lib/python3.8/site-packages + -DPYTHON3_EXECUTABLE=${PYTHON_EXE_PATH} + -DPYTHON3_LIBRARIES=${HOMEBREW_INSTALL_PREFIX}/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/lib/libpython3.8.dylib + -DPYTHON3_INCLUDE_DIR=${HOMEBREW_INSTALL_PREFIX}/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/include/python3.8/ + -DPYTHON3_INCLUDE_PATH=${HOMEBREW_INSTALL_PREFIX}/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/include/python3.8/ + -DPYTHON3INTERP_FOUND=ON + -DPYTHON3LIBS_FOUND=ON + -DPYTHON_DEFAULT_AVAILABLE=ON + -DPYTHON_DEFAULT_EXECUTABLE=${PYTHON_EXE_PATH} + -DPYTHON3_VERSION_MAJOR=3 + -DPYTHON3_VERSION_MINOR=8 + -DOPENCV_CONFIG_INSTALL_PATH= + -DOPENCV_PYTHON_INSTALL_PATH=${SB_INSTALL_DIR}/lib/python3.8/dist-packages + -DHAVE_opencv_python3=ON + -DOPENCV_PYTHON_SKIP_DETECTION=ON + -DOPENCV_LIB_INSTALL_PATH=${SB_INSTALL_DIR}/lib + -DOPENCV_BIN_INSTALL_PATH=${SB_INSTALL_DIR}/bin) endif() ExternalProject_Add(${_proj_name} @@ -41,6 +61,7 @@ ExternalProject_Add(${_proj_name} -DWITH_VTK=OFF -DWITH_EIGEN=OFF -DWITH_OPENNI=OFF + -DWITH_OPENEXR=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF @@ -60,7 +81,7 @@ ExternalProject_Add(${_proj_name} -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} ${WIN32_CMAKE_ARGS} - ${WIN32_CMAKE_EXTRA_ARGS} + ${OCV_CMAKE_EXTRA_ARGS} #--Build step----------------- BINARY_DIR ${_SB_BINARY_DIR} #--Install step--------------- @@ -69,4 +90,4 @@ ExternalProject_Add(${_proj_name} LOG_DOWNLOAD OFF LOG_CONFIGURE OFF LOG_BUILD OFF -) +) \ No newline at end of file diff --git a/SuperBuild/cmake/External-OpenMVS.cmake b/SuperBuild/cmake/External-OpenMVS.cmake index 95438758..7f2c6e3b 100644 --- a/SuperBuild/cmake/External-OpenMVS.cmake +++ b/SuperBuild/cmake/External-OpenMVS.cmake @@ -24,7 +24,8 @@ externalproject_add(eigen34 ) SET(ARM64_CMAKE_ARGS "") -if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64" ) + +if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64") SET(ARM64_CMAKE_ARGS -DOpenMVS_USE_SSE=OFF) endif() diff --git a/SuperBuild/cmake/External-OpenSfM.cmake b/SuperBuild/cmake/External-OpenSfM.cmake index ee720d58..43d76a60 100644 --- a/SuperBuild/cmake/External-OpenSfM.cmake +++ b/SuperBuild/cmake/External-OpenSfM.cmake @@ -3,12 +3,18 @@ set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}") include(ProcessorCount) ProcessorCount(nproc) +set(EXTRA_INCLUDE_DIRS "") if(WIN32) set(OpenCV_DIR "${SB_INSTALL_DIR}/x64/vc16/lib") set(BUILD_CMD ${CMAKE_COMMAND} --build "${SB_BUILD_DIR}/opensfm" --config "${CMAKE_BUILD_TYPE}") else() - set(OpenCV_DIR "${SB_INSTALL_DIR}/lib/cmake/opencv4") set(BUILD_CMD make "-j${nproc}") + if (APPLE) + set(OpenCV_DIR "${SB_INSTALL_DIR}") + set(EXTRA_INCLUDE_DIRS "${HOMEBREW_INSTALL_PREFIX}/include") + else() + set(OpenCV_DIR "${SB_INSTALL_DIR}/lib/cmake/opencv4") + endif() endif() ExternalProject_Add(${_proj_name} @@ -19,7 +25,7 @@ ExternalProject_Add(${_proj_name} #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} GIT_REPOSITORY https://github.com/OpenDroneMap/OpenSfM/ - GIT_TAG 288 + GIT_TAG 290 #--Update/Patch step---------- UPDATE_COMMAND git submodule update --init --recursive #--Configure step------------- @@ -28,6 +34,7 @@ ExternalProject_Add(${_proj_name} -DCERES_ROOT_DIR=${SB_INSTALL_DIR} -DOpenCV_DIR=${OpenCV_DIR} -DADDITIONAL_INCLUDE_DIRS=${SB_INSTALL_DIR}/include + -DYET_ADDITIONAL_INCLUDE_DIRS=${EXTRA_INCLUDE_DIRS} -DOPENSFM_BUILD_TESTS=off -DPYTHON_EXECUTABLE=${PYTHON_EXE_PATH} ${WIN32_CMAKE_ARGS} diff --git a/SuperBuild/cmake/External-PDAL.cmake b/SuperBuild/cmake/External-PDAL.cmake index 634c9899..4fda625c 100644 --- a/SuperBuild/cmake/External-PDAL.cmake +++ b/SuperBuild/cmake/External-PDAL.cmake @@ -3,6 +3,8 @@ set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}") if (WIN32) set(LASZIP_LIB "${SB_INSTALL_DIR}/lib/laszip.lib") +elseif(APPLE) +set(LASZIP_LIB "${SB_INSTALL_DIR}/lib/liblaszip.dylib") else() set(LASZIP_LIB "${SB_INSTALL_DIR}/lib/liblaszip.so") endif() diff --git a/VERSION b/VERSION index 80803faf..c8e38b61 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.8.8 +2.9.0 diff --git a/configure_macos.sh b/configure_macos.sh new file mode 100755 index 00000000..b86c5f30 --- /dev/null +++ b/configure_macos.sh @@ -0,0 +1,121 @@ +#!/bin/bash +uname=$(uname) +if [[ "$uname" != "Darwin" ]]; then + echo "This script is meant for MacOS only." + exit 1 +fi + +if [[ $2 =~ ^[0-9]+$ ]] ; then + processes=$2 +else + processes=$(sysctl -n hw.ncpu) +fi + +ensure_prereqs() { + export DEBIAN_FRONTEND=noninteractive + + if ! command -v xcodebuild &> /dev/null; then + echo "You need to install Xcode first. Go to the App Store and download Xcode" + exit 1 + fi + + if ! command -v brew &> /dev/null; then + echo "You need to install Homebrew first. https://brew.sh/" + exit 1 + fi + +} + +installreqs() { + ensure_prereqs + + brew install cmake gcc@12 python@3.8 tbb@2020 eigen gdal boost cgal libomp + brew link tbb@2020 + + python3.8 -m pip install virtualenv + + if [ ! -e ${RUNPATH}/venv ]; then + python3.8 -m virtualenv venv + fi + + source venv/bin/activate + pip install --ignore-installed -r requirements.txt +} + +install() { + installreqs + + echo "Compiling SuperBuild" + cd ${RUNPATH}/SuperBuild + mkdir -p build && cd build + cmake .. && make -j$processes + + cd /tmp + pip download GDAL==3.5.1 + tar -xpzf GDAL-3.5.1.tar.gz + cd GDAL-3.5.1 + if [ -e /opt/homebrew/bin/gdal-config ]; then + python setup.py build_ext --gdal-config /opt/homebrew/bin/gdal-config + else + python setup.py build_ext --gdal-config /usr/local/bin/gdal-config + fi + python setup.py build + python setup.py install + rm -fr /tmp/GDAL-3.5.1 /tmp/GDAL-3.5.1.tar.gz + + cd ${RUNPATH} + + echo "Configuration Finished" +} + +uninstall() { + echo "Removing SuperBuild and build directories" + cd ${RUNPATH}/SuperBuild + rm -rfv build src download install + cd ../ + rm -rfv build +} + +reinstall() { + echo "Reinstalling ODM modules" + uninstall + install +} + +clean() { + rm -rf \ + ${RUNPATH}/SuperBuild/build \ + ${RUNPATH}/SuperBuild/download \ + ${RUNPATH}/SuperBuild/src + + # find in /code and delete static libraries and intermediate object files + find ${RUNPATH} -type f -name "*.a" -delete -or -type f -name "*.o" -delete +} + +usage() { + echo "Usage:" + echo "bash configure.sh [nproc]" + echo "Subcommands:" + echo " install" + echo " Installs all dependencies and modules for running OpenDroneMap" + echo " reinstall" + echo " Removes SuperBuild and build modules, then re-installs them. Note this does not update OpenDroneMap to the latest version. " + echo " uninstall" + echo " Removes SuperBuild and build modules. Does not uninstall dependencies" + echo " installreqs" + echo " Only installs the requirements (does not build SuperBuild)" + echo " clean" + echo " Cleans the SuperBuild directory by removing temporary files. " + echo " help" + echo " Displays this message" + echo "[nproc] is an optional argument that can set the number of processes for the make -j tag. By default it uses $(nproc)" +} + +if [[ $1 =~ ^(install|installruntimedepsonly|reinstall|uninstall|installreqs|clean)$ ]]; then + RUNPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + "$1" +else + echo "Invalid instructions." >&2 + usage + exit 1 +fi diff --git a/opendm/system.py b/opendm/system.py index bf5f279a..4feff283 100644 --- a/opendm/system.py +++ b/opendm/system.py @@ -81,7 +81,10 @@ def run(cmd, env_paths=[context.superbuild_bin_path], env_vars={}, packages_path if len(packages_paths) > 0: env["PYTHONPATH"] = env.get("PYTHONPATH", "") + sep + sep.join(packages_paths) - + if sys.platform == 'darwin': + # Propagate DYLD_LIBRARY_PATH + cmd = "export DYLD_LIBRARY_PATH=\"%s\" && %s" % (env.get("DYLD_LIBRARY_PATH", ""), cmd) + for k in env_vars: env[k] = str(env_vars[k]) diff --git a/requirements.txt b/requirements.txt index d74435dd..c5441e9a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,16 +6,16 @@ edt==2.0.2 ODMExifRead==3.0.4 Fiona==1.8.17 ; sys_platform == 'linux' or sys_platform == 'darwin' https://github.com/OpenDroneMap/windows-deps/raw/main/Fiona-1.8.19-cp38-cp38-win_amd64.whl ; sys_platform == 'win32' -joblib==0.17.0 +joblib==1.1.0 laspy==1.7.0 lxml==4.6.1 matplotlib==3.3.3 networkx==2.5 numpy==1.23.1 Pillow==8.3.2 -vmem==1.0.1 +vmem==1.0.2 pyodm==1.5.8 -pyproj==3.0.0.post1 +pyproj==3.3.1 Pysolar==0.9 pytz==2020.4 PyYAML==5.1 @@ -23,10 +23,11 @@ rasterio==1.2.3 ; sys_platform == 'linux' or sys_platform == 'darwin' https://github.com/OpenDroneMap/windows-deps/raw/main/rasterio-1.2.3-cp38-cp38-win_amd64.whl ; sys_platform == 'win32' https://github.com/OpenDroneMap/windows-deps/raw/main/GDAL-3.2.3-cp38-cp38-win_amd64.whl ; sys_platform == 'win32' repoze.lru==0.7 -scikit-learn==0.24.2 -scikit-image==0.18.3 -scipy==1.5.4 +scikit-learn==1.1.1 +Pywavelets==1.3.0 +scikit-image==0.19.3 +scipy==1.8.1 xmltodict==0.12.0 fpdf2==2.4.6 Shapely==1.7.1 -onnxruntime==1.12.1 \ No newline at end of file +onnxruntime==1.12.1 diff --git a/run.sh b/run.sh index a743b6de..a01df6e2 100755 --- a/run.sh +++ b/run.sh @@ -1,6 +1,10 @@ #!/bin/bash RUNPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +if [ -e $RUNPATH/venv ]; then + source $RUNPATH/venv/bin/activate +fi export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RUNPATH/SuperBuild/install/lib +export DYLD_LIBRARY_PATH=$RUNPATH/SuperBuild/install/lib python3 $RUNPATH/run.py "$@"