#--------------------------------------------------------------------
#   makeunix.tcl
#   ============
#   Functions to generate GNU Make files. Is included in makemake.tcl.
#   (C) 2000 A.Weissflog
#--------------------------------------------------------------------

global src_list 

#--------------------------------------------------------------------
#   gen_module_make
#   Write the statements to compile the files that define a module
#   into the makefile.
#   04-Mar-00   floh    created
#   11-Mar-00   floh    + generate depend list for each source file
#   12-Mar-00   floh    + ignore redundant sources across multiple
#                         modules
#--------------------------------------------------------------------
proc gen_module_make {name type cid} {
    global mod
    global num_mods
    global src_list
    
    # get array index of module
    set i [findmodbyname $name]

    # write source file statements...
    for {set j 0} {$j < [llength $mod($i,objs)]} {incr j} {
        set cur_obj [lindex $mod($i,objs) $j]
        set cur_src [lindex $mod($i,srcs) $j]
        # ignore redundant sources
        if {[lsearch $src_list $cur_src] == -1} {
            lappend src_list $cur_src
            puts $cid "$cur_obj : $cur_src $mod($i,deps,$cur_src)" 
            set more_syms ""
            if {$type == "package"} {
                set more_syms "\$(SYM_OPT)N_STATIC \$(SYM_OPT)N_INIT=n_init_$name \$(SYM_OPT)N_FINI=n_fini_$name \$(SYM_OPT)N_NEW=n_new_$name \$(SYM_OPT)N_VERSION=n_version_$name \$(SYM_OPT)N_INITCMDS=n_initcmds_$name"
            }
            puts $cid "\t\$(CC) \$(CC_OPT)\$< \$(OBJ_OPT)\$@ \$(NOLINK_OPT) \$(CFLAGS) $more_syms"
        }
    }

    # write version file statement
    if {$mod($i,version) != ""} {
        # create fake .obj name to force compilation! 
        set cur_file "$mod($i,dir)/$mod($i,version)"
        set cur_obj "$cur_file\$(OBJ)"
        set cur_src "$cur_file.cc"
        puts $cid "$cur_obj : $cur_src" 
        puts $cid "\t\$(CC) \$(CC_OPT)\$< \$(OBJ_OPT)\$@ \$(NOLINK_OPT) \$(CFLAGS)"
    }
}

#--------------------------------------------------------------------
#   gen_target_make
#   Generate *.mak file for given target.
#
#   TODO:
#   - handle platform specific targets (ndxinputserver...)
#   - handle rsrc files
#   - cvs handling
#   12-Mar-00   floh    added target dependencies to Make dependency
#                       list
#   20-Mar-00   floh    + generate package toc file in build process
#--------------------------------------------------------------------
proc gen_target_make {name cid} {
    global mod
    global num_mods
    global tar
    global num_tars

    set i [findtargetbyname $name]

    # handle platform specific targets
    if {$tar($i,platform) != "all"} {
        if {$tar($i,platform) == "win32"} {
            puts $cid "ifeq (\$(N_PLATFORM),__WIN32__)"
        } elseif {$tar($i,platform) == "unix"} {
            puts $cid "ifeq (\$(N_PLATFORM),__LINUX__)"
        }
    }

    # write modules
    for {set j 0} {$j < [llength $tar($i,mods)]} {incr j} {
        gen_module_make [lindex $tar($i,mods) $j] $tar($i,type) $cid
    }

    # TODO: compile resource files

    # collect all source files that make up the target
    set files ""
    for {set j 0} {$j < [llength $tar($i,mods)]} {incr j} {
        set m [findmodbyname [lindex $tar($i,mods) $j]]
        addtolist files $mod($m,objs)
        if {$tar($i,type) != "exe"} {
            addtolist files "$mod($m,dir)/$mod($m,version)\$(OBJ)"
        }
        if {$tar($i,type) == "package"} {
            addtolist files "packages/$name\$(OBJ)"
        }
        # FIXME: resource files
    }

    # generate list of link libs for that target
    set libs_win32 ""
    for {set j 0} {$j < [llength $tar($i,libs_win32)]} {incr j} {
        addtolist libs_win32 "\$(LIB_OPT)[lindex $tar($i,libs_win32) $j]"
    }
    set libs_unix ""
    for {set j 0} {$j < [llength $tar($i,libs_unix)]} {incr j} {
        addtolist libs_unix "\$(LIB_OPT)[lindex $tar($i,libs_unix) $j]"
    }

    # generate list of target dependencies for that target
    set dep_win32 ""
    set dep_unix  ""
    for {set j 0} {$j < [llength $tar($i,depends)]} {incr j} {
        set dtar [lindex $tar($i,depends) $j]
        set d [findtargetbyname $dtar]
        if {$tar($d,platform)=="all"} {
            addtolist dep_win32 $dtar
            addtolist dep_unix  $dtar
        } elseif {$tar($d,platform)=="win32"} {
            addtolist dep_win32 $dtar
        } elseif {$tar($d,platform)=="unix"} {
            addtolist dep_unix $dtar
        }
    }

    # package specific stuff
    if {$tar($i,type) == "package"} {
        # write compile statement for package.cc file into Makefile
        puts $cid "packages/$name\$(OBJ) : packages/$name.cc" 
        puts $cid "\t\$(CC) \$(CC_OPT)\$< \$(OBJ_OPT)\$@ \$(NOLINK_OPT) \$(CFLAGS)"
    }

    # compile target itself
    if {$tar($i,type) == "dll"} {
        # FIXME: Libs!
        set t "\$(DLL_PRE)$name\$(DLL_POST)"
        set tarpath "\$(N_TARGETDIR)$t"
        puts $cid "ifeq (\$(N_COMPILER),__VC__)"
        puts $cid "$name : $dep_win32 $tarpath"
        puts $cid "$tarpath : $files"
        puts $cid "\t\$(LD) \$^ /OUT:\$@ \$(LFLAGS) \$(LIBDIR) \$(LIBS) $libs_win32 /DLL"
        puts $cid "else"
        puts $cid "$name : $dep_unix $tarpath"
        puts $cid "$tarpath : $files"
        puts $cid "\t\$(CC) \$^ -o \$@ \$(CFLAGS) \$(LIBDIR) \$(LIBS) $libs_unix -shared"
        puts $cid "endif"
    } elseif {$tar($i,type) == "package"} {
        # FIXME: Libs!
        set t "\$(DLL_PRE)$name\$(DLL_POST)"
        set tarpath "\$(N_TARGETDIR)$t"
        puts $cid "ifeq (\$(N_COMPILER),__VC__)"
        puts $cid "$name : $dep_win32 $tarpath"
        puts $cid "$tarpath : $files"
        puts $cid "\t\$(LD) \$^ /OUT:\$@ \$(LFLAGS) \$(LIBDIR) \$(LIBS) $libs_win32 /DLL"
        puts $cid "\t-\$(TCL) gentocfile.tcl $tar($i,name) win32"
        puts $cid "else"
        puts $cid "$name : $dep_unix $tarpath"
        puts $cid "$tarpath : $files"
        puts $cid "\t\$(CC) \$^ -o \$@ \$(CFLAGS) \$(LIBDIR) \$(LIBS) $libs_unix -shared"
        puts $cid "\t-\$(TCL) gentocfile.tcl $tar($i,name) linux"
        puts $cid "endif"
    } elseif {$tar($i,type) == "exe"} {
        set t "$name\$(EXE)"
        set tarpath "\$(N_TARGETDIR)$t"
        puts $cid "ifeq (\$(N_COMPILER),__VC__)"
        puts $cid "$name : $dep_win32 $tarpath"
        puts $cid "$tarpath : $files"
        puts $cid "\t\$(LD) \$^ /OUT:\$@ \$(LFLAGS) \$(LIBDIR) \$(LIBS) $libs_win32"
        puts $cid "else"
        puts $cid "$name : $dep_unix $tarpath"
        puts $cid "$tarpath : $files"
        puts $cid "\t\$(CC) \$^ -o \$@ \$(LIBDIR) \$(LIBS) $libs_unix"
        puts $cid "\tmv \$@ \$(N_TARGETDIR)$name"
        puts $cid "endif"
    }

    # handle platform specific targets
    if {$tar($i,platform) != "all"} {
        puts $cid "endif"
    }
}

#--------------------------------------------------------------------
#   gen_makefile
#   Generate a Makefile for a list of targets.
#   12-Mar-00   floh    code to ignore redundant sources across
#                       modules within identical makefile
#--------------------------------------------------------------------
proc gen_makefile {name list_of_targets} {
    global tar
    global num_tars
    global farwest_home
    global src_list

    puts "Generating makefile $name.mak..."

    # clear global list of sources (for redundancy check) 
    set src_list ""

    # for each package target, generate a package.cc file
    # and a platform specific global dependency list
    set tarlist_win32 ""
    set tarlist_unix  ""
    for {set i 0} {$i < [llength $list_of_targets]} {incr i} {
        set t [findtargetbyname [lindex $list_of_targets $i]]
        if {$tar($t,type) == "package"} {
            genpacksrc $tar($t,name)
        }
        if {$tar($t,platform)=="all"} {
            addtolist tarlist_win32 $tar($t,name)
            addtolist tarlist_unix $tar($t,name)
        } elseif {$tar($t,platform)=="win32"} {
            addtolist tarlist_win32 $tar($t,name)
        } elseif {$tar($t,platform)=="unix"} {
            addtolist tarlist_unix $tar($t,name)
        } else {
            puts "ERROR: UNKNOWN PLATFORM $tar($t,platform) IN TARGET $tar($t,name)!"
            exit
        }
    }

    set cid [open $farwest_home/code/src/$name.mak w]

    puts $cid "#--------------------------------------------------------------------"
    puts $cid "#    $name.mak"
    puts $cid "#    MACHINE GENERATED, DON'T EDIT!"
    puts $cid "#--------------------------------------------------------------------"
    puts $cid ""
    puts $cid "ifeq (\$(N_PLATFORM),__WIN32__)"
    puts $cid "$name: $tarlist_win32"
    puts $cid "endif"
    puts $cid "ifeq (\$(N_PLATFORM),__LINUX__)"
    puts $cid "$name: $tarlist_unix"
    puts $cid "endif"
    puts $cid ""
    for {set i 0} {$i < [llength $list_of_targets]} {incr i} {
        gen_target_make [lindex $list_of_targets $i] $cid
    }
    close $cid

    puts "...done generating $name.mak."
}

#--------------------------------------------------------------------
#   EOF
#--------------------------------------------------------------------

