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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
// file : libbuild2/cc/compile-rule.hxx -*- C++ -*-
// license : MIT; see accompanying LICENSE file
#ifndef LIBBUILD2_CC_COMPILE_RULE_HXX
#define LIBBUILD2_CC_COMPILE_RULE_HXX
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
#include <libbuild2/rule.hxx>
#include <libbuild2/file-cache.hxx>
#include <libbuild2/cc/types.hxx>
#include <libbuild2/cc/common.hxx>
#include <libbuild2/cc/export.hxx>
namespace build2
{
class depdb;
namespace cc
{
// The order is arranged so that their integral values indicate whether
// one is a "stronger" than another.
//
enum class preprocessed: uint8_t {none, includes, modules, all};
// Positions of the re-exported bmi{}s. See search_modules() for
// details.
//
struct module_positions
{
size_t start; // First imported bmi*{}, 0 if none.
size_t exported; // First re-exported bmi*{}, 0 if none.
size_t copied; // First copied-over bmi*{}, 0 if none.
};
class LIBBUILD2_CC_SYMEXPORT compile_rule: public simple_rule, virtual common
{
public:
compile_rule (data&&);
virtual bool
match (action, target&, const string&) const override;
virtual recipe
apply (action, target&) const override;
target_state
perform_update (action, const target&) const;
target_state
perform_clean (action, const target&) const;
public:
using appended_libraries = small_vector<const file*, 256>;
void
append_library_options (appended_libraries&, strings&,
const scope&,
action, const file&, bool, linfo) const;
optional<path>
find_system_header (const path&) const;
protected:
static void
functions (function_family&, const char*); // functions.cxx
private:
struct match_data;
using environment = small_vector<const char*, 2>;
template <typename T>
void
append_sys_hdr_options (T&) const;
template <typename T>
void
append_library_options (appended_libraries&, T&,
const scope&,
action, const file&, bool, linfo,
library_cache*) const;
template <typename T>
void
append_library_options (T&,
const scope&,
action, const target&, linfo) const;
// Mapping of include prefixes (e.g., foo in <foo/bar>) for auto-
// generated headers to directories where they will be generated.
//
// We are using a prefix map of directories (dir_path_map) instead of
// just a map in order to also cover sub-paths (e.g., <foo/more/bar> if
// we continue with the example). Specifically, we need to make sure we
// don't treat foobar as a sub-directory of foo.
//
// The priority is used to decide who should override whom. Lesser
// values are considered higher priority. See append_prefixes() for
// details.
//
// @@ The keys should be normalized.
//
struct prefix_value
{
dir_path directory;
size_t priority;
};
using prefix_map = dir_path_map<prefix_value>;
void
append_prefixes (prefix_map&, const target&, const variable&) const;
void
append_library_prefixes (prefix_map&,
const scope&,
action, target&, linfo) const;
prefix_map
build_prefix_map (const scope&, action, target&, linfo) const;
small_vector<const target_type*, 2>
map_extension (const scope&, const string&, const string&) const;
// Src-to-out re-mapping. See extract_headers() for details.
//
using srcout_map = path_map<dir_path>;
struct module_mapper_state;
bool
gcc_module_mapper (module_mapper_state&,
action, const scope&, file&, linfo,
ifdstream&, ofdstream&,
depdb&, bool&, bool&,
optional<prefix_map>&, srcout_map&) const;
pair<const file*, bool>
enter_header (action, const scope&, file&, linfo,
path&&, bool, bool,
optional<prefix_map>&, srcout_map&) const;
optional<bool>
inject_header (action, file&, const file&, timestamp, bool) const;
pair<file_cache::entry, bool>
extract_headers (action, const scope&, file&, linfo,
const file&, match_data&,
depdb&, bool&, timestamp, module_imports&) const;
string
parse_unit (action, file&, linfo,
const file&, file_cache::entry&,
const match_data&, const path&,
unit&) const;
void
extract_modules (action, const scope&, file&, linfo,
const compile_target_types&,
const file&, match_data&,
module_info&&, depdb&, bool&) const;
module_positions
search_modules (action, const scope&, file&, linfo,
const target_type&,
const file&, module_imports&, sha256&) const;
pair<dir_path, const scope&>
find_modules_sidebuild (const scope&) const;
const file&
make_module_sidebuild (action, const scope&, const file&,
const target&, const string&) const;
const file&
make_header_sidebuild (action, const scope&, const file&,
linfo, const file&) const;
void
append_header_options (environment&, cstrings&, small_vector<string, 2>&,
action, const file&,
const match_data&, const path&) const;
void
append_module_options (environment&, cstrings&, small_vector<string, 2>&,
action, const file&,
const match_data&, const path&) const;
// Compiler-specific language selection options. Return the number of
// options (arguments, really) appended.
//
size_t
append_lang_options (cstrings&, const match_data&) const;
void
append_symexport_options (cstrings&, const target&) const;
private:
const string rule_id;
};
}
}
#endif // LIBBUILD2_CC_COMPILE_RULE_HXX
|