Add default import paths for descriptor.proto and other well-known types to protoc.

Change-Id: I4afa295de4c8ed2a4cd0919cf84aedcd1327d9a5
This commit is contained in:
Feng Xiao 2015-05-21 16:45:47 -07:00
parent 56095026cc
commit e9abc404df

View File

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