aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/config/module.hxx
blob: 857a30cfa2288dee6cda7dbf70a25ed2818e8d51 (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
// file      : libbuild2/config/module.hxx -*- C++ -*-
// license   : MIT; see accompanying LICENSE file

#ifndef LIBBUILD2_CONFIG_MODULE_HXX
#define LIBBUILD2_CONFIG_MODULE_HXX

#include <map>

#include <libbutl/prefix-map.mxx>

#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>

#include <libbuild2/scope.hxx>
#include <libbuild2/module.hxx>
#include <libbuild2/variable.hxx>

#include <libbuild2/config/utility.hxx>

namespace build2
{
  namespace config
  {
    // An ordered list of build system modules each with an ordered list of
    // config.* variables and their "save flags" (see save_variable()) that
    // are used (as opposed to just being specified) in this configuration.
    // Populated by the config utility functions (required(), optional()) and
    // saved in the order populated. If flags are absent, then this variable
    // was marked as "unsaved" (always transient).
    //
    struct saved_variable
    {
      reference_wrapper<const variable> var;
      optional<uint64_t> flags;
    };

    struct saved_variables: vector<saved_variable>
    {
      // Normally each module only have a handful of config variables and we
      // only do this during configuration so for now we do linear search
      // instead of adding a map.
      //
      const_iterator
      find (const variable& var) const
      {
        return std::find_if (
          begin (),
          end (),
          [&var] (const saved_variable& v) {return var == v.var;});
      }
    };

    struct saved_modules: butl::prefix_map<string, saved_variables, '.'>
    {
      // Priority order with INT32_MIN being the highest. Modules with the
      // same priority are saved in the order inserted.
      //
      std::multimap<std::int32_t, const_iterator> order;

      pair<iterator, bool>
      insert (string name, int prio = 0)
      {
        auto p (emplace (move (name), saved_variables ()));

        if (p.second)
          order.emplace (prio, p.first);

        return p;
      }
    };

    struct module: build2::module
    {
      config::saved_modules saved_modules;

      // Return true if variable/module were newly inserted.
      //
      bool
      save_variable (const variable&, optional<uint64_t> flags);

      static void
      save_variable (scope&, const variable&, optional<uint64_t>);

      bool
      save_module (const char* name, int prio = 0);

      static void
      save_module (scope&, const char*, int);

      const saved_variable*
      find_variable (const variable& var)
      {
        auto i (saved_modules.find_sup (var.name));
        if (i != saved_modules.end ())
        {
          auto j (i->second.find (var));
          if (j != i->second.end ())
            return &*j;
        }

        return nullptr;
      }

      // Configure/disfigure hooks.
      //
      static bool
      configure_post (scope&, configure_post_hook*);

      static bool
      disfigure_pre (scope&, disfigure_pre_hook*);

      small_vector<configure_post_hook*, 1> configure_post_;
      small_vector<disfigure_pre_hook*,  1> disfigure_pre_;

      // Cached (during init) config.config.persist value, if defined.
      //
      const vector<pair<string, string>>* persist = nullptr;

      static const string name;
      static const uint64_t version;
    };

    // Implementation-specific utilities.
    //

    inline path
    config_file (const scope& rs)
    {
      return (rs.out_path () /
              rs.root_extra->build_dir /
              "config." + rs.root_extra->build_ext);
    }
  }
}

#endif // LIBBUILD2_CONFIG_MODULE_HXX