HaxeFoundation / haxe

Haxe - The Cross-Platform Toolkit
https://haxe.org
6.19k stars 656 forks source link

Compiler can't write to long paths on Windows, even with long paths enabled #11714

Open kigero opened 4 months ago

kigero commented 4 months ago

Windows has a 260 character path limitation, unless you enable Long Path Support - which I have done. I learned the hard way today that the Haxe compiler can't write to a directory with a long path. We're using Haxe as part of a much larger build process, which ends up working within a very deep path structure. I recently switched laptops, and changed my base project directory from c:\work on my old laptop to c:\u\work on my new one - apparently I have just been very lucky for the last several years, as that was enough to push our build paths for haxe over the limit.

To illustrate, I've created a directory named c:\testdir, with a very simple program in it:

class PathTest {
    static function main() {
        trace("Hello world");
    }
}

This builds and runs as expected in that directory:

> haxe --java out -p . -m PathTest PathTest
haxelib run hxjava hxjava_build.txt --haxe-version 4301 --feature-level 1 --out out/PathTest
javac.exe "-sourcepath" "src" "-d" "obj" "-g:none" "@cmd"

> java -jar out\PathTest.jar
PathTest.hx:3: Hello world

Now we'll create a ridiculously long path to output the files to:

> haxe --java subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_out -p . -m PathTest PathTest
Error: No such file or directory (subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_out)

The next few tests shorten that path a little bit at a time, and what happens is that Haxe can create more and more structure within that output folder, until finally it's short enough to succeed.

> haxe --java subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_out -p . -m PathTest PathTest
Error: No such file or directory (subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_out/src/haxe/root)

> haxe --java subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_out -p . -m PathTest PathTest
Sys_error("subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_out/src/haxe/lang/EmptyObject.java: No such file or directory")

> haxe --java subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_out -p . -m PathTest PathTest
Sys_error("subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_out/src/haxe/exceptions/PosException.java: No such file or directory")

> haxe --java subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_out -p . -m PathTest PathTest
haxelib run hxjava hxjava_build.txt --haxe-version 4301 --feature-level 1 --out subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4__out/PathTest
javac.exe "-sourcepath" "src" "-d" "obj" "-g:none" "@cmd"

> java -jar subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_subdir5_subdir6_subdir7_subdir8_subdir9_subdir0_subdir1_subdir2_subdir3_subdir4_out\PathTest.jar 
PathTest.hx:3: Hello world

I used Java in this example just because it creates some structure under that folder, making it a little easier to see the problem, but this is easily replicated with Python as well. Outside of Haxe in the command prompt, I can create that really long directory and VSCodium (and most other programs) will happily read and write to it, so this seems to be something not supported by the Haxe compiler.

The workaround is (of course) to use shorter paths, either real or symlinked. This works, but if it's possible to support long paths on windows that would be great. The link above states that an application has to opt in to supporting long paths and provides some documentation on how to do that.

Simn commented 4 months ago

https://discuss.ocaml.org/t/ocaml-on-windows-the-long-paths-issue/13283 seems related.