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