Переглянути джерело

Docs updates

default_compile_flags
vector-of-bool 5 роки тому
джерело
коміт
8e54b66941
5 змінених файлів з 284 додано та 143 видалено
  1. +18
    -15
      docs/guide/design.rst
  2. +1
    -1
      docs/guide/index.rst
  3. +0
    -123
      docs/guide/layout.rst
  4. +260
    -0
      docs/guide/packages.rst
  5. +5
    -4
      docs/index.rst

+ 18
- 15
docs/guide/design.rst Переглянути файл

@@ -4,25 +4,25 @@
``dds`` has been designed from the very beginning as an extremely opinionated
hybrid *build system* and *package manager*. Unlike most build systems however,
``dds`` has a hyper-specific focus on a particular aspect of software
development: C++ libraries.
development: C and C++ libraries.

This may sound pointless, right? Libraries are useless unless we can use them
to build applications!

Indeed, applications *are* essential, but that is "not our job."
Indeed, applications *are* essential, but that is "not our job" with ``dds``.

Another design decision is that ``dds`` is built to be driven by automated
tools as well as humans. ``dds`` will not build your AAA console game, nor will
it compile an OS kernel. Instead, the build system of your AAA console game or
OS kernel can *use* ``dds``.
tools as well as humans. ``dds`` is not designed to entirely replace existing
build systems and package management solutions. Rather, it is designed to be
easy to integrate *with* existing systems and tools.


Background
**********

I'm going to say something somewhat controversial: C++ doesn't need "package
management." At least, not *generalize* "package management." C++ needs
*library* "package management."
I'm going to say something somewhat controversial: C and C++ don't need
"package management." At least, not *generalized* "package management." C++
needs *library* "package management."

The C and C++ compilation model is inherently *more complex* than almost any
other language in use today. This isn't to say "bad," but rather than it is
@@ -68,9 +68,9 @@ For example, LLVM and Blender both use the CMake "Build System," but their
different, despite both using the same underlying "Build System."

``dds`` takes a massive divergence at this point. One project using ``dds`` as
their build system has an identical build process to every other project using
``dds``. Simply running :code:`dds -F` is enough to build *any* ``dds``
project.
their build system has a nearly identical build process to every other project
using ``dds``. Simply running :code:`dds build -t <toolchain>` should be enough
to build *any* ``dds`` project.

In order to reach this uniformity and simplicity, ``dds`` drops almost all
aspects of project-by-project customizability. Instead, ``dds`` affords the
@@ -106,8 +106,7 @@ violate any of the other existing rules.
on.

``dds`` contains a minimal amount of functionality for building simple
applications, but it is certainly not its primary purpose (See the ``--apps``
flag).
applications, but it is certainly not its primary purpose.


.. _design.rules.change:
@@ -135,7 +134,7 @@ structure layout with minimal differing options. ``dds`` prescribes the

.. note::
These prescriptions are not as draconian as they may sound upon first
reading. Refer to the :doc:`layout` page for more information.
reading. Refer to the :doc:`packages` page for more information.

.. _Pitchfork: https://api.csswg.org/bikeshed/?force=1&url=https://raw.githubusercontent.com/vector-of-bool/pitchfork/develop/data/spec.bs

@@ -178,7 +177,7 @@ No Arbitrary ``#include`` Directories

Only ``src/`` and ``include/`` will ever be used as the basis for header
resolution while building a library, so all ``#include`` directives should be
relative to those directories. Refer to :ref:`guide.layout.include`.
relative to those directories. Refer to :ref:`pkg.source-root`.


.. _design.rules.uniform-compile:
@@ -190,3 +189,7 @@ When DDS compiles a library, every source file will be compiled with an
identical set of options. Additionally, when DDS compiles a dependency tree,
every library in that dependency tree will be compiled with an identical set of
options. Refer to the :doc:`toolchains` page for more information.

Currently, the only exception to this rules is for flags that control compiler
warnings: Dependencies will be compiled without adding any warnings flags,
while the main project will be compiled with warnings enabled by default.

+ 1
- 1
docs/guide/index.rst Переглянути файл

@@ -7,5 +7,5 @@ User Guide
:maxdepth: 2

design
layout
packages
toolchains

+ 0
- 123
docs/guide/layout.rst Переглянути файл

@@ -1,123 +0,0 @@
Project Layout
##############

The layout expected by ``dds`` is based on the `Pitchfork layout`_ (PFL).
``dds`` does not make use of every provision of the layout document, but the
features it does have are based on PFL.

.. _Pitchfork layout: https://api.csswg.org/bikeshed/?force=1&url=https://raw.githubusercontent.com/vector-of-bool/pitchfork/develop/data/spec.bs

In particular, the following directories are used:

- ``src/``
- ``include/``
- ``libs/``
- ``_build/`` (the default build output directory used by ``dds``).

Note that the ``libs/*/`` directories can contain their own ``src/`` and
``include/`` directories, the purposes and behaviors of which match those of
their top-level counterparts.


.. _guide.layout.include:

Include Directories and Header Resolution
*****************************************

A compiler's "include path" is the list of directories in which it will attempt
to resolve ``#include`` directives.

The layout prescriptions permit either ``src/``, ``include/``, or both. In the
presence of both, the ``include/`` directory is used as the *public* include
directory, and ``src/`` is used as the *private* include directory. When only
one of either is present, that directory will be treated as the *public*
include directory (and there will be no *private* include directory).


.. _guide.layout.sources:

Source Files
************

``dds`` distinguishes between *headers* and *compilable* sources. The heuristic
used is based on common file extensions:

The following are considered to be *header* source files:

- ``.h``
- ``.hpp``
- ``.hxx``
- ``.inl``
- ``.h++``

While the following are considered to be *compilable* source files:

- ``.c``
- ``.cpp``
- ``.cc``
- ``.cxx``
- ``.c++``

``dds`` will compile every compilable source file that appears in the ``src/``
directory. ``dds`` will not compile compilable source files that appear in the
``include/`` directory and will issue a warning on each file found.


.. _guide.layout.apps-tests:

Applications and Tests
**********************

``dds`` will recognize certain compilable source files as belonging to
applications and tests. If a compilable source file stem ends with ``.main`` or
``.test``, that source file is assumed to correspond to an executable to
generate. The filename stem before the ``.main`` or ``.test`` will be used as
the name of the generated executable. For example:

- ``foo.main.cpp`` will generate an executable named ``foo``.
- ``bar.test.cpp`` will generate an executable named ``bar``.
- ``cat-meow.main.cpp`` will generate an executable named ``cat-meow``.
- ``cats.musical.test.cpp`` will generate an executable named ``cats.musical``.

.. note::
``dds`` will automatically append the appropriate filename extension to the
generated executables based on the host and toolchain.

If the inner extension is ``.main``, then ``dds`` will assume the corresponding
executable to be an *application*. If the inner extension is ``.test``, ``dds``
will assume the executable to be a test.

The building of tests and applications can be controlled when running
``dds build``. If tests are built, ``dds`` will automatically execute those
tests in parallel once the executables have been generated.

In any case, the executables are associated with a *library*, and, when those
executables are linked, the associated library (and its dependencies) will be
linked into the final executable. There is no need to manually specify this
linking behavior.


.. _guide.layout.libraries:

Libraries
*********

The *library* is a fundamental unit of consumable code, and ``dds`` is
specifically built to work with them. When you are in ``dds``, the library is
the center of everything.

A *source root* is a directory that contains the ``src/`` and/or ``include/``
directories. The ``src/`` and ``include/`` directories are themselves
*source directories*. A single *source root* will always correspond to exactly
one library. If the library has any compilable sources then ``dds`` will use
those sources to generate a static library file that is linked into runtime
binaries. If a library contains only headers then ``dds`` will not generate an
archive to be included in downstream binaries, but it will still generate link
rules for the dependencies of a header-only library.

In the previous section, :ref:`guide.layout.apps-tests`, it was noted that
applications and tests are associated with a library. This association is
purely based on being collocated within the same source root.

When an executable is built within the context of a library, that library (and
all of its dependencies) will be linked into that executable.

+ 260
- 0
docs/guide/packages.rst Переглянути файл

@@ -0,0 +1,260 @@
Package Layout
##############

The units of distribution in ``dds`` are *packages*. A single package consists
of one or more *libraries*. In the simplest case, a package will contain a
single library.

It may be easiest to work from the bottom-up when trying to understand how
``dds`` understands code.

The layout expected by ``dds`` is based on the `Pitchfork layout`_ (PFL).
``dds`` does not make use of every provision of the layout document, but the
features it does have are based on PFL.

.. _Pitchfork layout: https://api.csswg.org/bikeshed/?force=1&url=https://raw.githubusercontent.com/vector-of-bool/pitchfork/develop/data/spec.bs

In particular, the following directories are used:

- ``src/``
- ``include/``
- ``libs/``
- ``_build/`` (the default build output directory used by ``dds``).

Note that the ``libs/*/`` directories can contain their own ``src/`` and
``include/`` directories, the purposes and behaviors of which match those of
their top-level counterparts.


Source Files
************

The smallest subdivision of code that ``dds`` recognizes is the *source file*,
which is exactly as it sounds: A single file containing some amount of code.

Source files can be grouped on a few axes, the most fundamental of which is
"Is this compiled?"

``dds`` uses source file extensions to determine whether a source file should
be fed to the compiler. All of the common C and C++ file extensions are
supported:

.. list-table::

- * Compiled as C
* ``.c`` and ``.C``

- * Compiled as C++
* ``.cpp``, ``.c++``, ``.cc``, and ``.cxx``

- * Not compiled
* ``.H``, ``.H++``, ``.h``, ``.h++``, ``.hh``, ``.hpp``, ``.hxx``, and ``.inl``

If a file's extension is not listed in the table above, ``dds`` will ignore it.

.. note::
Although headers are not compiled, this does not mean they are ignored.
``dds`` still understands and respects headers, and they are collected
together as part of *source distribution*.


Applications and Tests
**********************

``dds`` will recognize certain compilable source files as belonging to
applications and tests. If a compilable source file stem ends with ``.main`` or
``.test``, that source file is assumed to correspond to an executable to
generate. The filename stem before the ``.main`` or ``.test`` will be used as
the name of the generated executable. For example:

- ``foo.main.cpp`` will generate an executable named ``foo``.
- ``bar.test.cpp`` will generate an executable named ``bar``.
- ``cat-meow.main.cpp`` will generate an executable named ``cat-meow``.
- ``cats.musical.test.cpp`` will generate an executable named ``cats.musical``.

.. note::
``dds`` will automatically append the appropriate filename extension to the
generated executables based on the host and toolchain.

An *application* source file is a source file whose file stem ends with
``.main``. ``dds`` will assume this source file to contain a program entry
point function and not include it as part of the main library build. Instead,
when ``dds`` is generating applications, the source file will be compiled, and
the resulting object will be linked together with the enclosing library into an
executable.

A *test* source file is a source file whose file stem ends with ``.test``. Like
application sources, a *test* source file is omitted from the main library, and
it will be used to generate tests. The exact behavior of tests is determined by
the ``Test-Driver`` setting for the package, but the default is that each test
source file will generate a single test executable that is executed by ``dds``
when running unit tests.

The building of tests and applications can be controlled when running
``dds build``. If tests are built, ``dds`` will automatically execute those
tests in parallel once the executables have been generated.

In any case, the executables are associated with a *library*, and, when those
executables are linked, the associated library (and its dependencies) will be
linked into the final executable. There is no need to manually specify this
linking behavior.


.. _pkg.source-root:

Source Roots
************

Source files are collected as children of some *source root*. A *source
root* is a single directory that contains some *portable* bundle of source
files. The word "portable" is important: It is what distinguishes the
source root from its child directories.


Portability
===========

By saying that a source root is "portable", It indicates that the directory
itself can be moved, renamed, or copied without breaking the ``#include``
directives of its children or of the directory's referrers.

As a practical example, let's examine such a directory, which we'll call
``src/`` for the purposes of this example. Suppose we have a directory named
``src`` with the following structure:

.. code-block:: text

<path>/src/
animals/
mammal/
mammal.hpp
cat/
cat.hpp
sound.hpp
sound.cpp
dog/
dog.hpp
sound.hpp
sound.cpp

In this example, ``src/`` is a *source root*, but ``src/animals/``,
``src/animals/cat/``, and ``src/animals/dog/`` are **not** source roots.
While they may be directories that contain source files, they are not "roots."

Suppose now that ``dog.hpp`` contains an ``#include`` directive:

.. code-block:: c++

#include <animals/mammal/mammal.hpp>

or even a third-party user that wants to use our library:

.. code-block:: c++

#include <animals/dog/dog.hpp>
#include <animals/dog/sound.hpp>

In order for any code to compile and resolve these ``#include`` directives, the
``src/`` directory must be added to their *include search path*.

Because the ``#include`` directives are based on the *portable* source root,
the exactly location of ``src/`` is not important to the content of the
consuming source code, and can thus be relocated and renamed as necessary.
Consumers only need to update the path of the *include search path* in a single
location rather than modifying their source code.


Source Roots in ``dds``
=======================

To avoid ambiguity and aide in portability, the following rules should be
strictly adhered to:

#. Source roots may not contain other source roots.
#. Only source roots will be added to the *include-search-path*.
#. All ``#include``-directives are relative to a source root.

By construction, ``dds`` cannot build a project that has nested source roots,
and it will only ever add source roots to the *include-search-path*.

``dds`` supports either one or two source roots in a library.


Library Roots
*************

In ``dds``, a *library root* is a directory that contains a ``src/`` directory,
an ``include/`` directory, or both. ``dds`` will treat both directories as
source roots, but behaves differently between the two. The ``src/`` and
``include/`` directories are themselves *source roots*.

``dds`` distinguishes between a *public* include-directory, and a *private*
include-directory. When ``dds`` is compiling a library, both its *private* and
its *public* include-paths will be added to the compiler's
*include-search-path*. When a downstream user of a library is compiling against
a library managed by ``dds``, only the *public* include-directory will be
added to the compiler's *include-search-path*. This has the effect that only
the files that are children of the source root that is the *public*
include-directory will be available when compiling consumers.

.. warning::
Because only the *public* include-directory is available when compiling
consumers, it is essential that no headers within the *public*
include-directory attempt to use headers from the *private*
include-directory, as they **will not** be visible.

If both ``src/`` and ``include/`` are present in a library root, then ``dds``
will use ``include/`` as the *public* include-directory and ``src/`` as the
*private* include-directory. If only one of the two is present, then that
directory will be treated as the *public* include-directory, and there will be
no *private* include-directory.

When ``dds`` exports a library, the header files from the *public*
include-directory source root will be collected together and distributed as
that library's header tree. The path to the individual header files relative to
their source root will be retained as part of the library distribution.

``dds`` will compile every compilable source file that appears in the ``src/``
directory. ``dds`` will not compile compilable source files that appear in the
``include/`` directory and will issue a warning on each file found.


Libraries
*********

The *library* is a fundamental unit of consumable code, and ``dds`` is
specifically built to work with them. When you are in ``dds``, the library is
the center of everything.

A single *library root* will always correspond to exactly one library. If the
library has any compilable sources then ``dds`` will use those sources to
generate a static library file that is linked into runtime binaries. If a
library contains only headers then ``dds`` will not generate an archive to be
included in downstream binaries, but it will still generate link rules for the
dependencies of a header-only library.

In order for ``dds`` to be able to distribute and interlink libraries, a
``library.dds`` file must be present at the corresponding library root.


Package Roots
*************

A *package root* is a directory that contains some number of library roots. If
the package root contains a ``src/`` and/or ``include/`` directory then the
package root is itself a library root, and a library is defined at the root of
the package. This is intended to be the most common and simplest method of
creating libraries with ``dds``.

If the package root contains a ``libs/`` directory, then each subdirectory of
the ``libs/`` directory is checked to be a library root. Each direct child of
the ``libs/`` directory that is also a library root is added as a child of the
owning package.


Packages
********

A package is defined by some *package root*, and contains some number of
*libraries*. In order for a package to be exported by ``dds`` it must have a
``package.dds`` file at its package root.

+ 5
- 4
docs/index.rst Переглянути файл

@@ -1,11 +1,12 @@
DDS
######

**dds** is the Drop-Dead-Simple Build and Library Management Tool.
**dds** is the Drop-Dead-Simple build and library management tool.

dds is a hybrid build system and package manager with a unique twist.
There's a lot to learn, but I'm glad you're here! I hope you find ``dds``
useful to you and your projects.
dds is a hybrid build system and package manager with a few distinguishing
design decisions that set it apart from current offerings. There's a lot to
learn, but I'm glad you're here! I hope you find ``dds`` useful to you and your
projects.

If you're completely new and have no idea what the project is about, check out
the :doc:`guide/design` page to get started.

Завантаження…
Відмінити
Зберегти