GSoC Week 0: Getting Started with Stitching SU2

5 minute read

Published:

Contributing to a Submodule in a Larger Project: A Case Study with MLPCpp in SU2

Introduction

When contributing to an open-source project that employs submodules, it is crucial to adopt a workflow that ensures contributions are effectively managed and integrated. This article outlines a recommended approach for contributing to a submodule within a larger repository, using the example of MLPCpp in the SU2 framework. It also includes technical steps for integrating modified submodules using symbolic links and Meson.


What Are Submodules?

In Git, a submodule is a repository embedded within another repository (the “superproject”). It allows a project to include and track an external repository at a specific commit. Submodules are commonly used when a project depends on external code but wants to maintain a fixed version or revision of that dependency.

For instance, in the SU2 project, MLPCpp is included as a submodule in the subprojects/MLPCpp directory. This means that SU2 references a specific commit of the MLPCpp repository, and updates to the submodule are controlled explicitly.


Key Considerations

When planning to modify MLPCpp, which is integrated as a submodule within SU2, an important question arises: Should the entire SU2 repository be forked, or should the fork be limited to the submodule (MLPCpp)?

Additionally, after installing and building SU2 (for example, using the Meson build system with -Denable-mlpcpp=true), it is natural to wonder whether modifications can be made directly within the submodule directory (subprojects/MLPCpp).


The recommended strategy is to fork and develop only the MLPCpp submodule, rather than the entire SU2 repository. This approach maintains clear version control boundaries and reduces the complexity of managing unrelated components.

Key steps include:

  1. Fork the MLPCpp repository independently. This isolates changes to the specific component of interest, making them easier to test, manage, and contribute back to the upstream project.

  2. Clone the forked MLPCpp repository locally and create a dedicated feature branch (it’s a best practice to keep the main branch of your fork clean and in sync with the upstream repository). This approach simplifies pulling updates from upstream, avoids merge conflicts, and provides a stable base for creating feature branches.

  3. To integrate and test these changes within the SU2 environment, replace the submodule directory in SU2 with a symbolic link or configure Meson to use the local version of MLPCpp. This allows testing the modified MLPCpp code without impacting SU2’s main repository or its submodule configuration.

  4. Once the changes have been verified, submit a pull request to the MLPCpp repository. This ensures that contributions are cleanly integrated into the upstream project.


Advantages of This Approach

  • Clear version control: Isolating submodule changes avoids unintended modifications to the larger project and makes it easier to track specific contributions.
  • Reduced risk of overwrites: Updates to the parent repository (SU2) will not overwrite changes made directly in the submodule directory.
  • Streamlined collaboration: Contributing to the submodule repository ensures that the changes are properly scoped and can be easily shared with the community.
  • Flexible testing: This approach allows switching between different versions of the submodule during development and testing, independent of the main repository.

Step-by-Step Guide: Integrating a Modified Submodule (MLPCpp) into SU2

This guide explains how to configure the SU2 build system to use a local version of MLPCpp that contains your modifications. This approach allows you to test changes in the submodule independently of the version tracked by SU2.

Prerequisites

  • A forked and cloned MLPCpp repository with your changes (e.g., at /home/youruser/dev/MLPCpp-modified).
  • A local SU2 repository (e.g., at /home/youruser/dev/SU2) with a successful initial build.
  • Meson and Ninja installed.

1. Replace the Submodule Reference with a Local Path

By default, SU2’s subprojects/MLPCpp points to a specific commit in the official MLPCpp repository. To override this:

  1. Backup the current MLPCpp submodule (optional but recommended):
cd /home/youruser/dev/SU2/subprojects
mv MLPCpp MLPCpp_backup
  1. Create a symbolic link to your modified MLPCpp:
ln -s /home/youruser/dev/MLPCpp-modified MLPCpp

Note on Symbolic Links:
A symbolic link (symlink) is a file that acts as a reference to another file or directory. In this case, the symlink MLPCpp points to your local modified repository. This ensures that changes in /home/youruser/dev/MLPCpp-modified are reflected in SU2’s build without altering the original submodule structure.


2. Reconfigure and Rebuild SU2 with Meson

  1. Navigate to the SU2 build directory (use the same directory as your initial build or create a new one):
cd /home/youruser/dev/SU2/build
  1. Reconfigure the build (this picks up the modified submodule).
    Correction: Meson requires the build directory to be separate from the source directory. Run:
meson setup --reconfigure ~/SU2

This tells Meson:

  • --reconfigure → Reconfigure an existing build.
  • ~/SU2 → Use this as the source directory (SU2’s codebase).
  • . → Use the current directory (which should be your separate build directory) as the build output directory.
  1. Build SU2 with the modified submodule:
./ninja -C build install

3. Testing Your Changes

Once built, use your modified SU2 executable (from build/bin/SU2_CFD) with configurations that invoke MLPCpp features. This ensures that SU2 is running with your modified submodule code.


Why This Approach Works

  • Safe Testing: You avoid accidental changes to the main SU2 repository.
  • Submodule Independence: Your local version of MLPCpp can evolve separately from SU2’s tracked version.
  • Reproducibility: You can easily switch between your modified MLPCpp and the official version by replacing the symlink.

Conclusion

When contributing to a submodule within a larger open-source project, such as MLPCpp within SU2, the recommended workflow is to fork and modify the submodule directly. Use symbolic links or build system overrides to integrate and test these changes with the main project. This approach ensures a clean, maintainable development workflow and facilitates contribution back to the original project.

Leave a Comment