aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler/command_line_interface.cc
diff options
context:
space:
mode:
authorGravatar Feng Xiao <xfxyjwf@gmail.com>2015-05-21 16:45:47 -0700
committerGravatar Feng Xiao <xfxyjwf@gmail.com>2015-05-21 16:45:47 -0700
commite9abc404df99ef85d3e25aaaccd4aa83e381b98f (patch)
treed49e61618c3bfc0d1d9865c02d324825924ad1f5 /src/google/protobuf/compiler/command_line_interface.cc
parent56095026ccc2f755a6fdb296e30c3ddec8f556a2 (diff)
Add default import paths for descriptor.proto and other well-known types to protoc.
Change-Id: I4afa295de4c8ed2a4cd0919cf84aedcd1327d9a5
Diffstat (limited to 'src/google/protobuf/compiler/command_line_interface.cc')
-rw-r--r--src/google/protobuf/compiler/command_line_interface.cc64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index 567238ae..8e0a0aa4 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++) {