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

#ifndef BUILD_FILE
#define BUILD_FILE

#include <build/types>
#include <build/variable> // list_value

namespace build
{
  class scope;
  class target;
  class location;
  class prerequisite_key;

  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);

  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);

  // 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);

  // 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?"
  //
  list_value
  import (scope& base, name, const location&);

  target&
  import (const prerequisite_key&);
}

#include <build/file.ixx>

#endif // BUILD_FILE