|  | # 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) ; | 
|  | } | 
|  |  | 
|  |  |