# -----------------------------------------------------------------------------------------
#
#   jamrules.hammer.inc
#
#   Bob Cook Development, Robotics Library
#   http://www.bobcookdev.com/rl/
#    
#   Implements the base jamrules for HAMMER (Samsung S3C2410A ARM920T) projects.
#
#   Copyright (C) 2009 Bob Cook
#
#       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 2 of the License, or (at your
#       option) any later version.
#     
#       This program 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, write to the Free Software Foundation, Inc., 
#       51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
# -----------------------------------------------------------------------------------------


if $(TRACE) { echo "trace /jamrules.hammer.inc" ; }


# -----------------------------------------------------------------------------------------

rule hammer_executable # name : src | lib | pkg ... ;
{
    if ! $(1[1]) { exit "*** hammer_executable: must have a exe name" ; }
    if   $(1[2]) { exit "*** hammer_executable: must not have extra names" ; }
    if ! $(2[1]) { exit "*** hammer_executable: must have at least one source file" ; }
    
    # override some built-in variables.
    
    local sv_SUFOBJ        = $(SUFOBJ) ;
    local sv_SUFLIB        = $(SUFLIB) ;
    local sv_SUFEXE        = $(SUFEXE) ;
    local sv_SUFMAP        = $(SUFMAP) ;
    local sv_SOURCE_GRIST  = $(SOURCE_GRIST) ;
    local sv_LOCATE_TARGET = $(LOCATE_TARGET) ;
    
    SUFOBJ = .o ;
    SUFLIB = .a ;
    SUFEXE = ;
    SUFMAP = .map ;

    # look for headers in the current dir as well as the top dir
        
    HAMMER_INCDIR  = [ FSubDirPath TOP ] ;
    HAMMER_INCDIR += $(SUBDIR) ;
    
    # sort the input files
    
    local f, sources, libs, packages ;
    
    sources  = ;
    libs     = ;
    packages = ;

    for f in $(2)
    {
        switch $(f:S)
        {
            case .c   : sources  += $(f) ;
            case .cpp : sources  += $(f) ;
            case .S   : sources  += $(f) ;
            case .lib : libs     += $(f) ;
            case .pkg : packages += $(f) ;
            case *    : exit "*** hammer_executable: unrecognized suffix $(f:S)" ;
        }
    }
    
    # set up the required libraries from libs

    local l ;
        
    for l in $(libs) 
    {
        HAMMER_LIBS += $(l:B) ;
    }
    
    # build the object files from local sources
    
    local grist_obj = ;
    
    LOCATE_TARGET = [ FSubDirPath TOP $(SUBDIR_TOKENS) gen ] ;
    SEARCH_SOURCE = $(SUBDIR) ;
    SOURCE_GRIST  = $(sv_SOURCE_GRIST) ;
    hammer_objects $(sources) ;
    
    grist_obj += [ FGristFiles $(sources:BS=$(SUFOBJ)) ] ;
    
    # build the object files from pkg sources
    
    for p in $(packages)
    {
        PKG_SOURCES = ;
        IncludePackage $(p) ;
        
        LOCATE_TARGET = [ FSubDirPath TOP $(SUBDIR_TOKENS) gen $(p) ] ;
        SEARCH_SOURCE = [ PackageDirFromNameVar $(p) ] ;
        SOURCE_GRIST  = $(sv_SOURCE_GRIST)!$(p) ;
        hammer_objects $(PKG_SOURCES) ;
        
        grist_obj += [ FGristFiles $(PKG_SOURCES:BS=$(SUFOBJ)) ] ;
    }
    
    # build the executable target
    
    LOCATE_TARGET = [ FSubDirPath TOP $(SUBDIR_TOKENS) bin ] ;
    hammer_executable_from_objects $(1[1]) : $(grist_obj) ;

    # restore the modified variables.
    
    SUFOBJ        = $(sv_SUFOBJ) ;
    SUFLIB        = $(sv_SUFLIB) ;
    SUFEXE        = $(sv_SUFEXE) ;
    SUFMAP        = $(sv_SUFMAP) ;
    SOURCE_GRIST  = $(sv_SOURCE_GRIST) ;
    LOCATE_TARGET = $(sv_LOCATE_TARGET) ;
}


# -----------------------------------------------------------------------------------------

rule hammer_executable_from_objects # name : gristed_obj ;
{
    local exename linkmap listing ;
    
    exename   = [ FAppendSuffix $(1) : $(SUFEXE) ] ;
    linkmap   = [ FAppendSuffix $(1) : $(SUFMAP) ] ;
    listing   = [ FAppendSuffix $(1) : .listing  ] ;

    if $(exename) != $(1)
    {
        Depends $(1) : $(exename) ;
        NotFile $(1) ;
    }

    Depends exe        : $(exename) $(listing) $(texthex) ;
    Depends $(exename) : $(2) ;
    Depends $(linkmap) : $(exename) ;
    Depends $(listing) : $(exename) ;

    MakeLocate $(exename) : $(LOCATE_TARGET) ;
    MakeLocate $(linkmap) : $(LOCATE_TARGET) ;
    MakeLocate $(listing) : $(LOCATE_TARGET) ;
    
    Clean clean : $(exename) $(linkmap) $(listing) ;

    HAMMER_LINKMAP on $(exename) = [ FDirName $(LOCATE_TARGET) $(linkmap) ] ;
    hammer_link $(exename) : $(2) ;
    
    SEARCH       on $(exename) = $(LOCATE_TARGET) ;
    HAMMER_OPTIM on $(exename) = -Os ;

    hammer_list_from_executable $(listing) : $(exename) ;
}


# -----------------------------------------------------------------------------------------

rule hammer_objects # src ;
{
    local s ;
    
    for s in $(1)
    {
        local o = [ FGristFiles $(s:BS=$(SUFOBJ)) ] ;
        hammer_object $(o) : $(s) ;
        Depends obj : $(o) ;
    }
}


# -----------------------------------------------------------------------------------------

rule hammer_object # obj : src ;
{
    Clean clean : $(1) ;

    MakeLocate $(1) : $(LOCATE_TARGET) ;
    SEARCH on $(2) = $(SEARCH_SOURCE) ;

    HDRS on $(1) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
    HAMMER_INCDIR on $(1) = $(SEARCH_SOURCE) $(HAMMER_INCDIR) ;

    HDRRULE on $(2) = HdrRule ;
    HDRSCAN on $(2) = $(HDRPATTERN) ;
    HDRSEARCH on $(2) = $(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HAMMER_INCDIR) ;
    HDRSEARCH on $(2) += "$(HAMMER_TOOLS_PATH)/usr/lib/gcc/arm-linux-uclibc/4.2.1" ;

    HDRGRIST on $(2) = $(HDRGRIST) ;

    DEFINES on $(1) += $(DEFINES) ;
    
    switch $(2:S)
    {
        case .c   : hammer_cc  $(1) : $(2) ;
        case .cpp : hammer_c++ $(1) : $(2) ;
        case .S   : hammer_as  $(1) : $(2) ;
        case *    : exit "*** hammer_object: unrecognized suffix $(2:S)" ;
    }
    
    Depends $(1) : $(2) ;
}


# -----------------------------------------------------------------------------------------

