# ****************************************************************************** # Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. # # These sources were developed at the Freie Universitaet Berlin, Computer # Systems and Telematics group (http://cst.mi.fu-berlin.de). # ------------------------------------------------------------------------------ # This file is part of FeuerWare. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation, either version 3 of the License, or (at your option) any later # version. # # FeuerWare is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this program. If not, see http://www.gnu.org/licenses/ . # ------------------------------------------------------------------------------ # For further information and questions please use the web site # http://scatterweb.mi.fu-berlin.de # and the mailinglist (subscription via web site) # scatterweb@lists.spline.inf.fu-berlin.de # ****************************************************************************** # $Id$ # # OS specifics # if $(NT) { POSIXSHELL = sh ; NULLDEV = NUL ; CAT = type ; NOARSCAN = true ; # redefine build rules for gcc on NT SUFOBJ = .o ; SUFLIB = .a ; actions As { $(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>) } actions Cc { $(CC) -c -o $(<) $(CCFLAGS) -D$(MODULE_DEFINES) $(CCDEFS) $(CCHDRS) $(>) } rule FDefines { return -D$(<) ; } rule FIncludes { return -I$(<) ; } } else { NULLDEV = /dev/null ; CAT = cat ; RM = rm -rf ; # use english language output for gcc actions Cc { LANG=C $(CC) -c -o $(<) $(CCFLAGS) -D$(MODULE_DEFINES) $(CCDEFS) $(CCHDRS) $(>) } switch $(OS) { case CYGWIN : # archive scanning does not work on cygwin, so leave object files NOARSCAN = true ; } } # # Plausbility checks and defaults # SUFEXE = .elf ; # # Rules and Actions # # # Concatenates path-segments into a OS specific path string # Usage: PATH = [ FPath path-segments ] ; rule FPath { return $(<:J=$(SLASH)) ; } # # Generate object archive actions updated together piecemeal Archive { $(AR) $(ARFLAGS) $(<) $(>) } # # Link target rule Link { # add map file Clean clean : $(<:S=.map) ; # generation of hex file Hexfile $(<:S=.hex) : $(<) ; } actions Link bind NEEDLIBS { echo "Old firmware size:" $(TOOLCHAIN)size $(<) 2> $(NULLDEV) || echo " No old binary for size comparison..." $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) -Wl,--start-group $(NEEDLIBS) $(LINKLIBS) -lm -Wl,--end-group -Wl,-Map=$(<:S=.map) || $(RM) -f $(<) $(<:S=.map) $(<:S=.hex) echo "New firmware size:" $(TOOLCHAIN)size $(<) } # # Clean binaries actions piecemeal together existing Clean { # remove all jam targets $(RM) $(>) } # # Clean binaries regardless of project and board rule Cleanall { } actions Cleanall { echo "> Cleaning binaries" $(RM) bin$(SLASH)* make -C $(TOP)$(SLASH)doc clean } # # Display usage text from manual rule Help { } actions Help { $(CAT) $(TOP)$(SLASH)doc$(SLASH)src$(SLASH)manual$(SLASH)examples$(SLASH)jam-usage.txt } # # Compile documentation rule Doc { } actions Doc { make -C $(TOP)$(SLASH)doc all } # # Generate hex-file from binary rule Hexfile { MakeLocate $(<) : $(LOCATE_TARGET) ; Depends $(<) : $(>) ; SEARCH on $(>) = $(LOCATE_TARGET) ; Clean clean : $(<) ; } actions Hexfile { $(OBJCOPY) -O ihex $(>) $(<) } # # Program binary to target device rule Flash { Depends $(<) : $(>) ; } actions Flash { $(FLASHER) $(FLASHFLAGS) $(>) } # Reset connected sensor node actions Reset { $(RESET) > /dev/null 2>&1 } # # Run debug server rule Debug { Depends $(<) : $(>) ; } actions Debug { $(GDB) $(GDBFLAGS) $(>) } # # Rules for convenient module building & dependency tracking rule Module { local _m = $(<:S=$(SUFLIB)) ; # echo Module Name: $(<) Files: $(>) Dependencies: $(3) ; DEFINED_MODULES += $(_m) ; ModuleFromObjects $(<) : $(>:S=$(SUFOBJ)) ; ObjectsNoDep $(>) ; ModuleDepends $(_m) : $(3) ; if $(_m) in $(USE_MODULES) { UseModule $(_m) ; } } # Add a pre-built library as module # Syntax: BinModule ; rule BinModule { local _m = $(<:S=$(SUFLIB)) ; DEFINED_MODULES += $(_m) ; BINARY_MODULES += $(_m) ; ModuleDepends $(_m) : $(3) ; if $(_m) in $(USE_MODULES) { UseModule $(_m) ; } } rule ModuleDepends { local _m = $(<:S=$(SUFLIB)) ; local _d = $(>:S=$(SUFLIB)) ; # for DEP in $(_d) { Depends $(_m) : $(_d) ; DEPENDS.$(_m) += $(_d) ; # } } rule UseModule { local _m = $(<:S=$(SUFLIB)) ; if $(_m) in $(BINARY_MODULES) { local _l _s ; _l = $(<:S=$(SUFLIB)) ; # name of the library file _s = [ FGristFiles $(_l) ] ; # source MakeLocate $(_l) : $(LOCATE_TARGET) ; # locate to bin directory File $(TARGET_DIR)/$(_l) : $(_s) ; } # echo UseModule $(<) ; if ! $(_m) in $(DEFINED_MODULES) { # echo Module not defined yet. ; USE_MODULES += $(_m) ; } else { LinkLibraries $(TARGET) : $(<) ; local _mdefine = MODULE_$(_m:S=:U) ; if ! $(_mdefine) in $(MODULE_DEFINES) { MODULE_DEFINES += $(_mdefine) ; } # echo Dependencies of $(_m): $(DEPENDS.$(_m)) ; for DEP in $(DEPENDS.$(_m)) { UseModule $(DEP) ; } } } # (slightly modified version of LibraryFromObjects) rule ModuleFromObjects { local _i _l _s ; # Add grist to file names _s = [ FGristFiles $(>) ] ; _l = $(<:S=$(SUFLIB)) ; # Set LOCATE for the library and its contents. The bound # value shows up as $(NEEDLIBS) on the Link actions. # For compatibility, we only do this if the library doesn't # already have a path. if ! $(_l:D) { MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ; } if $(NOARSCAN) { # If we can't scan the library to timestamp its contents, # we have to just make the library depend directly on the # on-disk object files. Depends $(_l) : $(_s) ; } else { # If we can scan the library, we make the library depend # on its members and each member depend on the on-disk # object file. Depends $(_l) : $(_l)($(_s:BS)) ; for _i in $(_s) { Depends $(_l)($(_i:BS)) : $(_i) ; } } Clean clean : $(_l) ; if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; } Archive $(_l) : $(_s) ; if $(RANLIB) { Ranlib $(_l) ; } # If we can't scan the library, we have to leave the .o's around. if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; } } # # Like Objects, but doesn't set dependencies on obj pѕeudotarget. rule ObjectsNoDep { local _i ; for _i in [ FGristFiles $(<) ] { Object $(_i:S=$(SUFOBJ)) : $(_i) ; } } actions ListModules { echo $(MODULE_DEFINES) | tr ' ' '\n' | sort } actions ShowFlags { echo "CCFLAGS: " echo $(CCFLAGS) $(CCDEFS) -D$(MODULE_DEFINES) | tr ' ' '\n ' | sort echo "" | $(CC) -E -dD - }