Closed laszlocsomor closed 7 years ago
FYI: @meteorcloudy , @dslomov
Workaround: use --output_user_root=/c/foo
, i.e. some path with no abbreviated components.
I have a fix for this, stay tuned.
Bad news: the Java File API that I was using to resolve short names seems to cache the results of getAbsolute{Path,File}
and getCanonical{Path,File}
, so if a previously nonexistent path ("c:/longpa~1") is later created such that the resolution should succeed ("c:/longpathname"), it still doesn't, and similarly if a previously existent path is deleted, the canonical form can still be retrieved.
Test:
public static void main(String[] args) throws IOException {
File f = new File("C:\\longpa~1");
System.out.printf(
"Before creating c:\\longpathname:\n" +
" f: absolute=%s, canonical=%s, exists=%d\n",
f.getAbsolutePath(), f.getCanonicalPath(), f.exists() ? 1 : 0);
File g = new File("C:\\longpathname");
g.mkdir();
System.out.printf(
"After creating c:\\longpathname:\n" +
" g: absolute=%s, canonical=%s, exists=%d\n",
g.getAbsolutePath(), g.getCanonicalPath(), g.exists() ? 1 : 0);
System.out.printf(
" f: absolute=%s, canonical=%s, exists=%d\n",
f.getAbsolutePath(), f.getCanonicalPath(), f.exists() ? 1 : 0);
File f2 = new File("C:\\longpa~1");
System.out.printf(
" f2: absolute=%s, canonical=%s, exists=%d\n",
f2.getAbsolutePath(), f2.getCanonicalPath(), f2.exists() ? 1 : 0);
g.delete();
System.out.printf(
"After deleting c:\\longpathname:\n" +
" g: absolute=%s, canonical=%s, exists=%d\n",
g.getAbsolutePath(), g.getCanonicalPath(), g.exists() ? 1 : 0);
File g2 = new File("C:\\longpathname");
System.out.printf(
" g2: absolute=%s, canonical=%s, exists=%d\n",
g2.getAbsolutePath(), g2.getCanonicalPath(), g2.exists() ? 1 : 0);
File h = new File("c:\\longpathn");
h.mkdir();
System.out.printf(
"After creating c:\\longpathn:\n" +
" h: absolute=%s, canonical=%s, exists=%d\n",
h.getAbsolutePath(), h.getCanonicalPath(), h.exists() ? 1 : 0);
File f3 = new File("C:\\longpa~1");
System.out.printf(
" f3: absolute=%s, canonical=%s, exists=%d\n",
f3.getAbsolutePath(), f3.getCanonicalPath(), f3.exists() ? 1 : 0);
h.delete();
}
Output:
Before creating c:\longpathname:
f: absolute=C:\longpa~1, canonical=C:\longpa~1, exists=0
After creating c:\longpathname:
g: absolute=C:\longpathname, canonical=C:\longpathname, exists=1
f: absolute=C:\longpa~1, canonical=C:\longpa~1, exists=1
f2: absolute=C:\longpa~1, canonical=C:\longpa~1, exists=1
After deleting c:\longpathname:
g: absolute=C:\longpathname, canonical=C:\longpathname, exists=0
g2: absolute=C:\longpathname, canonical=C:\longpathname, exists=0
After creating c:\longpathn:
h: absolute=c:\longpathn, canonical=C:\longpathn, exists=1
f3: absolute=C:\longpa~1, canonical=C:\longpathn, exists=1
Out of curiosity, I implemented this in JNI (using GetLongPathNameA
) and measured performance.
Everything is measured twice to reveal caching, if any.
Measured 6000 items because I could initialize a Java string array with that many 8dot3 names.
No source code because I don't have nice clean BUILD files, as I was playing around in Eclipse and just reused Bazel's //src/main/native:windows_jni
rule.
Resolution of c:\foo~1 (nonexistent, Java): C:\foo~1
Resolution of C:\foo\LO6C78~1 (existent, Java): C:\foo\longpath10
Resolution of c:\foo~1 (nonexistent, native):
Resolution of C:\foo\LO6C78~1 (existent, native): C:\foo\longpath10
6000 distinct files (nonexistent, Java): 761 ms
6000 distinct files (nonexistent, Java): 707 ms
6000 distinct files (nonexistent, native): 112 ms
6000 distinct files (nonexistent, native): 112 ms
6000 distinct files (existent, Java): 1070 ms
6000 distinct files (existent, Java): 1054 ms
6000 distinct files (existent, native): 894 ms
6000 distinct files (existent, native): 900 ms
same file 6000 times (nonexistent, Java): 5 ms
same file 6000 times (nonexistent, Java): 3 ms
same file 6000 times (nonexistent, native): 84 ms
same file 6000 times (nonexistent, native): 82 ms
same file 6000 times (existent, Java): 1 ms
same file 6000 times (existent, Java): 1 ms
same file 6000 times (existent, native): 425 ms
same file 6000 times (existent, native): 423 ms
Description of the problem / feature request / question:
If the exec root has a shortened path in it (e.g.
C:/users/laszlocsomor/...
->C:/users/laszlo~1/...
) then include validation fails because the execution root uses the shortened path segment and the dotD file uses long path names.If possible, provide a minimal example to reproduce the problem:
Add logging above this line:
Build bazel:
Create a workspace with a simple
cc_library
rule and a cc file including a header:Observe behavior with different user base paths, mind the differences in the
--output_user_root
values:Environment info
Operating System: Windows 10
If
bazel info release
returns "development version" or "(@non-git)", please tell us what source tree you compiled Bazel from; git commit hash is appreciated (git rev-parse HEAD
):Have you found anything relevant by searching the web? (e.g. GitHub issues, email threads in the bazel-discuss@googlegroups.com archive)
no
Anything else, information or logs or outputs that would be helpful?
(If they are large, please upload as attachment or provide link).