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.

188 lines
6.7KB

  1. Building and Using ``dds`` in Another Build System
  2. ##################################################
  3. One of ``dds``'s primary goals is to inter-operate with other build systems
  4. cleanly. One of ``dds``'s primary outputs is *libman* package indices. These
  5. package indices can be imported into other build systems that support the
  6. `libman`_ format. (At the time of writing there is a CMake module which can do
  7. the import, but other build systems are planned.)
  8. .. _libman: https://api.csswg.org/bikeshed/?force=1&url=https://raw.githubusercontent.com/vector-of-bool/libman/develop/data/spec.bs
  9. .. _PMM: https://github.com/vector-of-bool/PMM
  10. .. _CMakeCM: https://github.com/vector-of-bool/CMakeCM
  11. .. _lm-cmake: https://raw.githubusercontent.com/vector-of-bool/libman/develop/cmake/libman.cmake
  12. .. _build-deps.gen-libman:
  13. Generating a libman Index
  14. *************************
  15. Importing libman packages into a build system requires that we have a libman
  16. index generated on the filesystem. **This index is not generated globally**: It
  17. is generated on a per-build basis as part of the build setup. The index will
  18. describe in build-system-agnostic terms how to include a set of packages and
  19. libraries as part of a build.
  20. ``dds`` has first-class support for generating this index. The ``build-deps``
  21. subcommand of ``dds`` will download and build a set of dependencies, and places
  22. an ``INDEX.lmi`` file that can be used to import the built results.
  23. Declaring Dependencies
  24. ======================
  25. ``dds build-deps`` accepts a list of dependency statements as command line
  26. arguments, but it may be useful to specify those requirements in a file.
  27. ``dds build-deps`` accepts a JSON5 file describing the dependencies of a
  28. project as well. This file is similar to a very stripped-down version of a
  29. ``dds`` :ref:`package manifest <pkgs.pkgs>`, and only includes the ``depends``
  30. key. (The presence of any other key is an error.)
  31. Here is a simple dependencies file that declares a single requirement:
  32. .. code-block:: js
  33. :caption: ``dependencies.json5``
  34. {
  35. depends: [
  36. 'neo-sqlite3^0.2.0',
  37. ]
  38. }
  39. Building Dependencies and the Index
  40. ===================================
  41. We can invoke ``dds build-deps`` and give it the path to this file:
  42. .. code-block:: bash
  43. $ dds build-deps --deps-file dependencies.json5
  44. When finished, ``dds`` will write the build results into a subdirectory called
  45. ``_deps`` and generate a file named ``INDEX.lmi``. This file is ready to be
  46. imported into any build system that can understand libman files.
  47. .. note::
  48. The output directory and index filepath can be controlled with the
  49. ``--out`` and ``--lmi-path`` flags, respectively.
  50. Importing an Index: CMake
  51. *************************
  52. .. highlight:: cmake
  53. .. note::
  54. This section discusses how to import ``INDEX.lmi`` into CMake, but ``dds``
  55. also has built-in support for generating a CMake targets file. See
  56. :doc:`/howto/cmake` and :doc:`cmake` for even simpler integration steps.
  57. Supposed that we've generated a libman index and set of packages, and we want to
  58. import them into CMake. CMake doesn't know how to do this natively, but there
  59. exists a single-file module for CMake that allows CMake to import libraries from
  60. libman indices without any additional work.
  61. The module is not shipped with CMake, but is available online as a single
  62. stand-alone file. The `libman.cmake <lm-cmake_>`_ file can be downloaded and
  63. added to a project directly, or it can be obtained automatically through a
  64. CMake tool like `PMM`_ (recommended).
  65. Getting ``libman.cmake`` via PMM
  66. ================================
  67. Refer to the ``README.md`` file in `the PMM repo <PMM_>`_ for information on how
  68. to get PMM into your CMake project. In short, download and place the
  69. ``pmm.cmake`` file in your repository, and ``include()`` the file near the top
  70. of your ``CMakeLists.txt``::
  71. include(pmm.cmake)
  72. Once it has been included, you can call the ``pmm()`` function. To obtain
  73. *libman*, we need to start by enabling `CMakeCM`_::
  74. pmm(CMakeCM ROLLING)
  75. .. warning::
  76. It is not recommended to use the ``ROLLING`` mode, but it is the easiest to
  77. use when getting started. For reproducible and reliable builds, you should
  78. pin your CMakeCM version using the ``FROM <url>`` argument.
  79. Enabling CMakeCM will make available all of the CMake modules available in `the
  80. CMakeCM repository <CMakeCM_>`_, which includes `libman.cmake <lm-cmake_>`_.
  81. After the call to ``pmm()``, simply ``include()`` the ``libman`` module::
  82. include(libman)
  83. That's it! The only function from the module that we will care about for now
  84. is the ``import_packages()`` function.
  85. Importing Our Dependencies' Packages
  86. ====================================
  87. To import a package from a libman tree, we need only know the *name* of the
  88. package we wish to import. In our example case above, we depend on
  89. ``neo-sqlite3``, so we simply call the libman-CMake function
  90. ``import_packages()`` with that package name::
  91. import_packages("neo-sqlite3")
  92. You'll note that we don't request any particular version of the package: All
  93. versioning resolution is handled by ``dds``. You'll also note that we don't
  94. need to specify our transitive dependencies: This is handled by the libman
  95. index that was generated by ``dds``: It will automatically ``import_packages()``
  96. any of the transitive dependencies required.
  97. More than one package name can be provided to a single call to
  98. ``import_packages()``, and ``import_packages()`` may be called multiple times
  99. within a CMake project.
  100. Using Our Dependencies' Libraries
  101. =================================
  102. Like with ``dds``, CMake wants us to explicitly declare how our build targets
  103. *use* other libraries. When we import a package from a libman index, the
  104. import will generate CMake ``IMPORTED`` targets that can be linked against.
  105. In ``dds`` and in libman, a library is identified by a combination of
  106. *namespace* and *name*, joined together with a slash ``/`` character. This
  107. *qualified name* of a library is decided by the original package author, and
  108. should be documented. In the case of ``neo-sqlite3``, the only library is
  109. ``neo/sqlite3``.
  110. When the libman CMake module imports a library, it creates a qualified name
  111. using a double-colon "``::``" instead of a slash. As such, our ``neo/sqlite3``
  112. is imported in CMake as ``neo::sqlite3``. We can link against it as we would
  113. with any other target::
  114. add_executable(my-application app.cpp)
  115. target_link_libraries(my-application PRIVATE neo::sqlite3)
  116. Altogether, here is the final CMake file:
  117. .. code-block::
  118. :caption: ``CMakeLists.txt``
  119. :linenos:
  120. cmake_minimum_required(VERSION 3.15)
  121. project(MyApplication VERSION 1.0.0)
  122. include(pmm.cmake)
  123. pmm(CMakeCM ROLLING)
  124. include(libman)
  125. import_packages("neo-sqlite3")
  126. add_executable(my-application app.cpp)
  127. target_link_libraries(my-application PRIVATE neo::sqlite3)