Author: Jan Nijtmans <jan.nijtmans@gmail.com>
State: Final
Type: Project
Vote: Done
Tcl-Version: 8.7
Tcl-Branch: build-info
Vote-Summary Accepted 5/0/0
Votes-For: BG, JN, KW, MC, SL
Votes-Against: none
Votes-Present: none
Abstract
This TIP proposes new commands "tcl::build-info" (and "tk::build-info", and the same for any extension wanting to do this)
Example:
$ tclsh8.7 % tcl::build-info 8.7b1+4a8309fafe073cae4fb210cfcd37e6accd8e31e7558aefab3d7f2ad6a27540c2.clang-1200 % tcl::build-info commit 4a8309fafe073cae4fb210cfcd37e6accd8e31e7558aefab3d7f2ad6a27540c2 % tcl::build-info compiler clang-1200 % tcl::build-info version 8.7a6 % tcl::build-info patchlevel 8.7a6$ tclsh9.0 % tcl::build-info 9.0b1+f896257cbcef7829503585ca26430bb097c8c33258a3785f7611bbc21c3ba080.gcc-1002
> tclsh87 % tcl::build-info 8.7b1+4a8309fafe073cae4fb210cfcd37e6accd8e31e7558aefab3d7f2ad6a27540c2.magicsplat.msvc-1916
The build-info information consists of the version string, adding a '+' sign and some crucial build information, to be used in Fossil bug reports. This way we can determine quickly whether a 'static' build was used, whether a specific patched version (e.g. 'fedora', which has a slightly different directory layout) was used, just by asking the result of "tcl::build-info".
Another goal for this TIP is to provide additional information to applications using TIP #596: "Stubs support for Embedding Tcl in other applications". Such applications can now query Tcl build options even before creating an interpreter.
Specification
In Tcl 8.x, package versions consist of integers separated by dots or (as final one) 'a' or 'b'. e.g.:
- "1.2.6"
- "2.0a2"
This TIP proposes the possibility to get additional build metadata, which MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the version. Identifiers MUST comprise only ASCII alphanumerics and hyphens [0-9A-Za-z-]. Identifiers MUST NOT be empty. Build metadata MUST be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence. Examples:
- "1.2.6+tag1.tag2.tag3"
- "2.0a2+tag1.tag2.tag3"
Note that this is exactly the same way as how "Semanic Versioning" versions can add optional build metadata, that's not a coincidence. There's no need for Tcl to invent its own wheel.
The Tcl build process is adapted to retrieve the commit-id from Fossil or GIT such that
it even survives a "make dist". So, if the Tcl source code was checked out from Fossil
or GIT and built, then tcl::build-info
will contain the correct commit-id. If -
then - a "make dist" is used to create a tar.gz file, building Tcl from this
distribution will still show the same commit in tcl::build-info
. At this moment,
only Fossil and GIT are supported, support for more VCS'es could be added in the future.
In Tcl, we want to build an unique version string which tells us crucial information about how Tcl (or Tk or ....) was built. Advantage: anyone submitting a bug report, we can ask to type "tcl::build-info" and it will help being able to reproduce the bug.
- The first identifier is always the Fossil commit-id. If the package doesn't come from fossil but from GIT, it's "git-<commit-id>". This way we can always locate the exact commit which was used as base from the build, even when building from a tarball which originated from Fossil or GIT.
- All other identifiers are sorted alphabetical.
- There are 4 (optional) predefined tags for the compiler used: "clang-xxxx" "gcc-xxxx" "icc-xxxx" "msvc-xxxx" where "xxxx" is the version of the compiler (two digits for major and two digits for minor version). More compilers will be added in the future, as desired.
- Then there is the following list of (optional) identifiers. Presence of such identifier indicates that this is a non-standard build: the identifier string indicates what manner this build is non-standard. Other packages than Tcl can use a subset of these possible identifiers, but there is no obligation that all packages should implement all of them.
Identifier | Meaning |
---|---|
compiledebug |
Configured with "--enable-symbols=all", cflag TCL_COMPILE_DEBUG |
compilestats |
Configured with "--enable-symbols=all", cflag TCL_COMPILE_STATS |
cplusplus |
Compiled with a C++ compiler |
debug |
Configured with "--enable-symbols" |
ilp32 |
Compiled as 32-bit (integers, longs and pointers are all 32-bit) |
memdebug |
Configured with "--enable-symbols=mem", cflag TCL_MEM_DEBUG |
nmake |
Built with "nmake" in stead of "make" |
no-deprecate |
Deprecated features are removed, cflag TCL_NO_DEPRECATED |
no-thread |
Compiled without support for threads |
no-optimize |
Compiler optimization has been switched off |
objective-c |
Compiled with an objective-c compiler |
objective-cplusplus |
Compiled with an objective-c++ compiler |
purify |
Compiled with purify information |
profile |
Compiled with profile information |
static |
Compiled as static library |
More of those can be added in the future.
- Anyone patching Tcl can add its own identifier, so it's clear that Tcl is modified. E.g.:
Identifier | Meaning |
---|---|
activestate |
"Activestate" patches are applied |
apple |
"apple" patches are applied |
androwish |
"androwish" patches are applied |
bawt |
"BAWT" patches are applied |
bsd |
"BSD" patches are applied |
cygwin |
"Cygwin" patches are applied |
debian |
"Debian" patches are applied |
fedora |
"Fedora" patches are applied |
freebsd |
"FreeBSD" patches are applied |
microsoft |
"Microsoft" patches are applied |
magicsplat |
"Magicsplat" patches are applied |
openbsd |
"OpenBSD" patches are applied |
redhat |
"Redhat" patches are applied |
ubuntu |
"Ubuntu" patches are applied |
(just examples, you can invent your own). Binary distributions can patch Tcl adding their own identifier, even if it's only for 'branding'. There could be multiple ones (e.g. "ubuntu" could decide to use the "debian" patches as well)
- Calling
tcl::build-info <identifier>
will return1
if the identifier is present in the build-info,0
if not. But there are 4 pseudo-identifiers:
Identifier | Meaning |
---|---|
commit |
Returns the commit-id from Fossil (or GIT) |
compiler |
Returns the identifier identifying the compiler used |
patchlevel |
Returns the patchlevel |
version |
Returns the version |
The functions
Tcl_FindExecutable
,Tcl_InitSubsystems
,Tcl_SetPanicProc
andTclZipfs_AppHook
are modified to return the build-info string as described in this TIP. Those functions are meant to be used during Tcl initialization, which allows to double-check for presence or absence of certain identifiers as needed by the application (e.g. signaling "no-thread" when thread-support is missing).Deprecate the array elements tcl_platform[threaded] and tcl_platform[debug]. In Tcl 9.0 those will be gone.
Deprecate the following "tcl::pkgconfig" keys:
debug
,threaded
,profiled
,64bit
,optimized
,mem_debug
,compile_stats
. In Tcl 9.0 those will be gone.
Discussion
It has been suggested to put additional keys in tcl::pkgconfig. But tcl::pkgconfig
does not only contain build information, it also contains installation configuration
information (like "bindir,runtime") which is not useful in a build-info string. Also
it would prevent the build-info string to be usable in Tcl_InitSubsystems()
and
friends (TIP #596), before any Tcl interpreter is created.
An earlier implementation combined this approach with the "package" mechanism, but this was rejected.
Implementation
Implementation is in Tcl branch "build-info"
Compatibility
This is 100% upwards compatible with Tcl 8.6.
Copyright
This document has been placed in the public domain.