Tcl Source Code

View Ticket
Login
Ticket UUID: 61ba0b0661a14a921665500d77e5d8ac2543724a
Title: platform::identify broken on Red Hat Linux
Type: Bug Created on: 2026-07-10 18:07:14
Submitter: tomkiti Assigned to: jan.nijtmans
Subsystem: 81. Bundled Packages Severity: Critical
Priority: 5 Medium Last modified: 2026-09-22 07:34:00
Status: Closed Closed by: jan.nijtmans
Resolution: Fixed Closed on: 2026-09-22 07:34:00
Version: tip
Description:

The latest patch of platform.tcl [086b65e08f] throws an error on RHEL 8, 9, and 10:

package require platform
puts [platform::identify]

can't read "v": no such variable
    while executing
"split $v ."

platform::identify was changed from executing libc.so to executing ldd --version (https://core.tcl-lang.org/tcl/tktview/917c4a896afc744d7d5310a68ceccad4afcb2a6e). On Red Hat 10, the output is:

bash-5.2$ ldd --version
ldd (GNU libc) 2.39
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

The new patch uses the regular expression GLIBC ([0-9]+(\.[0-9]+)*), which does not match the output, so the variable v is never set. Suggest matching just the version number at the end of the first line.

User Comments:
apnadkarni added on 2026-07-11 03:11:34:
I'm not a big fan of executing external programs. Aside from security implications, output formats can change between different versions of the program or even between different localized platforms for the same version (at least on Windows, not sure about Linux/Unix).

I suspect the regexp will also fail for alternative Linux runtimes like musl.

Since `platform::identify` on Linux seems to mean the glibc version, would an alternative solution be to include the result of `gnu_get_libc_version` in the `tcl::build-info` and pick up the value from there? (Of course under __GLIBC__ conditional, "unknown" otherwise.)

jan.nijtmans added on 2026-07-11 10:53:14:

`tcl::build-info` is meant for information about how Tcl was built. The runtime glibc version doesn't belong there. But it could be added as a ::tcl::unsupported command, picked up by platform::identify if available (giving 'unknown' when not available).


jan.nijtmans added on 2026-07-13 12:13:27:

How about [c70ad78618832726|this]?

Thinking about it, I doubt the usefulness of the glibc version number in the identity. It would be more useful to just detect glibc vs musl vs unknown. Applications compiled for musl won't run on glibc-based linux and reverse, so that's useful to detect here.

Since platform::identity is broken already for a long time (always returning *-unknown-*), I doubt it's worth to make it more elaborate than this.


jan.nijtmans added on 2026-07-13 13:59:54:

I tried this on Alpine Linux: It doesn't work yet, because "ldd --version" writes to stderr in stead of stdout. This can be handled, but isn't done yet in this branch.


apnadkarni added on 2026-07-14 05:19:08:
The only use I have personally found for platform::identify is to distribute multiplatform packages on Windows with the shared libraries under the subdirectories as returned by platform::identify. I don't know if this kind of installation also makes sense for platforms other than Windows but if so, would there be compatibility issues by removing the version?

Other than that, not competent enough to comment.

jan.nijtmans added on 2026-07-14 08:13:59:

> would there be compatibility issues by removing the version?

I don't expect so, since this has been broken a long time, just returning linux-unknown-${cpu} for a long time. No-one reported this.

For Linux I expect the same usage as you describe for Windows. It would be possible to make subdirectories for every possible value of platform::identity. If we have the glibc version number in it, it would mean the user has to create shared libraries for every possible version of glibc. I don't think that's usefull.

Anyway, I now committed the fix to trunk. It now works for Linux (either 'glibc', 'musl' or 'unknown'). If it causes problems, please report it!


tomkiti added on 2026-07-14 11:57:10:

On RHEL 10, platform::identify now returns linux-glibc-x86_64. I need it to return linux-glibc2.39-x86_64, since I support multiple platforms and use that string as a directory name to store the binary libraries. Since RHEL 9, I've just been patching the glob pattern in ::platform::LibcVersion from libc* to libc.so.*.


jan.nijtmans added on 2026-07-14 13:26:26:

@tomkiti. Are you providing binaries for glibc 2.39, 2.40, 2.41, 2.42, 2.43 .... ? Would it be possible to produce a binary for glibc 2.38 (for example) and store it in a directory linux-glibc-x86_64 in addition to linux-glibc2.38-x86_64? This binary should work with higher glibc versions as well, isn't it?

I realize this is a change, but since glibc versions change twice a year I don't think it's reasonable to provide a binary for so many different glibc versions.


tomkiti added on 2026-07-14 16:54:37:

I've been using platform::identify since glibc2.5 (RHEL 5) in 2007. My architecture depends on the string including the version number. This scheme has worked flawlessly for 19 years across numerous Linux varieties. I'm sure the proposed change would affect many other people besides myself.


jan.nijtmans added on 2026-07-14 20:55:58:

Thanks! I'll revisit this after my vacation


anonymous added on 2026-07-27 21:04:08:

The current version breaks platform::patterns, when running

> tclsh platform.tcl


tcl_platform(byteOrder)     = littleEndian
tcl_platform(engine)        = Tcl
tcl_platform(machine)       = x86_64
tcl_platform(os)            = Linux
tcl_platform(osVersion)     = 6.17.0-35-generic
tcl_platform(pathSeparator) = :
tcl_platform(platform)      = unix
tcl_platform(pointerSize)   = 8
tcl_platform(user)          = obermeier
tcl_platform(wordSize)      = 8
====================================
Generic identification: linux-x86_64
Exact identification:   linux-glibc-x86_64
====================================
Search patterns:
expected integer but got ""
    while executing
"incr minor -1"
    (procedure "::platform::patterns" line 19)
    invoked from within
"::platform::patterns [::platform::identify]"
    invoked from within
"if {[info exists argv0] && ($argv0 eq [info script])} {
    puts ====================================
    parray tcl_platform
    puts ===============..."
    (file "platform.tcl" line 351)

Paul


jan.nijtmans added on 2026-09-09 12:51:40:

The `platform::patterns` problem should be fixed [aa19237f0855e463|here]

Still having a further look ....


tomkiti added on 2026-09-18 18:01:57:
Are you going to remove the glibc version number? If so, I'll have to maintain my own version of platform.tcl forever because I depend on it.

jan.nijtmans added on 2026-09-21 10:02:38:

Platform-1.1 has been broken a long time, always giving linux-unknown-$cpu, and it never worked on musl. Also glibc 2.x is always upwards compatible. So, applications compiled with an older glibc 2.x version always works fine on a newer glibc 2.x version. Therefore - the solution is to always compile applications/extensions against the oldest glibc version you want to support.

So, how about upwards/backwards compatibility. I propose to add the linux-glibc-$cpu and linux-unknown-$cpu directories to platform-1.1.2. This way, those directories can always be found, and you can simply place your binary in "linux-glibc-$cpu", without the need for further version numbers. If you still want to support older platform versions, just create a link from the linux-glibc-$cpu directory to linux-glibc?.?-$cpu directory (where ?.? stands for the oldest glibc version you support).

This way, you have the choice to stick with platform-1.1.x or switch to platform-1.2.x, this directory structure will continue to work with both. I won't backport platform-1.2.x to Tcl 9.0, in order to give more time to make the switch.

In short: The "linux-unknown-$cpu" is meant for extensions with statically linked libc (could be glibc, musl or any other). "linux-glibc-$cpu" is meant for linking against glibc, "linux-musl-$cpu" is meant for linking against musl. Note that platform-1.1 won't work with musl at all.

Hope this helps, Jan Nijtmans


jan.nijtmans added on 2026-09-21 11:43:41:

Just as a demo, this is what "tclsh platform.tcl" gives on latest Linux (WSL).

I don't think this is reasonable any more:

====================================
tcl_platform(byteOrder)     = littleEndian
tcl_platform(engine)        = Tcl
tcl_platform(machine)       = x86_64
tcl_platform(os)            = Linux
tcl_platform(osVersion)     = 6.18.35.2-microsoft-standard-WSL2
tcl_platform(pathSeparator) = :
tcl_platform(platform)      = unix
tcl_platform(pointerSize)   = 8
tcl_platform(user)          = jan
tcl_platform(wordSize)      = 8
====================================
Generic identification: linux-x86_64
Exact identification:   linux-glibc2.43-x86_64
====================================
Search patterns:
* linux-glibc2.43-x86_64
* linux-glibc2.42-x86_64
* linux-glibc2.41-x86_64
* linux-glibc2.40-x86_64
* linux-glibc2.39-x86_64
* linux-glibc2.38-x86_64
* linux-glibc2.37-x86_64
* linux-glibc2.36-x86_64
* linux-glibc2.35-x86_64
* linux-glibc2.34-x86_64
* linux-glibc2.33-x86_64
* linux-glibc2.32-x86_64
* linux-glibc2.31-x86_64
* linux-glibc2.30-x86_64
* linux-glibc2.29-x86_64
* linux-glibc2.28-x86_64
* linux-glibc2.27-x86_64
* linux-glibc2.26-x86_64
* linux-glibc2.25-x86_64
* linux-glibc2.24-x86_64
* linux-glibc2.23-x86_64
* linux-glibc2.22-x86_64
* linux-glibc2.21-x86_64
* linux-glibc2.20-x86_64
* linux-glibc2.19-x86_64
* linux-glibc2.18-x86_64
* linux-glibc2.17-x86_64
* linux-glibc2.16-x86_64
* linux-glibc2.15-x86_64
* linux-glibc2.14-x86_64
* linux-glibc2.13-x86_64
* linux-glibc2.12-x86_64
* linux-glibc2.11-x86_64
* linux-glibc2.10-x86_64
* linux-glibc2.9-x86_64
* linux-glibc2.8-x86_64
* linux-glibc2.7-x86_64
* linux-glibc2.6-x86_64
* linux-glibc2.5-x86_64
* linux-glibc2.4-x86_64
* linux-glibc2.3-x86_64
* linux-glibc2.2-x86_64
* linux-glibc2.1-x86_64
* linux-glibc2.0-x86_64
* linux-glibc-x86_64
* linux-unknown-x86_64
* tcl
====================================


oehhar added on 2026-09-21 14:38:11:

The biweekly telco of today has agreed to remove the glibc version from the choices for 9.1. Any comments to this, please speak up here.

Thanks for all, Harald