diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8382a5160e698c43881afdce2a6659a807e61204..2d8b05facafc19c2000fbef9fa8838c4f78a6d43 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -58,22 +58,29 @@ endif()
 #######################################################
 add_subdirectory(src)
 set(PKG_INST_DIR "${PROJECT_SOURCE_DIR}/inst")
-
 file(MAKE_DIRECTORY ${PKG_INST_DIR})
+
+# Options for mex compilation
 string(REGEX REPLACE ";" ";-I" _MKOCTFILE_INCLUDES "-I${CONAN_INCLUDE_DIRS}")
 string(REGEX REPLACE ";" ";-L" _MKOCTFILE_LIB_DIRS "-L${CONAN_LIB_DIRS}")
 string(REGEX REPLACE ";" ";-l" _MKOCTFILE_LIBS "-l${CONAN_LIBS}")
 string(REGEX REPLACE ";" ":" _MKOCTFILE_RPATH "${CONAN_LIB_DIRS}")
-set(_MKOCTFILE_OPTIONS "-o" "${PKG_INST_DIR}/caosdb.mex" "-Wl,-rpath,${_MKOCTFILE_RPATH}" "--mex" "-std=gnu++17"
+set(_MKOCTFILE_OPTIONS "-Wl,-rpath,${_MKOCTFILE_RPATH}" "--mex" "-std=gnu++17"
     "-L/usr/local/lib" ${_MKOCTFILE_INCLUDES} ${_MKOCTFILE_LIB_DIRS} ${_MKOCTFILE_LIBS})
 
-add_custom_command(OUTPUT ${PKG_INST_DIR}/caosdb.mex
-    COMMAND mkoctfile
-    ARGS ${_MKOCTFILE_OPTIONS} ${OCTAVE_CAOSDB_SRC}
-    DEPENDS ${OCTAVE_CAOSDB_SRC}
-    )
-add_custom_target(caosdb.mex ALL
-    SOURCES ${PKG_INST_DIR}/caosdb.mex)
+file(GLOB_RECURSE _CPP_SOURCES RELATIVE "${PROJECT_SOURCE_DIR}/src" src/*.cpp)
+foreach(sourcefile ${_CPP_SOURCES})
+    STRING(REGEX REPLACE ".cpp$" ".mex" _mex_ext_file ${sourcefile})
+    set(_mex_ext_file "${PKG_INST_DIR}/${_mex_ext_file}")
+    set(_mkoct_output "-o" "${_mex_ext_file}")
+    set(_abs_source "${PROJECT_SOURCE_DIR}/src/${sourcefile}")
+    add_custom_command(OUTPUT ${_mex_ext_file}
+        COMMAND mkoctfile
+        ARGS ${_MKOCTFILE_OPTIONS} ${_mkoct_output} ${_abs_source}
+        MAIN_DEPENDENCY ${_abs_source}
+        )
+    add_custom_target(mex ALL DEPENDS ${_mex_ext_file})
+endforeach(sourcefile)
 
 
 #######################################################
diff --git a/README_SETUP.md b/README_SETUP.md
index 688d7c97a0f88a355b55e37b7e2094842ddf1770..12cc034607da0c549d18d1e772a4d23057eb2a4f 100644
--- a/README_SETUP.md
+++ b/README_SETUP.md
@@ -51,20 +51,3 @@ static website. If you rather would like to use the native,
 - `sphinx-autoapi`
 - `recommonmark`
 
-### Writing Documentation
-
-- Example for texinfo documentation:
-  https://github.com/gnu-octave/octave/blob/default/scripts/geometry/inpolygon.m
-- Extract documentation from file:  
-  `[txt, form] = get_help_text_from_file(make_absolute_filename('pkg/inst/some_function.m'))`
-- Generate HTML documentation from single file:  
-  ```octave
-pkg uninstall caosdb
-pkg install caosdb.tar.gz
-pkg load caosdb
-html_help_text('some_function', './htdocs/some.html', 'octave-forge', pkgname="caosdb")
-```
-- Generate HTML documentation for a package:  
-  ```octave
-generate_package_html('caosdb', 'htdocs', 'octave-forge')
-```
diff --git a/doc/Development.rst b/doc/Development.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fca47d741ad4cf19b66d31719f101e3d4225d875
--- /dev/null
+++ b/doc/Development.rst
@@ -0,0 +1,31 @@
+Development
+===========
+
+Structure
+---------
+
+The sources for functions and classes are in ``src/``.  Private functions (mostly C++ source files
+which are to be compiled into ``*.mex``) are implemented in ``private/_some_function.*``.
+
+
+
+Writing Documentation
+---------------------
+
+- Example for texinfo documentation:
+  https://github.com/gnu-octave/octave/blob/default/scripts/geometry/inpolygon.m
+- Extract documentation from file:
+  ``[txt, form] = get_help_text_from_file(make_absolute_filename('pkg/inst/some_function.m'))``
+- Generate HTML documentation from single file:
+
+    .. code-block:: octave
+
+       pkg uninstall caosdb
+       pkg install caosdb.tar.gz
+       pkg load caosdb
+       html_help_text('some_function', './htdocs/some.html', 'octave-forge', pkgname="caosdb")
+- Generate HTML documentation for a package:
+
+    .. code-block:: octave
+
+       generate_package_html('caosdb', 'htdocs', 'octave-forge')
diff --git a/doc/Makefile b/doc/Makefile
index f985ba9f353c51c2d399d4bef6a05f623af81ce2..5f1840a185541ad9699c4ad79cb721d1295a3a34 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -42,7 +42,7 @@ doc-help:
 
 # Catch-all target: route all unknown targets to Sphinx using the new
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile octavedoc
+%: Makefile
 	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
 
 octavedoc:
diff --git a/doc/conf.py b/doc/conf.py
index b7c2ef8ec1d1614793f15cd97a2d74876318a9d1..514d7de89df4d982d8f25d114f5d7787a33843be 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -91,7 +91,7 @@ html_theme = "sphinx_rtd_theme"
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
 html_static_path = [
-    '_static',
+    # '_static',
     '_build_octave',
 ]
 
diff --git a/doc/index.rst b/doc/index.rst
index 0b144d0adc5de915e739e7a12e778195947ada34..6ccd2939ebe461fa4cb92af557b63c8e430dfbdb 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -38,6 +38,7 @@ This is work in progress.
     :caption: Contents:
 
     Welcome <self>
+    Development
     api/index
 
 * :ref:`genindex`
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 908c635c0eb62381f0a334549dda94bd3affe6bd..b8bdb6fd379c676a6c68bf434b2368d9a986edf6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -18,8 +18,9 @@
 # along with this program. If not, see <https://www.gnu.org/licenses/>.
 #
 
+# We want to compile all the _*.cpp files in `private`
 set(OCTAVE_CAOSDB_SRC
-    ${CMAKE_CURRENT_SOURCE_DIR}/caosdb.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/private/_caosdb.cpp
     )
 
 # pass variable to parent scope
diff --git a/src/configure b/src/configure
index 8574639dfbc8ebc2407bdd0b56dab904220ce8bb..5266b64232c56de3c21ca84025c79bf4cbab5646 100755
--- a/src/configure
+++ b/src/configure
@@ -9,6 +9,7 @@ INST_DIR="$(realpath ../inst)"
 echo "Octave CaosDB INST_DIR: $INST_DIR"
 rm -r "${INST_DIR}" || true
 mkdir -p "${INST_DIR}"
+mkdir -p "${INST_DIR}/private"
 
 BUILD_DIR="$(realpath ../build)"
 echo "Octave CaosDB BUILD_DIR: $BUILD_DIR"
diff --git a/src/caosdb.cpp b/src/private/_caosdb.cpp
similarity index 100%
rename from src/caosdb.cpp
rename to src/private/_caosdb.cpp