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