Skip to content

Commit d952b6f

Browse files
authored
Template generator (#214)
1 parent a0dc3ac commit d952b6f

21 files changed

+353
-116
lines changed

bootstrap/main.buildcc.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ int main(int argc, char **argv) {
4949
ExecutableTarget_generic buildcc_hybrid_simple_example(
5050
"buildcc_hybrid_simple_example", toolchain, "example/hybrid/simple");
5151
Reg::Toolchain(custom_toolchain_arg.state)
52-
// .Func([&]() { toolchain.Verify(); })
52+
.Func([&]() { toolchain.Verify(); })
5353
.BuildPackage(buildcc)
5454
.Build(hybrid_simple_example_cb, buildcc_hybrid_simple_example,
5555
buildcc_lib)

bootstrap/src/build_buildcc.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe) {
2828
generator.AddOutput("{gen_build_dir}/custom_generator_generated.h");
2929
generator.AddOutput("{gen_build_dir}/target_generated.h");
3030

31-
generator.AddDefaultArguments({
31+
generator.AddPatterns({
3232
{"flatc_compiler", fmt::format("{}", flatc_exe.GetTargetPath())},
3333
});
3434
// generator.AddCommand("{flatc_compiler} --help");
@@ -45,8 +45,7 @@ void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen,
4545
const TargetInfo &taskflow_ho, const BaseTarget &tpl) {
4646
// NOTE, Build as single lib
4747
target.AddIncludeDir("", true);
48-
const std::string &schema_build_dir =
49-
schema_gen.GetValueByIdentifier("gen_build_dir");
48+
const std::string &schema_build_dir = schema_gen.Get("gen_build_dir");
5049
target.AddIncludeDirAbsolute(schema_build_dir, true);
5150

5251
// ENV

buildcc/buildcc.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
// Base
3333
#include "toolchain/toolchain.h"
3434
#include "target/custom_generator.h"
35-
#include "target/generator.h"
35+
#include "target/file_generator.h"
36+
#include "target/template_generator.h"
3637
#include "target/target_info.h"
3738
#include "target/target.h"
3839

buildcc/lib/args/include/args/register.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222

2323
#include "args.h"
2424

25-
#include "target/generator.h"
25+
#include "target/custom_generator.h"
26+
#include "target/file_generator.h"
2627
#include "target/target.h"
2728

2829
#include "args/register/test_info.h"

buildcc/lib/target/cmake/common_target_src.cmake

+4-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ set(COMMON_TARGET_SRCS
3636
# Generator
3737
src/custom_generator/custom_generator.cpp
3838
include/target/custom_generator.h
39-
src/generator/generator.cpp
40-
include/target/generator.h
39+
src/generator/file_generator.cpp
40+
include/target/file_generator.h
41+
src/generator/template_generator.cpp
42+
include/target/template_generator.h
4143

4244
# Target Info
4345
src/target_info/target_info.cpp

buildcc/lib/target/include/target/custom_generator.h

+10-12
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,12 @@ class CustomGenerator : public internal::BuilderInterface {
115115
virtual ~CustomGenerator() = default;
116116
CustomGenerator(const CustomGenerator &) = delete;
117117

118-
// From env::Command module, forwarding here
119-
// TODO, Create a Mixin
120-
void AddDefaultArgument(const std::string &identifier,
121-
const std::string &pattern);
122-
void AddDefaultArguments(
123-
const std::unordered_map<std::string, std::string> &arguments);
124-
std::string Construct(
125-
const std::string &pattern,
126-
const std::unordered_map<const char *, std::string> &arguments = {});
127-
const std::string &
128-
GetValueByIdentifier(const std::string &file_identifier) const;
118+
// TODO, Doc
119+
void AddPattern(const std::string &identifier, const std::string &pattern);
120+
121+
// TODO, Doc
122+
void
123+
AddPatterns(const std::unordered_map<std::string, std::string> &pattern_map);
129124

130125
/**
131126
* @brief Single Generator task for inputs->generate_cb->outputs
@@ -168,6 +163,7 @@ class CustomGenerator : public internal::BuilderInterface {
168163
const fs::path &GetRootDir() const { return env_.GetTargetRootDir(); }
169164
const fs::path &GetBuildDir() const { return env_.GetTargetBuildDir(); }
170165
tf::Taskflow &GetTaskflow() { return tf_; }
166+
const std::string &Get(const std::string &file_identifier) const;
171167

172168
private:
173169
void Initialize();
@@ -184,6 +180,9 @@ class CustomGenerator : public internal::BuilderInterface {
184180
void IdAdded();
185181
void IdUpdated();
186182

183+
protected:
184+
env::Command command_;
185+
187186
private:
188187
std::string name_;
189188
TargetEnv env_;
@@ -196,7 +195,6 @@ class CustomGenerator : public internal::BuilderInterface {
196195
std::unordered_map<std::string, UserGenInfo> success_schema_;
197196

198197
// Internal
199-
env::Command command_;
200198
tf::Taskflow tf_;
201199

202200
// Callbacks

buildcc/lib/target/include/target/generator.h renamed to buildcc/lib/target/include/target/file_generator.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17-
#ifndef TARGET_GENERATOR_H_
18-
#define TARGET_GENERATOR_H_
17+
#ifndef TARGET_FILE_GENERATOR_H_
18+
#define TARGET_FILE_GENERATOR_H_
1919

2020
#include "target/custom_generator.h"
2121

buildcc/lib/target/include/target/interface/builder_interface.h

+20-34
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
namespace buildcc::internal {
2929

30-
enum PathState {
30+
enum class PathState {
3131
kNoChange,
3232
kRemoved,
3333
kAdded,
@@ -69,14 +69,14 @@ inline PathState CheckPaths(const internal::path_unordered_set &previous_path,
6969
const bool added_cond = (find == previous_path.end());
7070
if (added_cond) {
7171
dirty = true;
72-
state = kAdded;
72+
state = PathState::kAdded;
7373
} else {
7474
const bool updated_cond =
7575
(p.GetLastWriteTimestamp() >
7676
find->GetLastWriteTimestamp());
7777
if (updated_cond) {
7878
dirty = true;
79-
state = kUpdated;
79+
state = PathState::kUpdated;
8080
} else {
8181
dirty = false;
8282
}
@@ -110,7 +110,7 @@ class BuilderInterface {
110110
return;
111111
}
112112

113-
if (previous != current) {
113+
if (CheckChanged(previous, current)) {
114114
callback();
115115
dirty_ = true;
116116
}
@@ -130,39 +130,25 @@ class BuilderInterface {
130130
return;
131131
}
132132

133-
// * Old path is removed
134-
const bool removed =
135-
std::any_of(previous_path.begin(), previous_path.end(),
136-
[&](const internal::Path &p) {
137-
return current_path.find(p) == current_path.end();
138-
});
139-
if (removed) {
133+
auto path_state = CheckPaths(previous_path, current_path);
134+
switch (path_state) {
135+
case PathState::kRemoved:
140136
path_removed_cb();
141137
dirty_ = true;
142-
return;
138+
break;
139+
case PathState::kAdded:
140+
path_added_cb();
141+
dirty_ = true;
142+
break;
143+
case PathState::kUpdated:
144+
path_updated_cb();
145+
dirty_ = true;
146+
break;
147+
case PathState::kNoChange:
148+
default:
149+
dirty_ = false;
150+
break;
143151
}
144-
145-
dirty_ = std::any_of(
146-
current_path.cbegin(), current_path.cend(),
147-
[&](const internal::Path &p) -> bool {
148-
bool dirty = false;
149-
const auto find = previous_path.find(p);
150-
const bool added_cond = (find == previous_path.end());
151-
if (added_cond) {
152-
path_added_cb();
153-
dirty = true;
154-
} else {
155-
const bool updated_cond =
156-
(p.GetLastWriteTimestamp() > find->GetLastWriteTimestamp());
157-
if (updated_cond) {
158-
path_updated_cb();
159-
dirty = true;
160-
} else {
161-
dirty = false;
162-
}
163-
}
164-
return dirty;
165-
});
166152
}
167153

168154
protected:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2021-2022 Niket Naidu. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef TARGET_TEMPLATE_GENERATOR_H_
18+
#define TARGET_TEMPLATE_GENERATOR_H_
19+
20+
#include "target/custom_generator.h"
21+
22+
namespace buildcc {
23+
24+
class TemplateGenerator : public CustomGenerator {
25+
public:
26+
TemplateGenerator(const std::string &name, const TargetEnv &env)
27+
: CustomGenerator(name, env) {}
28+
29+
void AddTemplate(const fs::path &input_filename,
30+
const fs::path &output_filename);
31+
std::string Parse(const std::string &pattern);
32+
33+
/**
34+
* @brief Build FileGenerator Tasks
35+
*
36+
* Use `GetTaskflow` for the registered tasks
37+
*/
38+
void Build() override;
39+
40+
// Restrict access to certain custom generator APIs
41+
private:
42+
using CustomGenerator::AddDependencyCb;
43+
using CustomGenerator::AddGenInfo;
44+
using CustomGenerator::Build;
45+
46+
private:
47+
struct TemplateInfo {
48+
fs::path input;
49+
fs::path output;
50+
};
51+
52+
private:
53+
std::vector<TemplateInfo> template_infos_;
54+
};
55+
56+
} // namespace buildcc
57+
58+
#endif

buildcc/lib/target/src/custom_generator/custom_generator.cpp

+18-16
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,20 @@ constexpr const char *const kGenerateTaskName = "Generate";
2727

2828
namespace buildcc {
2929

30-
void CustomGenerator::AddDefaultArgument(const std::string &identifier,
31-
const std::string &pattern) {
30+
void CustomGenerator::AddPattern(const std::string &identifier,
31+
const std::string &pattern) {
3232
command_.AddDefaultArgument(identifier, command_.Construct(pattern));
3333
}
3434

35-
void CustomGenerator::AddDefaultArguments(
36-
const std::unordered_map<std::string, std::string> &arguments) {
37-
for (const auto &arg_iter : arguments) {
38-
AddDefaultArgument(arg_iter.first, arg_iter.second);
35+
void CustomGenerator::AddPatterns(
36+
const std::unordered_map<std::string, std::string> &pattern_map) {
37+
for (const auto &arg_iter : pattern_map) {
38+
AddPattern(arg_iter.first, arg_iter.second);
3939
}
4040
}
4141

42-
std::string CustomGenerator::Construct(
43-
const std::string &pattern,
44-
const std::unordered_map<const char *, std::string> &arguments) {
45-
return command_.Construct(pattern, arguments);
46-
}
47-
48-
const std::string &CustomGenerator::GetValueByIdentifier(
49-
const std::string &file_identifier) const {
42+
const std::string &
43+
CustomGenerator::Get(const std::string &file_identifier) const {
5044
return command_.GetDefaultValueByKey(file_identifier);
5145
}
5246

@@ -60,10 +54,16 @@ void CustomGenerator::AddGenInfo(
6054

6155
UserGenInfo schema;
6256
for (const auto &i : inputs) {
63-
schema.inputs.emplace(command_.Construct(path_as_string(i)));
57+
fs::path input =
58+
internal::Path::CreateNewPath(command_.Construct(path_as_string(i)))
59+
.GetPathname();
60+
schema.inputs.emplace(std::move(input));
6461
}
6562
for (const auto &o : outputs) {
66-
schema.outputs.emplace(command_.Construct(path_as_string(o)));
63+
fs::path output =
64+
internal::Path::CreateNewPath(command_.Construct(path_as_string(o)))
65+
.GetPathname();
66+
schema.outputs.emplace(std::move(output));
6767
}
6868
schema.generate_cb = generate_cb;
6969
schema.blob_handler = std::move(blob_handler);
@@ -90,6 +90,8 @@ void CustomGenerator::Initialize() {
9090
//
9191
fs::create_directories(env_.GetTargetBuildDir());
9292
command_.AddDefaultArguments({
93+
{"project_root_dir", path_as_string(Project::GetRootDir())},
94+
{"project_build_dir", path_as_string(Project::GetBuildDir())},
9395
{"gen_root_dir", path_as_string(env_.GetTargetRootDir())},
9496
{"gen_build_dir", path_as_string(env_.GetTargetBuildDir())},
9597
});

buildcc/lib/target/src/generator/generator.cpp renamed to buildcc/lib/target/src/generator/file_generator.cpp

+9-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
#include "target/generator.h"
17+
#include "target/file_generator.h"
1818

1919
#include <algorithm>
2020

@@ -80,32 +80,35 @@ namespace buildcc {
8080

8181
void FileGenerator::AddInput(const std::string &absolute_input_pattern,
8282
const char *identifier) {
83-
std::string absolute_input_string = Construct(absolute_input_pattern);
83+
std::string absolute_input_string =
84+
command_.Construct(absolute_input_pattern);
8485
const auto absolute_input_path =
8586
internal::Path::CreateNewPath(absolute_input_string);
8687
inputs_.insert(absolute_input_path.GetPathname());
8788

8889
if (identifier != nullptr) {
89-
AddDefaultArgument(identifier, absolute_input_path.GetPathAsString());
90+
AddPattern(identifier, absolute_input_path.GetPathAsString());
9091
}
9192
}
9293

9394
void FileGenerator::AddOutput(const std::string &absolute_output_pattern,
9495
const char *identifier) {
95-
std::string absolute_output_string = Construct(absolute_output_pattern);
96+
std::string absolute_output_string =
97+
command_.Construct(absolute_output_pattern);
9698
const auto absolute_output_path =
9799
internal::Path::CreateNewPath(absolute_output_string);
98100
outputs_.insert(absolute_output_path.GetPathname());
99101

100102
if (identifier != nullptr) {
101-
AddDefaultArgument(identifier, absolute_output_path.GetPathAsString());
103+
AddPattern(identifier, absolute_output_path.GetPathAsString());
102104
}
103105
}
104106

105107
void FileGenerator::AddCommand(
106108
const std::string &command_pattern,
107109
const std::unordered_map<const char *, std::string> &arguments) {
108-
std::string constructed_command = Construct(command_pattern, arguments);
110+
std::string constructed_command =
111+
command_.Construct(command_pattern, arguments);
109112
commands_.emplace_back(std::move(constructed_command));
110113
}
111114

0 commit comments

Comments
 (0)