docs: Move module structure documentation to root This change places module structure documentation into the core docs. Change-Id: Iaa38ae2ecc101d3c5eb9756748a89e35235e36dd
diff --git a/docs/BUILD.gn b/docs/BUILD.gn index fd9cfe4..4fa235d 100644 --- a/docs/BUILD.gn +++ b/docs/BUILD.gn
@@ -27,6 +27,7 @@ sources = [ "embedded_cpp_guide.rst", "getting_started.md", + "module_guide.rst", "style_guide.rst", ] }
diff --git a/docs/index.rst b/docs/index.rst index ec51171..3139e46 100644 --- a/docs/index.rst +++ b/docs/index.rst
@@ -13,5 +13,6 @@ docs/getting_started.md docs/embedded_cpp_guide docs/style_guide + docs/module_guide targets modules
diff --git a/docs/module_guide.rst b/docs/module_guide.rst new file mode 100644 index 0000000..594dc96 --- /dev/null +++ b/docs/module_guide.rst
@@ -0,0 +1,267 @@ +.. default-domain:: cpp + +.. highlight:: sh + +.. _chapter-module-guide: + +------------------- +What's in a module? +------------------- +The Pigweed module structure is designed to keep as much code as possible for a +particular slice of functionality in one place. That means including the code +from multiple languages, as well as all the related documentation and tests. + +Additionally, the structure is designed to limit the number of places a file +could go, so that when reading callsites it is obvious where a header is from. +That is where the duplicated ``<module>`` occurrences in file paths comes from. + +Example module structure +------------------------ +.. code-block:: python + + pw_foo/... + + docs.rst # If there is just 1 docs file, call it docs.rst + README.md # All modules must have a short README for gittiles + + BUILD.gn # GN build required + BUILD # Bazel build required + + # C++ public headers; the repeated module name is required + public/pw_foo/foo.h + public/pw_foo/baz.h + + # Exposed public headers go under internal/ + public/pw_foo/internal/bar.h + public/pw_foo/internal/qux.h + + # Public override headers must go in 'public_overrides' + public_overrides/gtest/gtest.h + public_overrides/string.h + + # Private headers go into <module>_*/... + pw_foo_internal/zap.h + pw_foo_private/zip.h + pw_foo_secret/alxx.h + + # C++ implementations go in the root + foo_impl.cc + foo.cc + baz.cc + bar.cc + zap.cc + zip.cc + alxx.cc + + # C++ tests also go in the root + foo_test.cc + bar_test.cc + zip_test.cc + + # Python files go into 'py/<module>/...' + py/setup.py # All Python must be a Python module with setup.py + py/foo_test.py # Tests go in py/ but outside of the Python module + py/bar_test.py + py/pw_foo/__init__.py + py/pw_foo/__main__.py + py/pw_foo/bar.py + + # Go files go into 'go/...' + go/... + + # Examples go in examples/, mixing different languages + examples/demo.py + examples/demo.cc + examples/demo.go + examples/BUILD.gn + examples/BUILD + + # Size reports go under size_report/ + size_report/BUILD.gn + size_report/base.cc + size_report/use_case_a.cc + size_report/use_case_b.cc + + # Protobuf definition files go into <module>_protos/... + pw_foo_protos/foo.proto + pw_foo_protos/internal/zap.proto + + # Other directories are fine, but should be private. + data/... + graphics/... + collection_of_tests/... + code_relating_to_subfeature/... + +Module name +~~~~~~~~~~~ +Pigweed upstream modules are always named with a prefix ``pw_`` to enforce +namespacing. Projects using Pigweed that wish to make their own modules can use +whatever name they like, but we suggest picking a short prefix to namespace +your product (e.g. for an Internet of Toast project, perhaps the prefix could +be ``it_``). + +C++ file and directory locations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C++ public headers +^^^^^^^^^^^^^^^^^^ +Located ``{pw_module_dir}/public/<module>``. These are headers that must be +exposed due to C++ limitations (i.e. are included from the public interface, +but are not intended for public use). + +**Public headers** should take the form: + +``{pw_module_dir}/public/<module>/*.h`` + +**Exposed private headers** should take the form: + +``{pw_module_dir}/public/<module>/internal/*.h`` + +Examples: + +.. code-block:: + + pw_foo/... + public/pw_foo/foo.h + public/pw_foo/a_header.h + public/pw_foo/baz.h + +For headers that must be exposed due to C++ limitations (i.e. are included from +the public interface, but are not intended for use), place the headers in a +``internal`` subfolder under the public headers directory; as +``{pw_module_dir}/public/<module>/internal/*.h``. For example: + +.. code-block:: + + pw_foo/... + public/pw_foo/internal/secret.h + public/pw_foo/internal/business.h + +.. note:: + + These headers must not override headers from other modules. For + that, there is the ``public_overrides/`` directory. + +Public override headers +^^^^^^^^^^^^^^^^^^^^^^^ +Located ``{pw_module_dir}/public_overrides/<module>``. In general, the Pigweed +philosophy is to avoid having "things hiding under rocks", and having header +files with the same name that can override each other is considered a rock +where surprising things can hide. Additionally, a design goal of the Pigweed +module structure is to make it so there is ideally exactly one obvious place +to find a header based on an ``#include``. + +However, in some cases header overrides are necessary to enable flexibly +combining modules. To make this as explicit as possible, headers which override +other headers must go in + +``{pw_module_dir}/public_overrides/...``` + +For example, the ``pw_unit_test`` module provides a header override for +``gtest/gtest.h``. The structure of the module is (omitting some files): + +.. code-block:: + + pw_unit_test/... + + public_overrides/gtest + public_overrides/gtest/gtest.h + + public/pw_unit_test + public/pw_unit_test/framework.h + public/pw_unit_test/simple_printing_event_handler.h + public/pw_unit_test/event_handler.h + +Note that the overrides are in a separate directory ``public_overrides``. + +C++ implementation files +^^^^^^^^^^^^^^^^^^^^^^^^ +Located ``{pw_module_dir}/``. C++ implementation files go at the top level of +the module. Implementation files must always use "" style includes. + +Example: + +.. code-block:: + + pw_unit_test/... + main.cc + framework.cc + test.gni + BUILD.gn + README.md + +Documentation +~~~~~~~~~~~~~ +Documentation should go in the root module folder, typically in the +``docs.rst`` file. There must be a docgen entry for the documentation in the +``BUILD.gn`` file with the target name ``docs``; so the full target for the +docs would be ``<module>:docs``. + +.. code-block:: + + pw_example_module/... + + docs.rst + +For modules with more involved documentation, create a separate directory +called ``docs/`` under the module root, and put the ``.rst`` files and other +related files (like images and diagrams) there. + +.. code-block:: + + pw_example_module/... + + docs/docs.rst + docs/bar.rst + docs/foo.rst + docs/image/screenshot.png + docs/image/diagram.svg + +Steps to create a new module for a Pigweed project +-------------------------------------------------- +These instructions are for creating a new module for contribution to the +Pigweed project. See below for an `example`__ of what the new module folder +might look like. + +__ `Example module structure`_ + +1. Create module folder following `Module name`_ guidelines +2. Add `C++ public headers`_ files in + ``{pw_module_dir}/public/{pw_module_name}/`` +3. Add `C++ implementation files`_ files in ``{pw_module_dir}/`` +4. Add module documentation + + - Add ``{pw_module_dir}/README.md`` that has a module summary + - Add ``{pw_module_dir}/docs.rst`` that contains the main module + documentation + +5. Add build support inside of new module + + - Add GN with ``{pw_module_dir}/BUILD.gn`` + - Add Bazel with ``{pw_module_dir}/BUILD`` + - Add CMake with ``{pw_module_dir}/CMakeLists.txt`` + +6. Add folder alias for new module variable in ``/modules.gni`` + + - dir_pw_new = "$dir_pigweed/pw_new" + +7. Add new module to main GN build + + - in ``/BUILD.gn`` to ``group("pw_modules")`` using folder alias variable + - General modules and backends of facades go in ``pw_modules``, facades go + in ``pw_facades`` + +8. Add test target for new module in ``/BUILD.gn`` to + ``pw_test_group("pw_module_tests")`` +9. Add new module to CMake build + + - In ``/CMakeLists.txt`` add ``add_subdirectory(pw_new)`` + +10. Add the new module to docs module + + - Add in ``docs/BUILD.gn`` to ``pw_doc_gen("docs")`` + +11. Run :ref:`chapter-module-module-check` + + - ``$ pw module-check {pw_module_dir}`` +
diff --git a/pw_module/docs.rst b/pw_module/docs.rst index 56808b3..0eea2d0 100644 --- a/pw_module/docs.rst +++ b/pw_module/docs.rst
@@ -1,285 +1,23 @@ -.. _chapter-module: - .. default-domain:: cpp .. highlight:: sh +.. _chapter-module: + --------- pw_module --------- +The ``pw_module`` module contains tools for managing Pigweed modules. +For information on the structure of a Pigweed module, refer to +:ref:`chapter-module-guide` -The ``pw_module`` module is the "meta-module" for Pigweed, containing -documentation for Pigweed's module structure as well as tools to detect when -modules are in or out of conformance to the module style. +Commands +-------- -The Pigweed module structure ----------------------------- +.. _chapter-module-module-check: -The Pigweed module structure is designed to keep as much code as possible for a -particular slice of functionality in one place. That means including the code -from multiple languages, as well as all the related documentation and tests. - -Additionally, the structure is designed to limit the number of places a file -could go, so that when reading callsites it is obvious where a header is from. -That is where the duplicated ``<module>`` occurrences in file paths comes from. - -Steps to create a new module Pigweed project --------------------------------------------- - -These instructions are for creating a new module for contribution to the -Pigweed project. See below for an `example`__ of what the new module folder -might look like. - -__ `Example module structure`_ - -1. Create module folder following `Module name`_ guidelines -2. Add `C++ public headers`_ files in - ``{pw_module_dir}/public/{pw_module_name}/`` -3. Add `C++ implementation files`_ files in ``{pw_module_dir}/`` -4. Add module documentation - - - Add ``{pw_module_dir}/README.md`` that has a module summary - - Add ``{pw_module_dir}/docs.rst`` that contains the main module - documentation - -5. Add build support inside of new module - - - Add GN with ``{pw_module_dir}/BUILD.gn`` - - Add Bazel with ``{pw_module_dir}/BUILD`` - - Add CMake with ``{pw_module_dir}/CMakeLists.txt`` - -6. Add folder alias for new module variable in ``/modules.gni`` - - - dir_pw_new = "$dir_pigweed/pw_new" - -7. Add new module to main GN build - - - in ``/BUILD.gn`` to ``group("pw_modules")`` using folder alias variable - - General modules and backends of facades go in ``pw_modules``, facades go - in ``pw_facades`` - -8. Add test target for new module in ``/BUILD.gn`` to - ``pw_test_group("pw_module_tests")`` -9. Add new module to CMake build - - - In ``/CMakeLists.txt`` add ``add_subdirectory(pw_new)`` - -10. Add the new module to docs module - - - Add in ``docs/BUILD.gn`` to ``pw_doc_gen("docs")`` - -11. Run `module check`__ - - - ``$ pw module-check {pw_module_dir}`` - -__ `Command: pw module-check`_ - -Example module structure ------------------------- - -.. code-block:: python - - pw_foo/... - - docs.rst # If there is just 1 docs file, call it docs.rst - README.md # All modules must have a short README for gittiles - - BUILD.gn # GN build required - BUILD # Bazel build required - - # C++ public headers; the repeated module name is required - public/pw_foo/foo.h - public/pw_foo/baz.h - - # Exposed public headers go under internal/ - public/pw_foo/internal/bar.h - public/pw_foo/internal/qux.h - - # Public override headers must go in 'public_overrides' - public_overrides/gtest/gtest.h - public_overrides/string.h - - # Private headers go into <module>_*/... - pw_foo_internal/zap.h - pw_foo_private/zip.h - pw_foo_secret/alxx.h - - # C++ implementations go in the root - foo_impl.cc - foo.cc - baz.cc - bar.cc - zap.cc - zip.cc - alxx.cc - - # C++ tests also go in the root - foo_test.cc - bar_test.cc - zip_test.cc - - # Python files go into 'py/<module>/...' - py/setup.py # All Python must be a Python module with setup.py - py/foo_test.py # Tests go in py/ but outside of the Python module - py/bar_test.py - py/pw_foo/__init__.py - py/pw_foo/__main__.py - py/pw_foo/bar.py - - # Go files go into 'go/...' - go/... - - # Examples go in examples/, mixing different languages - examples/demo.py - examples/demo.cc - examples/demo.go - examples/BUILD.gn - examples/BUILD - - # Size reports go under size_report/ - size_report/BUILD.gn - size_report/base.cc - size_report/use_case_a.cc - size_report/use_case_b.cc - - # Protobuf definition files go into <module>_protos/... - pw_foo_protos/foo.proto - pw_foo_protos/internal/zap.proto - - # Other directories are fine, but should be private. - data/... - graphics/... - collection_of_tests/... - code_relating_to_subfeature/... - -Module name ------------ -Pigweed upstream modules are always named with a prefix ``pw_`` to enforce -namespacing. Projects using Pigweed that wish to make their own modules can use -whatever name they like, but we suggest picking a short prefix to namespace -your product (e.g. for an Internet of Toast project, perhaps the prefix could -be ``it_``). - -C++ file and directory locations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -C++ public headers -^^^^^^^^^^^^^^^^^^ -Located ``{pw_module_dir}/public/<module>``. These are headers that must be -exposed due to C++ limitations (i.e. are included from the public interface, -but are not intended for public use). - -**Public headers** should take the form: - -``{pw_module_dir}/public/<module>/*.h`` - -**Exposed private headers** should take the form: - -``{pw_module_dir}/public/<module>/internal/*.h`` - -Examples: - -.. code-block:: - - pw_foo/... - public/pw_foo/foo.h - public/pw_foo/a_header.h - public/pw_foo/baz.h - -For headers that must be exposed due to C++ limitations (i.e. are included from -the public interface, but are not intended for use), place the headers in a -``internal`` subfolder under the public headers directory; as -``{pw_module_dir}/public/<module>/internal/*.h``. For example: - -.. code-block:: - - pw_foo/... - public/pw_foo/internal/secret.h - public/pw_foo/internal/business.h - -.. note:: - - These headers must not override headers from other modules. For - that, there is the ``public_overrides/`` directory. - -Public override headers -^^^^^^^^^^^^^^^^^^^^^^^ -Located ``{pw_module_dir}/public_overrides/<module>``. In general, the Pigweed -philosophy is to avoid having "things hiding under rocks", and having header -files with the same name that can override each other is considered a rock -where surprising things can hide. Additionally, a design goal of the Pigweed -module structure is to make it so there is ideally exactly one obvious place -to find a header based on an ``#include``. - -However, in some cases header overrides are necessary to enable flexibly -combining modules. To make this as explicit as possible, headers which override -other headers must go in - -``{pw_module_dir}/public_overrides/...``` - -For example, the ``pw_unit_test`` module provides a header override for -``gtest/gtest.h``. The structure of the module is (omitting some files): - -.. code-block:: - - pw_unit_test/... - - public_overrides/gtest - public_overrides/gtest/gtest.h - - public/pw_unit_test - public/pw_unit_test/framework.h - public/pw_unit_test/simple_printing_event_handler.h - public/pw_unit_test/event_handler.h - -Note that the overrides are in a separate directory ``public_overrides``. - -C++ implementation files -^^^^^^^^^^^^^^^^^^^^^^^^ -Located ``{pw_module_dir}/``. C++ implementation files go at the top level of -the module. Implementation files must always use "" style includes. - -Example: - -.. code-block:: - - pw_unit_test/... - main.cc - framework.cc - test.gni - BUILD.gn - README.md - -Documentation -~~~~~~~~~~~~~ -Documentation should go in the root module folder, typically in the -``docs.rst`` file. There must be a docgen entry for the documentation in the -``BUILD.gn`` file with the target name ``docs``; so the full target for the -docs would be ``<module>:docs``. - -.. code-block:: - - pw_example_module/... - - docs.rst - -For modules with more involved documentation, create a separate directory -called ``docs/`` under the module root, and put the ``.rst`` files and other -related files (like images and diagrams) there. - -.. code-block:: - - pw_example_module/... - - docs/docs.rst - docs/bar.rst - docs/foo.rst - docs/image/screenshot.png - docs/image/diagram.svg - -Command: ``pw module-check`` ----------------------------- - +``pw module-check`` +^^^^^^^^^^^^^^^^^^^ The ``pw module-check`` command exists to ensure that your module conforms to the Pigweed module norms.