GSoC Week 1: Setting up the Development Environment for Productive Coding
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:
Generate a new SSH key:
ssh-keygen -t ed25519 -C "your_email@example.com"
Add the private key to the agent:
eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519
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:
Update the remote URL:
git remote set-url origin git@github.com:your-username/project-name.git
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.
Recommended Extensions:
- 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:
Compile with profiling enabled: Add
-pg
to both compile and link flags.Run the program (avoid wrappers like Python when profiling):
./my_executable input.cfg
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 Type | Flags | Purpose |
---|---|---|
Debug | -g -O0 | Use with GDB to step through crashes or logic issues. |
Optimized | -O2 or -O3 | Measure real-world performance. |
Profiling | -pg | Collect 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