Skip to content

Sphinx Architecture documentation #176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Dec 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f2aea7a
Update pages.yml
coder137 Dec 23, 2021
243ca95
Update software_heirarchy.rst
coder137 Dec 23, 2021
a40f7b8
Update namespaces.rst
coder137 Dec 23, 2021
f2c75c1
Added serialization_schema file to documentation
coder137 Dec 23, 2021
62ab5cb
Update serialization_schema.rst
coder137 Dec 23, 2021
f7b5bcc
Update design_patterns.rst
coder137 Dec 23, 2021
1c555e9
Update design_patterns.rst
coder137 Dec 23, 2021
3c80fb8
Update design_patterns.rst
coder137 Dec 23, 2021
0b6e67c
Added cmake boilerplate
coder137 Dec 23, 2021
13475bb
Update testing.rst
coder137 Dec 23, 2021
8e83510
Update serialization_schema.rst
coder137 Dec 29, 2021
e8f1869
Update conf.py
coder137 Dec 29, 2021
f00a063
Update cmake_boilerplate.rst
coder137 Dec 29, 2021
46fef8e
Update style_guide.rst
coder137 Dec 29, 2021
a4a885c
Update doxygen.cmake
coder137 Dec 29, 2021
ebecda8
Update testing.rst
coder137 Dec 29, 2021
593f0b1
Added docstring to API
coder137 Dec 29, 2021
44f356a
Update expect_command.h
coder137 Dec 29, 2021
15fb11e
Update testing.rst
coder137 Dec 29, 2021
21a86f2
Update project_layout.rst
coder137 Dec 29, 2021
a7f95fe
Updated API documentation
coder137 Dec 29, 2021
5e36b97
Update testing.rst
coder137 Dec 29, 2021
9cc209b
Update testing.rst
coder137 Dec 30, 2021
3a5e7d3
Update testing.rst
coder137 Dec 30, 2021
d771d0c
Update outputs.rst
coder137 Dec 30, 2021
31eb362
Update outputs.rst
coder137 Dec 30, 2021
4563920
Update toc.rst
coder137 Dec 30, 2021
8d70eb3
Added examples toc
coder137 Dec 30, 2021
8cd3939
Added introduction toc
coder137 Dec 30, 2021
147389c
Added getting_started toc
coder137 Dec 30, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ jobs:
run: |
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILDCC_DOCUMENTATION=ON

- name: Build
working-directory: ${{github.workspace}}
shell: bash
run: cmake --build build --config $BUILD_TYPE

- name: Doxygen + Sphinx
working-directory: ${{github.workspace}}/build
shell: bash
Expand Down
11 changes: 9 additions & 2 deletions buildcc/lib/env/include/env/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,15 @@ class Command {
&arguments = {}) const;

/**
* @brief Execute a particular command and optionally redirect stdout and
* stderr to user supplied dynamic string lists
* @brief Execute a particular command over a subprocess and optionally
* redirect stdout and stderr to user supplied dynamic string lists
*
* @param command Command is run on the shell
* @param working_directory Current working directory
* @param stdout_data Redirect stdout to user OR default print to console
* @param stderr_data Redirect stderr to user OR default print to console
* @return true when exit code = 0
* @return false when exit code != 0
*/
// TODO, Update this to get an integer exit code number instead of boolean
// value
Expand Down
11 changes: 11 additions & 0 deletions buildcc/lib/env/mock/include/expect_command.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ constexpr const char *const TEST_VECTOR_STRING_TYPE = "vector_string";

namespace buildcc::env::m {

/**
* @brief `Command::Execute` expectation API
*
* @param calls Number of times the actual `Command::Execute` API is called
* @param expectation Return value of the actual `Command::Execute` API
* @param stdout_data Data passed into stdout_data is redirected into the
* actual `Command::Execute` API to check for expectations. See
* `VectorStringCopier`
* @param stderr_data Data passed into stderr_data is redirected into the actual
* `Command::Execute` API to check for expectations. See `VectorStringCopier`
*/
void CommandExpect_Execute(unsigned int calls, bool expectation,
std::vector<std::string> *stdout_data = nullptr,
std::vector<std::string> *stderr_data = nullptr);
Expand Down
4 changes: 4 additions & 0 deletions buildcc/lib/target/mock/expect_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

namespace buildcc::base::m {

/**
* @brief Runs the generator using Taskflow with 1 thread
* CppUTest cannot mock with multiple threads
*/
void GeneratorRunner(Generator &generator);

void GeneratorExpect_InputRemoved(unsigned int calls, Generator *generator);
Expand Down
4 changes: 4 additions & 0 deletions buildcc/lib/target/mock/expect_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ namespace buildcc {

namespace base::m {

/**
* @brief Runs the target using Taskflow with 1 thread
* CppUTest cannot mock with multiple threads
*/
void TargetRunner(Target &target);

void TargetExpect_SourceRemoved(unsigned int calls, Target *target);
Expand Down
8 changes: 4 additions & 4 deletions cmake/tool/doxygen.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ if (${BUILDCC_DOCUMENTATION})
message("Doxygen Found: ${DOXYGEN_FOUND}")
message("Doxygen Version: ${DOXYGEN_VERSION}")

set(DOXYGEN_EXCLUDE_PATTERNS
*test/*
*mock/*
)
# set(DOXYGEN_EXCLUDE_PATTERNS
# *test/*
# *mock/*
# )
set(DOXYGEN_EXTRACT_ALL YES)
set(DOXYGEN_WARN_IF_UNDOCUMENTED YES)
set(DOXYGEN_GENERATE_XML YES)
Expand Down
141 changes: 141 additions & 0 deletions docs/source/arch/cmake_boilerplate.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
CMake Boilerplate
=================

.. code-block:: cmake

if (${TESTING})
# setup mocking
# setup testing executables

# TODO, Add example
endif()

if(${BUILDCC_BUILD_AS_SINGLE_LIB})
# buildcc files as an aggregate to one CMake library
# third party libraries still remain seperate so do NOT add it here
# Add third party library dependency to `buildcc` library in `buildcc/CMakeLists.txt`

# TODO, Add example
endif()

if(${BUILDCC_BUILD_AS_INTERFACE})
# one buildcc library broken up into smaller library chunks instead of aggregated to one CMake library like in BUILDCC_BUILD_AS_SINGLE_LIB
# NOTE: Do not forget to add this small library chunk to `buildcc_i` library in `buildcc/CMakeLists.txt`

# TODO, Add example
endif()

if (${BUILDCC_INSTALL})
# Install behaviour when option selected

# TODO, Add example
endif()


When structuring our code we would like to create different folders with ``CMakeLists.txt`` files as individual compile units.
We can then ``add_subdirectory`` that particular folder. This helps us keep our codebase modular.


**Example: Environment**

.. code-block:: cmake

# Env test
if (${TESTING})
add_library(mock_env STATIC
mock/logging.cpp
mock/assert_fatal.cpp

src/env.cpp
src/task_state.cpp

src/command.cpp
mock/execute.cpp
)
target_include_directories(mock_env PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/mock/include
)
target_link_libraries(mock_env PUBLIC
fmt::fmt-header-only
Taskflow

CppUTest
CppUTestExt
gcov
)
target_compile_options(mock_env PUBLIC ${TEST_COMPILE_FLAGS} ${BUILD_COMPILE_FLAGS})
target_link_options(mock_env PUBLIC ${TEST_LINK_FLAGS} ${BUILD_LINK_FLAGS})

# Tests
add_executable(test_env_util test/test_env_util.cpp)
target_link_libraries(test_env_util PRIVATE mock_env)

add_executable(test_task_state test/test_task_state.cpp)
target_link_libraries(test_task_state PRIVATE mock_env)

add_executable(test_command test/test_command.cpp)
target_link_libraries(test_command PRIVATE mock_env)

add_test(NAME test_env_util COMMAND test_env_util)
add_test(NAME test_task_state COMMAND test_task_state)
add_test(NAME test_command COMMAND test_command)
endif()

set(ENV_SRCS
src/env.cpp
src/assert_fatal.cpp
src/logging.cpp
include/env/assert_fatal.h
include/env/assert_throw.h
include/env/env.h
include/env/logging.h
include/env/util.h

include/env/host_os.h
include/env/host_compiler.h
include/env/host_os_util.h

src/task_state.cpp
include/env/task_state.h

src/command.cpp
src/execute.cpp
include/env/command.h
)

if(${BUILDCC_BUILD_AS_SINGLE_LIB})
target_sources(buildcc PRIVATE
${ENV_SRCS}
)
target_include_directories(buildcc PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${BUILDCC_INSTALL_HEADER_PREFIX}>
)
endif()

if(${BUILDCC_BUILD_AS_INTERFACE})
m_clangtidy("env")
add_library(env
${ENV_SRCS}
)
target_include_directories(env PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${BUILDCC_INSTALL_HEADER_PREFIX}>
)
target_link_libraries(env PUBLIC fmt::fmt-header-only)
target_compile_options(env PRIVATE ${BUILD_COMPILE_FLAGS})
target_link_options(env PRIVATE ${BUILD_LINK_FLAGS})
target_link_libraries(env PRIVATE
spdlog::spdlog_header_only
tiny-process-library::tiny-process-library
)
endif()

if (${BUILDCC_INSTALL})
if (${BUILDCC_BUILD_AS_INTERFACE})
install(TARGETS env DESTINATION lib EXPORT envConfig)
install(EXPORT envConfig DESTINATION "${BUILDCC_INSTALL_LIB_PREFIX}/env")
endif()
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION "${BUILDCC_INSTALL_HEADER_PREFIX}")
endif()
43 changes: 43 additions & 0 deletions docs/source/arch/design_patterns.rst
Original file line number Diff line number Diff line change
@@ -1,2 +1,45 @@
Design Patterns
===============

CRTP / Mixins
--------------

`Article by fluentcpp.com on CRTP <https://www.fluentcpp.com/2017/05/16/what-the-crtp-brings-to-code/>`_

* Mixins are a design pattern used to add additional functionality to an existing class
* In this case, the ``TargetInfo`` and the ``Target`` class are meant to have a lot of setter APIs for user inputs.
* Adding more APIs to the class makes its difficult to read and maintain.
* For reference: See :doc:`serialization_schema`
* For example: In Target ``source_files`` have currently have several APIs
* ``AddSource``
* ``AddSourceAbsolute``
* ``GlobSources``
* ``GlobSourcesAbsolute``
* In the future we might have additional APIs such as
* ``AddSources`` that takes an ``std::initializer_list``
* ``AddSources`` that takes a ``std::vector<>`` or ``std::unordered_set<>``
* ``AddSource(s)ByPattern`` that takes a fmt string like ``{dir}/source.cpp``
* From our serialization schema we can see that each of these fields could have many APIs associated with them. Having 50+ APIs for different fields in a single header i.e ``target_info.h`` / ``target.h`` would not be readible and hard to maintain.
* The Mixin / CRTP pattern is used to easily add functionality for a particular field in its own header / source file.

Friend classes
---------------

* Friend classes are used when 2 classes have strong coupling with each other, but still need to maintain flexibility for other purposes. For example: Unit testing.
* In ``target.h`` we have 3 friend classes (non CRTP based)
* ``CompilePch``
* ``CompileObject``
* ``LinkTarget``
* These 3 classes are made friend classes for 2 main purposes
* Unit Testing
* Flexibility / Maintaibility
* Unit Testing
* If these were not friend classes, the functions would've been private in scope within the ``Target`` class
* Unit testing these individual private functions would not be possible would public interfaces
* By making them friend classes, We can now unit test the public functions and embed this class in a private context with the ``Target`` class
* Flexibility / Maintaibility
* Each one of the classes mentioned above have their own information / states / tasks to hold.
* Without this segregation all of the member variables, states and tasks would need to be present inside the ``Target`` class
* Strong Coupling
* The 3 friend classes have strong coupling with the ``Target`` class since it uses its internal member variables for setting / getting information.
* The friend class can interact with the parent class and vice versa.
19 changes: 19 additions & 0 deletions docs/source/arch/namespaces.rst
Original file line number Diff line number Diff line change
@@ -1,2 +1,21 @@
Namespaces
==========

User
-----

* ``buildcc``
* ``buildcc::env``
* ``buildcc::plugin``

.. admonition:: User/Developer opinion

Do we need to segregate the **Environment** into its own ``buildcc::env`` namespace or merge all those APIs into the ``buildcc`` namespace?

Developer
----------

* ``buildcc::base``
* ``buildcc::internal``

.. note:: Consider removing ``buildcc::base`` since a lot of the APIs are typedef`ed to the ``buildcc`` namespace
61 changes: 61 additions & 0 deletions docs/source/arch/outputs.rst
Original file line number Diff line number Diff line change
@@ -1,2 +1,63 @@
Outputs
=======

BuildCC Library
-----------------

The ``build_in_cpp`` project aims to remove DSLs by writing build files in C++.

However our C++ "script" first needs to be **built (compiled and linked)** then **executed (build targets)**.

When building (compiling and linking) our C++ "script" we need to link the ``buildcc`` library as well to provide the "script" with ``buildcc`` APIs.

BuildExe Executable
---------------------

``BuildExe`` is a standalone executable similar to ``make.exe``.

As part of the current release ``BuildExe`` requires the following folder structure.

.. note:: Proper details of ``BuildExe`` usage to be added. For now this is in its experimental stage with only support for GCC, MinGW and MSVC compilers.

.. uml::

@startmindmap
* ENV[BUILDCC_HOME]
** buildcc
** extensions
** libs
** host
@endmindmap

ENV[BUILDCC_HOME]
^^^^^^^^^^^^^^^^^^

Create your BUILDCC_HOME directory. For example: ``C:/BUILDCCHOME`` or ``local/mnt/BUILDCCHOME`` and add this path to the **environment variable BUILDCC_HOME**.

buildcc
^^^^^^^^

This directory contains the git cloned ``build_in_cpp`` repository

extensions
^^^^^^^^^^^

This directory contains several git cloned second and third party plugins and extensions

.. note:: BuildExe will have the ability to directly use these extensions after specifying them in the .toml file

libs
^^^^^

This directory contains several git cloned libraries that need to be used in your projects or code base once they are specified in your .toml file.

In this way, the ``build_in_cpp`` project automatically behaves like a package manager.

host
^^^^^

Host toolchain toml files that contain information pertaining to the various host toolchains installed on your operating system.

.. note:: The goal is to have a standalone executable to detect the host toolchains and automatically generate .toml files for each one of them. Users can then use these host toolchain files for building their "script"

.. note:: Consider adding a **cross** folder for cross compiled toolchains are well which cannot be used to build the "script" but instead can be used by the script to build cross compiled targets.
Loading