You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

210 lines
7.7KB

  1. Building ``dds`` from Source
  2. ############################
  3. While prebuilt ``dds`` executables are `available on the GitHub page
  4. <releases_>`_, one may wish to build ``dds`` from source.
  5. .. _releases: https://github.com/vector-of-bool/dds/releases
  6. The ``dds`` build process is designed to be as turn-key simple as possible.
  7. Platform Support
  8. ****************
  9. ``dds`` aims to be as cross-platform as possible. It currently build and
  10. executes on Windows, macOS, Linux, and FreeBSD. Support for additional
  11. platforms is possible but will require modifications to ``bootstrap.py`` that
  12. will allow it to be built on such platforms.
  13. Build Requirements
  14. ******************
  15. Building ``dds`` has a simple set of requirements:
  16. - **Python 3.6** or newer to run the bootstrap/CI scripts.
  17. - A C++ compiler that has rudimentary support for C++20 concepts. Newer
  18. releases of Visual C++ that ship with **VS 2019** will be sufficient on
  19. Windows, as will **GCC 9** with ``-fconcepts`` on other platforms.
  20. .. note::
  21. On Windows, you will need to execute the build from within a Visual C++
  22. enabled environment. This will involve launching the build from a Visual
  23. Studio Command Prompt.
  24. .. note::
  25. At the time of writing, C++20 Concepts has not yet been released in Clang,
  26. but should be available in LLVM/Clang 11 and newer.
  27. Build Scripts and the CI Process
  28. ********************************
  29. The main CI process is driven by Python. The root CI script is ``tools/ci.py``,
  30. and it accepts several command-line parameters. Only a few of are immediate
  31. interest:
  32. ``--bootstrap-with=<method>`` or ``-B <method>``
  33. Tell ``ci.py`` how to obtain the previous ``dds`` executable that can build
  34. the *current* ``dds`` source tree. This accepts one of three values:
  35. ``skip``, ``download``, or ``build``. Refer to :ref:`bootstrapping`.
  36. ``--build-only``
  37. A flag that tells ``ci.py`` to exit after it has successfully built the
  38. current source tree, and to not execute the phase-2 build nor the automated
  39. tests.
  40. ``--toolchain=<path>`` or ``-T <path>``
  41. Tell ``ci.py`` what toolchain to give to the prior ``dds`` to build the
  42. current ``dds``.
  43. The ``ci.py`` script performs the following actions, in order:
  44. #. Prepare the build output directory
  45. #. Prepare the prior version of ``dds`` that will build the current version.
  46. #. Import the embedded ``catalog.json`` into a catalog database stored within
  47. ``_prebuilt/``. This will be used to resolve the third-party packages that
  48. ``dds`` itself uses.
  49. #. Invoke the build of ``dds`` using the prebuilt ``dds`` from the prior
  50. bootstrap phase. If ``--build-only`` was specified, the CI script stops
  51. here.
  52. #. Use the new ``dds`` executable to rebuild itself *again* (phase-2 self-build
  53. test). A bit of a "sanity test."
  54. #. Execute the test suite using ``pytest``.
  55. .. _bootstrapping:
  56. Bootstrapping ``dds``
  57. *********************
  58. In the beginning, ``dds`` was built by a Python script that globbed the sources
  59. and invoked the compiler+linker on those sources. Once ``dds`` was able to
  60. build and link itself, this Python script was replaced instead with ``dds``
  61. building itself. ``dds`` has never used another build system.
  62. The ``ci.py`` script accepts one of three methods for the ``--bootstrap-with``
  63. flag: ``skip``, ``download``, or ``build``.
  64. Once bootstrapping is complete, a ``dds`` executable will be written to
  65. ``_prebuilt/dds``. This executable refers to a **previous** version of ``dds``
  66. that is able to build the newer ``dds`` source tree.
  67. .. note::
  68. For all development work on ``dds``, the ``_prebuilt/dds`` executable should
  69. always be used. This means that newer ``dds`` features are not available
  70. for use within the ``dds`` repository.
  71. Bootstrap: ``skip``
  72. ===================
  73. If given ``skip``, ``ci.py`` will not perform any bootstrapping steps. It will
  74. assume that there is an existing ``_prebuilt/dds`` executable. This option
  75. should be used once bootstrapping has been performed at least once with another
  76. method, as this is much faster than rebuilding/redownloading every time.
  77. Bootstrap: ``download``
  78. =======================
  79. The ``ci.py`` script has a reference to a download URL of the prior version of
  80. ``dds`` that has been designated for the bootstrap. These executables originate
  81. from `the GitHub releases <releases_>`_ page.
  82. If given ``download``, then ``ci.py`` will download a predetermined ``dds``
  83. executable and use it to perform the remainder of the build.
  84. Bootstrap: ``build``
  85. ====================
  86. Another script, ``tools/bootstrap.py`` is able to build ``dds`` from the ground
  87. up. It works by progressively cloning previous versions of the ``dds``
  88. repository and using them to build the next commit in the chain.
  89. While this is a neat trick, it isn't necessary for most development, as the
  90. resulting executable will be derived from the same commit as the executable
  91. that would be obtained using the ``download`` method. This is also more fragile
  92. as the past commits may make certain assumptions about the system that might
  93. not be true outside of the CI environment. The build process may be tweaked in
  94. the future to correct these assumptions.
  95. Selecting a Build Toolchain
  96. ***************************
  97. ``dds`` includes three toolchains that it uses to build itself in its CI
  98. environment: ``tools/gcc-9.jsonc`` for Linux and macOS,
  99. ``tools/freebsd-gcc-9.jsonc`` for FreeBSD, and ``tools/msvc.jsonc`` for
  100. Windows.
  101. While these toolchains will work perfectly well in CI, you may need to tweak
  102. these for your build setup. For example: ``gcc-9.jsonc`` assumes that the GCC 9
  103. executables are named ``gcc-9`` and ``g++-9``, which is incorrect on some
  104. Linux distributions.
  105. It is recommended to tweak these files as necessary to get the build working on
  106. your system. However, do not include those tweaks in a commit unless they are
  107. necessary to get the build running in CI.
  108. Giving a Toolchain to ``ci.py``
  109. ===============================
  110. Just like passing a toolchain to ``dds``, ``ci.py`` also requires a toolchain.
  111. Simply pass the path to your desired toolchain using the ``--toolchain``/
  112. ``-T`` argument:
  113. .. code-block:: bash
  114. $ python3 tools/ci.py [...] -T tools/gcc-9.jsonc
  115. Building for Development
  116. ************************
  117. While ``ci.py`` is rigorous in maintaining a clean and reproducible environment,
  118. we often don't need such rigor for a rapid development iteration cycle. Instead
  119. we can invoke the build command directly in the same way that ``ci.py`` does
  120. it:
  121. .. code-block:: bash
  122. $ _prebuilt/dds build -t [toolchain] \
  123. --catalog _prebuilt/catalog.db \
  124. --repo-dir _prebuilt/ci-repo
  125. The ``--catalog`` and ``--repo-dir`` arguments are not strictly necessary, but
  126. help to isolate the ``dds`` dev environment from the user-local ``dds``
  127. environment. This is important if modifications are made to the catalog
  128. database schema that would conflict with the one of an external ``dds``
  129. version.
  130. .. note::
  131. You'll likely want to run ``ci.py`` *at least once* for it to prepare the
  132. necessary ``catalog.db``.
  133. .. note::
  134. As mentioned previously, if using MSVC, the above command must execute with
  135. the appropriate VS development environment enabled.
  136. Running the Test Suite
  137. **********************
  138. The ``--build-only`` flag for ``ci.py`` will disable test execution. When this
  139. flag is omitted, ``ci.py`` will execute a self-build sanity test and then
  140. execute the main test suite, which is itself written as a set of ``pytest``
  141. tests in the ``tests/`` subdirectory.
  142. Unit Tests
  143. ==========
  144. Various pieces of ``dds`` contain unit tests. These are stored within the
  145. ``src/`` directory itself in ``*.test.cpp`` files. They are built and executed
  146. by the bootstrapped ``dds`` executable unconditionally. These tests execute
  147. in milliseconds and do not burden the development iteration cycle.