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

#include <build/context>

#include <ostream>
#include <cassert>
#include <system_error>

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

using namespace std;

namespace build
{
  dir_path work;
  dir_path home;

  const meta_operation_info* current_mif;
  const operation_info* current_oif;
  execution_mode current_mode;
  const target_rule_map* current_rules;

  void
  reset ()
  {
    targets.clear ();
    scopes.clear ();
    variable_pool.clear ();

    // Create global scope. For Win32 we use the empty path since there
    // is no "real" root path. On POSIX, however, this is a real path.
    // See the comment in <build/path-map> for details.
    //
#ifdef _WIN32
    global_scope = &scopes[dir_path ()];
#else
    global_scope = &scopes[dir_path ("/")];
#endif

    global_scope->variables["work"] = work;
    global_scope->variables["home"] = home;
  }

  fs_status<mkdir_status>
  mkdir (const dir_path& d)
  {
    // We don't want to print the command if the directory already
    // exists. This makes the below code a bit ugly.
    //
    mkdir_status ms;

    try
    {
      ms = try_mkdir (d);
    }
    catch (const system_error& e)
    {
      if (verb >= 1)
        text << "mkdir " << d.string ();
      else
        text << "mkdir " << d;

      fail << "unable to create directory " << d.string () << ": "
           << e.what ();
    }

    if (ms == mkdir_status::success)
    {
      if (verb >= 1)
        text << "mkdir " << d.string ();
      else
        text << "mkdir " << d;
    }

    return ms;
  }

  dir_path
  src_out (const dir_path& out, scope& s)
  {
    scope& rs (*s.root_scope ());
    return src_out (out, rs.path (), rs.src_path ());
  }

  dir_path
  out_src (const dir_path& src, scope& s)
  {
    scope& rs (*s.root_scope ());
    return out_src (src, rs.path (), rs.src_path ());
  }

  dir_path
  src_out (const dir_path& o,
           const dir_path& out_root, const dir_path& src_root)
  {
    assert (o.sub (out_root));
    return src_root / o.leaf (out_root);
  }

  dir_path
  out_src (const dir_path& s,
           const dir_path& out_root, const dir_path& src_root)
  {
    assert (s.sub (src_root));
    return out_root / s.leaf (src_root);
  }

  const dir_path* relative_base = &work;
}