Skip to main content
Buildling custom C++ modules requires building Basilisk from source. The PyPI wheels do not support linking external modules. See Building from source to get started. Keep your custom code outside the official Basilisk source tree. This lets you update Basilisk independently without losing your customizations and makes it easier to track your own changes in a separate repository. Starting with Basilisk 2.0, the build system accepts a single external folder containing any number of custom modules and message definitions. The resulting build product contains both the official Basilisk modules and your custom modules.
The conventions for writing Basilisk modules — naming, SWIG interface files, CMakeLists layout — apply equally to external modules. See the module authoring documentation for details.

Directory structure

Your external folder must follow a specific layout. The top-level folder can have any name; the sub-folder names are fixed.
External/                         <- top-level folder (any name)
├── ExternalModules/              <- required, must be named exactly this
│   ├── _GeneralModuleFiles/      <- optional shared source files
│   │   └── sharedHelper.cpp
│   ├── myCustomModule/           <- one sub-folder per module
│   │   ├── myCustomModule.cpp
│   │   ├── myCustomModule.h
│   │   ├── myCustomModule.i
│   │   └── CMakeLists.txt
│   └── anotherModule/
│       └── ...
├── msgPayloadDefC/               <- optional custom C message headers
│   └── myCustomMsgPayload.h
└── msgPayloadDefCpp/             <- optional custom C++ message headers
    └── myCustomCppMsgPayload.h

Folder descriptions

FolderRequiredDescription
ExternalModules/YesContains one sub-folder per custom module.
ExternalModules/_GeneralModuleFiles/NoShared source files used by multiple modules. All files must be placed directly in this folder — sub-folders are not supported.
msgPayloadDefC/NoCustom C message header files. Follow the naming convention <MessageType>MsgPayload.h.
msgPayloadDefCpp/NoCustom C++ message header files. Same naming convention as C headers.

Build with external modules

Pass the path to your external folder with --pathToExternalModules. Both absolute and relative paths are accepted. Assuming your External folder is located next to the Basilisk source directory:
python3 conanfile.py --clean --pathToExternalModules ../External
The build system integrates your modules and generates a project file that includes both official Basilisk components and your external modules. In the IDE, your modules appear under an ExternalModules group. Custom message types are merged with the core BSK messages under architecture/msgPayloadDefC and architecture/msgPayloadDefCpp.
On Windows, the external modules folder must be on the same drive as the Basilisk source directory.

Import custom modules in Python

Custom modules are built into the Basilisk.ExternalModules Python package. To use a module named customCppModule in a simulation script:
from Basilisk.ExternalModules import customCppModule

Full build example

The following is a complete workflow for building Basilisk with an external module folder:
1

Create your external folder structure

mkdir -p ../External/ExternalModules/myModule
mkdir -p ../External/msgPayloadDefC
2

Write your module files

Add your .cpp, .h, .i, and CMakeLists.txt files inside ../External/ExternalModules/myModule/.
3

Build Basilisk with the external folder

python3 conanfile.py --clean --pathToExternalModules ../External
4

Import the module in your simulation

from Basilisk.ExternalModules import myModule

Frequently asked questions

On Linux and macOS, yes. On Windows, the external folder must be on the same drive as the Basilisk source directory.
No. The key sub-folder names (ExternalModules, _GeneralModuleFiles, msgPayloadDefC, msgPayloadDefCpp) are fixed and cannot be changed. If you rename them, you must write your own CMake file.
Only if you add new message definitions or new source files that affect the auto-generated messaging layer. For iterative changes to existing module code, use an incremental build from the dist3/ folder after the initial configure step.
# Configure once
python3 conanfile.py --buildProject False --pathToExternalModules ../External

# Then build incrementally (Linux/macOS)
cd dist3
make -j5

Build docs developers (and LLMs) love