ttask

I've recently updated ttask . It is still a WIP but you may get some use out of it.

I've put some additional information/examples below. Knowing Tcl, you should be able to follow without too much trouble.

The first three examples are taken from the gcc, java, and file-copy documentation. They show the typical regular structure of simple ttaskfile build scripts.

config compFlags {-Wall -O2}

task dep {app build -exe dep}
task build {app build -exe build}
task clean {rmdir build}

project add app -type gcc
app src -add src/*.c
app build -buildDir build -compFlags $compFlags -name my_app
task dep {app build -exe dep}
task comp {app build -exe build}
task clean {rmdir build}

project add app -type java
app src -srcDir src -add my_pkg/*.java
app build -buildDir build
task build {copy build -exe build}
task clean {rmdir build}

project add copy -type file-copy
copy src -add images/*.png -srcDir reports -add *.txt
copy build -buildDir build

The following three build scripts are taken from a small Java project. The project makes use of the JNI and so there is a build script for compiling the Java code and another for compiling a library.

Note the jni task in the library script uses the outOfDate command to check if anything needs to be done when the jni task is run. And if the header file is out of date then the javah tool that is part of the JDK is run to get an updated header file.

The final script for this example is a top level script that uses the other two.

# java app script

task dep {app build -exe dep}
task comp {app build -exe build}
task run {
    cd build
    sys java -Djava.library.path=../../lib/build msgterm.MsgTerm
}
task clean {rmdir build}

project add app -type java
app src -srcDir src -add msgterm/*.java
app build -buildDir build -path build
# library script

config jdkInc /usr/lib/jvm/default-java/include
set app ../app/build

task jni {
    mkdir build
    if {[outOfDate build/msgterm_LibMsgTerm.h $app/msgterm/LibMsgTerm.class]} {
        sys javah -cp $app -d build msgterm.LibMsgTerm} {
    }
}
task dep {lib build -exe dep}
task build {lib build -exe build}
task clean {rmdir build}

project add lib -type gcc
lib src -add src/*.c
lib build -buildDir build -compFlags {-Wall -O2} \
        -incDirs [list $jdkInc $jdkInc/linux build] -name libmsgterm.so
# top level script

config jdkInc /usr/lib/jvm/default-java/include

task dep {app runTask dep; lib runTask dep}
task build {app runTask comp; lib runTask jni; lib runTask build}
task run {app runTask run}
task clean {app runTask clean; lib runTask clean}

project add app -slave app
project add lib -slave lib jdkInc=$jdkInc

The example scripts below are from an FPGA example project that includes a soft core processor, so there is a software related build script, an FPGA related build script, and then a top level script that uses the other two.

All the project does is flash an LED on an FPGA dev board. The files for this project are available at www.p-code.org/s430/s430_examples.html

The gcc build script is cross compiling for the MSP430 ISA, and needs compile flags, link flags, and then because we need to convert the linked file as well, convFlags. When adding source files they are grouped by ID so that different compFlags can be applied.

The FPGA script is longer than the previous scripts. For a start it has two 'project add' commands, one for simulating the FPGA and the other for implementing the FPGA. There are more tasks as well, for example for configuring the FPGA and for programming the non-volatile FPGA configuration memory. There is also a mem task that uses the outOfDate command when generating a memory file from the gcc output file. Also note the configs are using '-from'. This means you can select a value for the configs from the supplied values in the GUI.

Note that in the top level build script, the lower level software build script is referenced twice, once for building the software for simulation (test) and once for implementing the FPGA design. Because FPGA sim can take a loooong time, the software is configured so that the LED flash period is much shorter for simulation, so that simulation times are much reduced.

# software build script

config defines {-DDELAY_MS=500}
config compFlags {-Wall -Os}
set crtCompFlags {-mcpu=430 -mY}
set mainCompFlags "-mcpu=430 -mhwmult=none $defines $compFlags"
set linkFlags {-mcpu=430 -nostartfiles -T ../src/linker.ld}
set convFlags {-O binary}

task build {sw build -exe build}
task clean {rmdir build}

project add sw -type gcc
sw src -id crt -add src/*.s -id main -add src/*.c
sw build -buildDir build -tools msp430-elf-gcc -linkFlags $linkFlags \
        -convFlags $convFlags -name led.bin \
        -id crt -compFlags $crtCompFlags \
        -id main -compFlags $mainCompFlags
# fpga build script

config simulator -from {xilinx-xsim modelsim ghdl}
config devBoard -from {arty de0_nano_soc machxo3_9400}

if {$devBoard eq "arty"} {
    set part xc7a35ticsg324-1L
    set implTools xilinx-vivado
} elseif {$devBoard eq "de0_nano_soc"} {
    set part 5CSEMA4U23C6
    set implTools altera-quartus
} elseif {$devBoard eq "machxo3_9400"} {
    set part LCMXO3LF-9400C-5BG484C
    set implTools lattice-diamond
}
set binFile ../../sw/build/led.bin
set memFile mem_init.vhdl

task mem {
    mkdir build; cd build
    if {[outOfDate $memFile $binFile]} {
        sys memfile -pkg mem_init -width 16 -depth 512 $binFile $memFile
    }
}

task dep {sim build -exe dep}
task comp {sim build -exe build}
task test {sim build -exe test -index 1}
task waves {sim build -exe gui -index 1}

task new {fpga build -exe new}
task impl {fpga build -exe build}
task conv {fpga build -exe conv}
task conf {fpga build -exe conf}
task prog {fpga build -exe prog}

task clean {rmdir build}

set props [list -lib s430 -add lib/s430/src/*.vhdl -lib impl \
        -add build/$memFile -add lib/$devBoard/*.vhdl -lib led -add src/*.vhdl]

project add sim -type $simulator
sim src {*}$props -lib tbmsgs -add lib/tbmsgs/*.vhdl -lib tb -add test/*.vhdl
sim build -buildDir build/sim -libs {s430 impl led tbmsgs tb}

project add fpga -type $implTools
fpga src {*}$props -add impl/$devBoard/*
fpga build -buildDir build/impl -part $part -topLevel led.led -name led
# top level build script

config simulator -from {xilinx-xsim modelsim ghdl}
config devBoard -from {arty de0_nano_soc machxo3_9400}

task test {
    testSw runTask build
    fpga runTask mem
    fpga runTask dep
    fpga runTask comp
    fpga runTask test
}
task impl {
    sw runTask build
    fpga runTask mem
    fpga runTask new
    fpga runTask impl
    fpga runTask conv
}
task conf {fpga runTask conf}
task prog {fpga runTask prog}
task clean {
    sw runTask clean
    fpga runTask clean
}

project add testSw -slave sw defines=-DDELAY_MS=2
project add sw -slave sw
project add fpga -slave fpga simulator=$simulator devBoard=$devBoard

The final example below is from the verification of the processor used in the above example project. Note that there is a project add in a foreach loop, because six different test programs are used in the verification, so there are a total of 7 project adds in this script.

config simulator -from {xilinx-xsim modelsim ghdl}
config index ""
config threads 1

set compFlags {-mcpu=430 -mY}
set linkFlags {-nostartfiles -T ../../test/sw/linker.ld}
set convFlags {-O binary}
set bins {core reg_unary_word reg_unary_byte reg_binary_word reg_binary_byte
        jmp}

task asm {
    foreach bin $bins {
        $bin build -exe build
    }
}
task mem {
    mkdir build/sim; cd build/sim
    foreach bin $bins {
        if {[outOfDate ${bin}_mem.vhdl ../sw/$bin.bin]} {
            sys memfile -pkg ${bin}_mem -width 16 -depth 1024 ../sw/$bin.bin \
                    ${bin}_mem.vhdl
        }
    }
}
task dep {sim build -exe dep}
task comp {sim build -exe build}
task test {sim build -exe test -index $index}
task waves {sim build -exe gui -index $index}
task clean {rmdir build}

foreach bin $bins {
    project add $bin -type gcc
    $bin src -add test/sw/$bin.s
    $bin build -buildDir build/sw -tools msp430-elf-gcc -compFlags $compFlags \
            -linkFlags $linkFlags -convFlags $convFlags -name $bin.bin
}

project add sim -type $simulator
sim src -lib s430 -add src/*.vhdl -lib tbmsgs -add lib/tbmsgs/tbmsgs.vhdl \
        -lib tb -add build/sim/*.vhdl -add test/*.vhdl
sim build -buildDir build/sim -threads $threads -libs {s430 tbmsgs tb}

For ttask, the aim was to put the thinnest layer over the underlying tools. If you take a look at the Tcl files in the ttask tar.gz or zip download you'll see for example the gcc/java/file-copy.tcl files have similarities. The idea is that the tool is modular and you could modify one of these files to suit your needs - see near the bottom of the ttask overview documentation for some more details. Also you can create a new extension from scratch by using one of these files as an example. Note also for example the tar and zip file extensions make use the file-copy extension (and I purposely decided to stick to procedural code rather than using any oo framework).