aboutsummaryrefslogtreecommitdiff
path: root/build2/file
blob: 00ece856bdea001061f702f408d25593b8a3d670 (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
152
153
154
155
156
157
// file      : build2/file -*- C++ -*-
// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
// license   : MIT; see accompanying LICENSE file

#ifndef BUILD2_FILE
#define BUILD2_FILE

#include <map>

#include <build2/types>
#include <build2/utility>

#include <build2/scope>
#include <build2/variable> // list_value

namespace build2
{
  class target;
  class location;
  class prerequisite_key;

  using subprojects = std::map<string, dir_path>;

  extern const dir_path build_dir;     // build
  extern const dir_path bootstrap_dir; // build/bootstrap

  extern const path root_file;         // build/root.build
  extern const path bootstrap_file;    // build/bootstrap.build
  extern const path src_root_file;     // build/bootstrap/src-root.build

  bool
  is_src_root (const dir_path&);

  bool
  is_out_root (const dir_path&);

  // Given an src_base directory, look for a project's src_root
  // based on the presence of known special files. Return empty
  // path if not found.
  //
  dir_path
  find_src_root (const dir_path&);

  // The same as above but for project's out. Note that we also
  // check whether a directory happens to be src_root, in case
  // this is an in-tree build. The second argument is the out
  // flag that is set to true if this is src_root.
  //
  dir_path
  find_out_root (const dir_path&, bool* src = nullptr);

  // If buildfile is '-', then read from STDIN.
  //
  void
  source (const path& buildfile, scope& root, scope& base);

  // As above but first check if this buildfile has already been sourced for
  // the base scope.
  //
  void
  source_once (const path& buildfile, scope& root, scope& base);

  // As above but checks against the specified scope rather than base.
  //
  void
  source_once (const path& buildfile, scope& root, scope& base, scope& once);

  // Create project's root scope. Only set the src_root variable if the
  // passed src_root value is not empty.
  //
  scope&
  create_root (const dir_path& out_root, const dir_path& src_root);

  // Setup root scope. Note that it assume the src_root variable
  // has already been set.
  //
  void
  setup_root (scope&);

  // Setup the base scope (set *_base variables, etc).
  //
  scope&
  setup_base (scope_map::iterator,
              const dir_path& out_base,
              const dir_path& src_base);

  // Bootstrap the project's root scope, the out part.
  //
  void
  bootstrap_out (scope& root);

  // Bootstrap the project's root scope, the src part. Return true if
  // we loaded anything (which confirms the src_root is not bogus).
  //
  bool
  bootstrap_src (scope& root);

  // Return true if this scope has already been bootstrapped, that is, the
  // following calls have already been made:
  //
  //   bootstrap_out()
  //   setup_root()
  //   bootstrap_src()
  //
  bool
  bootstrapped (scope& root);

  // Create and bootstrap outer root scopes, if any. Loading is
  // done by load_root_pre() below.
  //
  void
  create_bootstrap_outer (scope& root);

  // Create and bootstrap inner root scopes between root and base,
  // if any. Return the innermost created root scope or root if
  // none were created. Loading is done by load_root_pre() below.
  //
  scope&
  create_bootstrap_inner (scope& root, const dir_path& out_base);

  // Load project's root[-pre].build unless already loaded. Also
  // make sure all outer root scopes are loaded prior to loading
  // this root scope.
  //
  void
  load_root_pre (scope& root);

  // Import has two phases: the first is triggered by the import
  // directive in the buildfile. It will try to find and load the
  // project. Failed that, it will return the project-qualified
  // name of the target which will be used to create a project-
  // qualified prerequisite. This gives the rule that will be
  // searching this prerequisite a chance to do some target-type
  // specific search. For example, a C++ link rule can search
  // for lib{} prerequisites in the C++ compiler default library
  // search paths (so that we end up with functionality identical
  // to -lfoo). If, however, the rule didn't do any of that (or
  // failed to find anything usable), it calls the standard
  // prerequisite search() function which sees this is a project-
  // qualified prerequisite and goes straight to the second phase
  // of import. Here, currently, we simply fail but in the future
  // this will be the place where we can call custom "last resort"
  // import hooks. For example, we can hook a package manager that
  // will say, "Hey, I see you are trying to import foo and I see
  // there is a package foo available in repository bar. Wanna
  // download and use it?"
  //
  names
  import (scope& base, name, const location&);

  target&
  import (const prerequisite_key&);
}

#include <build2/file.ixx>

#endif // BUILD2_FILE