[Boost-bugs] [Boost C++ Libraries] #12711: Cross-compiling with GCC on windows will hang due cygwin path resolution

Subject: [Boost-bugs] [Boost C++ Libraries] #12711: Cross-compiling with GCC on windows will hang due cygwin path resolution
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2016-12-23 09:19:10


#12711: Cross-compiling with GCC on windows will hang due cygwin path resolution
-------------------------------------+---------------------------
 Reporter: kirill.erofeev@… | Owner: vladimir_prus
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: build
  Version: Boost 1.61.0 | Severity: Regression
 Keywords: windows cross-compiling |
-------------------------------------+---------------------------
 Recently, since release 1.61. There were changes in Boost.Build which
 breaks cross-compilation on windows platform with GCC toolchain.
 == How to reproduce ==
 We use following user-config.jam
 {{{
    using gcc : 4.9 : arm-linux-androideabi-g++.exe ;
   }}}
 or we tried
 {{{
    using gcc : 4.9 : arm-linux-androideabi-g++.exe : <flavor>android ;
   }}}
 The toolchain is in %PATH%

 Trying to run bjam command:
 {{{#!sh
    b2 --clean-all -d+5 variant=release
 }}}

 Will leads to endless loops in cygwin path resolving:
 {{{#!txt
 (builtin):>>>>|>>>>|>>>>|>>>>|>>>> cygwin.software-registry-value Cygnus
 Solutions\Cygwin\mounts v2\c:/ : native
 (builtin):>>>>|>>>>|>>>>|>>>>|>>>>|> W32_GETREG
 HKEY_CURRENT_USER\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\c:/ : native
 (builtin):>>>>|>>>>|>>>>|>>>>|>>>>|> W32_GETREG
 HKEY_CURRENT_USER\SOFTWARE\Wow6432node\Cygnus Solutions\Cygwin\mounts
 v2\c:/ : native
 (builtin):>>>>|>>>>|>>>>|>>>>|>>>>|> W32_GETREG
 HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\c:/ : native
 (builtin):>>>>|>>>>|>>>>|>>>>|>>>>|> W32_GETREG
 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432node\Cygnus Solutions\Cygwin\mounts
 v2\c:/ : native
 }}}

 == Under the hood ==
 There is new rule (since Boost 1.61)
 {{{
 # Uses -print-prog-name to get the name of the tool.
 # Converts the path to native form if using cygwin.
 rule .get-prog-name ( command-string : tool : flavor ? )
 {
     local prog-name = [ NORMALIZE_PATH [ MATCH "(.*)[\n]+" :
         [ SHELL "$(command-string) -print-prog-name=$(tool)" ] ] ] ;
     if $(flavor) != mingw && [ os.name ] = NT
     {
         prog-name = [ cygwin.cygwin-to-windows-path $(prog-name) ] ;
     }
     return $(prog-name) ;
 }
 }}}

 flavor will be empty or android. And the cygwin path resolution will be
 triggered. Though no Cygwin is used or installed.
 I think this is not a good idea to trigger cygwin specific code but
 checking another falavor. Probably it is better to define `cygwin` flavor
 and check `if $(flavor) = cygwin && [ os.name ] = NT`

 But why the `cygwin.cygwin-to-windows-path` goes to dead loop?

 {{{
 rule cygwin-to-windows-path ( path )
 {
     path = $(path:R="") ; # strip any trailing slash

     local drive-letter = [ SUBST $(path) $(.cygwin-drive-letter-re) $1:/$2
 ] ;
     if $(drive-letter)
     {
         path = $(drive-letter) ;
     }
     else if $(path:R=/x) = $(path) # already rooted?
     {
         # Look for a cygwin mount that includes each head sequence in
 $(path).
         local head = $(path) ;
         local tail = "" ;

         while $(head)
         {
             local root = [ software-registry-value
                 "Cygnus Solutions\\Cygwin\\mounts v2\\"$(head) : native ]
 ;

             if $(root)
             {
                 path = $(tail:R=$(root)) ;
                 head = ;
             }
             tail = $(tail:R=$(head:D=)) ;

             if $(head) = /
             {
                 head = ;
             }
             else
             {
                 head = $(head:D) ;
             }
         }
     }
     return [ regex.replace $(path:R="") / \\ ] ;
 }
 }}}

 `path` is already rooted since it starts with `c:/` and `$(path:R=/x) =
 $(path)` will be true.
 `root` will be empty since not cygwin is involved.
 `head` variable will finally ends equal to `c:/` but never `/` or empty.
 == Possible solutions ==
 So as a quick solution I create a patch for cygwin.jam
 {{{#!diff
 diff -r -u4 a/boost_1_63_0/tools/build/src/tools/cygwin.jam
 b/boost_1_63_0/tools/build/src/tools/cygwin.jam
 --- a/boost_1_63_0/tools/build/src/tools/cygwin.jam Wed Nov 9
 18:10:39 2016
 +++ b/boost_1_63_0/tools/build/src/tools/cygwin.jam Fri Dec 23
 15:53:29 2016
 @@ -59,9 +59,9 @@
                  head = ;
              }
              tail = $(tail:R=$(head:D=)) ;

 - if $(head) = /
 + if $(head) = "/" || [ MATCH "^([a-zA-Z]:/)$" : $(head) ]
              {
                  head = ;
              }
              else

 }}}
 This will change `cygwin-to-windows-path` behavior to accepts full windows
 path (but not UNC path unfortunately).

 Another, I think better, approach is to introduce cygwin flavor and do
 cygwin specific things only for this flavor. But deeper knowledge is
 required for this (I think there is a reason for introducing mingw flavor
 but not cygwin, and it is necessary to track all dependency)

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/12711>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:20 UTC