<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Tue May 21 03:40:54 GMT 2013 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='34'>
<header><title>Modernize TEA Build System</title><author address="mailto:supermo@bayarea.net">Mo DeJong</author><author address="mailto:andreas_kupries@users.sourceforge.net">Andreas Kupries</author><status type='project' state='withdrawn' tclversion="8.5" vote='after'>$Revision: 2.7 $</status><history></history><created day='3' month='may' year='2001' /></header>
<abstract>A number of things in the original TEA specification and documentation have fallen out of date. Numerous complaints about the difficulty of creating a TEA compliant package have appeared on <url ref="news:comp.lang.tcl."/> Other complaints about the ease of building Tcl and Tk using the autoconf based build system have also surfaced. Addressing these concerns is made even more difficult by the fact that two independent build systems currently exist, one for UNIX, and one for Windows. Maintaining multiple build systems is a frustratingly slow process that wastes time better spent on other issues. In addition, the Tcl build scripts do not support cross compilation which makes the maintenance process even slower since one can&apos;t test simple build system changes for a given platform without access to that platform. This document describes how these concerns can be addressed.</abstract>
<body><section title="Documentation">
<para>As new software is released, existing documentation becomes obsolete. Some of the existing TEA documentation is now so badly out of date that suggested software releases are no longer available. For example, the TEA based build for Windows requires Cygwin, yet there is a lack of clear instructions that describe how to install Cygwin. The solution to this problem is simple, the TEA documentation and implementation must be updated.</para>
</section>
<section title="Platform Detection">
<para>Most open source packages make use of a pair of scripts called <emph style="italic">config.guess</emph> and <emph style="italic">config.sub</emph> to detect a platform specific configuration string. For example, running <emph style="italic">config.guess</emph> on an x86 Linux box might print:</para>
<verbatim><vline encoding='base64'>JSAuL2NvbmZpZy5ndWVzcw==</vline><vline encoding='base64'>aTY4Ni1wYy1saW51eC1nbnU=</vline></verbatim>
<para>This value can be accessed from the configure.in script by adding a call to the <emph style="italic">AC_CANONICAL_HOST()</emph> macro. One would then detect a specific platform by doing a switch on the value of the $host variable. Tcl currently detects the build platform by examining the results of running <emph style="italic">`uname -s`-`uname -r`</emph>. Tcl should use the <emph style="italic">config.guess</emph> and <emph style="italic">config.sub</emph> method of platform detection. This may not seem like a big change at first but it has quite a few ramifications.</para>
<para>This change cannot be made incrementally, so there is a real danger of breaking the build for configurations that currently work. For this reason, it would be a good idea to wait until a 8.4 release branch has been created before adding such a change to the CVS HEAD. The cross compiling section will describe some of the other maintenance benefits that can be realized by using <emph style="italic">config.sub</emph> and <emph style="italic">config.guess</emph>.</para>
</section>
<section title="Cross Compiling">
<para>Tcl&apos;s build system has never supported cross compiling. The use of uname instead of <emph style="italic">config.guess</emph> during platform detection is largely to blame for this. A configure script that makes use of the <emph style="italic">AC_CANONICAL_HOST()</emph> macro keeps track of two separate configuration variables, <emph style="italic">build</emph> and <emph style="italic">host</emph>. The <emph style="italic">build</emph> variable holds the configuration string for the platform running the <emph style="italic">./configure</emph> script. The <emph style="italic">host</emph> variable holds the configuration string for the platform the generated binaries will be run on. For example, if one were to build a Windows binary under Linux the <emph style="italic">build</emph> variable could be set to <emph style="italic">i686-pc-linux-gnu</emph> and the <emph style="italic">host</emph> variable could be set to <emph style="italic">i386-pc-mingw32msvc</emph>.</para>
<para>Using the host variable instead of the output of <emph style="italic">uname</emph> has another important benefit. The build system maintainer can often test out changes to the build system logic without having access to the system in question. This is important since a surprising number of &quot;broken builds&quot; are the result of stupid logic or syntax errors in the sh code for a particular platform. For example, one could test out the Windows build using a cross compiler prefixed by <emph style="italic">i386-mingw32msvc</emph> like so:</para>
<verbatim><vline encoding='base64'>JSAuL2NvbmZpZ3VyZSAtLWhvc3Q9aTM4Ni1taW5ndzMybXN2Yw==</vline><vline encoding='base64'>JSBtYWtl</vline></verbatim>
<para>The above commands will run the Windows configure script in bash and then generate Win32 .dll and .exe files. One can even create cross compilers for multiple systems. Binaries for Solaris, IRIX, or others can be created under Linux or even Windows. The attentive reader will note that even compiling a Win32 application under Cygwin is technically a cross compile since the generated executable would be run with the Win32 runtime instead of the Cygwin runtime. To properly support cross compiling and make it easy for the end user, an upgrade to autoconf is also required.</para>
</section>
<section title="Autoconf 2.50 Update">
<para>The autoconf 2.13 release is now several years old. The most recent stable release of autoconf is 2.50. A huge number of problems have been fixed in the autoconf 2.50 release, the most important of which is cross compiling support. Cross compiling with autoconf 2.13 is possible but far harder than it needs to be. The long and sordid history of this particular feature in autoconf will not be addressed in this document. It is safe to say that the autoconf 2.50 release is the first release to make cross compiling easy for the end user. The existing build system works with the autoconf 2.50 release on a number of systems, but it is possible that the build on some system would be broken by this upgrade. For this reason, the autoconf 2.50 upgrade should happen after an 8.4 branch has been created.</para>
</section>
<section title="Use a Config Header">
<para>Autoconf supports two ways to set platform specific flags set via the <emph style="italic">AC_DEFINE()</emph> macro. Tcl currently makes use of the default option. Each call to <emph style="italic">AC_DEFINE()</emph> adds a <emph style="italic">-DVAR=1</emph> value that is passed into the compiler. These <emph style="italic">-D</emph> flags are also included in the generated <emph style="italic">tclConfig.sh</emph> file so that extensions will use the same set of defines. The second option is to generate a .h file that will be #included into any needed header or source file. This file could be called <emph style="italic">tclconfig.h</emph>. Instead of passing <emph style="italic">-DVAR=1</emph> on the command line, the generated .h file might look like:</para>
<verbatim><vline encoding='base64'>IyBkZWZpbmUgVkFSIDE=</vline></verbatim>
<para>There is no functional difference between these two options. The benefit of using <emph style="italic">tclconfig.h</emph> will likely only be realized by the maintainers or people hacking on the core and extensions. By taking the -D flags out of the <emph style="italic">Makefile</emph>, we make it easier to hack around in the generated .h file without having to worry about also changing the flags in the generated <emph style="italic">tclConfig.sh</emph> file. It can be quite a pain to change an option in Tcl&apos;s <emph style="italic">Makefile</emph>, then again in the <emph style="italic">tclConfig.sh</emph> file, and then rerun the configure script in each extension. This pain can be avoided by adding a call to <emph style="italic">AM_CONFIG_HEADER(tclconfig.h)</emph> to the top of Tcl&apos;s <emph style="italic">configure.in</emph> script. One possible ramification of this change may be the need to install <emph style="italic">tclconfig.h</emph> in the event items in <emph style="italic">tclInt.h</emph> depend on #defines in <emph style="italic">tclconfig.h</emph>.</para>
</section>
<section title="Misplaced AC_SUBST Calls">
<para>The <emph style="italic">configure.in</emph> file for both Tcl and Tk invokes the <emph style="italic">AC_SUBST()</emph> macro for each variable that is to be substituted into the <emph style="italic">Makefile</emph>. This makes sense for variables defined in the <emph style="italic">configure.in</emph> file, but it makes no sense for those variables defined in <emph style="italic">tcl.m4</emph>. Invoking <emph style="italic">AC_SUBST()</emph> in <emph style="italic">configure.in</emph> for a variable defined in <emph style="italic">tcl.m4</emph> means that the maintainer will need to keep track of the variable in Tcl&apos;s <emph style="italic">configure.in</emph> as well as the <emph style="italic">configure.in</emph> of any extension that uses the given variable. This simply makes no sense. Each macro defined in <emph style="italic">tcl.m4</emph> should call <emph style="italic">AC_SUBST()</emph> for any variables it wishes to substitute into generated files.</para>
</section>
<section title="One Rule to Build Them All">
<para>Perhaps the most frustrating thing about maintaining Tcl&apos;s build system is the fact that each and every modification needs to be made and tested in at least 4 configurations. This is because Tcl and Tk have two separate build systems, one for Unix and one for Windows. Each and every change needs to be tested on Unix for both Tcl and Tk and then again on Windows for both Tcl and Tk. It is an incredible waste of time.</para>
<para>A single build system with properly abstracted macros can be used to build both a Unix and Windows version of Tcl. Changes would still need to be tested on each platform, but dealing with only one source base would save a significant amount of the maintainer&apos;s time.</para>
<para>A related problem is experienced by extension authors. It can be quite difficult to write a build system for an extension that works with both the Unix and Windows version of Tcl. Here is a telling quote from Todd Helfter, the maintainer of the Oratcl extension.</para>
<quote><emph style="italic">&quot;TEA specifies that there should be only one set of configure files. Why should extension writers have to comply with a standard that Tcl nor Tk does not?&quot;</emph></quote>
<para>For starters, some of the variables defined in the Unix version of <emph style="italic">tclConfig.sh</emph> do not exist in the Windows version. Most of the obvious problems in this area have already been corrected in the 8.4 release, but some difficult ones remain. For example, how would an extension author figure out how to name a generated library file in a cross platform way? One would assume that a couple of variables could be concatenated together, but in practice this is not so easy. A quick look at the <emph style="italic">configure.in</emph> scripts will turn up examples like this:</para>
<para>(Unix version)</para>
<verbatim><vline encoding='base64'>aWYgdGVzdCAiJHtTSEFSRURfQlVJTER9IiA9ICIxIiA7IHRoZW4=</vline><vline encoding='base64'>ICBldmFsICJUQ0xfTElCX0ZJTEU9bGlidGNsJHtUQ0xfU0hBUkVEX0xJQl9TVUZGSVh9Ig==</vline><vline encoding='base64'>ZWxzZQ==</vline><vline encoding='base64'>ICBldmFsICJUQ0xfTElCX0ZJTEU9bGlidGNsJHtUQ0xfVU5TSEFSRURfTElCX1NVRkZJWH0i</vline><vline encoding='base64'>Zmk=</vline></verbatim>
<para>(Windows version)</para>
<verbatim><vline encoding='base64'>ZXZhbCAiVENMX0xJQl9GSUxFPSR7TElCUFJFRklYfXRjbCRWRVIke0xJQlNVRkZJWH0i</vline></verbatim>
<para>The attentive reader will note that these are completely different! To understand the Unix version, one has to go exploring to find out how <emph style="italic">TCL_[UN]SHARED_LIB_SUFFIX</emph> gets set. To understand the Windows version, one needs to look into the origins of <emph style="italic">LIBPREFIX</emph> and <emph style="italic">LIBSUFFIX</emph>. It is really quite a bother and it gets even worse once you introduce additional compilers (like mingw) into the mix. The casual coder would poke around for a bit then give up.</para>
<para>The solution to this problem is to merge the two build systems and provide some properly abstracted macros that work on multiple platforms. These macros will need to be available to Tcl/Tk as well as extension authors. Here is a short example of a couple of macros that were developed while porting Tcl/Tk and Itcl to the Cygnus environment. These macros can be found in the current CVS HEAD of gdb/Insight.</para>
<verbatim><vline encoding='base64'>VENMX1RPT0xfU1RBVElDX0xJQl9MT05HTkFNRShWQVIsIExJQk5BTUUsIFNVRkZJWCk=</vline><vline encoding='base64'>VENMX1RPT0xfU0hBUkVEX0xJQl9MT05HTkFNRShWQVIsIExJQk5BTUUsIFNVRkZJWCk=</vline></verbatim>
<para>Using these macros, one could code the Unix and Windows versions to use the same logic.</para>
<verbatim><vline encoding='base64'>aWYgdGVzdCAiJHtTSEFSRURfQlVJTER9IiA9ICIxIiA7IHRoZW4=</vline><vline encoding='base64'>ICBUQ0xfVE9PTF9TSEFSRURfTElCX0xPTkdOQU1FKFRDTF9MSUJfRklMRSwgdGNsLCAke1RDTF9TSEFSRURfTElCX1NVRkZJWH0p</vline><vline encoding='base64'>ZWxzZQ==</vline><vline encoding='base64'>ICBUQ0xfVE9PTF9TVEFUSUNfTElCX0xPTkdOQU1FKFRDTF9MSUJfRklMRSwgdGNsLCAke1RDTF9VTlNIQVJFRF9MSUJfU1VGRklYfSk=</vline><vline encoding='base64'>Zmk=</vline></verbatim>
<para>Behind the scenes, the unix version might set <emph style="italic">TCL_LIB_FILE=libtcl83.so</emph> while the Windows version might set <emph style="italic">TCL_LIB_FILE=tcl83.dll</emph>. Once both build systems use the same code, we can abstract them out into a new <emph style="italic">tcl.m4</emph> file that is shared between the Unix and Windows versions. An extension that has only one build system can also make use of these macros. The concept is not a difficult one, the problem is that the implementation takes a very long time to get right.</para>
</section>
<section title="VC++ vs. GCC Library Names">
<para>The previous section touched on issues related to library naming and how they differ between Unix and Windows. This section will focus only on Windows and discuss some of the differences that make it difficult to support both the VC++ and gcc compilers. Two variables that are quite difficult to support properly are <emph style="italic">TCL_LIB_SPEC</emph> and <emph style="italic">TCL_BUILD_LIB_SPEC</emph>. The gcc compiler supports command line arguments like <emph style="italic">-L${dir} -l${lib}</emph> but VC++ does not. VC++ users must pass the fully qualified name of a .lib file or set an environment variable. To deal with this situation, the following macros were developed.</para>
<verbatim><vline encoding='base64'>VENMX1RPT0xfTElCX1NIT1JUTkFNRShWQVIsIExJQk5BTUUsIFZFUlNJT04p</vline><vline encoding='base64'>VENMX1RPT0xfTElCX1NQRUMoVkFSLCBESVIsIExJQkFSRyk=</vline></verbatim>
<para>A single <emph style="italic">configure.in</emph> file for Tcl or an extension could make use of these macros as follows:</para>
<verbatim><vline encoding='base64'>VENMX1RPT0xfTElCX1NIT1JUTkFNRShUQ0xfTElCX0ZMQUcsIHRjbCwgJHtUQ0xfVkVSU0lPTn0p</vline><vline encoding='base64'>VENMX1RPT0xfTElCX1NQRUMoVENMX0JVSUxEX0xJQl9TUEVDLCBgcHdkYCwgJHtUQ0xfTElCX0ZMQUd9KQ==</vline><vline encoding='base64'>VENMX1RPT0xfTElCX1NQRUMoVENMX0xJQl9TUEVDLCAke2V4ZWNfcHJlZml4fS9saWIsICR7VENMX0xJQl9GTEFHfSk=</vline></verbatim>
<para>When configured with VC++, the macros would set:</para>
<verbatim><vline encoding='base64'>VENMX0JVSUxEX0xJQl9TUEVDPSIvYnVpbGQvdGNsODMubGliIg==</vline><vline encoding='base64'>VENMX0xJQl9TUEVDPSIvaW5zdGFsbC90Y2w4My5saWIi</vline></verbatim>
<para>When configured with gcc, the macros would set:</para>
<verbatim><vline encoding='base64'>VENMX0JVSUxEX0xJQl9TUEVDPSItTC9idWlsZCAtbHRjbDgzIg==</vline><vline encoding='base64'>VENMX0xJQl9TUEVDPSItTC9pbnN0YWxsIC1sdGNsODMi</vline></verbatim>
<para>These macros are a good first step. They provide abstraction for library naming issues and work in both shared and static builds. This set of macros has been tested with Tcl, Tk, and Itcl and should be ready for incorporation into other extensions. One only needs to look at Tcl bug 219330 to find an example of a core extension that only builds with VC++ under Windows. An extension writer should not need to solve compiler problems such as this. The Tcl core needs to provide abstracted macros that can be used in extensions.</para>
</section>
<section title="Cygwin vs. Mingw">
<para>The Windows version of Tcl traditionally supported building with VC++ only. During the Tcl 8.3 development process, gcc support was added. Trouble is, the default version of gcc delivered with Cygwin had and continues to have some problems compiling the Windows Tcl code.</para>
<para>Cygwin is a Unix/POSIX compatibility layer built on top of the Win32 API. The Cygwin version of gcc is designed to help people compile C programs that make use of POSIX APIs. The Cygwin version of gcc was not designed to support compiling Win32 native applications. Some support for Win32 applications was added later via the <emph style="italic">-mno-cygwin</emph> command line switch, but it is far from perfect.</para>
<para>The Mingw project was created to produce a version of gcc that supports building native Win32 applications. This version of gcc is a native Windows application, it does not depend on the Cygwin dll and it does not link generated applications to the Cygwin dll. In fact, it is simply not possible to create an executable that accidently requires the Cygwin dll when compiling with the Mingw version of gcc. This can be a problem with the Cygwin version of gcc, especially when C++ is involved.</para>
<para>Tcl currently builds with the Mingw version of gcc. Tcl does not build with the Cygwin version of gcc even though the <emph style="italic">-mno-cygwin</emph> is used. Tcl also does not build using the Cygwin version of gcc in POSIX mode without the <emph style="italic">-mno-cygwin</emph> flag. In addition, the individual working on Cygwin compatibility for Tcl will not be pursuing it in the future. For all of these reasons, support for Cygwin gcc should be dropped in favor of Mingw gcc. Documentation should be updated to instruct people to install the Mingw version of gcc instead of the Cygwin version. It is even possible to have both Cygwin gcc and Mingw gcc installed on the same system, the user just needs to make sure the correct one is on the PATH before compiling Tcl. A check should also be placed in the configure.in script to keep people from accidently compiling with the Cygwin version of gcc since it does not work and will only lead to useless bug reports.</para>
</section>
<section title="A New tclconfig Module">
<para>A number of Tcl extensions copy Tcl&apos;s <emph style="italic">tcl.m4</emph> file into the extension&apos;s CVS module. For example, Itcl distributes a locally modified version of <emph style="italic">tcl.m4</emph> that supports building on Windows and Unix with a single <emph style="italic">configure.in</emph> script. It is very difficult to keep up maintenance when this sort of approach is used. For one thing, the maintainer has to constantly copy the <emph style="italic">tcl.m4</emph> into extensions. Each and every commit to a <emph style="italic">tcl.m4</emph> file in the <emph style="italic">tcl</emph> CVS module needs to be followed by a commit to the same file in the <emph style="italic">tk</emph> module. If an extension has made local modifications to the <emph style="italic">tcl.m4</emph> file, a new one can&apos;t just me copied over. The extension maintainer would need to merge the changes in my hand or make use of some fancy CVS maintainer branch features that are not commonly used. The result of all this trouble is a predictable lag in keeping an extension&apos;s build system up to date.</para>
<para>Perhaps the best solution to this problem is to create a new module in the Tcl CVS named <emph style="italic">tclconfig</emph>. This module would contain all the macro files and supporting scripts that were available to Tcl and any extensions. Anyone who has worked on tclpro will notice that this is equivalent to the <emph style="italic">config</emph> module that currently exists in the <emph style="italic">tclpro</emph> CVS. The idea is the same, but the new module needs to live in the <emph style="italic">tcl</emph> CVS repo not the <emph style="italic">tclpro</emph> CVS repo. When a user checks the <emph style="italic">tcl</emph> module out of the CVS a <emph style="italic">tclconfig</emph> directory will also be created. The <emph style="italic">tcl/unix/aclocal.m4</emph> script would then be changed from:</para>
<verbatim><vline encoding='base64'>YnVpbHRpbihpbmNsdWRlLHRjbC5tNCk=</vline></verbatim>
<para>To:</para>
<verbatim><vline encoding='base64'>YnVpbHRpbihpbmNsdWRlLC4uLy4uL3RjbGNvbmZpZy90Y2wubTQp</vline></verbatim>
<para>This approach will provide a single destination for all configure related changes. It will end the need to copy <emph style="italic">tcl.m4</emph> files into each extension and will help extension authors resist the urge to make local modifications to the <emph style="italic">tcl.m4</emph> script. If an extension author wants to change <emph style="italic">tcl.m4</emph> they will need to submit a patch via the normal channels. Nothing will force extension authors to use this new approach, but it will be available to them when they are ready to upgrade. This change should not be integrated until Tcl 8.5.</para>
</section>
<section title="Extension Defaults">
<para>A Tcl extension should default to the same configuration options that Tcl was compiled with. For example, if <emph style="italic">--prefix=/usr/local/tcl84</emph> is passed to Tcl&apos;s configure script, it should not also need to be passed to Tk&apos;s configure script [Tcl bug 428627]. Tk should use the compiler that Tcl was configured with by default. In fact, each of the following options could fit into this category:</para>
<itemize><item.i><para>--prefix</para></item.i><item.i><para>--exec-prefix</para></item.i><item.i><para>--host</para></item.i><item.i><para>--enable-threads</para></item.i><item.i><para>--enable-64bit</para></item.i><item.i><para>--enable-symbols</para></item.i><item.i><para>--enable-shared</para></item.i></itemize>
<para>Each one of these options will need to be saved in <emph style="italic">tclConfig.sh</emph>.</para>
</section>
<section title="Build vs. Install Configuration">
<para>The <emph style="italic">tclConfig.sh</emph> script should provide information that allows an extension to be built with either an installed or uninstalled version of Tcl. The current <emph style="italic">tclConfig.sh</emph> largely fails to provide this functionality to extensions. Both build variables and install variables are included in the <emph style="italic">tclConfig.sh</emph> file, but there is nothing to indicate to the script that loads <emph style="italic">tclConfig.sh</emph> whether or not a given <emph style="italic">tclConfig.sh</emph> has actually been installed.</para>
<para>An extension author has a couple of choices about how to deal with this situation. One could simply recreate needed flags like <emph style="italic">TCL_LIB_SPEC</emph> and <emph style="italic">TCL_STUB_LIB_SPEC</emph> and ignore the definitions in the <emph style="italic">tclConfig.sh</emph> file. Tk uses this approach.</para>
<para>One could also just pick from the build or install variables. If the extension author chose to use <emph style="italic">TCL_LIB_SPEC</emph> instead of <emph style="italic">TCL_BUILD_LIB_SPEC</emph> then the extension would only build with a version of Tcl that was already installed. Itcl uses this approach.</para>
<para>Both of these approaches are seriously flawed. Tcl needs to provide a means to load a <emph style="italic">tclConfig.sh</emph> file without having to worry about build vs. install flags. The <emph style="italic">SC_LOAD_TCLCONFIG</emph> macro can be modified in such a way as to define <emph style="italic">TCL_LIB_SPEC=$TCL_BUILD_LIB_SPEC</emph> when loading <emph style="italic">tclConfig.sh</emph> from the build directory. When <emph style="italic">tclConfig.sh</emph> is loaded from the install directory one could safely set <emph style="italic">TCL_BUILD_LIB_SPEC=$TCL_LIB_SPEC</emph>.</para>
<para>The above change would address the most obvious problem in <emph style="italic">tclConfig.sh</emph>, but others remain. Tcl bugs 219260 and 421835 provide some examples of variables in <emph style="italic">tclConfig.sh</emph> that may work at build time but not install time and vice versa. One possible long term solution could be to create a <emph style="italic">tclBuildConfig.sh</emph> as well as a <emph style="italic">tclConfig.sh</emph> script. The <emph style="italic">tclBuildConfig.sh</emph> could be loaded by the <emph style="italic">SC_LOAD_TCLCONFIG</emph> macro when <emph style="italic">--with-tcl</emph> indicated a build directory. The <emph style="italic">tclConfig.sh</emph> script would not contain any build variables and would be the only configuration file to get installed.</para>
</section>
<section title="Chicken or the Egg">
<para>A number of targets in the current Tcl build process depend on having a working version of Tcl on the users <emph style="italic">PATH</emph>. It is not entirely clear if this was intentional. Either way, it creates real problems for users. Tcl bugs 420501 and 464874 demonstrates how a user might get a build error indicating that tclsh cannot be found before tclsh is even built. This problem should be straightforward to fix. Tcl patch 465874 describes on possible approach. The fact that this problem exists in the first place is indicative of a larger issue.</para>
<para>The Tcl build process should minimize external dependencies. This seems like a simple thing to seek agreement on, but people are constantly advocating changes that fly in the face of this goal. Tcl bug 219259 describes one such misguided effort. Older releases of Itcl mistakenly assumed a version of tclsh would exist on the system and tried to install files using a Tcl script named <emph style="italic">installFile.tcl</emph>. <tipref type="text" tip="59"/> seeks to embed Tcl build information into tclsh so that Tcl extensions could build themselves using Tcl scripts. Each of these approaches make different assumptions about how Tcl will bootstrap itself.</para>
<para>The current bootstrap approach depends on tclsh in some circumstances and not in others. This tends to work most of the time. Trouble is, if the user does something to change the time-stamps of certain files, it can leave the tree in an unbuildable state. Another approach would be to remove all uses of tclsh in the Makefile. This removes the possibility of accidently depending on tclsh during the build process but it can make the maintainer&apos;s life much more difficult. The most drastic solution would be to bootstrap a version of tclsh that could be used to rebuild Tcl as well as extensions. This is doable, but it will get very tricky in the case of a cross compile since the bootstrap version of tclsh would need to run on the build system while the generated version of tclsh would need to run on the host system. If the normal build process is always going to depend on tclsh, a private build version of tclsh will need to be bootstrapped. Realistically, this may be too much work to implement. It seems the only workable approach is to make sure none of the targets in the normal build process depend on an external tclsh.</para>
</section>
<section title="Death to TCL_DBGX">
<para>The most thoroughly evil part of the entire Tcl build process is the <emph style="italic">TCL_DBGX</emph> variable used in <emph style="italic">configure.in</emph>, <emph style="italic">Makefile.in</emph>, and <emph style="italic">tclConfig.sh</emph>. The following quote from Brent Welch say it all:</para>
<quote><emph style="italic">&quot;The TCL_DBGX manifestation is one of the worst /bin/sh quoting hell situations I have encountered.&quot;</emph></quote>
<para>Presumably, the <emph style="italic">TCL_DBGX</emph> variable was introduced to support building of debug vs. non-debug versions of Tcl and installing them into the same directory. That may have been a noble goal, but in practice this indirection makes many parts of the build system extremely difficult to modify. This scheme also fails to deal with other identifying suffixes like &apos;s&apos; for a static build or &apos;t&apos; for a threaded build. A number of queries as to the usefulness of <emph style="italic">TCL_DBGX</emph> have appeared on <url ref="news:comp.lang.tcl"/> but none produced satisfactory results. The <emph style="italic">TCL_DBGX</emph> variable should be removed and never spoken of again.</para>
</section>
<section title="Configure Flags">
<para>The <emph style="italic">--enable-symbols</emph> should be renamed to <emph style="italic">--enable-debug</emph>. Quite a few other software projects use the <emph style="italic">--enable-debug</emph> flag. A Google search turned up no other projects that make use of the <emph style="italic">--enable-symbols</emph> flag. This change would have documentation impact, but it would be minimal. The old flag could be retained for compatibility if a significant number of folks were concerned.</para>
<para>The Tcl 8.4 release removes the <emph style="italic">--enable-gcc</emph> flag. This flag introduced a number of problems that are much better solved by simply setting the <emph style="italic">CC</emph> environment variable before running configure. This change has already been incorporated into the CVS and is only mentioned here for the sake of completeness.</para>
</section>
<section title="Risks">
<para>Implementing this TIP is by no means an easy task. Build system changes are by far the most dangerous since a broken configuration will not be noticed until someone actually tries to build on the given system. One can only ask for forgiveness before hand. Large scale build system changes will no doubt break something. For this reason, many of the suggested changes should be incorporated into the Tcl 8.5 release.</para>
</section>
<section title="Alternatives">
<para>One alternative is to continue to use the existing system. While things would get no worse, they would also get no better. Another alternative is to replace the existing TEA based build system with a build system written in Tcl. This TIP does explore some of the build issues a Tcl based system will face, but tries to focus on improving the existing system instead of replacing TEA.</para>
</section>
<section title="See Also">
<para>SourceForge bugs: 219259, 219260, 219330, 420501, 421835, 428627, 464874</para>
<para>SourceForge patch: 465874</para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>
