mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-16 17:22:21 +00:00
Added the code to embed the binary schema to the source (--bfbs-gen-embed). (#5701)
* Added the code to embed the binary schema to the source. This is pulled forward from a old PR #5162 that will be closed. * Update idl_gen_cpp.cpp Added a small comment to trigger a new build. The build was failing in a strange location and doesn't look like it has anything to do with the code. * Moved the EscapeAndWrapBuffer to util.cpp and did some formating. * One more camelCases removed and renamed some variables. * wrapped_line_xxx should have been passed as a const reference in the first place. * Moved the bfbs embed sample to it's own file. * Missed moving the namespace back. * Moved the embedded bfbs to test.cpp instead of using a sample. * Missed adding the generation of embedded bfbs to the build. * See if this makes the build happier. * Fixed a in-compatable cpp output of the generated header. * Did some changes to reflect the code review comments. 1. Update the EscapeAndWrapBuffer to BufferToHexText and fixed a variable name. 2. Moved the include of the embedded binary schema to all the other includes. * Moved some code to inline the instead of using a local variable. * Moved the BufferToHexText back to be a inline function in util.h
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
3f677f2414
commit
47026ea6ba
@@ -70,6 +70,9 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
|
||||
ss << " " << full_name.str() << " " << name << " " << help << ".\n";
|
||||
}
|
||||
// clang-format off
|
||||
|
||||
// Output width
|
||||
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
ss <<
|
||||
" -o PATH Prefix PATH to all generated files.\n"
|
||||
" -I PATH Search for includes in the specified path.\n"
|
||||
@@ -141,6 +144,7 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
|
||||
" --schema Serialize schemas instead of JSON (use with -b).\n"
|
||||
" --bfbs-comments Add doc comments to the binary schema files.\n"
|
||||
" --bfbs-builtins Add builtin attributes to the binary schema files.\n"
|
||||
" --bfbs-gen-embed Generate code to embed the bfbs schema to the source.\n"
|
||||
" --conform FILE Specify a schema the following schemas should be\n"
|
||||
" an evolution of. Gives errors if not.\n"
|
||||
" --conform-includes Include path for the schema given with --conform PATH\n"
|
||||
@@ -166,6 +170,7 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
|
||||
"Output files are named using the base file name of the input,\n"
|
||||
"and written to the current directory or the path given by -o.\n"
|
||||
"example: " << program_name << " -c -b schema1.fbs schema2.fbs data.json\n";
|
||||
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
// clang-format on
|
||||
return ss.str();
|
||||
}
|
||||
@@ -201,22 +206,22 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
||||
output_path = flatbuffers::ConCatPathFileName(
|
||||
flatbuffers::PosixPath(argv[argi]), "");
|
||||
} else if (arg == "-I") {
|
||||
if (++argi >= argc) Error("missing path following" + arg, true);
|
||||
if (++argi >= argc) Error("missing path following: " + arg, true);
|
||||
include_directories_storage.push_back(
|
||||
flatbuffers::PosixPath(argv[argi]));
|
||||
include_directories.push_back(
|
||||
include_directories_storage.back().c_str());
|
||||
} else if (arg == "--conform") {
|
||||
if (++argi >= argc) Error("missing path following" + arg, true);
|
||||
if (++argi >= argc) Error("missing path following: " + arg, true);
|
||||
conform_to_schema = flatbuffers::PosixPath(argv[argi]);
|
||||
} else if (arg == "--conform-includes") {
|
||||
if (++argi >= argc) Error("missing path following" + arg, true);
|
||||
if (++argi >= argc) Error("missing path following: " + arg, true);
|
||||
include_directories_storage.push_back(
|
||||
flatbuffers::PosixPath(argv[argi]));
|
||||
conform_include_directories.push_back(
|
||||
include_directories_storage.back().c_str());
|
||||
} else if (arg == "--include-prefix") {
|
||||
if (++argi >= argc) Error("missing path following" + arg, true);
|
||||
if (++argi >= argc) Error("missing path following: " + arg, true);
|
||||
opts.include_prefix = flatbuffers::ConCatPathFileName(
|
||||
flatbuffers::PosixPath(argv[argi]), "");
|
||||
} else if (arg == "--keep-prefix") {
|
||||
@@ -261,13 +266,13 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
||||
} else if (arg == "--gen-compare") {
|
||||
opts.gen_compare = true;
|
||||
} else if (arg == "--cpp-include") {
|
||||
if (++argi >= argc) Error("missing include following" + arg, true);
|
||||
if (++argi >= argc) Error("missing include following: " + arg, true);
|
||||
opts.cpp_includes.push_back(argv[argi]);
|
||||
} else if (arg == "--cpp-ptr-type") {
|
||||
if (++argi >= argc) Error("missing type following" + arg, true);
|
||||
if (++argi >= argc) Error("missing type following: " + arg, true);
|
||||
opts.cpp_object_api_pointer_type = argv[argi];
|
||||
} else if (arg == "--cpp-str-type") {
|
||||
if (++argi >= argc) Error("missing type following" + arg, true);
|
||||
if (++argi >= argc) Error("missing type following: " + arg, true);
|
||||
opts.cpp_object_api_string_type = argv[argi];
|
||||
} else if (arg == "--cpp-str-flex-ctor") {
|
||||
opts.cpp_object_api_string_flexible_constructor = true;
|
||||
@@ -278,10 +283,10 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
||||
} else if (arg == "--gen-generated") {
|
||||
opts.gen_generated = true;
|
||||
} else if (arg == "--object-prefix") {
|
||||
if (++argi >= argc) Error("missing prefix following" + arg, true);
|
||||
if (++argi >= argc) Error("missing prefix following: " + arg, true);
|
||||
opts.object_prefix = argv[argi];
|
||||
} else if (arg == "--object-suffix") {
|
||||
if (++argi >= argc) Error("missing suffix following" + arg, true);
|
||||
if (++argi >= argc) Error("missing suffix following: " + arg, true);
|
||||
opts.object_suffix = argv[argi];
|
||||
} else if (arg == "--gen-all") {
|
||||
opts.generate_all = true;
|
||||
@@ -319,6 +324,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
||||
opts.binary_schema_comments = true;
|
||||
} else if (arg == "--bfbs-builtins") {
|
||||
opts.binary_schema_builtins = true;
|
||||
} else if (arg == "--bfbs-gen-embed") {
|
||||
opts.binary_schema_gen_embed= true;
|
||||
} else if (arg == "--no-fb-import") {
|
||||
opts.skip_flatbuffers_import = true;
|
||||
} else if (arg == "--no-ts-reexport") {
|
||||
@@ -330,7 +337,7 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
||||
} else if (arg == "--reflect-names") {
|
||||
opts.mini_reflect = IDLOptions::kTypesAndNames;
|
||||
} else if (arg == "--root-type") {
|
||||
if (++argi >= argc) Error("missing type following" + arg, true);
|
||||
if (++argi >= argc) Error("missing type following: " + arg, true);
|
||||
opts.root_type = argv[argi];
|
||||
} else if (arg == "--force-defaults") {
|
||||
opts.force_defaults = true;
|
||||
@@ -466,8 +473,10 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
||||
auto err = parser->ConformTo(conform_parser);
|
||||
if (!err.empty()) Error("schemas don\'t conform: " + err);
|
||||
}
|
||||
if (schema_binary) {
|
||||
if (schema_binary || opts.binary_schema_gen_embed) {
|
||||
parser->Serialize();
|
||||
}
|
||||
if (schema_binary) {
|
||||
parser->file_extension_ = reflection::SchemaExtension();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,33 @@ static std::string GeneratedFileName(const std::string &path,
|
||||
return path + file_name + "_generated.h";
|
||||
}
|
||||
|
||||
static std::string GenIncludeGuard(const std::string &file_name,
|
||||
const Namespace &name_space,
|
||||
const std::string &postfix= "") {
|
||||
// Generate include guard.
|
||||
std::string guard = file_name;
|
||||
// Remove any non-alpha-numeric characters that may appear in a filename.
|
||||
struct IsAlnum {
|
||||
bool operator()(char c) const { return !is_alnum(c); }
|
||||
};
|
||||
guard.erase(std::remove_if(guard.begin(), guard.end(), IsAlnum()),
|
||||
guard.end());
|
||||
guard = "FLATBUFFERS_GENERATED_" + guard;
|
||||
guard += "_";
|
||||
// For further uniqueness, also add the namespace.
|
||||
for (auto it = name_space.components.begin();
|
||||
it != name_space.components.end(); ++it) {
|
||||
guard += *it + "_";
|
||||
}
|
||||
// Anything extra to add to the guard?
|
||||
if (!postfix.empty()) {
|
||||
guard += postfix + "_";
|
||||
}
|
||||
guard += "H_";
|
||||
std::transform(guard.begin(), guard.end(), guard.begin(), ToUpper);
|
||||
return guard;
|
||||
}
|
||||
|
||||
namespace cpp {
|
||||
|
||||
enum CppStandard { CPP_STD_X0 = 0, CPP_STD_11, CPP_STD_17 };
|
||||
@@ -182,28 +209,6 @@ class CppGenerator : public BaseGenerator {
|
||||
for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
|
||||
}
|
||||
|
||||
std::string GenIncludeGuard() const {
|
||||
// Generate include guard.
|
||||
std::string guard = file_name_;
|
||||
// Remove any non-alpha-numeric characters that may appear in a filename.
|
||||
struct IsAlnum {
|
||||
bool operator()(char c) const { return !is_alnum(c); }
|
||||
};
|
||||
guard.erase(std::remove_if(guard.begin(), guard.end(), IsAlnum()),
|
||||
guard.end());
|
||||
guard = "FLATBUFFERS_GENERATED_" + guard;
|
||||
guard += "_";
|
||||
// For further uniqueness, also add the namespace.
|
||||
auto name_space = parser_.current_namespace_;
|
||||
for (auto it = name_space->components.begin();
|
||||
it != name_space->components.end(); ++it) {
|
||||
guard += *it + "_";
|
||||
}
|
||||
guard += "H_";
|
||||
std::transform(guard.begin(), guard.end(), guard.begin(), ToUpper);
|
||||
return guard;
|
||||
}
|
||||
|
||||
void GenIncludeDependencies() {
|
||||
int num_includes = 0;
|
||||
for (auto it = parser_.native_included_files_.begin();
|
||||
@@ -241,13 +246,73 @@ class CppGenerator : public BaseGenerator {
|
||||
|
||||
std::string Name(const EnumVal &ev) const { return EscapeKeyword(ev.name); }
|
||||
|
||||
bool generate_bfbs_embed() {
|
||||
code_.Clear();
|
||||
code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
|
||||
|
||||
// If we don't have a root struct definition,
|
||||
if (!parser_.root_struct_def_) {
|
||||
// put a comment in the output why there is no code generated.
|
||||
code_ += "// Binary schema not generated, no root struct found";
|
||||
} else {
|
||||
auto &struct_def = *parser_.root_struct_def_;
|
||||
const auto include_guard = GenIncludeGuard(file_name_, *struct_def.defined_namespace, "bfbs");
|
||||
|
||||
code_ += "#ifndef " + include_guard;
|
||||
code_ += "#define " + include_guard;
|
||||
code_ += "";
|
||||
if (parser_.opts.gen_nullable) {
|
||||
code_ += "#pragma clang system_header\n\n";
|
||||
}
|
||||
|
||||
SetNameSpace(struct_def.defined_namespace);
|
||||
auto name = Name(struct_def);
|
||||
code_.SetValue("STRUCT_NAME", name);
|
||||
|
||||
// Create code to return the binary schema data.
|
||||
auto binary_schema_hex_text = BufferToHexText(parser_.builder_.GetBufferPointer(),
|
||||
parser_.builder_.GetSize(), 105, " ", "");
|
||||
|
||||
code_ += "struct {{STRUCT_NAME}}BinarySchema {";
|
||||
code_ += " static const uint8_t *data() {";
|
||||
code_ += " // Buffer containing the binary schema.";
|
||||
code_ += " static const uint8_t bfbsData[" + NumToString(parser_.builder_.GetSize()) + "] = {";
|
||||
code_ += binary_schema_hex_text;
|
||||
code_ += " };";
|
||||
code_ += " return bfbsData;";
|
||||
code_ += " }";
|
||||
code_ += " static size_t size() {";
|
||||
code_ += " return " + NumToString(parser_.builder_.GetSize()) + ";";
|
||||
code_ += " }";
|
||||
code_ += " const uint8_t *begin() {";
|
||||
code_ += " return data();";
|
||||
code_ += " }";
|
||||
code_ += " const uint8_t *end() {";
|
||||
code_ += " return data() + size();";
|
||||
code_ += " }";
|
||||
code_ += "};";
|
||||
code_ += "";
|
||||
|
||||
if (cur_name_space_) SetNameSpace(nullptr);
|
||||
|
||||
// Close the include guard.
|
||||
code_ += "#endif // " + include_guard;
|
||||
}
|
||||
|
||||
// We are just adding "_bfbs" to the generated filename.
|
||||
const auto file_path = GeneratedFileName(path_, file_name_ + "_bfbs");
|
||||
const auto final_code = code_.ToString();
|
||||
|
||||
return SaveFile(file_path.c_str(), final_code, false);
|
||||
}
|
||||
|
||||
// Iterate through all definitions we haven't generate code for (enums,
|
||||
// structs, and tables) and output them to a single file.
|
||||
bool generate() {
|
||||
code_.Clear();
|
||||
code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
|
||||
|
||||
const auto include_guard = GenIncludeGuard();
|
||||
const auto include_guard = GenIncludeGuard(file_name_, *parser_.current_namespace_);
|
||||
code_ += "#ifndef " + include_guard;
|
||||
code_ += "#define " + include_guard;
|
||||
code_ += "";
|
||||
@@ -519,7 +584,10 @@ class CppGenerator : public BaseGenerator {
|
||||
|
||||
const auto file_path = GeneratedFileName(path_, file_name_);
|
||||
const auto final_code = code_.ToString();
|
||||
return SaveFile(file_path.c_str(), final_code, false);
|
||||
|
||||
// Save the file and optionally generate the binary schema code.
|
||||
return SaveFile(file_path.c_str(), final_code, false) &&
|
||||
(!parser_.opts.binary_schema_gen_embed || generate_bfbs_embed());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -274,4 +274,5 @@ void SetupDefaultCRTReportMode() {
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
Reference in New Issue
Block a user