| # This file is used to build the Bionic library with the Jam build | 
 | # tool. For info, see www.perforce.com/jam/jam.html | 
 | # | 
 |  | 
 | BIONIC_TOP ?= $(DOT) ; | 
 |  | 
 | DEBUG = 1 ; | 
 |  | 
 | # pattern used for automatic heade inclusion detection | 
 | HDRPATTERN = "^[ 	]*#[ 	]*include[ 	]*[<\"]([^\">]*)[\">].*$" ; | 
 |  | 
 |  | 
 | # debugging support, simply define the DEBUG variable to activate verbose output | 
 | rule Debug | 
 | { | 
 |     if $(DEBUG) { | 
 |         Echo $(1) ; | 
 |     } | 
 | } | 
 |  | 
 | # return all elements from $(1) that are not in $(2) | 
 | rule Filter  list : filter | 
 | { | 
 |     local result = ; | 
 |     local item ; | 
 |     for item in $(list) { | 
 |         if ! $(item) in $(filter) { | 
 |             result += $(item) ; | 
 |         } | 
 |     } | 
 |     return $(result) ; | 
 | } | 
 |  | 
 |  | 
 | # reverse a list of elements | 
 | rule Reverse  list | 
 | { | 
 |     local  result = ; | 
 |     local  item ; | 
 |  | 
 |     for item in $(list) { | 
 |         result = $(item) $(result) ; | 
 |     } | 
 |     return $(result) ; | 
 | } | 
 |  | 
 |  | 
 | # decompose a path into a list of elements | 
 | rule PathDecompose  dir | 
 | { | 
 |     local  result ; | 
 |  | 
 |     while $(dir:D) | 
 |     { | 
 |         if ! $(dir:BS) {  # for rooted paths like "/foo" | 
 |             break ; | 
 |         } | 
 |         result = $(dir:BS) $(result) ; | 
 |         dir    = $(dir:D) ; | 
 |     } | 
 |     result = $(dir) $(result) ; | 
 |     return $(result) ; | 
 | } | 
 |  | 
 |  | 
 | # simply a file path, i.e. get rid of . or .. when possible | 
 | rule _PathSimplify  dir | 
 | { | 
 |     local  result = ; | 
 |     local  dir2 d ; | 
 |  | 
 |     dir  = [ PathDecompose $(dir) ] ; | 
 |  | 
 |     # get rid of any single dot | 
 |     dir2 = ; | 
 |     for d in $(dir) { | 
 |         if $(d) = "." { | 
 |             continue ; | 
 |         } | 
 |         dir2 += $(d) ; | 
 |     } | 
 |  | 
 |     # get rid of .. when possible | 
 |     for d in $(dir2) { | 
 |         if $(d) = ".." && $(result) { | 
 |             result = $(result[2-]) ; | 
 |         } | 
 |         else | 
 |             result = $(d) $(result) ; | 
 |     } | 
 |  | 
 |     # now invert the result | 
 |     result = [ Reverse $(result) ] ; | 
 |     if ! $(result) { | 
 |         result = "." ; | 
 |     } | 
 |     return $(result:J="/") ; | 
 | } | 
 |  | 
 |  | 
 | rule PathSimplify  dirs | 
 | { | 
 |     local result ; | 
 |     local d ; | 
 |     for d in $(dirs) { | 
 |         result += [ _PathSimplify $(d) ] ; | 
 |     } | 
 |     return $(result) ; | 
 | } | 
 |  | 
 |  | 
 | # retrieve list of subdirectories | 
 | rule ListSubDirs  paths | 
 | { | 
 |     local  result  = ; | 
 |     local  entry ; | 
 |     for entry in [ Glob $(paths) : * ] { | 
 |         if ! $(entry:S) { | 
 |             result += $(entry) ; | 
 |         } | 
 |     } | 
 |     return [ PathSimplify $(result) ] ; | 
 | } | 
 |  | 
 |  | 
 | # retrieve list of sources in a given directory | 
 | rule ListSources  path | 
 | { | 
 |     return [ Glob $(path) : *.S *.c ] ; | 
 | } | 
 |  | 
 |  | 
 | # find the prebuilt directory | 
 | # | 
 | if ! $(TOP) { | 
 |     Echo "Please define TOP as the root of your device build tree" ; | 
 |     Exit ; | 
 | } | 
 |  | 
 | Debug "OS is" $(OS) ; | 
 | Debug "CPU is" $(CPU) ; | 
 |  | 
 | if $(OS) = LINUX | 
 | { | 
 |     PREBUILT = $(TOP)/prebuilt/Linux ; | 
 | } | 
 | else if $(OS) = MACOSX | 
 | { | 
 |     switch $(CPU) { | 
 |         case i386 : PREBUILT = $(TOP)/prebuilt/darwin-x86 ; break ; | 
 |         case ppc  : PREBUILT = $(TOP)/prebuilt/darwin-ppc ; break ; | 
 |         case *    : Echo "unsupported CPU" "$(CPU) !!" ; | 
 |                     Echo "Please contact digit@google.com for help" ; | 
 |                     Exit ; | 
 |     } | 
 | } | 
 | else | 
 | { | 
 |     Echo "Unsupported operating system" $(OS) ; | 
 |     Echo "Please contact digit@google.com for help" ; | 
 |     Exit ; | 
 | } | 
 |  | 
 | Debug "TOP is" $(TOP) ; | 
 | Debug "PREBUILT is" $(PREBUILT) ; | 
 |  | 
 |  | 
 | # check architectures and setup toolchain variables | 
 | # | 
 | SUPPORTED_ARCHS = x86 arm ; | 
 |  | 
 | ARCH ?= $(SUPPORTED_ARCHS) ; | 
 |  | 
 | if ! $(ARCH) in $(SUPPORTED_ARCHS) { | 
 |     Echo "The variable ARCH contains an unsupported value, use one or more of these instead" ; | 
 |     Echo "separated by spaces:" $(SUPPORTED_ARCHS) ; | 
 |     Exit ; | 
 | } | 
 |  | 
 | x86_TOOLSET_PREFIX ?= "" ; | 
 | arm_TOOLSET_PREFIX ?= $(TOP)/prebuilt/Linux/toolchain-4.1.1/bin/arm-elf- ; | 
 |  | 
 | for arch in $(ARCH) { | 
 |     CC_$(arch)  = $($(arch)_TOOLSET_PREFIX)gcc ; | 
 |     C++_$(arch) = $($(arch)_TOOLSET_PREFIX)g++ ; | 
 |     AR_$(arch)  = $($(arch)_TOOLSET_PREFIX)ar ; | 
 | } | 
 |  | 
 |  | 
 | # the list of arch-independent source subdirectories | 
 | BIONIC_SRC_SUBDIRS = string ; | 
 | BIONIC_x86_SUBDIRS = ; | 
 | BIONIC_arm_SUBDIRS = ; | 
 |  | 
 | CFLAGS   = -O0 -g -W ; | 
 |  | 
 |  | 
 |  | 
 | # find sources in a given list of subdirectories | 
 | rule FindSources  dirs | 
 | { | 
 |     local dir ; | 
 |  | 
 |     for dir in $(dirs) | 
 |     { | 
 |         local LOCAL_SRC NO_LOCAL_SRC ; | 
 |  | 
 |         if [ Glob $(dir) : rules.jam ] { | 
 |             include $(dir)/rules.jam ; | 
 |             if $(LOCAL_SRC) { | 
 |                 _sources = $(LOCAL_SRC) ; | 
 |             } | 
 |             else { | 
 |                 _sources = [ Glob $(dir) : *.S *.c ] ; | 
 |                 _sources = $(_sources:BS) ; | 
 |             } | 
 |             if $(NO_LOCAL_SRC) { | 
 |                 _sources = [ Filter $(_sources) : $(NO_LOCAL_SRC) ] ; | 
 |             } | 
 |             sources += $(dir)/$(_sources) ; | 
 |         } | 
 |         else | 
 |             sources += [ ListSources $(dir) ] ; | 
 |     } | 
 | } | 
 |  | 
 | # Compile a given object file from a source | 
 | rule Compile  object : source | 
 | { | 
 |     Depends $(object) : $(source) ; | 
 |     Depends bionic : $(object) ; | 
 |     Clean clean : $(object) ; | 
 |  | 
 |     MakeLocate $(object) : $(OUT) ; | 
 |  | 
 |  | 
 |     CC on $(object)       = $(CC_$(arch)) ; | 
 |     CFLAGS on $(object)   = $(CFLAGS) ; | 
 |     INCLUDES on $(object) = $(INCLUDES) ; | 
 |     DEFINES on $(object)  = $(DEFINES) ; | 
 |  | 
 |     HDRRULE on $(>) = HdrRule ; | 
 |     HDRSCAN on $(>) = $(HDRPATTERN) ; | 
 |     HDRSEARCH on $(>) = $(INCLUDES) ; | 
 |     HDRGRIST on $(>) = $(HDRGRIST) ; | 
 | } | 
 |  | 
 |  | 
 | actions Compile | 
 | { | 
 |     $(CC) -c -o $(1) $(CFLAGS) -I$(INCLUDES) -D$(DEFINES) $(2) | 
 | } | 
 |  | 
 |  | 
 | rule RmTemps | 
 | { | 
 |     Temporary $(2) ; | 
 | } | 
 |  | 
 | actions quietly updated piecemeal together RmTemps | 
 | { | 
 |     rm -f $(2) | 
 | } | 
 |  | 
 | actions Archive | 
 | { | 
 |     $(AR) ru $(1) $(2) | 
 | } | 
 |  | 
 | rule Library  library : objects | 
 | { | 
 |     local  obj ; | 
 |  | 
 |     if ! $(library:S) { | 
 |         library = $(library:S=.a) ; | 
 |     } | 
 |     library = $(library:G=<$(arch)>) ; | 
 |  | 
 |     Depends all : $(library) ; | 
 |  | 
 |     if ! $(library:D) { | 
 |         MakeLocate $(library) $(library)($(objects:BS)) : $(OUT) ; | 
 |     } | 
 |  | 
 |     Depends $(library) : $(library)($(objects:BS)) ; | 
 |     for obj in $(objects) { | 
 |         Depends $(library)($(obj:BS)) : $(obj) ; | 
 |     } | 
 |  | 
 |     Clean clean : $(library) ; | 
 |  | 
 |     AR on $(library) = $(AR_$(arch)) ; | 
 |     Archive $(library) : $(objects) ; | 
 |  | 
 |     RmTemps $(library) : $(objects) ; | 
 | } | 
 |  | 
 |  | 
 | rule  ProcessDir | 
 | { | 
 |     local CFLAGS   = $(CFLAGS) ; | 
 |     local DEFINES  = $(DEFINES) ; | 
 |     local INCLUDES = $(INCLUDES) ; | 
 |     local local_rules = [ Glob $(1) : rules.jam ] ; | 
 |     local source sources ; | 
 |  | 
 |     if $(local_rules) { | 
 |         local LOCAL_CFLAGS LOCAL_DEFINES LOCAL_INCLUDES LOCAL_SRC NO_LOCAL_SRC ; | 
 |  | 
 |         include $(local_rules) ; | 
 |         CFLAGS   += $(LOCAL_CFLAGS) ; | 
 |         DEFINES  += $(LOCAL_DEFINES) ; | 
 |         INCLUDES += $(LOCAL_INCLUDES) ; | 
 |  | 
 |         if $(LOCAL_SRC) { | 
 |             sources = $(LOCAL_SRC) ; | 
 |         } | 
 |         else { | 
 |             sources = [ Glob $(1) : *.S *.c ] ; | 
 |             sources = $(sources:BS) ; | 
 |         } | 
 |  | 
 |         if $(NO_LOCAL_SRC) { | 
 |             sources = [ Filter $(sources) : $(NO_LOCAL_SRC) ] ; | 
 |         } | 
 |  | 
 |         sources = $(1)/$(sources) ; | 
 |     } | 
 |     else | 
 |         sources = [ Glob $(1) : *.S *.c ] ; | 
 |  | 
 |     for source in $(sources) { | 
 |         local name = $(source:B) ; | 
 |  | 
 |         if $(source:S) = ".S" { | 
 |             # record the list of assembler sources | 
 |             ASSEMBLER_SOURCES += $(name) ; | 
 |         } | 
 |         else if $(source:S) = ".c" && $(name) in $(ASSEMBLER_SOURCES) { | 
 |             # skip C source file if corresponding assembler exists | 
 |             continue ; | 
 |         } | 
 |  | 
 |         objname = <$(arch)>$(name).o  ; | 
 |  | 
 |         Compile $(objname) : $(source) ; | 
 |         ALL_OBJECTS += $(objname) ; | 
 |     } | 
 | } | 
 |  | 
 | rule ProcessDirs | 
 | { | 
 |     local  dir ; | 
 |     for dir in $(1) { | 
 |         ProcessDir $(dir) ; | 
 |     } | 
 | } | 
 |  | 
 | INCLUDES_x86 = /usr/src/linux/include ; | 
 |  | 
 | INCLUDES_arm = ../kernel_headers | 
 |                include/arch/arm | 
 |                include/bits32 | 
 |                ; | 
 |  | 
 | INCLUDES = include stdio string stdlib . | 
 |            ../msun/include | 
 |            ; | 
 |  | 
 | DEFINES  = ANDROID_CHANGES | 
 |            USE_LOCKS | 
 |            REALLOC_ZERO_BYTES_FREES | 
 |            _LIBC=1 | 
 |            SOFTFLOAT | 
 |            FLOATING_POINT | 
 |            NEED_PSELECT=1 | 
 |            ANDROID | 
 |            ; | 
 |  | 
 | CFLAGS_x86 = ; | 
 |  | 
 |  | 
 | for arch in $(ARCH) | 
 | { | 
 |     local ARCH_DIR = $(BIONIC_TOP)/arch-$(arch) ; | 
 |     local INCLUDES = $(INCLUDES_$(arch)) $(ARCH_DIR)/include $(INCLUDES) ; | 
 |     local DEFINES  = $(DEFINES_$(arch)) $(DEFINES) ARCH=$(arch)  ; | 
 |     local CFLAGS   = $(CFLAGS) $(CFLAGS_$(arch)) ; | 
 |     local OUT      = out/$(arch) ; | 
 |     local ASSEMBLER_SOURCES ALL_OBJECTS ; | 
 |  | 
 |     ProcessDirs [ ListSubDirs $(ARCH_DIR) ] ; | 
 |     ProcessDirs stdlib stdio unistd string tzcode inet ; | 
 |     ProcessDirs [ ListSubDirs netbsd ] ; | 
 |     ProcessDirs bionic ; | 
 |  | 
 |     Library bionic : $(ALL_OBJECTS) ; | 
 | } | 
 |  | 
 | BIONIC_SEARCH = $(BIONIC_TOP)/include ; | 
 |  | 
 |  | 
 |  | 
 | # /HdrRule source : headers ; | 
 | # | 
 | # Arranges the proper dependencies when the file _source_ includes the files | 
 | # _headers_ through the #include C preprocessor directive | 
 | # | 
 | # this rule is not intendend to be called explicitely. It is called | 
 | # automatically during header scanning on sources handled by the @Object | 
 | # rule (e.g. sources in @Main or @Library rules) | 
 | # | 
 | rule HdrRule | 
 | { | 
 |     # HdrRule source : headers ; | 
 |  | 
 |     # N.B.  This rule is called during binding, potentially after | 
 |     # the fate of many targets has been determined, and must be | 
 |     # used with caution: don't add dependencies to unrelated | 
 |     # targets, and don't set variables on $(<). | 
 |  | 
 |     # Tell Jam that anything depending on $(<) also depends on $(>), | 
 |     # set SEARCH so Jam can find the headers, but then say we don't | 
 |     # care if we can't actually find the headers (they may have been | 
 |     # within ifdefs), | 
 |  | 
 |     local s = $(>:G=$(HDRGRIST:E)) ; | 
 |  | 
 |     Includes $(<) : $(s) ; | 
 |     SEARCH on $(s) = $(HDRSEARCH) ; | 
 |     NoCare $(s) ; | 
 |  | 
 |     # Propagate on $(<) to $(>) | 
 |  | 
 |     HDRSEARCH on $(s) = $(HDRSEARCH) ; | 
 |     HDRSCAN on $(s) = $(HDRSCAN) ; | 
 |     HDRRULE on $(s) = $(HDRRULE) ; | 
 |     HDRGRIST on $(s) = $(HDRGRIST) ; | 
 | } | 
 |  | 
 |  |