From 464b0a0a4ae2c7a56d0864a3f55af07cbdac3960 Mon Sep 17 00:00:00 2001 From: Ioannis Paraskevakos Date: Wed, 3 Jun 2026 15:15:30 -0400 Subject: [PATCH 1/7] fix: intro and C++ guide --- source/cpp.rst | 92 ++++++++++++++++++++++++++++++++++++++++++------ source/intro.rst | 43 ++++++++++++++++++---- 2 files changed, 118 insertions(+), 17 deletions(-) diff --git a/source/cpp.rst b/source/cpp.rst index f3f95fb..411ffca 100644 --- a/source/cpp.rst +++ b/source/cpp.rst @@ -5,42 +5,114 @@ C/C++ Overview ======== -.. todo:: Emphasize grandparent clause here, because C/C++ syntax is - very permissive and there are a number of standards. +C++ is an important part of the software ecosystem of SO, and is used in important and +performance-critical code. C++ is a complex language and very permissive on formatting. + +In addition, formatting and styling from older standards (C++98, C++03) is very +different from modern C++ (C++11 and later). As a result, these guidelines will +not require old codebase to be reformatted, but will require new code to follow a +modern C++ style and formatting. + +Having said that refactoring that updates old code to modern C++ is encouraged. + Version Support =============== -.. todo:: C++11, gcc. +All SO C++ code must compile as C++11 or later. C++11 introduced +RAII-based resource management, lambda expressions, move semantics, and +the ```` library, among other features that modern code relies +on. New code should target C++11 at minimum; individual repositories +may choose a newer standard (C++14, C++17) if their environment +guarantees it, and should document that choice in their build +configuration and README. + +The supported compilers are GCC 11 or later and Clang 10 or later. +Both provide full C++11 through C++17 support. Certain site computing resources +may have older compilers. In such cases, the minimum supported version should be +documented in the repository of the software. Style ===== -.. todo:: Identify the elements of formatting, and the numerous - formatting Argue about C/C++ formatting. +Although there are many C++ style guides, and there is no single "correct" way to +write C++, we will adopt a modified Google C++ style guide. For any rule not explicity +specified in this document, please refer to the Google (C++ style guide)[https://google.github.io/styleguide/cppguide.html] + +In addition to the style description, we will provide a config file for clang-format +that can automatically format code. In case you find yourself working on code that is +not formatted according to the style, you can maintain the existing style. However, +we higlhy recommend to format the code in a different branch and submit a pull request. + Indentation ----------- -Proposal: +Indentation is one of the aspects of code formatting that is important to be consistent +across codebases, especially since we use multiple languages. + +We will use 4 spaces as the intendantion for C++. + +Tabs are not allowed for indentation. + +Line width +---------- + +The maximum line width allowed is 120 characters. -- The basic indent shall be 4 spaces (2 is hard to follow, 8 is too - wasteful; non-powers of 2 are too weird). -- Spaces, not tabs. Naming Conventions ------------------ +The name of a variable, function or class is one of the most important aspects of code +readability. It can immediately inform about the puspose of the named thing. Please avoid +single letter names, except for loop variables, even if it is a commonly understandable +variable. + +We will utilize the following naming conventions: +1. Class and struct names should be in PascalCase, e.g. `MyClass`. +2. Function names should be in camelCase, e.g. `myFunction`. +3. Variable names should be in snake_case, e.g. `my_variable`. +4. Constants should be in ALL_CAPS with underscores, e.g. `MAX_SIZE`. +5. Namespaces should be in snake_case, e.g. `my_namespace`. + Use of Language Features ------------------------ - + .. todo:: We will add guidelines on the use of language features, such as smart pointers, + exceptions, etc. We will also provide guidelines on the use of modern C++ features + such as lambda functions, auto keyword, etc. Documentation of Code ===================== +Documentation of the code provides information about the code to users and developers alike. +There are two types of documentation that are important: inline comments, and API docstrings. + +For comments `/*..*/` and `//` are acceptable`, but try to be consistent within the +code. + +For API docstrings, we will use Doxygen style comments. The block starts with `/**` and +ends with `*/`. Each block should contain a `@brief` description, `@param` for each +parameter, and `@return` for the return value, unless it is a void. + +For example: + .. code-block:: cpp + + /** + * @brief Adds two integers and returns the result. + * + * @param a The first integer to add. + * @param b The second integer to add. + * @return The sum of a and b. + */ + int add(int a, int b) { + return a + b; + } + Unit Testing ============ + https://github.com/catchorg/Catch2 diff --git a/source/intro.rst b/source/intro.rst index 63f0f6f..777d1bc 100644 --- a/source/intro.rst +++ b/source/intro.rst @@ -2,12 +2,41 @@ Introduction to the Developer Guide =================================== -Welcome to these lines. +Welcome to Simons Observatory (SO) Developer Guide. -This document is intended to establish rules but also to provide -guidance and tips for helping SO produce high quality code with an -effective workflow. +The purpose of this document is to establish the rules and guidelines for contributing +to SO's codebase across all repositories. It is intended to establish rules but also +provide guidance and tips for helping SO produce high quality code with an effective +workflow. -General best practices for coding, documentation and workflow are -provided in the first few chapters. Afterwards, special policies -relating to particular working groups are given. +General best practices for coding, documentation and workflow are provided in the first +few chapters. Afterwards, special policies relating to particular working groups are given. + +As code is a live entity, this document is also live. We will update the document as +needed and as coding practices evolve over time. If you have any suggestions or corrections, +please submit a pull request or open an issue in the appropriate repository. + + +Why have a Developer's Guide and Style Guide? +============================================== + +Code, especially open source code, is a collaborative effort. In addition, we all have +our own coding styles and preferences, and that's a good thing. Furthermore, software +code is a product that is distributed to the public and hopefully will be used by many +people outside of the collaboration. Incosistent code styles makes it harder for +contributors and users to read, understand and reuse code. A developer and style +guide aims to lower this friction. + +A style guide removes trivial decision-making from code review. When formatting and +naming are settled by convention, reviewers can focus on correctness, design, and +scientific validity. It also makes automated tooling—linters, formatters, documentation +generators—easy to apply consistently across repositories. + +A developer guide goes further: it captures the institutional knowledge that experienced +SO developers carry in their heads. Which testing framework do we use? How should a +new package be structured? Writing these decisions down means a new collaborator can be +productive in as little time as possble. + +The purpose of the guide is not to enforce uniformity just for the sake of uniformity. +Rather to reduce the time needed for new contributors to get up to speed, and reduce +review times so that we produce better and faster science. From b74ae4c71dc8b1238d5867f0287c87739a85cfa7 Mon Sep 17 00:00:00 2001 From: Ioannis Paraskevakos Date: Wed, 3 Jun 2026 15:20:39 -0400 Subject: [PATCH 2/7] fix: sphinx --- requirements.txt | 4 ++-- source/conf.py | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/requirements.txt b/requirements.txt index 69e61c1..1aef75d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -sphinx==4.2.0 -sphinx_rtd_theme==1.0.0 +sphinx==7.4.7 +sphinx_rtd_theme==2.0.0 diff --git a/source/conf.py b/source/conf.py index 5805202..772399f 100644 --- a/source/conf.py +++ b/source/conf.py @@ -64,14 +64,14 @@ source_suffix = '.rst' # The master toctree document. -master_doc = 'index' +root_doc = 'index' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'en' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -141,7 +141,7 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'SODeveloperGuide.tex', 'SO Developer Guide Documentation', + (root_doc, 'SODeveloperGuide.tex', 'SO Developer Guide Documentation', 'Simons Observatory Collaboration', 'manual'), ] @@ -153,7 +153,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, 'sodeveloperguide', 'SO Developer Guide Documentation', + (root_doc, 'sodeveloperguide', 'SO Developer Guide Documentation', [author], 1) ] @@ -164,7 +164,7 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'SODeveloperGuide', 'SO Developer Guide Documentation', + (root_doc, 'SODeveloperGuide', 'SO Developer Guide Documentation', author, 'SODeveloperGuide', 'One line description of project.', 'Miscellaneous'), ] From eaa74749425acb5848b379be692efc390a4cbf0f Mon Sep 17 00:00:00 2001 From: Ioannis Paraskevakos Date: Tue, 23 Jun 2026 15:54:55 -0400 Subject: [PATCH 3/7] comment addressing and unit testing --- source/cpp.rst | 19 +++++++++++++++---- source/intro.rst | 8 +++++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/source/cpp.rst b/source/cpp.rst index 411ffca..e1feade 100644 --- a/source/cpp.rst +++ b/source/cpp.rst @@ -13,7 +13,7 @@ different from modern C++ (C++11 and later). As a result, these guidelines will not require old codebase to be reformatted, but will require new code to follow a modern C++ style and formatting. -Having said that refactoring that updates old code to modern C++ is encouraged. +Though not required, if time permits, refactoring old code to modern C++ is encouraged. Version Support @@ -37,7 +37,7 @@ Style Although there are many C++ style guides, and there is no single "correct" way to write C++, we will adopt a modified Google C++ style guide. For any rule not explicity -specified in this document, please refer to the Google (C++ style guide)[https://google.github.io/styleguide/cppguide.html] +specified in this document, please refer to the Google [C++ style guide](https://google.github.io/styleguide/cppguide.html) In addition to the style description, we will provide a config file for clang-format that can automatically format code. In case you find yourself working on code that is @@ -51,7 +51,7 @@ Indentation Indentation is one of the aspects of code formatting that is important to be consistent across codebases, especially since we use multiple languages. -We will use 4 spaces as the intendantion for C++. +We will use 2 or 4 spaces as the intendantion for C++. Tabs are not allowed for indentation. @@ -113,6 +113,17 @@ For example: Unit Testing ============ +Unit testing is an important part of software development. It helps ensure that the code +is working as expected, helps catch bugs early and verify that the code is not regressing +when feature or changes are made. Testing suites are only expected to grow over time. + +Due to the importance of unit testing, we will require that all new code be accompanied by at +least one unit test. The unit test should be in a separate file, and should be named +`_test.cpp`, where `` is the name of the file being tested. + +[Catch2](https://github.com/catchorg/Catch2) is the unit testing framework for C++ we will +use for SO as it is easy to use, represents tests a normal boolean expressions and +also allows to benchmark code. + -https://github.com/catchorg/Catch2 diff --git a/source/intro.rst b/source/intro.rst index 777d1bc..d402f73 100644 --- a/source/intro.rst +++ b/source/intro.rst @@ -27,10 +27,12 @@ people outside of the collaboration. Incosistent code styles makes it harder for contributors and users to read, understand and reuse code. A developer and style guide aims to lower this friction. -A style guide removes trivial decision-making from code review. When formatting and +A style guide removes trivial decision-making from code review. When formatting and naming are settled by convention, reviewers can focus on correctness, design, and -scientific validity. It also makes automated tooling—linters, formatters, documentation -generators—easy to apply consistently across repositories. +scientific validity. For this reason we require the use of source formatters. A diff +produced by a formatter-compliant change contains only the actual logical edit, not +incidental whitespace, indentation, or line-wrapping noise, keeping pull requests +small, focused, and easier on maintainers to review. A developer guide goes further: it captures the institutional knowledge that experienced SO developers carry in their heads. Which testing framework do we use? How should a From 011ad623b1c2cbc945eb9a2283484d2003222f22 Mon Sep 17 00:00:00 2001 From: Ioannis Paraskevakos Date: Tue, 23 Jun 2026 15:56:08 -0400 Subject: [PATCH 4/7] fix: missing reference --- source/cpp.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/cpp.rst b/source/cpp.rst index e1feade..6255677 100644 --- a/source/cpp.rst +++ b/source/cpp.rst @@ -125,5 +125,4 @@ least one unit test. The unit test should be in a separate file, and should be n use for SO as it is easy to use, represents tests a normal boolean expressions and also allows to benchmark code. - - +Please refer to the Catch2 documentation for more information on how to write unit tests. From ab43e3d6f5ee427eae2699cd0887b5803350ee63 Mon Sep 17 00:00:00 2001 From: Ioannis Paraskevakos Date: Thu, 25 Jun 2026 10:12:01 -0400 Subject: [PATCH 5/7] Addressing comments, adding clang config --- source/cpp.rst | 67 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/source/cpp.rst b/source/cpp.rst index 6255677..c82c64b 100644 --- a/source/cpp.rst +++ b/source/cpp.rst @@ -10,7 +10,7 @@ performance-critical code. C++ is a complex language and very permissive on form In addition, formatting and styling from older standards (C++98, C++03) is very different from modern C++ (C++11 and later). As a result, these guidelines will -not require old codebase to be reformatted, but will require new code to follow a +not require old codebases to be reformatted, but will require new code to follow a modern C++ style and formatting. Though not required, if time permits, refactoring old code to modern C++ is encouraged. @@ -35,14 +35,15 @@ documented in the repository of the software. Style ===== -Although there are many C++ style guides, and there is no single "correct" way to -write C++, we will adopt a modified Google C++ style guide. For any rule not explicity -specified in this document, please refer to the Google [C++ style guide](https://google.github.io/styleguide/cppguide.html) +Although there are many C++ style guides, and there is no single "correct" way to +write C++, we adopt a modified Google C++ style guide. For any rule not explicitly +specified in this document, please refer to the `Google C++ style guide`_. -In addition to the style description, we will provide a config file for clang-format +In addition to the style description, we provide a :ref:`config file for clang-format ` that can automatically format code. In case you find yourself working on code that is not formatted according to the style, you can maintain the existing style. However, -we higlhy recommend to format the code in a different branch and submit a pull request. +when you are formatting the code, we highly recommend to use a branch which only contains +the formatting changes and submit a pull request. Indentation @@ -51,10 +52,11 @@ Indentation Indentation is one of the aspects of code formatting that is important to be consistent across codebases, especially since we use multiple languages. -We will use 2 or 4 spaces as the intendantion for C++. +We will use 2 or 4 spaces as the indentation for C++. Tabs are not allowed for indentation. + Line width ---------- @@ -65,7 +67,7 @@ Naming Conventions ------------------ The name of a variable, function or class is one of the most important aspects of code -readability. It can immediately inform about the puspose of the named thing. Please avoid +readability. It can immediately inform about the purpose of the named thing. Please avoid single letter names, except for loop variables, even if it is a commonly understandable variable. @@ -77,18 +79,50 @@ We will utilize the following naming conventions: 5. Namespaces should be in snake_case, e.g. `my_namespace`. +Header Files +------------ + +All header files must guard against multiple inclusion. Use ``#pragma once`` at the +top of the file, rather than traditional ``#ifndef``/``#define``/``#endif`` guards:: + + #pragma once + + // header contents + +``#pragma once`` is supported by all compilers we target (GCC and Clang) and avoids +the maintenance burden and risk of typos or naming collisions inherent to manually +written include guard macros. + + Use of Language Features ------------------------ - .. todo:: We will add guidelines on the use of language features, such as smart pointers, - exceptions, etc. We will also provide guidelines on the use of modern C++ features - such as lambda functions, auto keyword, etc. + +Guidance on modern C++ features is already covered by the `Google C++ style guide`_, +and we follow it without modification. + +.. _cpp-clang-format-config: + +Clang-format Config +------------------- +As formatting tool, we will use clang-format. The config file for the expected formatting +is: + +.. code-block:: yaml + + BasedOnStyle: Google + ColumnLimit: 120 + IndentWidth: 2 + +Please copy this in `.clang-format` file in the root of your repository. + +Note: Indentation width can be 2 or 4 spaces, but it should be consistent across the codebase. Documentation of Code ===================== Documentation of the code provides information about the code to users and developers alike. There are two types of documentation that are important: inline comments, and API docstrings. -For comments `/*..*/` and `//` are acceptable`, but try to be consistent within the +For comments `/*..*/` and `//` are acceptable, but try to be consistent within the code. For API docstrings, we will use Doxygen style comments. The block starts with `/**` and @@ -110,6 +144,7 @@ For example: } + Unit Testing ============ @@ -121,8 +156,10 @@ Due to the importance of unit testing, we will require that all new code be acco least one unit test. The unit test should be in a separate file, and should be named `_test.cpp`, where `` is the name of the file being tested. -[Catch2](https://github.com/catchorg/Catch2) is the unit testing framework for C++ we will -use for SO as it is easy to use, represents tests a normal boolean expressions and -also allows to benchmark code. +`Catch2`_ is the unit testing framework for C++ we will use for SO as it is easy +to use, represents tests as normal boolean expressions and also allows benchmarking code. Please refer to the Catch2 documentation for more information on how to write unit tests. + +.. _Google C++ style guide: https://google.github.io/styleguide/cppguide.html +.. _Catch2: https://github.com/catchorg/Catch2 \ No newline at end of file From 4589b5b5d0826eacc2e61e00209c495bb985a748 Mon Sep 17 00:00:00 2001 From: Ioannis Paraskevakos Date: Thu, 25 Jun 2026 16:26:05 -0400 Subject: [PATCH 6/7] Adding automatic semantic versioning Helped by Claude Sonnet 4.6 --- source/cpp.rst | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/source/cpp.rst b/source/cpp.rst index c82c64b..98aaa8a 100644 --- a/source/cpp.rst +++ b/source/cpp.rst @@ -161,5 +161,71 @@ to use, represents tests as normal boolean expressions and also allows benchmark Please refer to the Catch2 documentation for more information on how to write unit tests. + +Automatic Semantic Versioning +============================== + +`cmake-git-version-tracking`_ is the recommended tool for versioning. At configure +time CMake queries ``git describe``, writes the result into a generated C++ +header, and re-runs automatically whenever the git state changes. +There is no version string to maintain by hand. + +**Step 1 — fetch the module.** Copy ``git_watcher.cmake`` and +``git_version.h.in`` from the repository into your tree, e.g.:: + + cmake/ + git_watcher.cmake + git_version.h.in # provided by the library + +**Step 2 — wire it into** ``CMakeLists.txt``:: + + cmake_minimum_required(VERSION 3.14) + project(my_project) + + # Pull in the version-tracking module. + include(cmake/git_watcher.cmake) + + # This target re-runs whenever .git/HEAD or the index changes. + add_git_version_header(${PROJECT_NAME}_version + HEADER_FILE_NAME git_version.h + ) + + add_library(my_lib src/my_lib.cpp) + # Make the generated header visible to your targets. + target_link_libraries(my_lib PRIVATE ${PROJECT_NAME}_version) + +**Step 3 — use the version in C++.** Include the generated header:: + + #include "git_version.h" + + void printVersion() { + // GIT_RETRIEVED_STATE is false when building outside a git repo. + if (GIT_RETRIEVED_STATE) { + std::cout << "Version: " << GIT_DESCRIBE << "\n"; + // GIT_IS_DIRTY is true if there are uncommitted changes. + } + } + +The most useful macros exposed by the header are: + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Macro + - Description + * - ``GIT_DESCRIBE`` + - Output of ``git describe --tags --dirty`` (e.g. ``v1.2.3-4-gabcdef0-dirty``) + * - ``GIT_TAG`` + - Most recent tag (e.g. ``v1.2.3``) + * - ``GIT_COMMIT_DATE_ISO8601`` + - Commit timestamp + * - ``GIT_IS_DIRTY`` + - ``true`` if there are uncommitted changes + * - ``GIT_RETRIEVED_STATE`` + - ``false`` when built outside a git repository + + +.. _cmake-git-version-tracking: https://github.com/andrew-hardin/cmake-git-version-tracking .. _Google C++ style guide: https://google.github.io/styleguide/cppguide.html .. _Catch2: https://github.com/catchorg/Catch2 \ No newline at end of file From 59b25acea1db1656230aa611d92c63df82f82df4 Mon Sep 17 00:00:00 2001 From: Ioannis Paraskevakos Date: Mon, 29 Jun 2026 11:49:19 -0400 Subject: [PATCH 7/7] adding a second tool for C++ auto symver --- source/cpp.rst | 64 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/source/cpp.rst b/source/cpp.rst index 98aaa8a..50084a5 100644 --- a/source/cpp.rst +++ b/source/cpp.rst @@ -226,6 +226,68 @@ The most useful macros exposed by the header are: - ``false`` when built outside a git repository + +`cmake-git-semver`_ is a lightweight single-file alternative that parses a +``vMAJOR.MINOR.PATCH[-pre][+build]`` git tag directly into individual CMake +variables, which can be useful when you need to embed numeric version +components into build artefacts (shared library ``SOVERSION``, pkg-config +files, installers, etc.) rather than just exposing a raw ``git describe`` +string to C++ code. + +**Step 1 — fetch the module.** Copy ``git_semver.cmake`` into your tree:: + + cmake/ + git_semver.cmake + +**Step 2 — wire it into** ``CMakeLists.txt``:: + + cmake_minimum_required(VERSION 3.14) + project(my_project) + + include(cmake/git_semver.cmake) + git_semver(GIT_SEMVER) + + # Use the parsed components anywhere CMake variables are valid. + message(STATUS "Version: ${GIT_SEMVER}") + set_target_properties(my_lib PROPERTIES + VERSION "${GIT_SEMVER_MAJOR}.${GIT_SEMVER_MINOR}.${GIT_SEMVER_PATCH}" + SOVERSION "${GIT_SEMVER_MAJOR}" + ) + +The variables set after calling ``git_semver()`` are: + +.. list-table:: + :header-rows: 1 + :widths: 40 60 + + * - Variable + - Description + * - ```` + - Full version string (e.g. ``1.2.3-alpha+001``) + * - ``_MAJOR`` + - Major version component + * - ``_MINOR`` + - Minor version component + * - ``_PATCH`` + - Patch version component + * - ``_PRE_RELEASE`` + - Pre-release label (e.g. ``alpha``), empty if absent + * - ``_BUILD_METADATA`` + - Build metadata (e.g. ``001``), empty if absent + +.. note:: + + Tags must follow the ``vMAJOR.MINOR.PATCH`` format exactly. + ``cmake-git-semver`` will set all variables to ``0`` (and emit a + warning) if no conforming tag is found, so it is safe to use on a + fresh repository. + + .. _cmake-git-version-tracking: https://github.com/andrew-hardin/cmake-git-version-tracking +.. _cmake-git-semver: https://github.com/nunofachada/cmake-git-semver .. _Google C++ style guide: https://google.github.io/styleguide/cppguide.html -.. _Catch2: https://github.com/catchorg/Catch2 \ No newline at end of file +.. _Catch2: https://github.com/catchorg/Catch2 + +.. note:: + + Portions of this page were drafted with the assistance of `Claude Code Sonnet 4.6`. \ No newline at end of file