It is not clear, after reading Critcl pages, exactly what files have to be installed on a Windows machine to use Critcl. Does one have to install the critcl source code and then some other piece(s)?
June 2002 - Yes, you need critcl installed as a normal Tcl package (i.e. so "package require critcl" works in tclsh or tclkit) and you need to set things up so "gcc" works. What I do is install the mingw system, and set up the PATH so "gcc" works from the command line. That's it. -jcw
Q: When does the code get compiled? In an example such as
critcl::cproc triple {int i} int { return i * 3; /* this is C code */ } puts "three times 123 is [triple 123]"
when is the C-coded triple command created?
A: When it is called the first time. The critcl::cproc command creates an auto_index entry for the command it defines. The script in this entry causes complete C sources to be written, the compiler to be run, and the resulting dynamic library to be loaded. (It takes longer time than the source or load you'd normally find in such entries, and there are more ways in which it can go wrong, but there is no difference in principle.) Compiled commands are created on a per source-file basis.
Paolo Noli: A little question: How to call a tcl commands from inside a c funcion declared with the statement "ccode"? (I need this to implement a callback procedure.. but I think this can be an interesting tip for others people. :)
RS 2007-10-03: Well, the classical way to call Tcl commands from C is Tcl_Eval. The following snippet works as expected (prints "this should come") in Odyce's Critcl emulation, on old faithful W95:
critcl::cproc do {Tcl_Interp* interp int i char* cmd} ok { if(i) Tcl_Eval(interp, cmd); } do 1 {puts "this should come"} do 0 {puts "this should not"}
and runs in local variable scope, as can be verified:
17% proc f x {do 1 {info locals}} 18% f 42 x
In critcl::ccode however you cannot pass in the Tcl_Interp pointer. Maybe arrange for a cproc to deposit the pointer to the (one and only) interp in a global variable?
Instructions for installing critcl in an existing "traditional" (i.e. non-starkit) Tcl installation
tclkit critcl.kit test-critcl.tcl
tclkit sdx.kit unwrap critcl.kit
cd critcl.vfs/lib
cp -a * /path/to/tcl/lib cd /path/to/tcl/lib
ln -s /path/to/tcl/lib/app-critcl/critcl.tcl /usr/local/bin/critcl
tclsh test-critcl.tcl
critcl test-critcl.tcl
The file test-critcl.tcl:
lappend auto_path . package require critcl critcl::cproc triple {int i} int { return i * 3; /* this is C code */ } puts "three times 123 is [triple 123]"
Older versions of the Critcl package builder had a severe bug [L1 ], in that the pkgIndex scripts they generated would conflict with this traditional of use of Critcl. To see if you're affected, enter the commands
catch {package require f00bar}; # To make sure package indices are loaded. package provide critcl ; # This is the result you're interested in
(f00bar should not be the name of an existing package). If the result is empty then all is well, but if it is "0.0" then you've got a bad pkgIndex.tcl script installed.
The sad thing here is that you don't have to use the bad package for anything to be hurt by this; it is sufficient that you have it installed. However, even if you cannot remove the bad package, you can work around it by doing something like the following trickery instead of a normal package require:
# Save [package ifneeded] scripts for functional versions of critcl. set cmds "" foreach ver [package versions critcl] { if {$ver ne "0.0"} then { append cmds [list package ifneeded critcl $ver [package ifneeded critcl $ver]] \n } } # Forget critcl package declarations package forget critcl # Restore useful critcl package declarations eval $cmds # Now load a working package package require critcl
Sarnold had problems with whitespaces in directory names on Windows XP. Here is the trace :
gcc -r -nostdlib -DUSE_TCL_STUBS {-IC:/Program Files/msys/1.0/home/St‚phane ARNOLD/.critcl/Windows-x86} -o C:/Program Files/msys/1.0/home/St‚phane ARNOLD/.critcl/Windows-x86/v034_1e3ab721192aa1df5ef708c68f019a0b_pic.o C:/Program Files/msys/1.0/home/St‚phane ARNOLD/.critcl/Windows-x86/v034_1e3ab721192aa1df5ef708c68f019a0b.c gcc.exe: Files/msys/1.0/home/St‚phane: No such file or directory gcc.exe: ARNOLD/.critcl/Windows-x86/v034_1e3ab721192aa1df5ef708c68f019a0b_pic.o: No such file or directory gcc.exe: C:/Program: No such file or directory gcc.exe: Files/msys/1.0/home/St‚phane: No such file or directory gcc.exe: ARNOLD/.critcl/Windows-x86/v034_1e3ab721192aa1df5ef708c68f019a0b.c: No such file or directory
I fixed on my local copy of critcl.vfs/lib/critcl/critcl.tcl :
line 601 : set cmdline "$v::compile $copts -o [list $libfile] [list $base.c] $srcs" line 757 : set cmdline "$v::compile $copts [list [file normalize $src]] -o [list $pref.o]"
Please, would you like to fix it ? Thanks in advance.
17jun06 jcw - Fixed in 0.36, thank you.
24oct07 XO - The issue is there again in critcl-new.kit (version2.0) Tweaked the code a little bit, and it worked after I made the following changes...