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