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
|
#pragma once
#include <string>
#include <unordered_map>
#include <stdexcept>
#include <vector>
namespace ninja
{
enum class NinjaError
{
NONE,
VARIABLE_ALREADY_DEFINED,
RULE_ALREADY_DEFINED,
INVALID_NAME
};
class NinjaException : public std::runtime_error
{
public:
NinjaException(const NinjaError _errorCode, const std::string &errMsg = "") :
std::runtime_error(errMsg),
errorCode(_errorCode)
{
}
const NinjaError errorCode;
};
struct NinjaVariable
{
NinjaVariable(const std::string &name);
const std::string name;
};
class NinjaBuildFile;
class NinjaArg
{
public:
enum class Type
{
NONE,
VALUE,
VARIABLE,
RAW
};
NinjaArg() : type(Type::NONE) {}
NinjaArg(const std::string &value) : type(Type::VALUE), arg(value) {}
NinjaArg(const NinjaVariable &var) : type(Type::VARIABLE), arg(var.name) {}
static NinjaArg createRaw(const std::string &value)
{
NinjaArg arg;
arg.type = Type::RAW;
arg.arg = value;
return arg;
}
Type type;
std::string arg;
};
struct NinjaArgValue
{
const NinjaVariable arg;
const std::string value;
};
class NinjaBuild;
// Functions throw NinjaException on failure
class NinjaRule
{
public:
NinjaRule(NinjaBuildFile *buildFile, const std::string &name, const std::string &command);
NinjaBuild* build(const std::string &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds = {});
NinjaBuild* build(const std::vector<std::string> &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds = {});
const std::string name;
const std::string command;
std::string depFile;
std::string deps;
private:
NinjaBuildFile *buildFile;
};
struct NinjaBuild
{
const NinjaRule *rule;
const std::vector<std::string> in;
const std::string out;
const std::vector<ninja::NinjaArgValue> additionalArgs;
const std::vector<NinjaBuild*> dependsOnBuilds;
};
// Functions throw NinjaException on failure
class NinjaBuildFile
{
public:
~NinjaBuildFile();
void defineGlobalVariable(const std::string &name, const std::string &value);
NinjaRule* createRule(const std::string &name, const std::vector<NinjaArg> &commandArgs);
NinjaBuild* build(const NinjaRule *rule, const std::string &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds = {});
NinjaBuild* build(const NinjaRule *rule, const std::vector<std::string> &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds = {});
std::string generate() const;
private:
std::unordered_map<std::string, std::string> globalVariables;
std::unordered_map<std::string, NinjaRule*> rules;
std::vector<NinjaBuild*> builds;
};
}
|