Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make --bfbs-filenames default to location of first schema file. #6705

Merged
merged 3 commits into from
Jun 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/source/IntermediateRepresentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ There are some quirks:
field of `Schema`. These mark the presence of new, backwards incompatible,
schema features. Code generators must error if generating a schema with
unrecognized advanced features.
- Filenames are relative to a "project root" denoted by "//" in the path. This
may be specified in flatc with `--bfbs-filenames=$PROJECT_ROOT`, or it will be
inferred to be the directory containing the first provided schema file.


## Invocation
Expand Down
10 changes: 8 additions & 2 deletions src/flatc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,11 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
" --oneof-union Translate .proto oneofs to flatbuffer unions.\n"
" --grpc Generate GRPC interfaces for the specified languages.\n"
" --schema Serialize schemas instead of JSON (use with -b).\n"
" --bfbs-filenames PATH Adds declaration filenames, relative to PATH and prefixed with"
" `//`, to the binary schema.\n"
" --bfbs-filenames PATH Sets the root path where reflection filenames in \n"
" reflection.fbs are relative to. The 'root' is denoted with \n"
" `//`. E.g. if PATH=/a/b/c \n then /a/d/e.fbs will be serialized\n"
" as //../d/e.fbs. (PATH defaults to the directory of the first\n"
" provided schema file.)\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"
Expand Down Expand Up @@ -444,6 +447,9 @@ int FlatCompiler::Compile(int argc, const char **argv) {
static_cast<size_t>(file_it - filenames.begin()) >= binary_files_from;
auto ext = flatbuffers::GetExtension(filename);
const bool is_schema = ext == "fbs" || ext == "proto";
if (is_schema && opts.project_root.empty()) {
opts.project_root = StripFileName(filename);
}
const bool is_binary_schema = ext == reflection::SchemaExtension();
if (is_binary) {
parser->builder_.Clear();
Expand Down
35 changes: 22 additions & 13 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,20 +225,29 @@ std::string RelativeToRootPath(const std::string &project,
std::string absolute_project = PosixPath(AbsolutePath(project));
if (absolute_project.back() != '/') absolute_project += "/";
std::string absolute_filepath = PosixPath(AbsolutePath(filepath));
if (absolute_filepath.size() < absolute_project.size() ||
absolute_filepath.substr(0, absolute_project.size()) !=
absolute_project) {
printf(
"The --bfbs-filenames directory must contain all files and included "
"files.\n");
printf("project: %s\n", project.c_str());
printf("filepath: %s\n", filepath.c_str());
printf("absolute_project: %s\n", absolute_project.c_str());
printf("absolute_filepath:%s\n", absolute_filepath.c_str());
FLATBUFFERS_ASSERT(0);

// Find the first character where they disagree.
// The previous directory is the lowest common ancestor;
const char *a = absolute_project.c_str();
const char *b = absolute_filepath.c_str();
size_t common_prefix_len = 0;
while (*a != '\0' && *b != '\0' && *a == *b) {
if (*a == '/') common_prefix_len = a - absolute_project.c_str();
a++;
b++;
}
const std::string relpath = absolute_filepath.substr(absolute_project.size());
return "//" + relpath;
// the number of ../ to prepend to b depends on the number of remaining
// directories in A.
const char *suffix = absolute_project.c_str() + common_prefix_len;
size_t num_up = 0;
while (*suffix != '\0')
if (*suffix++ == '/') num_up++;
num_up--; // last one is known to be '/'.
std::string result = "//";
for (size_t i = 0; i < num_up; i++) result += "../";
result += absolute_filepath.substr(common_prefix_len + 1);

return result;
}

// Locale-independent code.
Expand Down
5 changes: 1 addition & 4 deletions tests/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1339,7 +1339,6 @@ void ParseProtoTestWithIncludes() {
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = true;
opts.proto_mode = true;
opts.project_root = test_data_path;

// Parse proto.
flatbuffers::Parser parser(opts);
Expand All @@ -1357,9 +1356,7 @@ void ParseProtoTestWithIncludes() {
auto import_fbs = flatbuffers::GenerateFBS(import_parser, "test");

// Ensure generated file is parsable.
flatbuffers::IDLOptions opts2;
opts2.project_root = protopath;
flatbuffers::Parser parser2(opts2);
flatbuffers::Parser parser2;
// Since `imported.fbs` isn't in the filesystem AbsolutePath can't figure it
// out by itself. We manually construct it so Parser works.
std::string imported_fbs = flatbuffers::PosixPath(
Expand Down