Boost C++ Libraries: Ticket #12711: Cross-compiling with GCC on windows will hang due cygwin path resolution https://svn.boost.org/trac10/ticket/12711 <p> Recently, since release 1.61. There were changes in Boost.Build which breaks cross-compilation on windows platform with GCC toolchain. </p> <h2 class="section" id="Howtoreproduce">How to reproduce</h2> <p> We use following user-config.jam </p> <pre class="wiki"> using gcc : 4.9 : arm-linux-androideabi-g++.exe ; </pre><p> or we tried </p> <pre class="wiki"> using gcc : 4.9 : arm-linux-androideabi-g++.exe : &lt;flavor&gt;android ; </pre><p> The toolchain is in %PATH% </p> <p> Trying to run bjam command: </p> <div class="wiki-code"><div class="code"><pre> b2 --clean-all -d+5 <span class="nv">variant</span><span class="o">=</span>release </pre></div></div><p> Will leads to endless loops in cygwin path resolving: </p> <div class="wiki-code"><div class="code"><pre>(builtin):&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt; cygwin.software-registry-value Cygnus Solutions\Cygwin\mounts v2\c:/ : native (builtin):&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt; W32_GETREG HKEY_CURRENT_USER\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\c:/ : native (builtin):&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt; W32_GETREG HKEY_CURRENT_USER\SOFTWARE\Wow6432node\Cygnus Solutions\Cygwin\mounts v2\c:/ : native (builtin):&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt; W32_GETREG HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\c:/ : native (builtin):&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt;&gt;&gt;&gt;|&gt; W32_GETREG HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432node\Cygnus Solutions\Cygwin\mounts v2\c:/ : native </pre></div></div><h2 class="section" id="Underthehood">Under the hood</h2> <p> There is new rule (since Boost 1.61) </p> <pre class="wiki"># 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 &amp;&amp; [ os.name ] = NT { prog-name = [ cygwin.cygwin-to-windows-path $(prog-name) ] ; } return $(prog-name) ; } </pre><p> 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 <code>cygwin</code> flavor and check <code>if $(flavor) = cygwin &amp;&amp; [ os.name ] = NT</code> </p> <p> But why the <code>cygwin.cygwin-to-windows-path</code> goes to dead loop? </p> <pre class="wiki">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="") / \\ ] ; } </pre><p> <code>path</code> is already rooted since it starts with <code>c:/</code> and <code>$(path:R=/x) = $(path)</code> will be true. <code>root</code> will be empty since not cygwin is involved. <code>head</code> variable will finally ends equal to <code>c:/</code> but never <code>/</code> or empty. </p> <h2 class="section" id="Possiblesolutions">Possible solutions</h2> <p> So as a quick solution I create a patch for cygwin.jam </p> <div class="wiki-code"> <div class="diff"> <ul class="entries"> <li class="entry"> <h2> <a>boost_1_63_0/tools/build/src/tools/cygwin.jam</a> </h2> <pre>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</pre> <table class="trac-diff inline" cellspacing="0"> <colgroup> <col class="lineno"/><col class="lineno"/><col class="content"/> </colgroup> <thead> <tr> <th title="File a/boost_1_63_0/tools/build/src/tools/cygwin.jam Wed Nov 9 18:10:39 2016"> a </th> <th title="File b/boost_1_63_0/tools/build/src/tools/cygwin.jam Fri Dec 23 15:53:29 2016"> b </th> <td> <em></em> &nbsp; </td> </tr> </thead> <tbody class="unmod"> <tr> <th>59</th><th>59</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; head = ;</span></td> </tr> <tr> <th>60</th><th>60</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span></td> </tr> <tr> <th>61</th><th>61</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tail = $(tail:R=$(head:D=)) ;</span></td> </tr> <tr> <th>62</th><th>62</th><td class="l"><span></span></td> </tr> </tbody> <tbody class="mod"> <tr class="first"> <th>63</th><th>&nbsp;</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if $(head) = <del>/</del></span></td> </tr> <tr class="last"> <th>&nbsp;</th><th>63</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if $(head) = <ins>"/" || [ MATCH&nbsp; "^([a-zA-Z]:/)$" : $(head) ]</ins></span></td> </tr> </tbody> <tbody class="unmod"> <tr> <th>64</th><th>64</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {</span></td> </tr> <tr> <th>65</th><th>65</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; head = ;</span></td> </tr> <tr> <th>66</th><th>66</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span></td> </tr> <tr> <th>67</th><th>67</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else</span></td> </tr> </tbody> </table> </li> </ul> </div></div><p> This will change <code>cygwin-to-windows-path</code> behavior to accepts full windows path (but not UNC path unfortunately). </p> <p> 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) </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/12711 Trac 1.4.3