aboutsummaryrefslogtreecommitdiff
path: root/build/install/module.cxx
blob: dc88ec2feeccfd6123736ca5d2943b56eadefab8 (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
// file      : build/install/module.cxx -*- C++ -*-
// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
// license   : MIT; see accompanying LICENSE file

#include <build/install/module>

#include <build/scope>
#include <build/target>
#include <build/rule>
#include <build/diagnostics>

#include <build/config/utility>

#include <build/install/operation>

using namespace std;
using namespace butl;

namespace build
{
  namespace install
  {
    // Set install.<name> values based on config.install.<name> values
    // or the defaults.
    //
    static void
    set_dir (scope& r, const char* name, const char* path, const char* mode)
    {
      string vn ("config.install.");
      vn += name;

      const list_value* pv (config::optional<list_value> (r, vn));

      vn += ".mode";
      const list_value* mv (config::optional<list_value> (r, vn));

      vn = "install.";
      vn += name;
      auto p (r.assign (vn));

      if (pv != nullptr && !pv->empty ())
        p = *pv;
      else if (path != nullptr)
        p = path;

      vn += ".mode";
      auto m (r.assign (vn));

      if (mv != nullptr && !mv->empty ())
        p = *mv;
      else if (mode != nullptr)
        p = mode;
    }

    extern "C" void
    install_init (scope& root,
                  scope& base,
                  const location& l,
                  unique_ptr<build::module>&,
                  bool first)
    {
      tracer trace ("install::init");

      if (&root != &base)
        fail (l) << "install module must be initialized in bootstrap.build";

      if (!first)
      {
        warn (l) << "multiple install module initializations";
        return;
      }

      const dir_path& out_root (root.path ());
      level4 ([&]{trace << "for " << out_root;});

      // Register the install operation.
      //
      operation_id install_id (root.operations.insert (install));

      {
        auto& rs (base.rules);

        // Register the standard alias rule for the install operation.
        //
        rs.insert<alias> (install_id, "alias", alias_rule::instance);
      }

      // Configuration.
      //
      // Note that we don't use any defaults -- the location must
      // be explicitly specified or the installer will complain if
      // and when we try to install.
      //
      if (first)
      {
        set_dir (root, "root", nullptr, nullptr);
        set_dir (root, "data_root", "root", "644");
        set_dir (root, "exec_root", "root", "755");

        set_dir (root, "bin", "exec_root/bin", nullptr);
        set_dir (root, "sbin", "exec_root/sbin", nullptr);
      }
    }
  }
}