diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/google/protobuf/compiler/command_line_interface.cc | 64 | ||||
-rw-r--r-- | src/google/protobuf/unittest_well_known_types.proto | 3 |
2 files changed, 67 insertions, 0 deletions
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 291fb054..667b2b63 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -181,6 +181,68 @@ bool TryCreateParentDirectory(const string& prefix, const string& filename) { return true; } +// Get the absolute path of this protoc binary. +bool GetProtocAbsolutePath(string* path) { +#ifdef _WIN32 + char buffer[MAX_PATH]; + int len = GetModuleFileName(NULL, buffer, MAX_PATH); +#else + char buffer[PATH_MAX]; + int len = readlink("/proc/self/exe", buffer, PATH_MAX); +#endif + if (len > 0) { + path->assign(buffer, len); + return true; + } else { + return false; + } +} + +// Whether a path is where google/protobuf/descriptor.proto and other well-known +// type protos are installed. +bool IsInstalledProtoPath(const string& path) { + // Checking the descriptor.proto file should be good enough. + string file_path = path + "/google/protobuf/descriptor.proto"; + return access(file_path.c_str(), F_OK) != -1; +} + +// Add the paths where google/protobuf/descritor.proto and other well-known +// type protos are installed. +void AddDefaultProtoPaths(vector<pair<string, string> >* paths) { + // TODO(xiaofeng): The code currently only checks relative paths of where + // the protoc binary is installed. We probably should make it handle more + // cases than that. + string path; + if (!GetProtocAbsolutePath(&path)) { + return; + } + // Strip the binary name. + size_t pos = path.find_last_of("/\\"); + if (pos == string::npos || pos == 0) { + return; + } + path = path.substr(0, pos); + // Check the binary's directory. + if (IsInstalledProtoPath(path)) { + paths->push_back(pair<string, string>("", path)); + return; + } + // Check if there is an include subdirectory. + if (IsInstalledProtoPath(path + "/include")) { + paths->push_back(pair<string, string>("", path + "/include")); + return; + } + // Check if the upper level directory has an "include" subdirectory. + pos = path.find_last_of("/\\"); + if (pos == string::npos || pos == 0) { + return; + } + path = path.substr(0, pos); + if (IsInstalledProtoPath(path + "/include")) { + paths->push_back(pair<string, string>("", path + "/include")); + return; + } +} } // namespace // A MultiFileErrorCollector that prints errors to stderr. @@ -644,6 +706,8 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { break; } + AddDefaultProtoPaths(&proto_path_); + // Set up the source tree. DiskSourceTree source_tree; for (int i = 0; i < proto_path_.size(); i++) { diff --git a/src/google/protobuf/unittest_well_known_types.proto b/src/google/protobuf/unittest_well_known_types.proto index 2d422d8c..e157260e 100644 --- a/src/google/protobuf/unittest_well_known_types.proto +++ b/src/google/protobuf/unittest_well_known_types.proto @@ -2,6 +2,9 @@ syntax = "proto3"; package protobuf_unittest; +option java_multiple_files = true; +option java_package = "com.google.protobuf.test"; + import "google/protobuf/any.proto"; import "google/protobuf/api.proto"; import "google/protobuf/duration.proto"; |