Skip to content

Commit 8f493d2

Browse files
authored
[Redesign] Generator (#137)
1 parent 9c94c40 commit 8f493d2

File tree

13 files changed

+308
-749
lines changed

13 files changed

+308
-749
lines changed

buildcc/lib/command/include/command/command.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Command {
2828
public:
2929
explicit Command() = default;
3030

31+
void AddDefaultArgument(const char *key, const std::string &value);
3132
void AddDefaultArguments(
3233
const std::unordered_map<const char *, std::string> &arguments);
3334

buildcc/lib/command/src/command.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626

2727
namespace buildcc {
2828

29+
void Command::AddDefaultArgument(const char *key, const std::string &value) {
30+
default_values_.emplace(key, value);
31+
}
32+
2933
void Command::AddDefaultArguments(
3034
const std::unordered_map<const char *, std::string> &arguments) {
3135
default_values_.insert(arguments.begin(), arguments.end());

buildcc/lib/target/include/target/generator.h

Lines changed: 37 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -19,95 +19,64 @@
1919

2020
#include <functional>
2121
#include <string>
22+
#include <unordered_map>
2223
#include <vector>
2324

2425
#include "taskflow/taskflow.hpp"
2526

2627
#include "env/env.h"
2728

29+
#include "command/command.h"
30+
2831
#include "target/builder_interface.h"
2932

3033
#include "target/generator_loader.h"
3134
#include "target/path.h"
3235

3336
namespace buildcc::base {
3437

35-
typedef std::function<bool(
36-
const internal::geninfo_unordered_map &previous_info,
37-
const internal::geninfo_unordered_map &current_info,
38-
std::vector<const internal::GenInfo *> &output_generated_files,
39-
std::vector<const internal::GenInfo *> &output_dummy_generated_files)>
40-
custom_regenerate_cb_params;
41-
4238
class Generator : public BuilderInterface {
4339
public:
44-
Generator(const std::string &name, const fs::path &path)
45-
: name_(name), loader_(name, path) {
46-
unique_id_ = name;
40+
Generator(const std::string &name,
41+
const fs::path &target_path_relative_to_root, bool parallel = false)
42+
: name_(name), generator_root_dir_(env::get_project_root_dir() /
43+
target_path_relative_to_root),
44+
generator_build_dir_(env::get_project_build_dir() / name),
45+
loader_(name, generator_build_dir_), parallel_(parallel) {
46+
Initialize();
4747
}
4848
Generator(const Generator &generator) = delete;
4949

5050
/**
51-
* @brief Define your input - output - command relation
51+
* @brief Add default arguments for input, output and command requirements
5252
*
53-
* @param name GenInfo task name
54-
* @param inputs Input files
55-
* @param outputs Output files generated
56-
* @param commands Commands for input files to generate output files
57-
* @param parallel Run commands in parallel
58-
*/
59-
void AddGenInfo(const std::string &name,
60-
const internal::fs_unordered_set &inputs,
61-
const internal::fs_unordered_set &outputs,
62-
const std::vector<std::string> &commands, bool parallel);
63-
64-
/**
65-
* @brief Implement your own Regenerate callback.
66-
* - See `Regenerate` function for generic implementation
67-
* - See `Recheck*` APIs in BuilderInterface for custom checks
68-
*
69-
* @param cb Gives 4 parameters
70-
*
71-
* const internal::geninfo_unordered_map &previous_info
72-
* const internal::geninfo_unordered_map &current_info
73-
* std::vector<const internal::GenInfo *> &output_generated_files
74-
* std::vector<const internal::GenInfo *> &output_dummy_generated_files
75-
*
76-
* @return cb should return true or false which sets the dirty_ flag
77-
*/
78-
void AddCustomRegenerateCb(const custom_regenerate_cb_params &cb);
79-
80-
/**
81-
* @brief Custom pre generate callback run before the core generate function
53+
* @param arguments Key-Value pair for arguments
54+
* NOTE, Key must be a variable (lvalue) not a constant (rvalue)
8255
*
83-
* @param cb
8456
*/
85-
void AddPregenerateCb(const std::function<void(void)> &cb);
57+
void AddDefaultArguments(
58+
const std::unordered_map<const char *, std::string> &arguments);
8659

87-
/**
88-
* @brief Custom post generate callback run after the core generate function
89-
* IF dirty_ == true
90-
*
91-
* @param cb
92-
*/
93-
void AddPostgenerateCb(const std::function<void(void)> &cb);
60+
void AddInput(const std::string &absolute_input_pattern,
61+
const char *identifier = nullptr);
62+
void AddOutput(const std::string &absolute_output_pattern,
63+
const char *identifier = nullptr);
64+
void AddCommand(
65+
const std::string &command_pattern,
66+
const std::unordered_map<const char *, std::string> &arguments = {});
9467

9568
void Build() override;
96-
void Build(tf::FlowBuilder &builder);
9769

9870
// Getter
9971
fs::path GetBinaryPath() const { return loader_.GetBinaryPath(); }
10072
tf::Taskflow &GetTaskflow() { return tf_; }
10173

10274
private:
103-
void GenerateTask(tf::FlowBuilder &builder);
75+
void Initialize();
76+
77+
void GenerateTask();
10478
void Convert();
105-
void
106-
BuildGenerate(std::vector<const internal::GenInfo *> &generated_files,
107-
std::vector<const internal::GenInfo *> &dummy_generated_files);
108-
bool
109-
Regenerate(std::vector<const internal::GenInfo *> &generated_files,
110-
std::vector<const internal::GenInfo *> &dummy_generated_files);
79+
void BuildGenerate();
11180

11281
bool Store() override;
11382

@@ -120,15 +89,20 @@ class Generator : public BuilderInterface {
12089
void CommandChanged();
12190

12291
private:
92+
// Constructor
12393
std::string name_;
124-
std::unordered_map<std::string, internal::GenInfo> current_info_;
125-
126-
custom_regenerate_cb_params custom_regenerate_cb_;
127-
std::function<void(void)> pregenerate_cb_{[]() {}};
128-
std::function<void(void)> postgenerate_cb_{[]() {}};
129-
94+
fs::path generator_root_dir_;
95+
fs::path generator_build_dir_;
13096
internal::GeneratorLoader loader_;
13197

98+
// Serialization
99+
internal::default_files current_input_files_;
100+
internal::fs_unordered_set current_output_files_;
101+
std::vector<std::string> current_commands_;
102+
bool parallel_{false};
103+
104+
// Internal
105+
Command command_;
132106
tf::Taskflow tf_;
133107
};
134108

buildcc/lib/target/include/target/generator_loader.h

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -29,45 +29,10 @@
2929

3030
namespace buildcc::internal {
3131

32-
struct GenInfo {
33-
std::string name;
34-
default_files inputs;
35-
fs_unordered_set outputs;
36-
std::vector<std::string> commands;
37-
bool parallel{false};
38-
39-
static GenInfo CreateInternalGenInfo(const std::string &n,
40-
const path_unordered_set &internal_i,
41-
const fs_unordered_set &o,
42-
const std::vector<std::string> &c,
43-
bool p) {
44-
return GenInfo(n, internal_i, {}, o, c, p);
45-
}
46-
47-
static GenInfo CreateUserGenInfo(const std::string &n,
48-
const fs_unordered_set &user_i,
49-
const fs_unordered_set &o,
50-
const std::vector<std::string> &c, bool p) {
51-
return GenInfo(n, {}, user_i, o, c, p);
52-
}
53-
54-
GenInfo(GenInfo &&info) = default;
55-
GenInfo(const GenInfo &info) = delete;
56-
57-
private:
58-
explicit GenInfo(const std::string &n, const path_unordered_set &internal_i,
59-
const fs_unordered_set &user_i, const fs_unordered_set &o,
60-
const std::vector<std::string> &c, bool p)
61-
: name(n), inputs(internal_i, user_i), outputs(o), commands(c),
62-
parallel(p) {}
63-
};
64-
65-
typedef std::unordered_map<std::string, GenInfo> geninfo_unordered_map;
66-
6732
class GeneratorLoader : public LoaderInterface {
6833
public:
69-
GeneratorLoader(const std::string &name, const fs::path &path)
70-
: name_(name), path_(path) {}
34+
GeneratorLoader(const std::string &name, const fs::path &absolute_path)
35+
: name_(name), path_(absolute_path) {}
7136

7237
GeneratorLoader(const GeneratorLoader &loader) = delete;
7338

@@ -78,13 +43,25 @@ class GeneratorLoader : public LoaderInterface {
7843
return path_ / fmt::format("{}.bin", name_);
7944
}
8045

81-
const geninfo_unordered_map &GetLoadedInfo() { return loaded_info_; }
46+
const internal::path_unordered_set &GetLoadedInputFiles() const {
47+
return loaded_input_files_;
48+
}
49+
50+
const internal::fs_unordered_set &GetLoadedOutputFiles() const {
51+
return loaded_output_files_;
52+
}
53+
54+
const std::vector<std::string> &GetLoadedCommands() const {
55+
return loaded_commands_;
56+
}
8257

8358
private:
8459
std::string name_;
8560
fs::path path_;
8661

87-
geninfo_unordered_map loaded_info_;
62+
internal::path_unordered_set loaded_input_files_;
63+
internal::fs_unordered_set loaded_output_files_;
64+
std::vector<std::string> loaded_commands_;
8865
};
8966

9067
} // namespace buildcc::internal

buildcc/lib/target/include/target/path.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,6 @@ typedef std::unordered_set<fs::path, PathHash> fs_unordered_set;
132132
// optimization by caching the `user` information and `internal` information
133133
// together
134134
struct default_files {
135-
path_unordered_set internal;
136-
fs_unordered_set user;
137-
138135
default_files() {}
139136
default_files(const path_unordered_set &i, const fs_unordered_set &u)
140137
: internal(i), user(u) {}
@@ -150,6 +147,10 @@ struct default_files {
150147
}
151148
}
152149

150+
public:
151+
path_unordered_set internal;
152+
fs_unordered_set user;
153+
153154
private:
154155
bool done_once{false};
155156
};

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ class Target : public BuilderInterface {
131131
: name_(name), type_(type), toolchain_(toolchain), config_(config),
132132
target_root_dir_(env::get_project_root_dir() /
133133
target_path_relative_to_root),
134-
target_build_dir_(fs::path(env::get_project_build_dir()) /
135-
toolchain.GetName() / name),
134+
target_build_dir_(env::get_project_build_dir() / toolchain.GetName() /
135+
name),
136136
loader_(name, target_build_dir_), ext_(*this), compile_pch_(*this),
137137
compile_object_(*this), link_target_(*this) {
138138
Initialize();

buildcc/lib/target/mock/generator/task.cpp

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,30 @@
66

77
namespace buildcc::base {
88

9-
void Generator::GenerateTask(tf::FlowBuilder &builder) {
10-
(void)builder;
11-
12-
pregenerate_cb_();
9+
void Generator::GenerateTask() {
1310
Convert();
14-
std::vector<const internal::GenInfo *> generated_files;
15-
std::vector<const internal::GenInfo *> dummy_generated_files;
16-
BuildGenerate(generated_files, dummy_generated_files);
11+
BuildGenerate();
12+
13+
if (!dirty_) {
14+
return;
15+
}
1716

1817
// NOTE, info->parallel is not checked
19-
for (const auto &info : generated_files) {
20-
for (const auto &command : info->commands) {
21-
bool success = Command::Execute(command);
22-
env::assert_fatal(success, fmt::format("{} failed", command));
23-
}
24-
for (const auto &output_file : info->outputs) {
25-
std::string file = output_file.string();
26-
bool success = env::SaveFile(file.c_str(), "", false);
27-
env::assert_fatal(success, fmt::format("{} failed", file));
28-
}
18+
// Run the command
19+
for (const auto &command : current_commands_) {
20+
bool success = Command::Execute(command);
21+
env::assert_fatal(success, fmt::format("{} failed", command));
22+
}
23+
24+
// Generate the output file
25+
for (const auto &output_file : current_output_files_) {
26+
std::string file = output_file.string();
27+
bool success = env::SaveFile(file.c_str(), "", false);
28+
env::assert_fatal(success, fmt::format("{} failed", file));
2929
}
30-
(void)dummy_generated_files;
3130

3231
if (dirty_) {
3332
Store();
34-
postgenerate_cb_();
3533
}
3634
}
3735

0 commit comments

Comments
 (0)