The problem is hard, because it's not well specified. One could do "[join [array get tcl_platform] { }]", and end up with a name that is definitely unique, but huge. The trouble is that for shared libraries, this approach is in fact wrong - there are many details in tcl_platform that differ between machines, yet are irrelevant w.r.t. binary compatibility. An example from Joe English's post: [IRIX] has numerous variations with intricate compatibility issues, while Linux does not really care - all shared libs will load anywhere regardless of kernel version.So, let's try to come up with some logic, and extend / perfect it along the way. Here's a start:
JE It may be a better idea for the outer switch to dispatch on $tcl_plaform(os) instead of $tcl_platform(machine); the meaning of the other fields depends more heavily on the former (which comes from uname -s) than the latter.We should also check $tcl_platform(platform) (unix vs. windows vs. macos vs. ...). Also need to consider threaded vs. non-threaded, 32-bit vs. 64-bit, and (at least on Windows) debug vs. non-debug. Basically any build variant that affects binary compatibility.Anyway, this is what I suggest for IRIX (following LV's suggestion below, it returns a GNU-style "canonical system"):
Anyway, the idea for this page is to tweak the above [platform] command, so we can use it as "easy shared-lib discriminator" on more and more platforms. Here's a modified version with Bob's HPUX changes added:
LV Any reason to not pattern the names after autoconf's config.guess ? For instance, platform, above, says on my sparc solaris 2.6 machine:
Another reason for generating generic platform names is to make tcl_platform(machine) consistent across platforms. For example, Power PC should be "ppc" on both AIX and MacOSX. At the moment on MacOSX it is "Power Macintosh" whereas on Linux it is "ppc". Note that CriTcl tries to do this as far as is possible (e.g. ppc, x86, sparc, etc) - stevel
Another issue we need to address is that certain platforms encode the unique machine ID in tcl_platform(machine) - and this needs to be extracted if the value of tcl_platform(machine) is going to be useful.For example, whereas on Linux/x86 you get something like
See also PkgIndexUtil.tcl - determining a platform name
PWQ 13 Feb 06, The obvious qustion that noone has asked is , why is the above such a mess and who determines what string is returned for what platform?.The big problem with all the above is that you cannot test your code unless you have the platform in question as you won't know what string to test for , or more importantly what difference this platform has that you have to have a test.All the above is to make up for poor decision making that has not been corrected.
proc platform {} { global tcl_platform set plat [lindex $tcl_platform(os) 0] set mach $tcl_platform(machine) switch -glob -- $mach { sun4* { set mach sparc } intel - i*86* { set mach x86 } "Power Macintosh" { set mach ppc } } set mach [regsub -all {[ /]} $mach "-"] return "$plat-$mach" }Some output:
Linux-x86 Darwin-ppc (Mac OSX) Windows-x86 SunOS-sparcThe goal is to come up with a unique identifier that can be used as directory name (no slashes or colons, please), for each context that requires a different binary. For contexts that are compatible, the goal is to end up with the same identifier each time.Failures are not necessarily show-stoppers. If a specific shared library needs more differentiation than the identifier provides, one can always add add-hoc logic for it (example: a high-performance binary that is built differently for Pentium vs. Athlon cpu's). If it turns out that two different identifiers are produced for what is determined to be compatible after all (IRIX comes to mind), then one can either store copies, or post-process the output from the [platform] command.
JE It may be a better idea for the outer switch to dispatch on $tcl_plaform(os) instead of $tcl_platform(machine); the meaning of the other fields depends more heavily on the former (which comes from uname -s) than the latter.We should also check $tcl_platform(platform) (unix vs. windows vs. macos vs. ...). Also need to consider threaded vs. non-threaded, 32-bit vs. 64-bit, and (at least on Windows) debug vs. non-debug. Basically any build variant that affects binary compatibility.Anyway, this is what I suggest for IRIX (following LV's suggestion below, it returns a GNU-style "canonical system"):
switch $tcl_platform(os) { ... IRIX - IRIX64 { return "mips-sgi-irix$tcl_platform(osVersion)" } ... }(IRIX64 only indicates that the machine is 'capable' of 64-bit. Since by default Tcl uses the n32 ABI even on IRIX64 machines, IRIX64 and IRIX are handled the same way. This is what GNU config.guess does.)
Anyway, the idea for this page is to tweak the above [platform] command, so we can use it as "easy shared-lib discriminator" on more and more platforms. Here's a modified version with Bob's HPUX changes added:
proc platform {} { global tcl_platform set plat [lindex $tcl_platform(os) 0] set mach $tcl_platform(machine) switch -glob -- $mach { sun4* { set mach sparc } intel - i*86* { set mach x86 } "Power Macintosh" { set mach ppc } 9000* {set mach 9000} } set mach [regsub -all {[ /]} $mach "-"] return "$plat-$mach" }Please feel free to alter the above (carefully, so it doesn't break). The history of this page (warning: it only gets updated once per day) can be used to see all previous versions if you need to go back and check things out:
http://mini.net/tclhist/8522~ (annotated per line) http://mini.net/tclhist/8522* (list of all versions)
LV Any reason to not pattern the names after autoconf's config.guess ? For instance, platform, above, says on my sparc solaris 2.6 machine:
SunOS-sparcwhile config.guess says
sparc-sun-solaris2.6Without OS version, you run into basic runtime incompatibilities (like between major releases of Linux and Solaris at least - maybe other platforms as well). config.guess when possible.stevel Yes - there's a reason - this was done to facilitate loading platform specific shared libraries when, in most instances, the OS version is irrelevant (and can be obtained if you need it).JE But on platforms where the OS version 'is' relevant (SunOS and IRIX come to mind), it should be included in the identifier.
Another reason for generating generic platform names is to make tcl_platform(machine) consistent across platforms. For example, Power PC should be "ppc" on both AIX and MacOSX. At the moment on MacOSX it is "Power Macintosh" whereas on Linux it is "ppc". Note that CriTcl tries to do this as far as is possible (e.g. ppc, x86, sparc, etc) - stevel
Another issue we need to address is that certain platforms encode the unique machine ID in tcl_platform(machine) - and this needs to be extracted if the value of tcl_platform(machine) is going to be useful.For example, whereas on Linux/x86 you get something like
tcl_platform(byteOrder) = littleEndian tcl_platform(machine) = i686 tcl_platform(os) = Linux tcl_platform(osVersion) = 2.4.19-64GB-SMP tcl_platform(platform) = unix tcl_platform(user) = steve tcl_platform(wordSize) = 4But on AIX, for example, I get
tcl_platform(byteOrder) = bigEndian tcl_platform(machine) = 0042065B4C00 tcl_platform(os) = AIX tcl_platform(osVersion) = 5.1 tcl_platform(platform) = unix tcl_platform(user) = steve tcl_platform(wordSize) = 4In particular, note the machine field - this is the same as is returned by "uname -m". The uname man page says
- "The machine ID number contains 12 characters in the following digit format: xxyyyyyymmss. The xx positions indicate the system and is always 00. The yyyyyy positions contain the unique ID number for the entire system. The mm position represents the model ID. The ss position is the submodel number and is always 00. The model ID describes the ID of the CPU Planar, not the model of the System as a whole."
if {$plat eq "AIX"} { set mach ppc } if {$plat eq "HP-UX"} { set mach hppa }Note the last one conflicts with Bob's suggestion - so I haven't added it to platform()stevel
See also PkgIndexUtil.tcl - determining a platform name
PWQ 13 Feb 06, The obvious qustion that noone has asked is , why is the above such a mess and who determines what string is returned for what platform?.The big problem with all the above is that you cannot test your code unless you have the platform in question as you won't know what string to test for , or more importantly what difference this platform has that you have to have a test.All the above is to make up for poor decision making that has not been corrected.
LV In Tcl 8.5, a new package called platform has various functions some of which, when called, return a string of a specific format for identifying a platform.