GSoC Week 1: Setting up the Development Environment for Productive Coding

5 minute read

Published:

Streamlining Open-Source Contributions in C++ with GitHub and VS Code

Getting started with contributing to a large-scale open-source project can feel daunting—especially if you’re new to collaborative software development, C++, or tools like GitHub. This guide is intended for beginners, like myself, who are taking their first steps into this space, such as through Google Summer of Code (GSoC) or other contribution opportunities.

The practices and tools shared here will help you efficiently navigate large C++ projects, whether your goal is to fix documentation, add new features, or improve performance.


1. GitHub Workflow: Fork, Clone, Branch

To contribute to a GitHub-hosted project, start by forking the repository. This creates a personal copy where you can make changes safely.

Steps:

  • Fork the repo from the GitHub website.

  • Clone it to your local system:

    git clone https://github.com/your-username/project-name.git
    cd project-name
    
  • Add the original repo as the upstream to keep your fork up to date:

    git remote add upstream https://github.com/original-owner/project-name.git
    

    This allows you to fetch updates later using:

    git fetch upstream
    git merge upstream/main  # or 'develop', depending on the repo
    
  • Create a dedicated branch for your work:

    git checkout -b feature-branch
    git push -u origin feature-branch
    

Using -u links your local branch to the remote one, so future git push commands will automatically target the correct destination.


2. SSH Keys: Avoid Typing Credentials Every Time

GitHub recommends setting up SSH-based authentication for secure and password-free interaction.

Steps:

  1. Generate a new SSH key:

    ssh-keygen -t ed25519 -C "your_email@example.com"
    
  2. Add the private key to the agent:

    eval "$(ssh-agent -s)"
    ssh-add ~/.ssh/id_ed25519
    
  3. Add the public key to GitHub:

    cat ~/.ssh/id_ed25519.pub
    

    Copy and paste this into GitHub > Settings > SSH and GPG keys.

If you cloned using HTTPS and want to switch to SSH:

  1. Update the remote URL:

    git remote set-url origin git@github.com:your-username/project-name.git
    
  2. Verify it:

    git remote -v
    

    It should now show the SSH URL:

    origin  git@github.com:your-username/project-name.git
    

Now git push will use SSH without prompting for credentials.


3. Choosing an Editor: Why I Recommend VS Code

While some experienced developers might opt for terminal-based editors like vim or emacs, I found Visual Studio Code (VS Code) to be a practical and user-friendly choice, especially when dealing with large C++ codebases.

  • C/C++ (Microsoft): Provides IntelliSense and debugging support.
  • CMake Tools: For configuring and building CMake-based projects.
  • CodeLLDB or C++ GDB: Enables powerful in-editor debugging.
  • GitLens: Adds powerful Git features inside VS Code.

4. Automating Builds with tasks.json

Instead of manually switching to a terminal and typing build commands each time, you can define build tasks in VS Code using tasks.json. This file allows you to run common shell commands from within the editor.

Example:

{
  "label": "Build Project",
  "type": "shell",
  "command": "ninja -C build install",
  "group": {
    "kind": "build",
    "isDefault": true
  }
}

This configuration builds your project using the ninja build system (or make, depending on your setup). You can trigger it by pressing Ctrl+Shift+B in VS Code.

Your provided tasks.json is set up to install the project after building it:

"command": "ninja -C build_serial install"

Adjust the build directory name as needed for different configurations.


5. Debugging with GDB and launch.json

For larger projects, simple print statements quickly become inefficient. A proper debugger helps you step through the code, inspect variables, and set breakpoints.

launch.json helps you:

  • Specify the binary to debug.
  • Pass runtime arguments (e.g., config files).
  • Set the working directory.
  • Choose GDB or LLDB as the backend.

Here’s a simplified version inspired by your setup:

{
  "name": "Debug Project",
  "type": "cppdbg",
  "request": "launch",
  "program": "${workspaceFolder}/build/bin/my_executable",
  "args": ["input.cfg"],
  "cwd": "${workspaceFolder}/test_cases/my_case",
  "stopAtEntry": false,
  "MIMode": "gdb",
  "externalConsole": false
}

This allows debugging directly within VS Code using breakpoints and variable inspection, without leaving the editor.

Your custom launch.json even supports debugging with MPI-enabled programs—this is very helpful for parallel simulations.


6. Profiling with gprof

After ensuring your code works, it’s useful to measure its performance. gprof is a lightweight tool for profiling C++ applications compiled with -pg.

Steps:

  1. Compile with profiling enabled: Add -pg to both compile and link flags.

  2. Run the program (avoid wrappers like Python when profiling):

    ./my_executable input.cfg
    
  3. Analyze results:

    gprof ./my_executable gmon.out > analysis.txt
    

    This will generate a text file detailing function call times and frequencies, helping you identify bottlenecks.


7. Maintaining Multiple Builds

For robust development, maintain separate build directories for different purposes:

Build TypeFlagsPurpose
Debug-g -O0Use with GDB to step through crashes or logic issues.
Optimized-O2 or -O3Measure real-world performance.
Profiling-pgCollect runtime statistics using gprof.

Use separate build directories (build_debug, build_release, build_profile) with different CMake options or toolchain files.


Final Thoughts

With this setup, you can:

  • Organize your GitHub workflow.
  • Edit and build efficiently within VS Code.
  • Debug with breakpoints and variable inspection.
  • Profile performance bottlenecks.
  • Push changes back to your forked repository.

The next step in your contribution journey is to submit a pull request (PR)—a topic I’ll cover in a future post once I’ve gone through the process myself.

Leave a Comment