|
|
|
@ -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++) { |
|
|
|
|