protobuf icon indicating copy to clipboard operation
protobuf copied to clipboard

--proto_path cannot recognize network drive paths on Windows

Open magmajia-pki opened this issue 3 years ago • 3 comments

What version of protobuf and what language are you using? Version: 3.21.6 Language: C++/C#/Javascript

What operating system (Linux, Windows, ...) and version? Windows10

What runtime / compiler are you using (e.g., python version or gcc version) Visual Studio 2019

What did you do? Steps to reproduce the behavior:

  1. Set post-build options on Visual Studio 2019:
  2. \\shald062\Code\vcpkg\installed\x64-windows\tools\protobuf\protoc.exe --proto_path="\\shald062\Code\vcpkg\installed\x64-windows\include" --proto_path="./protos" --cpp_out="./generated" ./protos/*.proto
  3. Build the project
  4. See error: \\shald062\Code\vcpkg\installed\x64-windows\include : warning : directory does not exist.

What did you expect to see Build successful

What did you see instead? Build failed

Anything else we should know about your project / environment I also tried the command in Powershell. Fail too. When I use a local path, both VS and command line success.

magmajia-pki avatar Oct 21 '22 06:10 magmajia-pki

I don't think protoc supports network drive paths right now, and I don't think we necessarily have plans to add this. What's your use-case for wanting this, and if this is something we would be willing to help support/review, would you be interested in contributing this yourself?

zhangskz avatar Oct 21 '22 19:10 zhangskz

@zhangskz Thanks a lot for replying. My use-case is: I exported the c++ package of protobuf from vcpkg and stored it on a network drive, so all team members can build projects using the same source library. Once I need to use the types supplied by protobuf (like 'any'), I have to set the --proto_path as the network drive, the the problem occurs. Surely I can also add the "Include/google" folder into our repository, but I don't think it's the best way. Do you have any suggestion for my use-case?

magmajia-pki avatar Oct 24 '22 00:10 magmajia-pki

Note that UNC (network) path should be recognized as normal file paths by the windows API and standard C/C++ functions on Windows. I'm not sure what the problem is here but it may be an easy fix.

ajasmin avatar Dec 22 '22 21:12 ajasmin

Hi, I came here because I have a similar problem. I use compiler API directly to parse .proto files is C++/Qt application. Here is what my code looks like

google::protobuf::compiler::DiskSourceTree sourceTree;
sourceTree.MapPath("", "//server/share/");
ProtoParseErrors errors;
google::protobuf::compiler::Importer importer(&sourceTree, &errors);
if (errors.hasErrors())
{
    qWarning() << "Unable to import" << protoPath << "correctly";
}
else
{
    if (auto fd = importer.Import("Messages.proto"))
    {
        int msgCount = fd->message_type_count();
        for (int i(0) ; i < msgCount ; ++i)
            msgTypes << QString::fromStdString(fd->message_type(i)->name());
        }
        else
        {
            qCritical() << "An error occured trying to read PROTO file" << fileInfo.fileName();
        }
    }
}
else
    qWarning() << "Cannot open" << protoPath;

When I run this, auto fd = importer.Import("Messages.proto") returns a nullptr. When I step into the Import with a debugger, I reach as_windows_path inside io_win32.cc

bool as_windows_path(const char* path, wstring* result) {
  if (null_or_empty(path)) {
    result->clear();
    return true;
  }
  wstring wpath;
  if (!strings::utf8_to_wcs(path, &wpath)) {
    return false;
  }
  if (has_longpath_prefix(wpath.c_str())) {
    *result = wpath;
    return true;
  }
  if (is_separator(path[0]) || is_drive_relative(path)) {
    return false;
  }


  if (!is_path_absolute(wpath.c_str())) {
    int size = ::GetCurrentDirectoryW(0, nullptr);
    if (size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
      return false;
    }
    std::unique_ptr<WCHAR[]> wcwd(new WCHAR[size]);
    ::GetCurrentDirectoryW(size, wcwd.get());
    wpath = join_paths(wcwd.get(), wpath);
  }
  wpath = normalize(wpath);
  if (!has_longpath_prefix(wpath.c_str())) {
    // Add the "\\?\" prefix unconditionally. This way we prevent the Win32 API
    // from processing the path and "helpfully" removing trailing dots from the
    // path, for example.
    // See https://github.com/bazelbuild/bazel/issues/2935
    wpath = wstring(L"\\\\?\\") + wpath;
  }
  *result = wpath;
  return true;
}

It falls into if (is_separator(path[0]) || is_drive_relative(path)) because my path indeed starts with a separator (//server/share/Messages.proto). Since it's not considered a "windows_path", the wopen fails then the Import fails.

I don't understand why if the first char of the path is a separator (is_separator(path[0])), then the path is wrong. I tried bypassing this test (I commented it out), but then the path is considered "not absolute" and appended to the current working directory. Which is not what I was looking for.

I haven't yet figured out what needs fixing to accept "//paths". The thing I tried and that worked in this particular case was to comment out

#define SUPPORT_LONGPATHS

inside io_win32.cc to avoid passing by this as_windows_path method. But I figured it wasn't the cleanest solution.

Mathsoum avatar Nov 07 '23 14:11 Mathsoum

We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please add a comment.

This issue is labeled inactive because the last activity was over 90 days ago.

github-actions[bot] avatar Feb 06 '24 10:02 github-actions[bot]

We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please reopen it.

This issue was closed and archived because there has been no new activity in the 14 days since the inactive label was added.

github-actions[bot] avatar Feb 20 '24 10:02 github-actions[bot]