Provided by: critcl_3.1.9-1_all bug

NAME

       critcl_use - Using Critcl

DESCRIPTION

       Welcome  to the C Runtime In Tcl, CriTcl for short, a system to build C extension packages
       for Tcl on the fly, from C code embedded within Tcl scripts, for  all  who  wish  to  make
       their code go faster.

       This  document  is a (hopefully) gentle introduction to Critcl by way of a series of small
       examples.

       Readers which came directly to this document through a search or similar, and are thus  in
       need  of  an  overview of the whole system, are advised to read the Introduction To CriTcl
       first.

       The examples here cover both how to embed C into  Tcl  with  it,  and  how  to  build  the
       distributable  packages.   As such the intended audience are both writers of packages with
       embedded C, and people building such packages.  To make things easier the two themes  each
       have  their  own  section  in this document, enabling all readers to quickly skip the part
       they are not interested in.

       The sources of Critcl, should you have gotten them, contain several larger examples  show-
       casing various aspects of the system. These demonstration packages can all be found in the
       sub-directory "examples/" of the sources.

EMBEDDING C

       This is the section for developers writing, or wishing to write,  a  package  embedding  C
       into Tcl via critcl.

       I  guess that we are allowed to asssume that you, gentle reader, are here because you have
       written some Tcl code which is not fast enough (any more) and you  wish  to  make  it  "go
       faster" by replacing parts (or all) of it with speedy C.

       Another,  and  I  believe  reasonable  assumption  to  make would be that you have already
       investigated and ruled out or done things like changes to data structures  and  algorithms
       which  reduce O(n*n) work to O (n*log n), O(n), or even O(1).  Of course, nothing prevents
       you from forging ahead here even if you have not done such. Still, even  in  that  case  I
       would recommend that you consider investigating this line of making your code go faster as
       well.

       Now, with these introductory words out of the way, lets jump into the meat of things.

   A SIMPLE PROCEDURE
       Starting simple, let us assume that the Tcl code in question is something like
              proc math {x y z} {
              return [expr {(sin($x)*rand())/$y**log($z)}]
              }
       with the expression pretending to be something very complex and slow. Converting this to C
       we get:
              package require critcl
              critcl::cproc math {double x double y double z} double {
              double up   = rand () * sin (x);
              double down = pow(y, log (z);
              return up/down;
              }
       Notable about this translation:

       [1]    All the arguments got type information added to them, here "double".  Like in C the
              type precedes the  argument  name.  Other  than  that  it  is  pretty  much  a  Tcl
              dictionary, with keys and values swapped.

       [2]    We now also have to declare the type of the result, here "double", again.

       [3]    The  reference  manpage  lists  all  the  legal  C types supported as arguments and
              results.

   HANDLING A VARIABLE NUMBER OF ARGUMENTS
       In A Simple Procedure we demonstrated how easy a translation to C can be. Is it  still  as
       easy  when  we  introduce  something moderately complex like handling a variable number of
       arguments ? A feature which is  needed  to  handle  commands  with  options  and  optional
       arguments  ?  Unfortunately not.  We can use critcl::cproc only if the number of arguments
       is known beforehand, i.e. at the time of declaration. This of course also means that  they
       do not support default arguments either.

       Thus, to handle something like the example below
              proc math {args} {
              set sum 0
              foreach y { set sum [expr {$sum + $y}] }
              return $sum
              }
       we have to use critcl::ccommand instead.

       Its  advantage:  Access to the low-level C arguments representing the Tcl arguments of the
       command.  That allows things  like  variable  number  of  arguments,  optional  arguments,
       options, etc.

       Its  disadvantage:  Access  to the low-level C arguments representing the Tcl arguments of
       the command.  Where critcl::cproc handles the task of converting from Tcl to C values (for
       arguments) and back (for the result), with critcl::commands we have to do this on our own.

       Here is the translation of the example:
              package require critcl
              critcl::ccommand math {cd ip oc ov} {
              double sum = 0;
              double y;
              while (oc) {
              if (Tcl_GetDoubleFromObj (ip, ov[oc], &y) != TCL_OK) {
              return TCL_ERROR;
              }
              sum += y;
              oc --;
              }
              Tcl_SetObjResult (ip, Tcl_NewDoubleObj (sum));
              return TCL_OK:
              }
       Notable about this translation:

       [1]    As  promised/threatened,  all  the  conversions  between  the Tcl and C domains are
              exposed, and the developer should know her way around Tcl's C API.

       [2]    The four arguments "cd ip oc ov" are our names for the low-level arguments holding

              [1]    ClientData (reference)

              [2]    Tcl_Interp (reference)

              [3]    Number of arguments, and

              [4]    Array of argument values, each a Tcl_Obj*.

              This list of arguments, while not optional in  itself,  is  allowed  to  be  empty,
              and/or to contain empty strings as argument names. If we do that critcl will supply
              standard names for the missing pieces, namely:

              [1]    clientdata

              [2]    interp

              [3]    objc

              [4]    objv

   DATA AS A TCL COMMAND
       Here we assume that we have a Tcl procedure which returns a fixed  string.  In  the  final
       product we are going to C to hide this string from the casual user.
              proc somedata {} {
              return {... A large blob of characters ...}
              }
       The translation of this is simple and easy:
              package require critcl
              critcl::cdata somedata {... A large blob of characters ...}
       There is nothing really notable here.

   BLOCKS OF ARBITRARY C
       Often just defining Tcl commands in C, as demonstrated in the sections A Simple Procedure,
       Handling A Variable Number Of Arguments, and Data As A Tcl Command is not  really  enough.
       For  example  we may have several of our new C commands using the same code over and over,
       and we wish avoid this duplication. Or we wish to pull  in  declarations  and  definitions
       from some external library.

       In  both  cases  we require the ability to embed an unstructured block of C code which can
       contain whatever we want, defines, functions, includes, etc. without being  directly  tied
       to  Tcl commands.  The command critcl::code provides us with exactly that.  As our example
       now an excerpt taken from real code, the top of the "sha1c.tcl" critcl file  in  the  sha1
       module of Tcllib:
              critcl::ccode {
              #include "sha1.h"
              #include <stdlib.h>
              #include <assert.h>
              static
              Tcl_ObjType sha1_type; /* fast internal access representation */
              static void
              sha1_free_rep(Tcl_Obj* obj)
              {
              SHA1_CTX* mp = (SHA1_CTX*) obj->internalRep.otherValuePtr;
              Tcl_Free(mp);
              }
              }
       We  see here the beginning of the C code defining a custom Tcl_ObjType holding the data of
       a SHA1 context used during the incremental calculation of sha1 hashes.

   LIFTING CONSTANTS
       When writing a critcl-based package to make a third-party library available to scripts  we
       do  not only have to make the relevant functions available as commands, often we also have
       to know all the various constants, flags, etc. these functions take.

       Rather than writing such magic numbers directly we would greatly prefer  to  use  symbolic
       names  instead.   Instead  of  providing  one  or  more commands to list and map the magic
       numbers to strings critcl only provides a single command which  allows  the  export  of  C
       defines  and  enumeration  values, mapping them to Tcl variables of the given names, whose
       values are the associated magic numbers.

       This is good enough because the developers of the third-party  library  were  very  likely
       like us and wanted to use symbolic names instead of magic numbers. Which in C are declared
       as via defines and enumeration types. We just have to lift them up.

       Our example comes from cryptkit, a Tcl binding to cryptlib, a cryptography  library.   The
       command
              critcl::cdefines CRYPT_* ::crypt
       maps  all  Cryptlib specific #defines and enums into the namespace ::crypt, telling critcl
       to create aliases to the symbols.

       Similarly
              critcl::cdefines {
              NULL
              TRUE
              FALSE
              TCL_OK
              TCL_ERROR
              } ::crypt
       maps the listed defines into the namespace ::crypt.

       An important thing to note: These commands do not create the defines in the C level.  They
       only  lift  pre-existing  material.   Which  can  come from the headers of the third-party
       library, the usual case, but also from Blocks of arbitrary C.

       A corrollary to the above: What is not where, cannot  be  lifted.  All  listed  names  and
       patterns which have no actual C code declaring them are ignored, i.e. not mapped.

   FINDING HEADER FILES
       A notable thing in the example shown in the section about Blocks of arbitrary C is the
              #include "sha1.h"
       statement.  Where  does this header come from ?  Looking at the Tcllib module we will find
       that the header is actually a sibling to the "sha1c.tcl" file containing  the  embedded  C
       code.   However,  critcl  does  not  know  that.  It  has  to be told.  While without that
       knowledge it will invoke the compiler just fine, the compilation  will  fail  because  the
       header is not on the include paths used by the compiler, and therefore will not be found.

       For  this  we have the critcl::cheaders command. It enables us to either tell the compiler
       the path(s) where the required headers can be found, using
              critcl::cheaders -I/path/to/headers/
       or to tell it directly which headers we are using and where they live:
              critcl::cheaders sha1.h
       And now critcl knows that "sha1.h" is important, and that it lives besides  the  ".critcl"
       file  which  referenced  it  (because  of the relative path used).  Note that this doesn't
       absolve us of the need to "#include" the header through a critcl::ccode block.  This  only
       tells  critcl where it lives so that it can configure the compiler with the proper include
       paths to actually find it on use.

       Further note that a C development environment is usually configured to find all the system
       headers,  obviating  the  need  for a critcl::cheaders declaration when such are used. For
       these a plain "#include" in a critcl::ccode block is good enough.   In  other  words,  the
       second  form  of invoking critcl::cheaders is pretty much only for headers which accompany
       the ".critcl" file.

   SEPARATE C SOURCES
       In all of the examples shown so far the C code was fully embedded  in  a  ".critcl"  file.
       However,  if  the  C part is large it can make sense to break it out of the ".critcl" file
       into one or more separate proper ".c" file(s).

       The critcl::csources command can then be used to make this  code  known  to  the  original
       ".critcl"  file again.  This command accepts the paths to the ".c" files as arguments, and
       glob patterns as well.  Our example comes from the struct::graph package in  Tcllib.   Its
       core C functions are in separate files, and the ".critcl" code then makes them known via:
              namespace eval ::struct {
              # Supporting code for the main command.
              critcl::cheaders graph/*.h
              critcl::csources graph/*.c
              }
       which  tells  critcl  that  these  files  are  in the subdirectory "graph" relative to the
       location of "graph_c.tcl", which is the relevant ".critcl" file.

       This example also demonstrates again the use of critcl::cheaders, which  we  also  saw  in
       section Finding header files.

   FINDING EXTERNAL LIBRARIES
       When  creating  a package exposing some third-party library to Tcl Finding header files is
       only the first part, to  enable  failure-free  compilation.  We  also  have  to  find  the
       library/ies  themselves so that they can be linked to our package. This is described here.
       The last issue, Lifting constants from C to Tcl for the use by scripts  is  handled  in  a
       separate section and example.

       The  relevant  command  is  critcl::clibraries.  Its  basic  semantics  are  like  that of
       critcl::cheaders, i.e. It enables us to tell the linker the  path(s)  where  the  required
       libraries can be found, using
              critcl::clibraries -L/path/to/libraries/
       name them
              critcl::clibraries -lfoo
       or tell it directly which libraries we are using and where they live:
              critcl::clibraries /path/to/library/foo.so
       This last way of using should be avoided however, as it intermingles searching and naming,
       plus the name is platform dependent.

       For OS X we additionally have the critcl::framework command which enables us to  name  the
       frameworks  used  by  our package.  Note that this command can be used unconditionally. If
       the build target is not OS X it is ignored.

   CUSTOMIZING THE COMPILE AND LINK STEPS
       The commands critcl::cflags and critcl::ldflags enable you to provide  custom  options  to
       the compile and link phases for a ".critcl" file.

       This usually becomes necessary if the C code in question comes from an external library we
       are writing a Tcl binding for, with multiple configurations to select, non-standard header
       locations, and other things.  Among the latter, especially platform-specific settings, for
       example byteorder.

       This makes critcl::check an important adjunct command, as this is the API for Checking The
       Environment, and then selecting the compile & link flags to use.

       I currently have no specific example to demonstrate these commands.

   HAVING BOTH C AND TCL FUNCTIONALITY
       Often enough only pieces of a package require recoding in C to boost the whole system. Or,
       alternatively, the package in question consists of a low-level layer C with  a  Tcl  layer
       above encoding policies and routing to the proper low-level calls, creating a nicer (high-
       level) API to the low-level functionality, etc.

       For all of this we have to be able to write a package  which  contains  both  C  and  Tcl,
       nevermind the fact the C parts are embedded in Tcl.

       The  easiest  way  to  structure  such  a  package  is  to have several files, each with a
       different duty. First, a ".critcl" file containing the embedded C, and second one or  more
       ".tcl"  files  providing  the  Tcl  parts.   Then  use the critcl::tsources command in the
       ".critcl" file to link the two parts together, declaring the  ".tcl"  files  as  necessary
       companions of the C part.
              package require critcl
              critcl::tsources your-companion.tcl ; # Companion file to use
       With  a  declaration  as shown above the companion file will be automatically sourced when
       the C parts are made available, thus making the Tcl parts available as well.

   USING C WITH TCL FUNCTIONALITY AS FALLBACK
       There is one special case of Having both C and Tcl functionality which  deserves  its  own
       section.

       The  possibility  of  not  having the fast C code on some platform, and using a slower Tcl
       implementation of the functionality. In other words, a fallback which  keeps  the  package
       working in the face of failure to build the C parts. A more concrete example of this would
       be a module implementing the SHA hash, in both C and Tcl, and using the latter if and only
       if the C implementation is not available.

       There two major possibilities in handling such a situation.

       [1]    Keep  all  the  pieces  separated.  In  that scenario our concrete example would be
              spread over three packages. Two low-level packages sha::c and  sha::tcl  containing
              the  two  implementations of the algorithm, and, thirdly, a coordinator package sha
              which loads either of them, based on availability.

              The Tcllib bundle of packages contains a number  of  packages  structured  in  this
              manner, mostly in the struct module.

              Writing  the  C and Tcl parts should be simple by now, with all the examples we had
              so far. The only non-trivial part is the coordinator, and even that if and only  if
              we  wish to make it easy to write a testsuite which can check both branches, C, and
              Tcl without gymnastics. So, the most basic coordinator would be
              set sha::version 1
              if {[catch {
              package require sha::c $sha::version
              }]} {
              package require sha::tcl $sha::version
              }
              package provide sha $sha::version

              It  tries  to  load  the  C  implementation  first,  and  falls  back  to  the  Tcl
              implementation  if  that  fails.  The  code as is assumes that both implementations
              create exactly the same command names, leaving the caller unaware of the choice  of
              implementations.

              A  concrete  example  of this scheme can be found in Tcllib's md5 package. While it
              actually uses ythe Trf as its accelerator,  and  not  a  critcl-based  package  the
              principle  is the same. It also demonstrates the need for additional glue code when
              the C implementation doesn't exactly match the signature and semantics of  the  Tcl
              implementation.

              This  basic coordinator can be easily extended to try more than two packages to get
              the needed implementation. for example, the C implementation may not just exist  in
              a  sha::c  package,  but  also  bundled  somewhere else. Tcllib, for example, has a
              tcllibc package which bundles all the C parts of its packages which have them in  a
              single binary.

              Another  direction  to  take  it  in  is  to write code which allows the loading of
              multiple implementations at the same time,  and  then  switching  between  them  at
              runtime.  Doing this requires effort to keep the implementations out of each others
              way, i.e. they cannot provide the same command names anymore, and  a  more  complex
              coordinator as well, which is able to map from the public command names to whatever
              is provided by the implementation.

              The main benefit of this extension is that  it  makes  testing  the  two  different
              implementations  easier,  simply  run through the same set of tests multiple times,
              each time with different implementation active. The disadvantage is the  additional
              complexity  of  the  coordinator's internals. As a larger example of this technique
              here  is  the  coordinator  "modules/struct/queue.tcl"  handling  the  C  and   Tcl
              implementations of Tcllib's struct::queue package:
              # queue.tcl --
              #       Implementation of a queue data structure for Tcl.
              package require Tcl 8.4
              namespace eval ::struct::queue {}
              ## Management of queue implementations.
              # ::struct::queue::LoadAccelerator --
              #       Loads a named implementation, if possible.
              proc ::struct::queue::LoadAccelerator {key} {
              variable accel
              set r 0
              switch -exact -- $key {
              critcl {
              # Critcl implementation of queue requires Tcl 8.4.
              if {![package vsatisfies [package provide Tcl] 8.4]} {return 0}
              if {[catch {package require tcllibc}]} {return 0}
              set r [llength [info commands ::struct::queue_critcl]]
              }
              tcl {
              variable selfdir
              if {
              [package vsatisfies [package provide Tcl] 8.5] &&
              ![catch {package require TclOO}]
              } {
              source [file join $selfdir queue_oo.tcl]
              } else {
              source [file join $selfdir queue_tcl.tcl]
              }
              set r 1
              }
              default {
              return -code error "invalid accelerator/impl. package $key: must be one of [join [KnownImplementations] {, }]"
              }
              }
              set accel($key) $r
              return $r
              }
              # ::struct::queue::SwitchTo --
              #       Activates a loaded named implementation.
              proc ::struct::queue::SwitchTo {key} {
              variable accel
              variable loaded
              if {[string equal $key $loaded]} {
              # No change, nothing to do.
              return
              } elseif {![string equal $key ""]} {
              # Validate the target implementation of the switch.
              if {![info exists accel($key)]} {
              return -code error "Unable to activate unknown implementation \"$key\""
              } elseif {![info exists accel($key)] || !$accel($key)} {
              return -code error "Unable to activate missing implementation \"$key\""
              }
              }
              # Deactivate the previous implementation, if there was any.
              if {![string equal $loaded ""]} {
              rename ::struct::queue ::struct::queue_$loaded
              }
              # Activate the new implementation, if there is any.
              if {![string equal $key ""]} {
              rename ::struct::queue_$key ::struct::queue
              }
              # Remember the active implementation, for deactivation by future
              # switches.
              set loaded $key
              return
              }
              # ::struct::queue::Implementations --
              #       Determines which implementations are
              #       present, i.e. loaded.
              proc ::struct::queue::Implementations {} {
              variable accel
              set res {}
              foreach n [array names accel] {
              if {!$accel($n)} continue
              lappend res $n
              }
              return $res
              }
              # ::struct::queue::KnownImplementations --
              #       Determines which implementations are known
              #       as possible implementations.
              proc ::struct::queue::KnownImplementations {} {
              return {critcl tcl}
              }
              proc ::struct::queue::Names {} {
              return {
              critcl {tcllibc based}
              tcl    {pure Tcl}
              }
              }
              ## Initialization: Data structures.
              namespace eval ::struct::queue {
              variable  selfdir [file dirname [info script]]
              variable  accel
              array set accel   {tcl 0 critcl 0}
              variable  loaded  {}
              }
              ## Initialization: Choose an implementation,
              ## most preferred first. Loads only one of the
              ## possible implementations. And activates it.
              namespace eval ::struct::queue {
              variable e
              foreach e [KnownImplementations] {
              if {[LoadAccelerator $e]} {
              SwitchTo $e
              break
              }
              }
              unset e
              }
              ## Ready
              namespace eval ::struct {
              # Export the constructor command.
              namespace export queue
              }
              package provide struct::queue 1.4.2

              In  this  implementation  the  coordinator  renames  the  commands of the low-level
              packages to the public commands, making the future  dispatch  as  fast  as  if  the
              commands had these names anyway, but also forcing a spike of bytecode recompilation
              if switching is ever done at the runtime of an application, and not just  used  for
              testing,  and possibly disrupting introspection by the commands, especially if they
              move between different namespaces.

              A different implementation would be to provide the public  commands  as  procedures
              which  consult  a  variable  to  determine  which  of the loaded implementations is
              active, and then call on its commands. This doesn't disrupt introspection, nor does
              it  trigger bytecode recompilation on switching. But it takes more time to dispatch
              to the actual implementation, in every call of the public API for  the  package  in
              question.

              A concrete example of this scheme can be found in Tcllib's crc32 package.

       [2]    Mix  the  pieces  together. Please note that while I am describing how to make this
              work I strongly prefer and recommend to use the  previously  shown  approach  using
              separate  files/packages.  It  is much easier to understand and maintain. With this
              warning done, lets go into the nuts and bolts.

              If we care only about mode "compile & run" things are easy:
              package require critcl
              if {![critcl::compiling]} {
              proc mycommand {...} {
              }
              } else {
              critcl::cproc mycommand {...} {
              }
              }

              The command critcl::compiling tells us whether we have a compiler available or not,
              and in the latter case we implement our command in Tcl.

              Now what happens when we invoke mode "generate package" ?

   UNLAZY PACKAGES
       By  default  critcl  is  a  bit  inconsistent  between modes "compile & run" and "generate
       package". The result of the latter is a standard Tcl package which loads and  sources  all
       of  its  files  immediately  when  it  is  required. Whereas "compile & run" defers actual
       compilation, linking, and loading until the first time one of  the  declared  commands  is
       actually used, making this very lazy.

       This  behaviour  can  be  quite  unwanted  if Tcl companion files, or other users of the C
       commands use introspection to determine the features they have available. Just using [info
       commands]  doesn't  cut  it, the auto_index array has to be checked as well, making things
       quite inconvenient for the users.

       To fix this issue at the source, instead of in each user, be  it  inside  of  the  package
       itself,  or other packages, we have the command critcl::load.  Used as the last command in
       a ".critcl" file it forces the compile, link,  and  load  trinity,  ensuring  that  all  C
       commands are available immediately.
              package require critcl
              critcl::load ; # Force build and loading.
       Note  that  is  not  allowed, nor possible to use critcl commands declaring anything after
       critcl::load has been called. I.e., code like
              package require critcl
              critcl::load ; # Force build and loading.
              critcl::code { ... }
       will result in an error. The only package-related commands still allowed are

       [1]    critcl::done

       [2]    critcl::failed

       [3]    critcl::load

       as these only query information, namely  the  build  status,  and  are  protected  against
       multiple calls.

CHECKING YOUR C

       As  said  several  times,  by  default critcl defers the compile and link steps for a file
       until it is needed, i.e. the first command of the ".critcl" file in question  is  actually
       invoked.

       This not only has the effect of lazily loading the package's functionality, but also, when
       developing using mode "compile & run", of us not seeing any errors in our  code  until  we
       are actually trying to run some demonstration.

       If  we do not wish to have such a delay we have to be able to force at least the execution
       of the compile step.

       The command critcl::failed is exactly that. When called it forcibly builds the C code  for
       the ".critcl" file it is part of, and returns a boolean vlaue signaling failure (true), or
       success (false).
              package require critcl
              if {[critcl::failed]} {
              }
       It is related and similar to critcl::load, the command to overcome the  lazy  loading,  as
       shown in section Unlazy Packages.

       Like  it  is  not  allowed,  nor  possible to use critcl commands declaring anything after
       critcl::failed has been called, making it  pretty  much  the  last  critcl  command  in  a
       ".critcl" file.  Code like
              package require critcl
              if {[critcl::failed]} { ... }
              critcl::code { ... }
       will result in an error. The only package-related commands still allowed are

       [1]    critcl::done

       [2]    critcl::failed

       [3]    critcl::load

       as  these  only  query  information,  namely  the  build status, and are protected against
       multiple calls.

   WHICH TCL ?
       When building the shared library from the embedded C sources one of the things critcl does
       for us is to provide the Tcl headers, especially the stubs declarations.

       By  default  these  are the Tcl 8.4 headers and stubs, which covers 90% of the cases. What
       when the package in question is meant for use  with  Tcl  8.5  or  higher,  using  C-level
       features of this version of Tcl.

       Use  the  critcl::tcl  command to declare to critcl the minimum version of Tcl required to
       operate the package. This can be either 8.4, 8.5, or 8.6, and  critcl  then  supplies  the
       proper headers and stubs.
              package require critcl
              critcl::tcl 8.5

   MAKING A WIDGET
       stubs.  For our convenience we have a simple, single command to activate all the necessary
       machinery, with critcl supplying the header files and stubs C code, instead of  having  to
       make   it   work   on  our  own  via  critcl::cflags,  critcl::ldflags,  critcl::cheaders,
       critcl::csources.

       This command is critcl::tk.
              package require critcl
              critcl::tk ; # And now critcl knows to put in the Tk headers and other support.
       Please note that this doesn't release you from the necessity of learning Tk's  C  API  and
       how to use it to make a widget work. Sorry.

   CHECKING THE ENVIRONMENT
       library.  The  headers  for this library may be found in non-standard locations, ditto for
       the library/ies itself. We may not have the headers and/or  library  on  the  build  host.
       Types  with  platform-dependent  sizes  and  definitions. Endianness issues. Any number of
       things.

       TEA-based packages can use autoconf and various predefined macros to deal with  all  this.
       We have the Power Of Tcl (tm) and critcl::check.

       This command takes a piece of C code as argument, like critcl::ccode. Instead of saving it
       for later it however tries to compile it immediately, using the current settings, and then
       returns  a boolean value reporting on the success (true) or failure (false). From there we
       can then branch to different declarations.

       As example let us check for the existence of some header "FOO.h":
              package require critcl
              if {[critcl::check {
              #include <FOO.h>
              }]} {
              } else {
              }
       Should we, on the other hand, wish to search for the  header  ourselves,  in  non-standard
       locations we have the full power of Tcl available, i.e. loops, the file and glob commands,
       etc., which can then be followed by a critcl::cheader command to declare the  location  we
       found (See also Finding header files).

       A  nice  extension to critcl would be a package collecting pocedures for common tasks like
       that, sort of like an autoconf for Tcl. critcl::config seems to be nice name  for  such  a
       package.

       Obvious adjunct commands which can be driven by results from critcl::check are

       critcl::cflags

       critcl::cheaders

       critcl::clibraries

       critcl::framework

       critcl::ldflags

       Less obvious, yet still valid are also

       critcl::ccode

       critcl::ccommand

       critcl::cdata

       critcl::cproc

       critcl::csources

       critcl::ctsources

       and pretty much everything else you can imagine.

   LICENSE INVOKED
       When  writing  packages  it  is  always good manners to provide prospective users with the
       license the package is under, so that they can decide whether they truly want to  use  the
       package, or not.

       As  critcl-based  packages often consist of only a single file a nice way of doing that is
       to embed the license in that file. By using a critcl command, namely critcl::license  this
       information  is  then  also  available  to the critcl application, which can put it into a
       standard location, i.e. "license.terms", of the generated packages.

       I currently have no specific example to demonstrate the command.

BUILDING CRITCL PACKAGES

       This is the section for developers having to generate packages from ".critcl"  files,  i.e
       binaries for deployment,

   GETTING HELP ...
              critcl -help
       prints the basics of using the application to stdout.

   PRE-FILLING THE RESULT CACHE
       The  default  mode of the critcl application is to take a series of ".critcl" files, build
       their binaries, and leave them behind in the  result  cache.  When  the  files  are  later
       actually used the compile and link steps can be skipped, leading to shorter load times.

       The command line for this is
              critcl foo.tcl
       or, to process multiple files
              critcl foo.tcl bar.tcl ...
       One  thing  to be aware of, should critcl find that the cache already contains the results
       for the input files, no building will be done. If you are  sure  that  these  results  are
       outdated use the option -force to force(sic!) critcl to rebuild the binaries.
              critcl -force foo.tcl
       For  debugging  purposes  it  may be handy to see the generated intermediate ".c" files as
       well. Their removal from the cache can be prevented by specifying the option -keep.
              critcl -keep foo.tcl
       These can be combined, of course.

   BUILDING A PACKAGE
       To build the binary package for a ".critcl" file, instead of Pre-Filling The Result Cache,
       simply specify the option -pkg.
              critcl -pkg foo.tcl
       This will geneate a package named foo.  A simpler alternative to the above is
              critcl -pkg foo
       The application will automatically assume that the input file to look for is "foo.tcl".

       But what when the name of the input file is not the name of the package to build ? This we
       can handle as well:
              critcl -pkg foo bar.tcl
       The argument foo specifies the name, and "bar.tcl" is the file to process.

       Going back to the very first example, it is of course possible to use an absolute path  to
       specify the file to process:
              critcl -pkg /path/to/foo.tcl
       The package name derived from that is still foo.

   BUILDING AND INSTALLING A PACKAGE
       Here  we  assume  that you know the basics of how to build a package.  If not, please read
       section Building A Package first.

       By default critcl will place all newly-made packages in  the  subdirectory  "lib"  of  the
       current working directory.  I.e. running
              critcl -pkg foo
       will create the directory "lib/foo" which contains all the files of the package.

       When  this  behaviour  is  unwanted the option -libdir is available, allowing the explicit
       specification of the destination location to use.
              critcl -pkg -libdir /path/to/packages foo
       A common use might be to not only build the package in question, but to  also  immediately
       install it directly in the path where the user's tclsh will be able to find it.  Assuming,
       for example, that the tclsh in question is installed  at  "/path/to/bin/tclsh",  with  the
       packages searched for under "/path/to/lib" ([info library]), the command
              critcl -pkg -libdir /path/to/lib foo
       will build the package and place it in the directory "/path/to/lib/foo".

   BUILDING FOR DEBUGGING
       Here  we  assume  that you know the basics of how to build a package.  If not, please read
       section Building A Package first.

       An important issue, when there is trouble with the package, debugging becomes necessary  a
       evil.   Critcl  supports  this  through the -debug option.  Using it enables various build
       modes which help with that.

       For example, to activate the Tcl core's built-in memory  debugging  subsystem  build  your
       package with
              critcl -pkg -debug memory foo
       The  resulting  binary  for  package  foo  will  use  Tcl's  debug-enabled  (de)allocation
       functions, making them visible to Tcl's memory command. This of course  assumes  that  the
       Tcl core used was also built for memory debugging.

       Further, built your package with
              critcl -pkg -debug symbols foo
       to  see  the  foo's  symbols (types, functions, variables, etc.)  when inspecting a "core"
       file it is involved in with a symbolic debugger,

       To activate both memory debugging and symbols use either
              critcl -pkg -debug all foo
       or
              critcl -pkg -debug symbols -debug memory foo

   RETARGETING THE BINARIES
       The configuration settings critcl uses to drive the compiler, linker, etc. are by  default
       selected  based  on the platform it is run on, to generate binaries which properly work on
       this platform.

       There is one main use-case for overriding this selection, which is done  with  the  option
       -target:

       [1]    Cross-compilation.  The building of binaries for a platform T while critcl actually
              runs on platform B.  The standard configuration of critcl  currently  has  settings
              for  two  cross-compilation targets. So, to build 32bit Windows binaries on a Linux
              host which has the Xmingw cross-compilation development environment installed use
              critcl -pkg -target mingw32 foo

              Similarly, building a package for use on ARM processors while critcl is running  in
              an Intel environment use
              critcl -pkg -target linux-arm foo

              Note that both configurations assume that the cross-compiling compiler, linke, etc.
              are found first in the PATH.

   CUSTOM CONFIGURATIONS
       The compiler configurations coming with  critcl  currently  cover  all  hosts  having  gcc
       installed  (the foremost among these are Linux and OS X), plus the native compilers of the
       more common unix-like operating systems, i.e. Solaris, HP-UX, and AIX, and,  on  the  non-
       unix side, Windows.

       Developers using operating systems and compilers outside of this range will either have to
       install a gcc-based development environment, i.e. get into the  covered  range,  or  write
       their own custom configuration and then tell critcl about it.

       The  latter  is  the  easier  part,  given  that  critcl supports the option -config whose
       argument is the path to the file containing the custom configuration(s). I.e.
              critcl -config /path/to/config ...
       will run critcl with the custom configuration in "/path/to/config", with the other options
       and  arguments  as explained in previous sections. Depending on the choice of name for the
       new configuration(s) this  may  or  may  not  require  a  -target  option  to  select  the
       configuration needed.

       For  the  former,  the  writing  of the custom configuration, the reader is refered to the
       section "Configuration Internals" of  the  CriTcl  Package  Reference  for  the  necessary
       details.  This is an advanced topic pretty much out of scope for this tutorial beyond what
       was already said.

   CUSTOM HEADER PATH
       Sometimes the use of critcl::headers might not  be  enough  for  a  package  to  find  its
       headers.  Maybe  they  are  outside  of  the paths checked by the setup code.  To help the
       application recognizes the option -I which allows the user to supply a  single  additional
       include path to use during the build phase of the package.

       Simply use
              critcl -I /path/to/header ...
       and the specified header will be handed to the package to be built.

   INTROSPECTION OF TARGETS AND CONFIGURATIONS
       To see a list containing the names of all the available configurations, run
              critcl -targets
       The  configuration  settings for either the default or user-chosen target can be inspected
       on stdout with
              critcl -show
       and
              critcl -show -target TARGET
       The raw contents of the configuration file used by critcl are dumped to stdout with
              critcl -showall
       All of the above can of course be combined with custom configuration files.

AUTHORS

       Jean Claude Wippler, Steve Landers, Andreas Kupries

BUGS, IDEAS, FEEDBACK

       This document, and the package it describes,  will  undoubtedly  contain  bugs  and  other
       problems.   Please report them at https://github.com/andreas-kupries/critcl/issues.  Ideas
       for enhancements you may have for either package, application,  and/or  the  documentation
       are   also   very   welcome   and   should   be  reported  at  https://github.com/andreas-
       kupries/critcl/issues as well.

KEYWORDS

       C code, Embedded C Code, code generator, compile & run, compiler, dynamic code generation,
       dynamic   compilation,   generate  package,  linker,  on  demand  compilation,  on-the-fly
       compilation

CATEGORY

       Glueing/Embedded C code

COPYRIGHT

       Copyright (c) Jean-Claude Wippler
       Copyright (c) Steve Landers
       Copyright (c) 2011-2013 Andreas Kupries