Version 3 of Compiling Tcl on a Mac

Updated 2001-11-27 13:01:56

Compiling Tcl on an Apple Macintosh seems to be harder than it has any reasonable right to be due to bizarrenesses of other libraries and wierdnesses of compilers. Here we try to document some of these and their work-arounds...

Please feel free to modify and update this page!


From a posting by Jim Ingham on news:comp.lang.tcl

 >> Has anyone had any luck compiling Tcl8.3.1 for Mac? After the same adventure
 >> with
 >> NavigationLib I succesfully built 'Simple Tk (PPC)' in the TkShells.pi. This,
 >> I guess,
 >> is the static version of Tk, which seems to work. Building 'wish' there are
 >> complaints
 >> about this 'MathLibCFM68K Fa(4i_8d).Lib' not found. But I found another lib
 >> 'MathLibCFM68K(4i_F_8d).Lib' dated december '99 which I guessed was the right
 >> one.

 These two are not the same.  I forget now what the _F_ version is, but it is
 NOT far data.  It is kind of a pain that you have to build one of the Math
 libraries in order to build Tcl, but if you don't have Far data turned on,
 then Tcl will crash, and I can't really tell MetroWerks what to ship with
 their IDE...  I think I sent instructions on how to build the Far data
 version of the Math library before, did that not work?  You just have to
 find the Math Libraries project (it is in the folder above where all the
 Math Libraries themselves live), open it, select the CFM68K target, change
 the output name to 'MathLibCFM68K Fa(4i_8d).Lib', go to the C Preferences
 panel and select 4 Byte Ints, 8 Byte doubles, Far data, and "Enums always
 Int" and build.  This should produce a library you can link to.

For CW5 (after opening the project) the settings are found under Edit:mathLibCFM68K settings. This brings up the Target Settings Panel window.

- under Code Generation:68k Processor enable 4-Byte ints, 8-Byte doubles, and Far Data.

- under Language Settings:C/C++ Language enable Enum always int.

- under Target:68k target set the Project as Library and the file name as MathLibCFM68K Fa(4i_8d).Lib

The only question I have is whether the Project should be set as a Libary or as a CFM68k Shared Libary.

Richard Burton


Here are some observations that I wrote up while compiling this last version of MacTk (8.3.1).

I don't actually think compiling MacTk is all that hard to do, but the issue is complicated by the fact that you are really compiling for two platforms at once (68K and PPC) and by the fact that the 68K runtime model is really two runtime models - classic static compilation, and CFM for 68K. So there are a somewhat bewildering maze of compilation targets in the project files. It doesn't help that MW doesn't ship all the standard libraries that we need either...

Anyway, try to follow these notes, and tell me how it goes.

Jim Ingham

P.S. I have only compiled using the Universal Headers version 3.2. I have heard that there are problems compiling with the latest (3.3.1) versions of the headers. So if you have installed the 3.3.1 headers, be prepared to hack a bit more than this note indicates.

3.2 is what ships with CW Pro 5, however, so if you stick with that you should be okay.

--------------------- Begin Notes --------------------------- Hi, all,

This little README is an attempt to get you started with the process of building MacTk for PPC and 68K systems.

1) I started with a clean install of MacOS 9.0.4, and installed CodeWarrior Pro 5.

You need to install BOTH the PPC & the 68K compilers. If you don't, then you will not be able to build the Tk MDEF. You can still build PPC Tk without this, but you will not be able to change the fonts or colors of menu items, and you won't be able to use multi-column menus.

Also, if you want to build the D&D Tclets Application, then you need to install the "Output Flags Post Linker" & its preference panel from the CW CD into the "Codewarrior Plugins" folder.

2) I applied the 5.3 patch from the CD (including the library install).

3) Next, I opened the project:

{Compiler}:MacOS Support:Libraries:MacOS 68K:MathLib68K:MathLib68K.mpc

a) Choose the target mathLibCFM68K, open the project Settings panel.

b) Select the "68K Target" panel, and change the "File Name" to "MathLibCFM68K Fa(4i_8d).Lib"

c) Select the "C/C++ Language" panel, and click "Enums Always Int"

d) Select the "68K Processor" panel, and click "Far Data"

e) Then close the settings panel, and build.

4) Open the QuickTime Settings control panel, choose "QuickTime Exchange" from the dropdown menu, and turn OFF QuickTime Exchange. If you don't do this, QuickTime will change the type of the .bmp include files in Tk, and CW will refuse to open them.

5) Now get the sources from Scriptics. I use MacCVS Pro, but any CVS client will do.

I got the "core-8-3-1-branch" tag of the "tcl" & "tk" modules. It is probably good to get the branch, since there were a few errors in the project files, and I have checked the corrected versions into this branch. Let's call the folder in which you put the source {Tcl/Tk Source}.

6) Get MoreFiles from the Scriptics dev. site, or from Apple, or from the Developers CD series, or whatever... Put it in a file called MoreFiles in {Tcl/Tk Source}. We use version 1.4.9.

7) Now make the Build Folder. In the {Tcl/Tk Source} folder, make a folder called "Build".

Unstuff the two files

    "{Tcl/Tk Source}:tcl:mac:tclMacProjects.sea.hqx" 

and

    "{Tcl/Tk Source}:tk:mac:tkMacProjects.sea.hqx"

into the "Build" folder. Now your sources should look like this:

  {Tcl/Tk Source}
    Build
        tcl
            BOA_TclShells.<pi>
            MacTcl MSL.<pi>
            Tclapplescript.<pi>
            TclLibraries.<pi>
            TclShells.<pi>
        tk
            TkLibraries.<pi>
            TkShells.<pi>
            Tk_MDEF.<pi>
    MoreFiles
        C Headers
        Sources
        Other stuff we don't use...
    tcl
        The Tcl sources...
    tk
        The Tk sources...

8) Okay, what are all these projects:

* tcl:BOA_TclShells.<pi>: This projects builds a "Background Only" version of the Tcl Shell. It is useful for writing "Driver" or background type tools. To use it, you build the shell, and either put a file called bgScript.tcl in the same folder as the application, or put a bgScript.tcl TEXT resource in the Shell. It will run the file as its startup script.

* tcl:MacTcl MSL.<pi>: This project rebuilds the MetroWerks Standard Libraries. It differs from the standard build in that it exports the symbols out of the library. We do this so we can export them from the Tcl Shared library, which allows Tk and other Tcl extensions to use a single copy of the Standard C Library - namely that exported from the Tcl Shared Library.

* tcl:Tclapplescript.<pi>: This builds the Tclapplescript extension.

* tcl:TclLibraries.<pi>: This builds various Shared & Static versions of the Tcl library.

* tcl:TclShells.<pi>: This builds various versions of the Tcl shell application.

* tk:TkLibraries.<pi>: This builds various Shared & Static versions of the Tk library.

* tk:TkShells.<pi>: This builds various versions of the Wish application.

* tk:Tk_MDEF.<pi>: This builds the Tk MDEF, which is basically a glue routine to go from the MDEF that the Menu Manager calls to the actual Tk Menu code contained in the Tk Library.

9) The targets in these libraries are all linked, so you really don't need to know about all the targets (though I will describe them below). To quickly build ALL of the standard MacTk Products, open the TkShells.<pi> project, select the "Tk Release Build" and build. If all goes well, the build will complete in something between around 5 minutes (on a fast G4) to half an hour or so on a slower PPC.

You will get lots of warnings, all benign. There are some stub X functions which don't have prototypes, there is one case where a CONST needs to be added, but can't because the non-const-ed version is already in the stub table. There are lots of duplicate symbols, these are on purpose, they are either redefinitions of Std C functions by Tcl, or by the libmoto, or redefinitions of SIOUX functions in Tk to support the Tk console. There are also duplicate resource definitions coming from merging the PPC & CFM versions of the shells.

You should not get any errors.

10) Having done the build, if you now look in the build folder, you will notice a whole bunch of junk. What of it do you need? The following is the list of the end products I include in the final distribution:

Applications:

* Drag & Drop Tclets: This is a FAT shell for making Tclets out of script files.

* TclShell: This is a FAT shell for running Tcl scripts.

* Wish: This is a FAT shell for running Tk scripts.

* Simple BOA Tcl (PPC): This is a statically bound shell which runs as a Background Only Application.

All the other shells are merged into the ones given above. You can use them on their own, but they also link dynamically to the MSL Runtime Libraries, so if you want to use them rather than the FAT shells you need to either provide the MSL Runtime Library (either PPC or CFM68K), or use the Merge linker to merge this into the libraries (which is one of the things that the FAT targets do).

Shared Libraries:

* Tcl8.3.shlb: The PPC version of the Tcl library.

* Tcl8.3CFM68K.shlb: The CFM68K version of the Tcl library.

* Tclapplescript1.1.shlb: The PPC version of the Tclapplescript extension.

* TclapplescriptCFM1.1.shlb: The CFM68K version of the Tclapplescript extension.

One bogosity in the current setup is that you have to go edit the pkgindex resource in the two Applescript libraries, to change the .shlb references to match the disk names of the library (so Tclapplescript.shlb->Tclapplescript1.1.shlb in the PPC version, and Tclapplescript.shlb->TclapplescriptCFM1.1.shlb). Getting this to work automatically was hard because you couldn't use #defines in .r files, and I didn't want to have two teeny .h files to include. So I did the fix by hand. Sorry...

* Tk8.3.shlb: The PPC version of the Tk library.

* Tk8.3CFM68K.shlb: The CFM68K version of the Tk library.

All the shared libraries also contain the basic startup Tcl scripts that are needed. However, they do not contain things like the http library, etc... These need to be copied over to the "Tool Command Language" folder of the Extension folder.

Static Libraries:

* TclStub.lib: The PPC Tcl Stub library.

* Tcl8.3CFM68KStub.lib: The CFM68K version of the Tcl Stub library.

* TkStub.lib: The PPC Tk Stub library.

* Tk8.3CFM68KStub.lib: The CFM68K version of the Tk Stub library.

All the other static libraries are used in building the shared libraries, and can be thrown away.

11) Using the Build folder keeps most of the build junk out of the sources, but there doesn't seem any way to keep the precompiled headers out of the mac folder. So if you want to package up the sources, you need to remember to remove these.

12) Also if you use MacCVS Pro, it puts hidden CVS directories in the source, and also puts 'ckid' resources in all the text files. You can get rid of these en masse by using the "Actions->Orphan Files" menu item, though of course if you do this, you can't do any more CVS operations on the sources. The cheesy way to get around this is to duplicate the tcl & tk folders, orphan the originals, make the release, and then move the duplicates back on top of the originals...

13) So, now you want to put together a release build. I have been using Stuffit InstallerMaker to make the releases up, but this has gotten a bit tedious, and so for this release, I am going to just copy stuff by hand... The following script will assemble a moderately convenient release folder:

  set release "::Release"
  set macTk_shells "::Release:MacTk 8.3.1:"
  set macTk_stubs "::Release:MacTk 8.3.1:stubs:"
  set common_libs "::Release:Tool Command Language:"
  set ppc_libs "::Release:Tool Command Language (PPC):"
  set 68k_libs "::Release:Tool Command Language (68K):"

  file mkdir $release
  file mkdir $macTk_shells
  file mkdir $macTk_stubs
  file mkdir $common_libs
  file mkdir $ppc_libs
  file mkdir $68k_libs

  foreach shell {"Drag & Drop Tclets" "TclShell" "Simple BOA Tcl (PPC)" Wish} {
    file copy $shell $macTk_shells
  }

  foreach stub {"TclStub.lib" "TclStubCFM68K.lib" "TkStub.lib" "TkStubCFM68K.lib"} {
    file copy $stub $macTk_stubs
  }

  foreach lib {Tcl8.3.shlb Tclapplescript1.1.shlb Tk8.3.shlb} {
      file copy $lib $ppc_libs
  }

  foreach lib {Tcl8.3CFM68K.shlb TclapplescriptCFM1.1.shlb Tk8.3CFM68K.shlb} {
    file copy $lib $68k_libs
  }

  file copy "::tcl:library" [file join $common_libs tcl8.3]
  file copy "::tk:library"  [file join $common_libs tk8.3]

  # Remove the DDE extensions, since it is useless on the Mac.

  file delete -force [file join $common_libs tcl8.3 dde1.0]
  file delete -force [file join $common_libs tcl8.3 dde1.1]

  set install_readme [file join $release "Readme-Install"]
  set fileH [open $install_readme w]
  puts $fileH {Readme-Install

  To install this release of MacTk (version 8.3.1) just copy the      platform
  specific file from either "Tool Command Language (PPC)" or "Tool Command Language (68K)"
  into the "Tool Command Language" folder, and copy that into your Extensions folder.
  Then put the "MacTk 8.3.1" folder wherever you want to store the shells.

  Jim Ingham 6/18/2000}

  close $fileH
  file attributes $install_readme -type TEXT -creator CWIE

To run the script, you can just save it into a file in the Build folder, fire up the TclShell, and source it in. It will create a folder called Release at the same level as the Build folder. Don't forget to either Orphan the files in the source folders, or go through and delete all the ckid resources, and the CVS folders...

You can get the HTML versions of the man pages from http://purl.org/tcl/home/ .

14) Okay, what are all these targets & libraries about anyway...

There are three basic choices that can be made in building the Tcl Shell and the Wish applications.

a) Whether to build PPC or 68K binaries.

b) Whether you link statically or dynamically to the Tcl & Tk shared libraries.

c) Whether you turn on the TCL_TEST and TK_TEST defines when you build the shells, so that you can fully run the Tcl & Tk test suites.

First, the library targets:

We provide both Static & Shared targets for the Test disabled version, and PPC Static targets for the Test enabled version.

The naming convention is:

    {ppc,68K}*{*, *ShLib, TestLibrary}

where * is Tcl or Tk. The RHS of th * indicates the target architecture, the LHS indicates the type of library, static, shared or test enabled respectively.

The Library projects also contain targets to build the PPC & CFM68K versions of the Stub library.

The one slightly confusing thing here is that we build a static PPC library, and link that INTO the shared PPC library, but in the 68K case we don't use the static 68K library in the shared (CFM68K) library. This is mostly historical, the original 68K static target was not a CFM application, so we couldn't use it's library in the CFM68K shared library.

Next the Shells:

The Shell projects follow the same naming conventions. They also contain some extra targets. First, there are the merge targets, which make the FAT shells (Wish in the TkShells.<pi> project, and TclShell in the TclShells.<pi> project). And then there are the test shells that you can use for running the test suites.

The TkShells.<pi> project also contains some other release oriented targets. You have already seem the Tk Release Build target, which builds the Tcl & Tk shells, the PPC and CFM68K libraries, Tclapplescript and the D&D Tclets. There is also a target to build the D&D Tclets, a target to build all the static shells, and one to build the entire world...

15) One other bit that I occasionally mess up is the proper linking of optional system libraries. In our case the optional libraries are put in a group called "Weak Link Libraries" in all the projects in which they are used. You just have to make sure that all these libraries are indeed Weak Linked. To check this, select the library, choose the project inspector, and make sure the Weak Link checkbox is ON. The problem is that all these libraries exist by default on all systems more recent that 8.6, so you won't be able to tell whether you have gotten this right, unless you have a system older than this.

Hope this helps...

Jim Ingham

work - [email protected]

home - [email protected]

--------------------------- End Notes ------------------------------

P.S. The line wraps in the wiki may have messed up the release preparation script. Should be pretty obvious how to fix it up, however.

Jim

Hi,

Is anyone considering getting the tbcload lib working on the Mac?

Sincerely,

Nicolas Boretos


Daniel Steffen recently posted in comp.lang.tcl [L1 ] that http://www.maths.mq.edu.au/~steffen/tcltk/darwin.php describes how to build Tcl 8.3.3 as close as possible to what Apple does for MacOS X so that you can install the new version on top of what Apple delivers. (I've updated this page for Tcl 8.3.4, patching is no longer necessary as I have nowchecked all necessary changes into cvs)