[build] File / path lengths difficult to manage on Windows
I was unzipping boost 1.55 on my Windows machine, into what I thought was a reasonable location. 7-zip eventually complained about a file that it could not write because the path was too long. Most APIs on Windows restrict paths to ~260 characters. The longest file in the boost 1.55 release is the following: boost_1_55_0\libs\geometry\doc\html\geometry\reference\spatial_indexes\boost__geometry__index__rtree\rtree_parameters_type_const____indexable_getter_const____value_equal_const____allocator_type_const___.html This is 207 characters long. Next on the list are a whole bunch of html and png documentation files, all with length 174. Here is one example: boost_1_55_0\doc\html\images\accumulators\structboost_1_1accumulators_1_1detail_1_1is__tail__variate__feature_3_01tag_1_1tail__variate_3_01bd5040caa5e48b0af425af2314206bf.png As you may notice, the end of that particular file ends in a uuid / guid. It may be as easy as making that uuid appear 30 or 40 characters sooner in the path. ************************************************************************************************************** Is it unreasonable to ask that the boost zip only use half (130 characters) of the available Windows path size for itself? ************************************************************************************************************** On a related note, is it unreasonable to ask that an --abbreviate-paths build of boost limit itself to 130 characters? I acknowledge that this one is a bit harder to solve as there can be a large number of build "pivots" that all add to the path, but some clients (like me) need to layer other build pivot and version information on top of what boost already provides, and I need some amount of character wiggle room to make that happen. This isn't currently in as bad of a shape as the zip file. For an outdated piece of information, my win64 builds of boost 1.50 have a path part of 151 characters. boost\bin.v2\libs\test\build\msvc-11.0\rls\adrs-mdl-64\async-excpt-on\dbg-symbl-on\lnk-sttc\thrd-mlt\libboost_unit_test_framework-vc110-mt-1_50.lib.rsp Is there significant value in putting "bin.v2\libs" in the path?
On 13.11.2013 18:16, Ben Craig wrote:
On a related note, is it unreasonable to ask that an --abbreviate-paths build of boost limit itself to 130 characters? I acknowledge that this one is a bit harder to solve as there can be a large number of build "pivots" that all add to the path, but some clients (like me) need to layer other build pivot and version information on top of what boost already provides, and I need some amount of character wiggle room to make that happen.
I suppose you can always build with --hash to trade path readability for previty. It will replace all properties with just md5 checksum thereof. - Volodya
On a related note, is it unreasonable to ask that an --abbreviate-paths build of boost limit itself to 130 characters? I acknowledge that
From: Vladimir Prus
On 13.11.2013 18:16, Ben Craig wrote: this one is a bit harder to solve as there can be a large number of build "pivots" that all add to the path, but some clients (like me) need to layer other build pivot and version information on top of what boost already provides, and I need some amount of character wiggle room to make that happen.
I suppose you can always build with --hash to trade path readability for previty. It will replace all properties with just md5 checksum thereof.
- Volodya
I was not aware of --hash. That can do the trick on the build side. It would be nice for --hash and --abbreviate-paths to be documented better, but this will do. The file name lengths in the zip still need to be addressed though.
When building on windows, I've taken to building at the root of a volume. Although at some point this methodology will also fail. Charles Wilson Principal Software Development Engineer Dell | Enterprise Solutions Group
-----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Ben Craig Sent: Wednesday, November 13, 2013 6:17 AM To: boost@lists.boost.org Subject: [boost] [build] File / path lengths difficult to manage on Windows
I was unzipping boost 1.55 on my Windows machine, into what I thought was a reasonable location. 7-zip eventually complained about a file that it could not write because the path was too long. Most APIs on Windows restrict paths to ~260 characters. The longest file in the boost 1.55 release is the following:
boost_1_55_0\libs\geometry\doc\html\geometry\reference\spatial_indexe s\boost__geometry__index__rtree\rtree_parameters_type_const____ind exable_getter_const____value_equal_const____allocator_type_const___. html
This is 207 characters long. Next on the list are a whole bunch of html and png documentation files, all with length 174. Here is one example:
boost_1_55_0\doc\html\images\accumulators\structboost_1_1accumulator s_1_1detail_1_1is__tail__variate__feature_3_01tag_1_1tail__variate_3_01b d5040caa5e48b0af425af2314206bf.png
As you may notice, the end of that particular file ends in a uuid / guid. It may be as easy as making that uuid appear 30 or 40 characters sooner in the path.
********************************************************** **************************************************** Is it unreasonable to ask that the boost zip only use half (130 characters) of the available Windows path size for itself? ********************************************************** ****************************************************
On a related note, is it unreasonable to ask that an --abbreviate-paths build of boost limit itself to 130 characters? I acknowledge that this one is a bit harder to solve as there can be a large number of build "pivots" that all add to the path, but some clients (like me) need to layer other build pivot and version information on top of what boost already provides, and I need some amount of character wiggle room to make that happen.
This isn't currently in as bad of a shape as the zip file. For an outdated piece of information, my win64 builds of boost 1.50 have a path part of 151 characters.
boost\bin.v2\libs\test\build\msvc-11.0\rls\adrs-mdl-64\async-excpt-on\dbg- symbl-on\lnk-sttc\thrd-mlt\libboost_unit_test_framework-vc110-mt- 1_50.lib.rsp
Is there significant value in putting "bin.v2\libs" in the path?
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 13 Nov 2013 at 8:16, Ben Craig wrote:
I was unzipping boost 1.55 on my Windows machine, into what I thought was a reasonable location. 7-zip eventually complained about a file that it could not write because the path was too long. Most APIs on Windows restrict paths to ~260 characters. The longest file in the boost 1.55 release is the following:
I would report this as a bug to 7zip. The MAX_PATH limit is purely for backwards compatibility only, and every Win32 API can easily take 32k paths by prepending a magic marker. FYI the NT kernel API always takes 32k paths, and there you prepend a magic marker to indicate you are sending a DOS compatibility path. The Win32 layer basically gets in the way. As a result, AFIO uses the NT kernel API directly and skips the Win32 imposed nonsense which actually doubles the maximum rate of file handle creation :) Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/
On 14/11/2013 06:31, Quoth Niall Douglas:
I would report this as a bug to 7zip. The MAX_PATH limit is purely for backwards compatibility only, and every Win32 API can easily take 32k paths by prepending a magic marker.
There are some downsides to this, such as losing current directories and relative paths. (Also, there are many applications that still only use the ANSI APIs, which do not accept the magic marker.) Having said that, 7zip is the sort of program that shouldn't have trouble with any of that. (But it still might make building or browsing the documentation harder later on.)
There are some downsides to this, such as losing current directories and relative paths. (Also, there are many applications that still only use the ANSI APIs, which do not accept the magic marker.)
Even worse, windows explorer still seems to be using the ANSI api's (or it is itself introducing path limits?), and cannot reliably interact with files in long paths. So it may very well be a deliberate decision on the part of 7zip to not let the user end up with files they can't delete and such. In windows 7 i've previously noticed explorer doing some trickery with the shortform filenames (with the ~1 thingies) to reduce path length, but i can't seem to trigger this now.
On 14/11/2013 13:45, Quoth Simon Sasburg:
Even worse, windows explorer still seems to be using the ANSI api's (or it is itself introducing path limits?), and cannot reliably interact with files in long paths.
It's definitely not using the ANSI APIs but it's not using the extended syntax for the most part either. (And if you look at the docs for the shell library interfaces, most of the ones that accept complete pathnames are still limited to MAX_PATH. Although there are workarounds for that such as using item ids instead of filenames.)
From: Gavin Lambert On 14/11/2013 06:31, Quoth Niall Douglas:
I would report this as a bug to 7zip. The MAX_PATH limit is purely for backwards compatibility only, and every Win32 API can easily take 32k paths by prepending a magic marker.
There are some downsides to this, such as losing current directories and relative paths. (Also, there are many applications that still only use the ANSI APIs, which do not accept the magic marker.)
Having said that, 7zip is the sort of program that shouldn't have trouble with any of that. (But it still might make building or browsing the documentation harder later on.)
I think this is being unrealistic. If we take this approach, then you should request every Win32 program that uses fopen, iostreams, or CreateFile without the magic marker to change their program to use a non-portable API. This includes programs like cmd.exe, explorer, bjam, 7zip, and countless others. I wish that "normal" Windows APIs permitted a higher maximum path length, but they don't. Reasonable Windows support means acknowledging this limitation.
On 14/11/2013 14:31, Quoth Ben Craig:
I think this is being unrealistic. If we take this approach, then you should request every Win32 program that uses fopen, iostreams, or CreateFile without the magic marker to change their program to use a non-portable API. This includes programs like cmd.exe, explorer, bjam, 7zip, and countless others.
Did you mean to quote someone else? Because I was agreeing with you.
I wish that "normal" Windows APIs permitted a higher maximum path length, but they don't. Reasonable Windows support means acknowledging this limitation.
It's unfortunately a wart of its DOS outgrowth. Back in the days of 8.3 filename limits a total path length of 260 was ample, and most of the early DOS APIs were based around local stack buffers of [MAX_PATH]. This has ended up getting carried forward via backwards-compatibility, because the APIs don't provide any way to accept the buffer size explicitly and it can't be increased arbitrarily without crashing older programs.
From: Gavin Lambert
On 14/11/2013 14:31, Quoth Ben Craig:
I think this is being unrealistic. If we take this approach, then you should request every Win32 program that uses fopen, iostreams, or CreateFile without the magic marker to change their program to use a non-portable API. This includes programs like cmd.exe, explorer, bjam, 7zip, and countless others.
Did you mean to quote someone else? Because I was agreeing with you.
Sorry about that. I misinterpreted your position. Easy to get into "violent agreement" on the internet sometimes :)
On 13 Nov 2013 at 19:31, Ben Craig wrote:
I think this is being unrealistic. If we take this approach, then you should request every Win32 program that uses fopen, iostreams, or CreateFile without the magic marker to change their program to use a non-portable API. This includes programs like cmd.exe, explorer, bjam, 7zip, and countless others.
Mmm, you make a good point. Microsoft ought to flip the default instead of everybody else making the change.
I wish that "normal" Windows APIs permitted a higher maximum path length, but they don't. Reasonable Windows support means acknowledging this limitation.
I've bumped the notion of raising that limit to our friends in Microsoft. Who knows, it may be possible for Windows 8.2! Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/
On 15/11/2013 08:52, Quoth Niall Douglas:
I've bumped the notion of raising that limit to our friends in Microsoft. Who knows, it may be possible for Windows 8.2!
As I previously mentioned, I don't think it's something they can do on a version boundary, only on an ABI boundary (eg. 32-bit vs. 64-bit, or by introducing new APIs). There's just too much existing (and will not be recompiled) code that has stack based char[MAX_PATH] buffers. They can't even do the manifest-version-based shimming that they're doing for some other things, as that's defined at the process level -- just because an application claims that it knows about a larger MAX_PATH doesn't mean that all the DLLs that it uses does. (Not that I wouldn't love them to try, I just wouldn't hold out much hope for it.)
On 15 Nov 2013 at 13:52, Gavin Lambert wrote:
On 15/11/2013 08:52, Quoth Niall Douglas:
I've bumped the notion of raising that limit to our friends in Microsoft. Who knows, it may be possible for Windows 8.2!
As I previously mentioned, I don't think it's something they can do on a version boundary, only on an ABI boundary (eg. 32-bit vs. 64-bit, or by introducing new APIs).
There's just too much existing (and will not be recompiled) code that has stack based char[MAX_PATH] buffers.
They can't even do the manifest-version-based shimming that they're doing for some other things, as that's defined at the process level -- just because an application claims that it knows about a larger MAX_PATH doesn't mean that all the DLLs that it uses does.
I wouldn't be proposing that MAX_PATH should be changed for any code not being compiled for the latest toolset where MAX_PATH was extended. So, if you're linking to MSVCRT13.DLL then you get MAX_PATH=1024, while any previous MSVCRT gets MAX_PATH=260. What about mixed MSVCRT apps? Well, already those aren't reliable and you shouldn't do them :) But it still should usually work as usually application code is compiled with a newer toolset than library code, and therefore you're passing in a larger buffer which may cause library code to puke on the longer path, but not corrupt memory. A lot of time library code simply passes through externally supplied buffers anyway, and therefore doesn't care.
(Not that I wouldn't love them to try, I just wouldn't hold out much hope for it.)
I got a response - it is thought highly unlikely to be successful. I guess you'd need to make a convincing business case, and I agree given Windows' size in the market they don't have to bother adapting to others i.e. if you're porting to Windows, you accept the 260 char path limit as part of the porting effort and all the code refactoring therefore needed. BTW, my current side project of implementing a standard transactional graph database gets rid of the path length limitation on Windows. One of its interfaces is a POSIX-like file system interface, and by POSIX-like I mean it looks just like a POSIX file system except it has more reserved characters for working with things like multiple file versions, creating directories which are really live searches on the graph store, being able to transact update many files atomically or not at all etc. My idea is that (eventually) you could mount this graph store as a fuse filesystem and work with it as if it were a real file system. Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/
On 16/11/2013 10:34, Quoth Niall Douglas:
I wouldn't be proposing that MAX_PATH should be changed for any code not being compiled for the latest toolset where MAX_PATH was extended. So, if you're linking to MSVCRT13.DLL then you get MAX_PATH=1024, while any previous MSVCRT gets MAX_PATH=260.
That's not where MAX_PATH comes from though. It's in the Windows SDK, not the C Runtime. There's plenty of code that calls the WinAPI directly, and that's where the value of MAX_PATH matters.
BTW, my current side project of implementing a standard transactional graph database gets rid of the path length limitation on Windows. One of its interfaces is a POSIX-like file system interface, and by POSIX-like I mean it looks just like a POSIX file system except it has more reserved characters for working with things like multiple file versions, creating directories which are really live searches on the graph store, being able to transact update many files atomically or not at all etc. My idea is that (eventually) you could mount this graph store as a fuse filesystem and work with it as if it were a real file system.
Sounds a little like the database-based filesystem MS were planning to replace everything with in Vista, but eventually abandoned. (WinFS, I think it might have been called..?)
On 18 Nov 2013 at 11:25, Gavin Lambert wrote:
I wouldn't be proposing that MAX_PATH should be changed for any code not being compiled for the latest toolset where MAX_PATH was extended. So, if you're linking to MSVCRT13.DLL then you get MAX_PATH=1024, while any previous MSVCRT gets MAX_PATH=260.
That's not where MAX_PATH comes from though. It's in the Windows SDK, not the C Runtime. There's plenty of code that calls the WinAPI directly, and that's where the value of MAX_PATH matters.
You are right, though by MSVCRT version I was meaning MSVC toolset version e.g. the v120 thing you can choose. And of course well written Win32 API code ought to adjust to a larger MAX_PATH without any problems at all :) Still, it would be hard to create a business case in favour of it within Microsoft, and therefore it is very hard to imagine it happening.
BTW, my current side project of implementing a standard transactional graph database gets rid of the path length limitation on Windows. One of its interfaces is a POSIX-like file system interface, and by POSIX-like I mean it looks just like a POSIX file system except it has more reserved characters for working with things like multiple file versions, creating directories which are really live searches on the graph store, being able to transact update many files atomically or not at all etc. My idea is that (eventually) you could mount this graph store as a fuse filesystem and work with it as if it were a real file system.
Sounds a little like the database-based filesystem MS were planning to replace everything with in Vista, but eventually abandoned. (WinFS, I think it might have been called..?)
I could talk about that one for several hours ... yes, you're right I've spoken extensively with colleagues who used to work on WinFS back in the day. They believe my design approach to be correct. Whether it *is* correct of course I may find out some day depending on what happens after we relocate from Canada back to Europe. Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/
On 25/11/2013 07:35, Quoth Niall Douglas:
And of course well written Win32 API code ought to adjust to a larger MAX_PATH without any problems at all :)
If you get to recompile it, sure. The trouble is that there are a LOT of existing Windows apps that aren't going to get recompiled. Even mission-critical LOB ones for which source code no longer exists (or is otherwise inaccessible, eg. external developer no longer in business). The problem is that most of the APIs themselves don't have a parameter that specifies the buffer size actually provided, they just have an assumption that the buffer is "at least MAX_PATH characters". There is no safe way to increase the value of MAX_PATH with these APIs, without either making a new parallel set of APIs that use eg. MAX_PATH2, or (better) add an extra parameter that allows the buffer size to be specified. (It doesn't matter so much with APIs that only take string input, such as CreateFile; but there are a lot of string output APIs too, and quite a bit of external code that hooks APIs at various levels, or library code that abstracts and encapsulates the APIs.)
Still, it would be hard to create a business case in favour of it within Microsoft, and therefore it is very hard to imagine it happening.
Exactly. Although even they run into it from time to time. (I had a case recently where an SQL Server install failed because the installer was being run from a pathname that was too long for its internal support files, which is why their install wrappers tend to use a random-numbered folder in the root instead of the "real" temporary folder.)
participants (6)
-
Ben Craig
-
Charles_J_Wilson@Dell.com
-
Gavin Lambert
-
Niall Douglas
-
Simon Sasburg
-
Vladimir Prus