diff --git a/src/tools/cygwin.jam b/src/tools/cygwin.jam new file mode 100644 index 0000000..d7872cc --- /dev/null +++ b/src/tools/cygwin.jam @@ -0,0 +1,74 @@ +# Copyright 2004 Vladimir Prus. +# Copyright 2016 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +# Provides utility functions for handling cygwin paths + +import regex ; + +.cygwin-drive-letter-re = ^/cygdrive/([a-z])/(.*) ; + +# Like W32_GETREG, except prepend HKEY_CURRENT_USER\SOFTWARE and +# HKEY_LOCAL_MACHINE\SOFTWARE to the first argument, returning the first result +# found. Also accounts for the fact that on 64-bit machines, 32-bit software has +# its own area, under SOFTWARE\Wow6432node. +# +local rule software-registry-value ( path : data ? ) +{ + local result ; + for local root in HKEY_CURRENT_USER HKEY_LOCAL_MACHINE + { + for local x64elt in "" Wow6432node\\ # Account for 64-bit windows + { + if ! $(result) + { + result = [ W32_GETREG $(root)\\SOFTWARE\\$(x64elt)$(path) : $(data) ] ; + } + } + + } + return $(result) ; +} + +# :W only works in Cygwin builds of bjam. This one works on NT builds as well. +# +local 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="") / \\ ] ; +} diff --git a/src/tools/gcc.jam b/src/tools/gcc.jam index e94eced..0f346a5 100644 --- a/src/tools/gcc.jam +++ b/src/tools/gcc.jam @@ -12,6 +12,7 @@ import "class" : new ; import common ; +import cygwin ; import feature ; import fortran ; import generators ; @@ -231,13 +232,9 @@ rule init ( version ? : command * : options * ) # programs as needed to prefer using their installation specific versions. # This is essential for correct use of MinGW and for cross-compiling. - local nl = " -" ; - # - Archive builder. local archiver = [ common.get-invocation-command gcc - : [ NORMALIZE_PATH [ MATCH "(.*)[$(nl)]+" : - [ SHELL "$(command-string) -print-prog-name=ar" ] ] ] + : [ .get-prog-name $(command-string) : ar : $(flavor) ] : [ feature.get-values : $(options) ] : $(bin) : search-path ] ; @@ -249,8 +246,7 @@ rule init ( version ? : command * : options * ) # - Ranlib. local ranlib = [ common.get-invocation-command gcc - : [ NORMALIZE_PATH [ MATCH "(.*)[$(nl)]+" : - [ SHELL "$(command-string) -print-prog-name=ranlib" ] ] ] + : [ .get-prog-name $(command-string) : ranlib : $(flavor) ] : [ feature.get-values : $(options) ] : $(bin) : search-path ] ; @@ -286,6 +282,19 @@ if [ os.name ] = NT JAMSHELL = % ; } +# 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) ; +} + generators.register-c-compiler gcc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : gcc ; generators.register-c-compiler gcc.compile.c.preprocess : C : PREPROCESSED_C : gcc ; generators.register-c-compiler gcc.compile.c++ : CPP : OBJ : gcc ;