forked from BigfootDev/flatbuffers
Make --bfbs-filenames default to location of first schema file. (#6705)
* Make --bfbs-filenames default to location of first schema file. Make RelativeToProjectRoot always work, applying "../" where needed. This is needed for backwards compatibility. The first input file may be deeper in some directory than the other files. Now, there will always be a declaration file. * documentation * clang format Co-authored-by: Casper Neo <cneo@google.com>
This commit is contained in:
@@ -13,6 +13,9 @@ There are some quirks:
|
|||||||
field of `Schema`. These mark the presence of new, backwards incompatible,
|
field of `Schema`. These mark the presence of new, backwards incompatible,
|
||||||
schema features. Code generators must error if generating a schema with
|
schema features. Code generators must error if generating a schema with
|
||||||
unrecognized advanced features.
|
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
|
## Invocation
|
||||||
|
|||||||
@@ -149,8 +149,11 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
|
|||||||
" --oneof-union Translate .proto oneofs to flatbuffer unions.\n"
|
" --oneof-union Translate .proto oneofs to flatbuffer unions.\n"
|
||||||
" --grpc Generate GRPC interfaces for the specified languages.\n"
|
" --grpc Generate GRPC interfaces for the specified languages.\n"
|
||||||
" --schema Serialize schemas instead of JSON (use with -b).\n"
|
" --schema Serialize schemas instead of JSON (use with -b).\n"
|
||||||
" --bfbs-filenames PATH Adds declaration filenames, relative to PATH and prefixed with"
|
" --bfbs-filenames PATH Sets the root path where reflection filenames in \n"
|
||||||
" `//`, to the binary schema.\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-comments Add doc comments to the binary schema files.\n"
|
||||||
" --bfbs-builtins Add builtin attributes 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"
|
" --bfbs-gen-embed Generate code to embed the bfbs schema to the source.\n"
|
||||||
@@ -444,6 +447,9 @@ int FlatCompiler::Compile(int argc, const char **argv) {
|
|||||||
static_cast<size_t>(file_it - filenames.begin()) >= binary_files_from;
|
static_cast<size_t>(file_it - filenames.begin()) >= binary_files_from;
|
||||||
auto ext = flatbuffers::GetExtension(filename);
|
auto ext = flatbuffers::GetExtension(filename);
|
||||||
const bool is_schema = ext == "fbs" || ext == "proto";
|
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();
|
const bool is_binary_schema = ext == reflection::SchemaExtension();
|
||||||
if (is_binary) {
|
if (is_binary) {
|
||||||
parser->builder_.Clear();
|
parser->builder_.Clear();
|
||||||
|
|||||||
35
src/util.cpp
35
src/util.cpp
@@ -225,20 +225,29 @@ std::string RelativeToRootPath(const std::string &project,
|
|||||||
std::string absolute_project = PosixPath(AbsolutePath(project));
|
std::string absolute_project = PosixPath(AbsolutePath(project));
|
||||||
if (absolute_project.back() != '/') absolute_project += "/";
|
if (absolute_project.back() != '/') absolute_project += "/";
|
||||||
std::string absolute_filepath = PosixPath(AbsolutePath(filepath));
|
std::string absolute_filepath = PosixPath(AbsolutePath(filepath));
|
||||||
if (absolute_filepath.size() < absolute_project.size() ||
|
|
||||||
absolute_filepath.substr(0, absolute_project.size()) !=
|
// Find the first character where they disagree.
|
||||||
absolute_project) {
|
// The previous directory is the lowest common ancestor;
|
||||||
printf(
|
const char *a = absolute_project.c_str();
|
||||||
"The --bfbs-filenames directory must contain all files and included "
|
const char *b = absolute_filepath.c_str();
|
||||||
"files.\n");
|
size_t common_prefix_len = 0;
|
||||||
printf("project: %s\n", project.c_str());
|
while (*a != '\0' && *b != '\0' && *a == *b) {
|
||||||
printf("filepath: %s\n", filepath.c_str());
|
if (*a == '/') common_prefix_len = a - absolute_project.c_str();
|
||||||
printf("absolute_project: %s\n", absolute_project.c_str());
|
a++;
|
||||||
printf("absolute_filepath:%s\n", absolute_filepath.c_str());
|
b++;
|
||||||
FLATBUFFERS_ASSERT(0);
|
|
||||||
}
|
}
|
||||||
const std::string relpath = absolute_filepath.substr(absolute_project.size());
|
// the number of ../ to prepend to b depends on the number of remaining
|
||||||
return "//" + relpath;
|
// 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.
|
// Locale-independent code.
|
||||||
|
|||||||
@@ -1339,7 +1339,6 @@ void ParseProtoTestWithIncludes() {
|
|||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = true;
|
opts.include_dependence_headers = true;
|
||||||
opts.proto_mode = true;
|
opts.proto_mode = true;
|
||||||
opts.project_root = test_data_path;
|
|
||||||
|
|
||||||
// Parse proto.
|
// Parse proto.
|
||||||
flatbuffers::Parser parser(opts);
|
flatbuffers::Parser parser(opts);
|
||||||
@@ -1357,9 +1356,7 @@ void ParseProtoTestWithIncludes() {
|
|||||||
auto import_fbs = flatbuffers::GenerateFBS(import_parser, "test");
|
auto import_fbs = flatbuffers::GenerateFBS(import_parser, "test");
|
||||||
|
|
||||||
// Ensure generated file is parsable.
|
// Ensure generated file is parsable.
|
||||||
flatbuffers::IDLOptions opts2;
|
flatbuffers::Parser parser2;
|
||||||
opts2.project_root = protopath;
|
|
||||||
flatbuffers::Parser parser2(opts2);
|
|
||||||
// Since `imported.fbs` isn't in the filesystem AbsolutePath can't figure it
|
// Since `imported.fbs` isn't in the filesystem AbsolutePath can't figure it
|
||||||
// out by itself. We manually construct it so Parser works.
|
// out by itself. We manually construct it so Parser works.
|
||||||
std::string imported_fbs = flatbuffers::PosixPath(
|
std::string imported_fbs = flatbuffers::PosixPath(
|
||||||
|
|||||||
Reference in New Issue
Block a user