aboutsummaryrefslogtreecommitdiff
path: root/libbutl/b.mxx
blob: cca9696270fa45efb85261577cd06bf1211559c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// file      : libbutl/b.mxx -*- C++ -*-
// license   : MIT; see accompanying LICENSE file

#ifndef __cpp_modules_ts
#pragma once
#endif

// C includes.

#ifndef __cpp_lib_modules_ts
#include <string>
#include <vector>
#include <utility>    // move()
#include <cstddef>    // size_tu
#include <cstdint>    // uint16_t
#include <stdexcept>  // runtime_error
#include <functional>
#endif

// Other includes.

#ifdef __cpp_modules_ts
export module butl.b;
#ifdef __cpp_lib_modules_ts
import std.core;
#endif
import butl.url;
import butl.path;
import butl.process;
import butl.optional;
import butl.project_name;
import butl.standard_version;
#else
#include <libbutl/url.mxx>
#include <libbutl/path.mxx>
#include <libbutl/process.mxx>
#include <libbutl/optional.mxx>
#include <libbutl/project-name.mxx>
#include <libbutl/standard-version.mxx>
#endif

#include <libbutl/export.hxx>

LIBBUTL_MODEXPORT namespace butl
{
  class LIBBUTL_SYMEXPORT b_error: public std::runtime_error
  {
  public:
    // Build system program exit information. May be absent if the error
    // occured before the process has been started.
    //
    // Can be used by the caller to decide if to print the error message to
    // stderr. Normally, it is not required if the process exited normally
    // with non-zero code, since presumably it has issued diagnostics. Note
    // that the normal() function can be used to check for this.
    //
    optional<process_exit> exit;

    // Return true if the build2 process exited normally with non-zero code.
    //
    bool
    normal () const {return exit && exit->normal () && !*exit;}

    explicit
    b_error (const std::string& description, optional<process_exit> = nullopt);
  };

  // Run `b info: <project-dir>...` command and parse and return (via argument
  // to allow appending and for error position; see below) the build2 projects
  // information it prints to stdout. Return the empty list if the specified
  // project list is empty. Throw b_error on error. Note that the size of the
  // result vector can be used to determine which project information caused
  // the error.
  //
  // Unless you need information that may come from external modules
  // (operations, meta-operations, etc), pass false as the ext_mods argument,
  // which results in passing --no-external-modules to the build2 program and
  // speeds up its execution.
  //
  // You can also specify the build2 verbosity level, command line callback
  // (see process_run_callback() for details), build program search details,
  // and additional options.
  //
  // Note that version_string is only parsed to standard_version if a project
  // uses the version module. Otherwise, standard_version is empty.
  //
  struct b_project_info
  {
    using url_type = butl::url;

    struct subproject
    {
      project_name name;  // Empty if anonymous.
      dir_path     path;  // Relative to the project root.
    };

    project_name     project;
    std::string      version_string;
    standard_version version;
    std::string      summary;
    url_type         url;

    dir_path src_root;
    dir_path out_root;

    dir_path                amalgamation; // Relative to project root and
                                          // empty if not amalgmated.
    std::vector<subproject> subprojects;

    std::vector<std::string> operations;
    std::vector<std::string> meta_operations;

    std::vector<std::string> modules;
  };

  using b_callback = void (const char* const args[], std::size_t n);

  LIBBUTL_SYMEXPORT void
  b_info (std::vector<b_project_info>& result,
          const std::vector<dir_path>& projects,
          bool ext_mods,
          std::uint16_t verb = 1,
          const std::function<b_callback>& cmd_callback = {},
          const path& program = path ("b"),
          const dir_path& search_fallback = {},
          const std::vector<std::string>& options = {});

  // As above but retrieve information for a single project.
  //
  inline b_project_info
  b_info (const dir_path& project,
          bool ext_mods,
          std::uint16_t verb = 1,
          const std::function<b_callback>& cmd_callback = {},
          const path& program = path ("b"),
          const dir_path& search_fallback = {},
          const std::vector<std::string>& options = {})
  {
    std::vector<b_project_info> r;
    b_info (r,
            std::vector<dir_path> ({project}),
            ext_mods,
            verb,
            cmd_callback,
            program,
            search_fallback,
            options);

    return std::move (r[0]);
  }
}