|
TABS (Tcl Automated Build System) is a tool for building cookfs, mk4 and zip archives. It is loosely based on idea of SDX (Starkit Developer eXtension) and Makefile-like approach. It is mainly used to create starkits, zipkits, starpacks and cookfs-based archives and binaries. Initially it was developed mainly for cookfs, however, all jobs now support all major archive formats used in Tcl world.
TABS can be downloaded as single file archives in multiple formats - mk4 starkit, zipkit and cookfs based starkit. The most convenient one is zipkit as it can be read by almost all Tcl binaries and distributions - ActiveTcl, tclkit and cookit. All that's needed is to download the archive in preferred format and then run it - for example:
Sample use
$ ./tclkit tabs.tcl wrap -output myapp.run -copy "myapp.vfs/*" -binary ./tclkit
Â
TABS can be used both to run single commands (i.e. wrap, unwrap, split) or can be used to parse Tabsfile and run jobs based on dependencies and targets. Sample above is an example of running a single command from command line - which is similar to how SDX works. It can also be used to build one or more targets by running the make pseudo-job:
Build target from Tabsfile
$ ./tclkit tabs.tcl make myapp.run
Running jobs
One of most common uses of tabs is to run single jobs - same as SDX. First snippet shows how to use tabs for this purpose. Each of the job types has documentation with examples of using specific job. This should help make tabs straightforward to adopt for SDX users.
Aside from slight differences and more verbose parameters, tabs works almost the same as SDX, with the difference that it supports more formats - for example is also a convenient tool to build zip archives.
Creating Tabsfile
This feature is mainly intended for building more complex solutions and requires a bit more effort to get started. However, the benefit is that it allows defining more complex build flows. Tabsfile is a Tcl script that calls target command to define targets to be built. It takes target name and one or more options for this target. Option -body specifies Tcl script to run. For example:
| Sample Tabsfile |
1
2
3
|
target myapp.run -body {
  runjob wrap -output myapp.run -copy "myapp.vfs/*" -binary ./tclkit
}
|
Body of a target can be any code. Calling tabs jobs can be done using runjob command - as shown above.
Â
Unlike with Makefile, name of the target does not have to reflect actual target file name. It is only used to decide order of targets to be built. A target can also build multiple files.
Checking whether a file should be created is always done at job level. In order for tabs to only run specified jobs, flag -checkuptodate needs to be enabled. For example:
| Sample Tabsfile with checking up to date |
1
2
3
|
target myapp.run -body {
  runjob wrap -output myapp.run -copy "myapp.vfs/*" -binary ./tclkit -checkuptodate 1
}
|
This will cause a check to be made each time a binary should be built - output file's modification time will be compared against modification time of each file directly or indirectly under myapp.vfs/ directory. If any of files are newer, binary is rebuilt. If not, it is not built. This allows preventing cases such as rebuilding binaries where nothing changed - this avoids the case where even though nothing changed, binary's contents changes due to rebuilding it. It is especially problematic for systems with automatic updates where such unnecessary operations should be avoided.
Â
Option -depends can be used to specify targets that should be built before this target. For example:
| Sample Tabsfile with dependencies |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
# global variables can be used as common data information
set ::fileinfo {...}
Â
target t-binary-win32.exe -body {
  runjob wrap \
    -checkuptodate 1 \
    -output output/t-binary-win32.exe \
    -binary binaries/win32-x86/cookit-ui.exe \
    -icons {icon/icon16.ico icon/icon24.ico icon/icon32.ico icon/icon48.ico icon/icon64.ico} \
    -fileinfo $::fileinfo \
    -driver cookfs \
    -packages {
      binaries/win32-x86/packages/tls-1.6.cfspkg
      binaries/win32-x86/packages/sqlite3-3.6.23.cfspkg
      binaries/win32-x86/packages/tclx-8.4.cfspkg
    }
}
Â
target binary-win32.exe -depends {t-binary-win32.exe} -body {
  runjob wrap \
    -checkuptodate 1 \
    -output output/binary-win32.exe \
    -binary output/t-binary-win32.exe \
    -driver cookfs \
    -copy {
      {src-binary/* .}
    }
}
Â
|
Example above shows how to build a "template" binary which is then used to build target binary. The idea is that template binary is created with customized icons, resources and additional packages added. This is usually only built once since packages do not change often. Next, target binary is built by only adding source code of the binary - this speeds up build process sine template binary is only built once and target binary is built every time source code changes.
Extending tabs with new jobs
Currently tabs has only few built-in job types, however, it is also possible to extend tabs. All jobs are Tcl packages and snit objects, created as tabs::job::Â name. TABS source code also comes with a sample job. To run it all that's needed is to:
Running sample job
$ ./tclkit tabs.tcl -path sample-jobs sample
Hello world
Â
Option -path sample-jobs tells tabs to look for packages in sample-jobs directory. Jobs are Tcl snit classes that should mainly implement execute method.
Â
The entire job definition for sample is as follows:
| sample-1.0.tm |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
snit::type tabs::job::sample {
  # -manager is needed for internal purposes
  option -manager
Â
  option -message -default "Hello world"
Â
  constructor {args} {
    $self configurelist $args
  }
Â
  method inputs {} {
    # if applicable, return a list of files that are used as input for the job
    return [list]
  }
Â
  method outputs {} {
    # if applicable, return a list of files that are used as input for the job
    return [list]
  }
Â
  method execute {} {
    puts [$self cget -message]
  }
}
|
|