Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -23,5 +23,8 @@ build/argon2/src-patched build/argon2/src-patched.new build/argon2/INST build/work build/tcl +build/kits/kitcreator-*.tar.gz +build/kits/kitcreator-build-* +build/kits/tcl-nano-* ADDED build/kits/app/lib/defer/defer.tcl Index: build/kits/app/lib/defer/defer.tcl ================================================================== --- /dev/null +++ build/kits/app/lib/defer/defer.tcl @@ -0,0 +1,96 @@ +namespace eval ::defer { + namespace export defer + + variable idVar "\n" +} + +proc ::defer::with {args} { + if {[llength $args] == 1} { + set varlist [list] + set code [lindex $args 0] + } elseif {[llength $args] == 2} { + set varlist [lindex $args 0] + set code [lindex $args 1] + } else { + return -code error "wrong # args: defer::with ?varlist? script" + } + + if {[info level] == 1} { + set global true + } else { + set global false + } + + # We can't reliably handle cleanup from the global scope, don't let people + # register ineffective handlers for now + if {$global} { + return -code error "defer may not be used from the global scope" + } + + # Generate an ID to un-defer if requested + set id [clock clicks] + for {set i 0} {$i < 5} {incr i} { + append id [expr rand()] + } + + # If a list of variable names has been supplied, slurp up their values + # and add the appropriate script to set those variables in the lambda + ## Generate a list of commands to create the variables + foreach var $varlist { + if {![uplevel 1 [list info exists $var]]} { + continue + } + + if {[uplevel 1 [list array exists $var]]} { + set val [uplevel 1 [list array get $var]] + lappend codeSetVars [list unset -nocomplain $var] + lappend codeSetVars [list array set $var $val] + } else { + set val [uplevel 1 [list set $var]] + lappend codeSetVars [list set $var $val] + } + } + + ## Format the above commands in the structure of a Tcl command + if {[info exists codeSetVars]} { + set codeSetVars [join $codeSetVars "; "] + set code "${codeSetVars}; ${code}" + } + + ## Unset the "args" variable, which is just an artifact of the lambda + set code "# ${id}\nunset args; ${code}" + + # Register our interest in a variable to monitor for it to disappear + + uplevel 1 [list trace add variable $::defer::idVar unset [list apply [list args $code]]] + + return $id +} + +proc ::defer::defer {args} { + set code $args + tailcall ::defer::with $code +} + +proc ::defer::autowith {script} { + tailcall ::defer::with [uplevel 1 {info vars}] $script +} + +proc ::defer::cancel {args} { + set idList $args + + set traces [uplevel 1 [list trace info variable $::defer::idVar]] + + foreach trace $traces { + set action [lindex $trace 0] + set code [lindex $trace 1] + + foreach id $idList { + if {[string match "*# $id*" $code]} { + uplevel 1 [list trace remove variable $::defer::idVar $action $code] + } + } + } +} + +package provide defer 1 ADDED build/kits/app/lib/defer/pkgIndex.tcl Index: build/kits/app/lib/defer/pkgIndex.tcl ================================================================== --- /dev/null +++ build/kits/app/lib/defer/pkgIndex.tcl @@ -0,0 +1,1 @@ +package ifneeded defer 1 [list source [file join $dir defer.tcl]] ADDED build/kits/app/main.tcl Index: build/kits/app/main.tcl ================================================================== --- /dev/null +++ build/kits/app/main.tcl @@ -0,0 +1,27 @@ +#! /usr/bin/env tclsh + +package require starkit +starkit::startup + +apply {{} { + set topdir $::starkit::topdir + + switch -glob -- [info nameofexecutable] { + "*-rpc-client" - "rpc-client" - "rpc-client.*" { + set mode "rpc-client" + } + default { + set mode "node" + + # XXX: Override the built-in log file location + set ::logfd [open node.log a+] + } + } + + package require nano + set nanoVersion [package present nano] + + set nanoDir [file join $topdir lib tcl-nano${nanoVersion}] + + tailcall source [file join $nanoDir bin $mode] +}} ADDED build/kits/make-kit Index: build/kits/make-kit ================================================================== --- /dev/null +++ build/kits/make-kit @@ -0,0 +1,173 @@ +#! /usr/bin/env bash + +kitcreator_version='0.11.0' +kitcreator_tarball="kitcreator-${kitcreator_version}.tar.gz" +kitcreator_url="http://www.rkeene.org/devel/kitcreator-${kitcreator_version}.tar.gz" +kitcreator_sha256='9999f6456e6cefe0db4e37e3945d453e9420c7408ae9014e296a052670395150' + +function download() { + local file hash urls + local authoritativeURL url + local tryDownloadProgram tryDownloadProgramPath + local downloadProgram + local hashMethod checkHash + + file="$1" + hash="$2" + shift 2 + + if [ -f "${file}" ]; then + return 0 + fi + + hashMethod='sha256' + urls=("http://hashcache.rkeene.org/${hashMethod}/${hash}" "$@") + authoritativeURL="${urls[@]: -1}" + + for tryDownloadProgram in wget curl; do + tryDownloadProgramPath="$(command -v "${tryDownloadProgram}" 2>/dev/null)" + + if [ -z "${tryDownloadProgramPath}" ]; then + continue + fi + + if [ -x "${tryDownloadProgramPath}" ]; then + downloadProgram="${tryDownloadProgram}" + + break + fi + done + + case "${downloadProgram}" in + curl) + downloadProgramArgs=(--header "X-Cache-URL: ${authoritativeURL}" --location --insecure --fail --output "${file}.new") + ;; + wget) + downloadProgramArgs=(--header="X-Cache-URL: ${authoritativeURL}" --no-check-certificate --output-document="${file}.new") + ;; + esac + + for url in "${urls[@]}" __fail__; do + rm -f "${file}.new" + + if [ "${url}" = '__fail__' ]; then + return 1 + fi + + "${downloadProgram}" "${downloadProgramArgs[@]}" "${url}" && break + done + + checkHash="$(openssl dgst "-${hashMethod}" "${file}.new" | sed 's@.*= *@@')" + + if [ "${checkHash}" != "${hash}" ]; then + echo "Hash (${hashMethod}) mismatch: Got: ${checkHash}; Expected: ${hash}" >&2 + + return 1 + fi + + mv "${file}.new" "${file}" + + return 0 +} + +function cleanup() { + if [ -n "${workdir}" -a -d "${workdir}" ]; then + rm -rf "${workdir}" + fi +} + +set -e + +topdir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +workdir="$(pwd)/kitcreator-build-$(openssl rand -base64 6 | sed 's@[/+]@X@g')" +trap cleanup EXIT + +# Download KitCreator +download "${kitcreator_tarball}" "${kitcreator_sha256}" "${kitcreator_url}" + +# Extract KitCreator +mkdir "${workdir}" +gzip -dc "${kitcreator_tarball}" | ( + cd "${workdir}" || exit 1 + tar -xf - + shopt -s dotglob + mv */* . + rmdir kitcreator-[0-9]* +) + +# Copy the library into the build system +mkdir "${workdir}/nano" >/dev/null 2>/dev/null || : +mkdir "${workdir}/nano/buildsrc" +( + cd "${topdir}" || exit 1 + find . '(' \ + -path './build/argon2' -o \ + -path './build/argon2/*' -o \ + -path './build/pre.sh' -o \ + -path './build/post.sh' -o \ + ! -path './build/*' \ + ')' -print0 | cpio --quiet -0p "${workdir}/nano/buildsrc" || exit 1 + + cd "${workdir}/nano/buildsrc" || exit 1 + ./build/pre.sh || exit 1 + ./build/post.sh || exit 1 + ./configure || exit 1 + make distclean || exit 1 +) + +# Prepare the build system for the library +( + cd "${workdir}/nano" || exit 1 + + if [ ! -f "build.sh" ]; then + cat << \_EOF_ > build.sh +#! /usr/bin/env bash + +# BuildCompatible: KitCreator + +version="1.0" +configure_extra=(--enable-stubs) + +function preconfigure() { + sed -i 's@stack-protector-all@donot-stack-protector-all@g' configure +} + +function postinstall() { + rm -f "${installdir}/lib/tcl-nano${version}/nano.man" + if [ -f "${installdir}/lib/tcl-nano${version}/nano.lib" -a ! -f "${installdir}/lib/tcl-nano${version}/nano.a" ]; then + mv "${installdir}/lib/tcl-nano${version}/nano.lib" "${installdir}/lib/tcl-nano${version}/nano.a" + fi +} +_EOF_ + chmod +x build.sh + fi +) + +# Copy the application into the kit +mkdir "${workdir}/app" +mkdir "${workdir}/app/in" +( + cp -rp app/* "${workdir}/app/in" || exit 1 + + cd "${workdir}/app" || exit 1 + cat << \_EOF_ > "build.sh" || exit 1 +#! /usr/bin/env bash + +cp -rp in out +_EOF_ + chmod +x build.sh +) + +# Build the kit +( + cd "${workdir}" + + export KITCREATOR_PKGS='nano tcllib udp lmdb app' + ./kitcreator "$@" --enable-kit-storage=cvfs +) + +# XXX:TODO: +platform='linux-x86_64' + +# Copy the kit out +mv "${workdir}"/tclkit-* ./tcl-nano-"${platform}"