The JSON file has the following structure: | The JSON file has the following structure: | ||||
.. code-block:: jsonc | |||||
.. code-block:: javascript | |||||
{ | { | ||||
// Import version spec. | // Import version spec. |
packages | packages | ||||
toolchains | toolchains | ||||
source-dists | source-dists | ||||
repo | |||||
catalog | catalog | ||||
interdeps |
.. highlight:: yaml | |||||
Library and Package Dependencies | |||||
################################ | |||||
``dds`` considers that all libraries belong to a single *package*, but a single | |||||
package may contain one or more *libraries*. For this reason, and to better | |||||
interoperate with other build and packaging tools, we consider the issues of | |||||
package dependencies and library dependencies separately. | |||||
Package Dependencies | |||||
******************** | |||||
Consider that we are creating a package ``acme-gadgets@4.3.6``. We declare the | |||||
name and version in the ``package.dds`` in the package root: | |||||
.. code-block:: | |||||
Name: acme-gadgets | |||||
Version: 4.3.6 | |||||
Namespace: acme | |||||
.. note:: | |||||
The ``Namespace`` field is required, but will be addressed in the | |||||
:ref:`deps.lib-deps` section. | |||||
Suppose that our package's libraries build upon the libraries in the | |||||
``acme-widgets`` package, and that we require version ``1.4.3`` or newer, but | |||||
not as new as ``2.0.0``. Such a dependency can be declared with the ``Depends`` | |||||
key: | |||||
.. code-block:: | |||||
:emphasize-lines: 5 | |||||
Name: acme-gadgets | |||||
Version: 4.3.6 | |||||
Namespace: acme | |||||
Depends: acme-widgets ^1.4.3 | |||||
If we wish to declare additional dependencies, we simply declare them with | |||||
additional ``Depends`` keys | |||||
.. code-block:: | |||||
:emphasize-lines: 5-7 | |||||
Name: acme-gadgets | |||||
Version: 4.3.6 | |||||
Namespace: acme | |||||
Depends: acme-widgets ^1.4.3 | |||||
Depends: acme-gizmos ~5.6.5 | |||||
Depends: acme-utils ^3.3.0 | |||||
When ``dds`` attempts to build a project, it will first build the dependency | |||||
solution by iteratively scanning the dependencies of the containing project and | |||||
all transitive dependencies. | |||||
.. note:: | |||||
Unlike other packaging tools, ``dds`` will find a solution with the | |||||
*lowest* possible version that satisfies the given requirements for each | |||||
package. | |||||
.. _deps.lib-deps: | |||||
Library Dependencies | |||||
******************** | |||||
In ``dds``, library interdependencies are tracked separately from the packages | |||||
that contain them. A library must declare its intent to use another library | |||||
in the ``library.dds`` at its library root. The minimal content of a | |||||
``library.dds`` is the ``Name`` key: | |||||
.. code-block:: | |||||
Name: gadgets | |||||
To announce that a library wishes to *use* another library, use the aptly-named | |||||
``Uses`` key: | |||||
.. code-block:: | |||||
:emphasize-lines: 3-5 | |||||
Name: gadgets | |||||
Uses: acme/widgets | |||||
Uses: acme/gizmos | |||||
Uses: acme/utils | |||||
Here is where the package's ``Namespace`` key comes into play: A library's | |||||
qualified name is specified by joining the ``Namespace`` of the containing | |||||
package with the ``Name`` of the library within that package with a ``/`` | |||||
between them. | |||||
It is the responsibility of package authors to document the ``Namespace`` and | |||||
``Name`` of the packages and libraries that they distribute. | |||||
.. note:: | |||||
The ``Namespace`` of a package is completely arbitrary, and need not relate | |||||
to a C++ ``namespace``. | |||||
.. note:: | |||||
The ``Namespace`` need not be unique to a single package. For example, a | |||||
single organization (Like Acme Inc.) can share a single ``Namespace`` for | |||||
many of their packages and libraries. | |||||
However, it is essential that the ``<Namespace>/<Name>`` pair be | |||||
universally unique, so choose wisely! | |||||
Once the ``Uses`` key appears in the ``library.dds`` file of a library, ``dds`` | |||||
will make available the headers for the library being used, and will | |||||
transitively propagate that usage requirement to users of the library. |
Obtaining Packages | Obtaining Packages | ||||
****************** | ****************** | ||||
.. seealso:: See also: :doc:`catalog` | |||||
When ``dds`` builds a package, it will also build the dependency libraries of | When ``dds`` builds a package, it will also build the dependency libraries of | ||||
that package. In order for the dependency build to succeed, it must have a | that package. In order for the dependency build to succeed, it must have a | ||||
local copy of the source distribution of that dependency. | local copy of the source distribution of that dependency. | ||||
packages in the local repository, as well as packages that are available from | packages in the local repository, as well as packages that are available from | ||||
the :doc:`package catalog <catalog>`. If the dependency solution requires any | the :doc:`package catalog <catalog>`. If the dependency solution requires any | ||||
packages that are not in the local repository, it will use the information in | packages that are not in the local repository, it will use the information in | ||||
the catalog to obtain a source distribution for each missing package. The | |||||
the catalog to obtain a source distribution for each missing package. These | |||||
source distributions will automatically be added to the local repository, and | source distributions will automatically be added to the local repository, and | ||||
later dependency resolutions will not need to download that package again. | later dependency resolutions will not need to download that package again. | ||||
Manually Downloading a Dependency | |||||
================================= | |||||
It may be useful to obtain a copy of the source distribution of a package | |||||
contained in the catalog. The ``catalog get`` command can be used to do this:: | |||||
> dds catalog get <name>@<version> | |||||
This will obtain the source distribution of the package matching the named | |||||
identifier and place that distribution in current working directory, using the | |||||
package ID as the name of the source distribution directory:: | |||||
$ dds catalog get spdlog@1.4.2 | |||||
[ ... ] | |||||
$ ls . | |||||
. | |||||
.. | |||||
spdlog@1.4.2 | |||||
$ ls ./spdlog@1.4.2/ | |||||
include/ | |||||
src/ | |||||
library.dds | |||||
package.dds | |||||
.. _repo.export-local: | .. _repo.export-local: | ||||
Exporting a Project into the Repository | Exporting a Project into the Repository | ||||
*************************************** | *************************************** | ||||
``dds`` can only use packages that are available in the local repository. For | ``dds`` can only use packages that are available in the local repository. For | ||||
packages that have a listing in the catalog, this is not a problem. If one is | |||||
developing a local package and wants to allow it to be used in another local | |||||
packages that have a listing in the catalog, this is not a problem. But if one | |||||
is developing a local package and wants to allow it to be used in another local | |||||
package, that can be done by exporting a source distribution from the package | package, that can be done by exporting a source distribution from the package | ||||
root:: | root:: | ||||
> dds sdist export | > dds sdist export | ||||
This command will create a source distribution and put it into the local | |||||
repository. The package available to other projects on the local system. | |||||
This command will create a source distribution and place it in the local | |||||
repository. The package is now available to other projects on the local system. | |||||
.. note:: | .. note:: | ||||
This doesn't export in "editable" mode: A snapshot of the package root | This doesn't export in "editable" mode: A snapshot of the package root |
only maintaining the files that are necessary for ``dds`` to reproduce the | only maintaining the files that are necessary for ``dds`` to reproduce the | ||||
build of that package. | build of that package. | ||||
The ``--project=<dir>``` flag can be provided to override the directory that | |||||
The ``--project=<dir>`` flag can be provided to override the directory that | |||||
``dds`` will use as the package root. The default is the working directory of | ``dds`` will use as the package root. The default is the working directory of | ||||
the project. | the project. | ||||