Home | History | Annotate | Download | only in awk
      1 # Copyright (C) 2010 The Android Open Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #      http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 #
     15 
     16 # This script is used to generate a Makefile fragment that will be evaluated
     17 # at runtime by the NDK build system during its initialization pass.
     18 #
     19 # The purpose of this generated fragment is to define a function, named
     20 # 'cygwin-to-host-path' that will transform a Cygwin-specific path into the
     21 # corresponding Windows specific one, i.e. calling
     22 #
     23 #   $(call cygwin-to-host-path,/cygdrive/c/Stuff/)  --> c:/Stuff
     24 #
     25 # A naive implementation of this function would be the following:
     26 #
     27 #   cygwin-to-host-path = $(shell cygpath -m $1)
     28 #
     29 # Unfortunately, calling 'cygpath -m' from GNU Make is horridly slow and people
     30 # have complained that this was adding several minutes to their builds, even in
     31 # the case where there is nothing to do.
     32 #
     33 # The script expects its input to be the output of the Cygwin "mount" command
     34 # as in:
     35 #
     36 #  C:/cygwin/bin on /usr/bin type ntfs (binary,auto)
     37 #  C:/cygwin/lib on /usr/lib type ntfs (binary,auto)
     38 #  C:/cygwin on / type ntfs (binary,auto)
     39 #  C: on /cygdrive/c type ntfs (binary,posix=0,user,noumount,auto)
     40 #  D: on /cygdrive/d type udf (binary,posix=0,user,noumount,auto)
     41 #
     42 # The script's output will be passed to the GNU Make 'eval' function
     43 # and will look like:
     44 #
     45 #  $(patsubst /%,C:/cygwin/,
     46 #  $(patsubst /usr/bin/%,C:/cygwin/bin/,
     47 #  $(patsubst /usr/lib/%,C:/cygwin/lib/,
     48 #  $(patsubst /cygdrive/C/%,C:/,
     49 #  $(patsubst /cygdrive/D/%,D:/,
     50 #  $(patsubst /cygdrive/c/%,C:/,
     51 #  $(patsubst /cygdrive/d/%,D:/,$1)))))
     52 #
     53 BEGIN {
     54   # setup our count
     55   count = 0
     56 }
     57 
     58 $2 == "on" {
     59     # record a new (host-path,cygwin-path) pair
     60     count ++
     61     host[count] = $1
     62     cygwin[count] = $3
     63 }
     64 
     65 END {
     66     # Drive letters are special cases because we must match both
     67     # the upper and lower case versions to the same drive, i.e.
     68     # if "mount" lists that /cygdrive/c maps to C:, we need to
     69     # map both /cygdrive/c and /cygdrive/C to C: in our final rules.
     70     #
     71     count1 = count
     72     for (nn = 1; nn <= count1; nn++) {
     73         if (!match(host[nn],"^[A-Za-z]:$")) {
     74             # not a driver letter mapping, skip this pair
     75             continue
     76         }
     77         letter = substr(host[nn],1,1)
     78         lo     = tolower(letter)
     79         up     = toupper(letter)
     80 
     81         # If the cygwin path ends in /<lo>, then substitute it with /<up>
     82         # to create a new pair.
     83         if (match(cygwin[nn],"/"lo"$")) {
     84             count++
     85             host[count] = host[nn]
     86             cygwin[count] = substr(cygwin[nn],1,length(cygwin[nn])-1) up
     87             continue
     88         }
     89 
     90         # If the cygwin path ends in /<up>, then substitute it with /<lo>
     91         # to create a new pair.
     92         if (match(cygwin[nn],"/"up"$")) {
     93             count++
     94             host[count] = host[nn]
     95             cygwin[count] = substr(cygwin[nn],1,length(cygwin[nn])-1) lo
     96             continue
     97         }
     98     }
     99 
    100     # We have recorded all (host,cygwin) path pairs,
    101     # now try to sort them so that the ones with the longest cygwin path
    102     # appear first
    103     for (ii = 2; ii <= count; ii++) {
    104         for (jj = ii-1; jj > 0; jj--) {
    105             if (length(cygwin[jj]) > length(cygwin[jj+1])) {
    106                 break;
    107             }
    108             if (length(cygwin[jj]) == length(cygwin[jj+1]) &&
    109                 cygwin[jj] > cygwin[jj+1]) {
    110                 break
    111             }
    112             tmp = cygwin[jj]
    113             cygwin[jj] = cygwin[jj+1]
    114             cygwin[jj+1] = tmp
    115             tmp = host[jj]
    116             host[jj] = host[jj+1]
    117             host[jj+1] = tmp
    118         }
    119     }
    120 
    121     # build/core/init.mk defines VERBOSE to 1 when it needs to dump the
    122     # list of substitutions in a human-friendly format, generally when
    123     # NDK_LOG is defined in the environment
    124     #
    125     # Otherwise, just generate the corresponding Make function definition
    126     #
    127     if (VERBOSE == 1) {
    128         for (nn = 1; nn <= count; nn++) {
    129             printf( "$(info %s => %s)", cygwin[nn], host[nn]);
    130         }
    131     } else {
    132         RESULT = "$1"
    133         for (nn = 1; nn <= count; nn++) {
    134             add_drive_rule(host[nn], cygwin[nn])
    135         }
    136         print RESULT
    137     }
    138 }
    139 
    140 function add_drive_rule (hostpath,cygpath)
    141 {
    142     if (cygpath == "/") {
    143         # Special case for /
    144         RESULT = "$(patsubst /%," hostpath "/%,\n" RESULT ")"
    145         return
    146     }
    147     # default rule otherwise
    148     RESULT = "$(patsubst " cygpath "/%," hostpath "/%,\n" RESULT ")"
    149 }
    150