Python: fix +tkinter+tix support (#23980)
* Tcl: fix TCLLIBPATH * Fix TCL|TK|TIX_LIBRARY paths * Fix TCL_LIBRARY, no tcl8.6 subdir * Don't rely on os.listdirs sorting For tcl and tk, we also install the source directory, so there are two init.tcl and tk.tcl locations. We want the one in lib/lib64, which should come before the one in share. * Add more patches * Fix dylib on macOS * Tk: add smoke tests * Tix: add smoke test
This commit is contained in:
parent
f33c4e7280
commit
92be358582
@ -9,14 +9,13 @@
|
||||
|
||||
|
||||
class Tcl(AutotoolsPackage, SourceforgePackage):
|
||||
"""Tcl (Tool Command Language) is a very powerful but easy to
|
||||
learn dynamic programming language, suitable for a very wide
|
||||
range of uses, including web and desktop applications,
|
||||
networking, administration, testing and many more. Open source
|
||||
and business-friendly, Tcl is a mature yet evolving language
|
||||
that is truly cross platform, easily deployed and highly
|
||||
extensible."""
|
||||
homepage = "http://www.tcl.tk"
|
||||
"""Tcl (Tool Command Language) is a very powerful but easy to learn dynamic
|
||||
programming language, suitable for a very wide range of uses, including web and
|
||||
desktop applications, networking, administration, testing and many more. Open source
|
||||
and business-friendly, Tcl is a mature yet evolving language that is truly cross
|
||||
platform, easily deployed and highly extensible."""
|
||||
|
||||
homepage = "https://www.tcl.tk/"
|
||||
sourceforge_mirror_path = "tcl/tcl8.6.11-src.tar.gz"
|
||||
|
||||
version('8.6.11', sha256='8c0486668586672c5693d7d95817cb05a18c5ecca2f40e2836b9578064088258')
|
||||
@ -38,7 +37,7 @@ def install(self, spec, prefix):
|
||||
with working_dir(self.build_directory):
|
||||
make('install')
|
||||
|
||||
# http://wiki.tcl.tk/17463
|
||||
# https://wiki.tcl-lang.org/page/kitgen
|
||||
if self.spec.satisfies('@8.6:'):
|
||||
make('install-headers')
|
||||
|
||||
@ -81,22 +80,39 @@ def libs(self):
|
||||
def command(self):
|
||||
"""Returns the tclsh command.
|
||||
|
||||
:returns: The tclsh command
|
||||
:rtype: Executable
|
||||
Returns:
|
||||
Executable: the tclsh command
|
||||
"""
|
||||
return Executable(os.path.realpath(self.prefix.bin.tclsh))
|
||||
# Although we symlink tclshX.Y to tclsh, we also need to support external
|
||||
# installations that may not have this symlink, or may have multiple versions
|
||||
# of Tcl installed in the same directory.
|
||||
return Executable(os.path.realpath(self.prefix.bin.join(
|
||||
'tclsh{0}'.format(self.version.up_to(2)))))
|
||||
|
||||
def setup_run_environment(self, env):
|
||||
# When using Tkinter from within spack provided python+tkinter, python
|
||||
# will not be able to find Tcl/Tk unless TCL_LIBRARY is set.
|
||||
env.set('TCL_LIBRARY', self.spec['tcl'].libs.directories[0])
|
||||
"""Set TCL_LIBRARY to the directory containing init.tcl.
|
||||
|
||||
For further info see:
|
||||
|
||||
* https://wiki.tcl-lang.org/page/TCL_LIBRARY
|
||||
"""
|
||||
# When using tkinter from within spack provided python+tkinter,
|
||||
# python will not be able to find Tcl unless TCL_LIBRARY is set.
|
||||
env.set('TCL_LIBRARY', os.path.dirname(
|
||||
sorted(find(self.prefix, 'init.tcl'))[0]))
|
||||
|
||||
def setup_dependent_build_environment(self, env, dependent_spec):
|
||||
"""Set TCLLIBPATH to include the tcl-shipped directory for
|
||||
"""Set TCL_LIBRARY to the directory containing init.tcl.
|
||||
Set TCLLIBPATH to include the tcl-shipped directory for
|
||||
extensions and any other tcl extension it depends on.
|
||||
For further info see: https://wiki.tcl.tk/1787"""
|
||||
|
||||
env.set('TCL_LIBRARY', self.spec['tcl'].libs.directories[0])
|
||||
For further info see:
|
||||
|
||||
* https://wiki.tcl-lang.org/page/TCL_LIBRARY
|
||||
* https://wiki.tcl-lang.org/page/TCLLIBPATH
|
||||
"""
|
||||
env.set('TCL_LIBRARY', os.path.dirname(
|
||||
sorted(find(self.prefix, 'init.tcl'))[0]))
|
||||
|
||||
# If we set TCLLIBPATH, we must also ensure that the corresponding
|
||||
# tcl is found in the build environment. This to prevent cases
|
||||
@ -106,35 +122,40 @@ def setup_dependent_build_environment(self, env, dependent_spec):
|
||||
if not is_system_path(self.prefix.bin):
|
||||
env.prepend_path('PATH', self.prefix.bin)
|
||||
|
||||
tcl_paths = [join_path(self.spec['tcl'].libs.directories[0],
|
||||
'tcl{0}'.format(self.version.up_to(2)))]
|
||||
# WARNING: paths in $TCLLIBPATH must be *space* separated,
|
||||
# its value is meant to be a Tcl list, *not* an env list
|
||||
# as explained here: https://wiki.tcl-lang.org/page/TCLLIBPATH:
|
||||
# "TCLLIBPATH is a Tcl list, not some platform-specific
|
||||
# colon-separated or semi-colon separated format"
|
||||
|
||||
# WARNING: Tcl and Tcl extensions like Tk install their configuration files
|
||||
# in subdirectories like `<prefix>/lib/tcl8.6`. However, Tcl is aware of this,
|
||||
# and $TCLLIBPATH should only contain `<prefix>/lib`. $TCLLIBPATH is only needed
|
||||
# because we install Tcl extensions to different directories than Tcl. See:
|
||||
# https://core.tcl-lang.org/tk/tktview/447bd3e4abe17452d19a80e6840dcc8a2603fcbc
|
||||
env.prepend_path(
|
||||
'TCLLIBPATH', self.spec['tcl'].libs.directories[0], separator=' ')
|
||||
|
||||
for d in dependent_spec.traverse(deptype=('build', 'run', 'test')):
|
||||
if d.package.extends(self.spec):
|
||||
# Tcl libraries may be installed in lib or lib64, see #19546
|
||||
for lib in ['lib', 'lib64']:
|
||||
tcl_paths.append(join_path(
|
||||
d.prefix, lib, 'tcl{0}'.format(self.version.up_to(2))))
|
||||
|
||||
# WARNING: paths in $TCLLIBPATH must be *space* separated,
|
||||
# its value is meant to be a Tcl list, *not* an env list
|
||||
# as explained here: https://wiki.tcl.tk/1787:
|
||||
# "TCLLIBPATH is a Tcl list, not some platform-specific
|
||||
# colon-separated or semi-colon separated format"
|
||||
tcllibpath = ' '.join(tcl_paths)
|
||||
env.set('TCLLIBPATH', tcllibpath)
|
||||
tcllibpath = join_path(d.prefix, lib)
|
||||
if os.path.exists(tcllibpath):
|
||||
env.prepend_path('TCLLIBPATH', tcllibpath, separator=' ')
|
||||
|
||||
def setup_dependent_run_environment(self, env, dependent_spec):
|
||||
"""Set TCLLIBPATH to include the tcl-shipped directory for
|
||||
extensions and any other tcl extension it depends on.
|
||||
For further info see: https://wiki.tcl.tk/1787"""
|
||||
|
||||
# For run time environment set only the path for
|
||||
# dependent_spec and prepend it to TCLLIBPATH
|
||||
if dependent_spec.package.extends(self.spec):
|
||||
# Tcl libraries may be installed in lib or lib64, see #19546
|
||||
for lib in ['lib', 'lib64']:
|
||||
tcllibpath = join_path(
|
||||
self.prefix, lib, 'tcl{0}'.format(self.version.up_to(2)))
|
||||
if os.path.exists(tcllibpath):
|
||||
env.prepend_path('TCLLIBPATH', tcllibpath, separator=' ')
|
||||
For further info see:
|
||||
|
||||
* https://wiki.tcl-lang.org/page/TCLLIBPATH
|
||||
"""
|
||||
for d in dependent_spec.traverse(deptype=('build', 'run', 'test')):
|
||||
if d.package.extends(self.spec):
|
||||
# Tcl libraries may be installed in lib or lib64, see #19546
|
||||
for lib in ['lib', 'lib64']:
|
||||
tcllibpath = join_path(d.prefix, lib)
|
||||
if os.path.exists(tcllibpath):
|
||||
env.prepend_path('TCLLIBPATH', tcllibpath, separator=' ')
|
||||
|
@ -3,20 +3,46 @@
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
import os
|
||||
|
||||
from spack import *
|
||||
|
||||
|
||||
class Tix(AutotoolsPackage):
|
||||
"""Tix is a powerful high-level widget set that expands the capabilities
|
||||
of your Tk/Tcl and Python applications."""
|
||||
"""Tix, the Tk Interface eXtension, is a powerful set of user interface components
|
||||
that expands the capabilities of your Tcl/Tk and Python applications. Using Tix
|
||||
together with Tk will greatly enhance the appearance and functionality of your
|
||||
application."""
|
||||
|
||||
homepage = "https://sourceforge.net/projects/tix/"
|
||||
url = "https://sourceforge.net/projects/tix/files/tix/8.4.3/Tix8.4.3-src.tar.gz/download"
|
||||
|
||||
version('8.4.3', sha256='562f040ff7657e10b5cffc2c41935f1a53c6402eb3d5f3189113d734fd6c03cb')
|
||||
|
||||
extends('tcl')
|
||||
depends_on('tk@:8.5.99')
|
||||
depends_on('tcl@:8.5.99')
|
||||
extends('tcl', type=('build', 'link', 'run'))
|
||||
depends_on('tk', type=('build', 'link', 'run'))
|
||||
|
||||
patch('https://raw.githubusercontent.com/macports/macports-ports/master/x11/tix/files/panic.patch',
|
||||
sha256='1be1a1c7453f6ab8771f90d7e7c0f8959490104752a16a8755bbb7287a841a96',
|
||||
level=0)
|
||||
patch('https://raw.githubusercontent.com/macports/macports-ports/master/x11/tix/files/implicit.patch',
|
||||
sha256='8a2720368c7757896814684147029d8318b9aa3b0914b3f37dd5e8a8603a61d3',
|
||||
level=0)
|
||||
patch('https://raw.githubusercontent.com/macports/macports-ports/master/x11/tix/files/patch-generic-tixGrSort.c.diff',
|
||||
sha256='99b33cc307f71bcf9cc6f5a44b588f22956884ce3f1e4c716ad64c79cf9c5f41',
|
||||
level=0)
|
||||
patch('https://raw.githubusercontent.com/macports/macports-ports/master/x11/tix/files/patch-missing-headers.diff',
|
||||
sha256='d9f789dcfe5f4c5ee4589a18f9f410cdf162e41d35d00648c1ef37831f4a2b2b',
|
||||
level=0)
|
||||
patch('https://raw.githubusercontent.com/macports/macports-ports/master/x11/tix/files/patch-tk_x11.diff',
|
||||
sha256='1e28d8eee1aaa956a00571cf495a4775e72a993958dff1cabfbc5f102e327a6f',
|
||||
level=0)
|
||||
patch('https://raw.githubusercontent.com/macports/macports-ports/master/x11/tix/files/patch-tk_aqua.diff',
|
||||
sha256='41a717f5d95f61b4b8196ca6f14ece8f4764d4ba58fb2e1ae15e3240ee5ac534',
|
||||
level=0, when='platform=darwin')
|
||||
patch('https://raw.githubusercontent.com/macports/macports-ports/master/x11/tix/files/patch-dyld_variable.diff',
|
||||
sha256='719eb2e4d8c5d6aae897e5f676cf5ed1a0005c1bd07fd9b18705d81a005f592b',
|
||||
level=0, when='platform=darwin')
|
||||
|
||||
def configure_args(self):
|
||||
spec = self.spec
|
||||
@ -27,7 +53,39 @@ def configure_args(self):
|
||||
]
|
||||
return args
|
||||
|
||||
@run_after('install')
|
||||
def darwin_fix(self):
|
||||
# The shared library is not installed correctly on Darwin; fix this
|
||||
if 'platform=darwin' in self.spec:
|
||||
fix_darwin_install_name(self.prefix.lib.Tix + str(self.version))
|
||||
|
||||
def test(self):
|
||||
test_data_dir = self.test_suite.current_test_data_dir
|
||||
test_file = test_data_dir.join('test.tcl')
|
||||
self.run_test(self.spec['tcl'].command.path, test_file,
|
||||
purpose='test that tix can be loaded')
|
||||
|
||||
@property
|
||||
def libs(self):
|
||||
return find_libraries(['libTix{0}'.format(self.version)],
|
||||
root=self.prefix, recursive=True)
|
||||
|
||||
def setup_run_environment(self, env):
|
||||
"""Set TIX_LIBRARY to the directory containing Tix.tcl.
|
||||
|
||||
For further info, see:
|
||||
|
||||
* http://tix.sourceforge.net/docs/pdf/TixUser.pdf
|
||||
"""
|
||||
# When using tkinter.tix from within spack provided python+tkinter+tix,
|
||||
# python will not be able to find Tix unless TIX_LIBRARY is set.
|
||||
env.set('TIX_LIBRARY', os.path.dirname(find(self.prefix, 'Tix.tcl')[0]))
|
||||
|
||||
def setup_dependent_build_environment(self, env, dependent_spec):
|
||||
"""Set TIX_LIBRARY to the directory containing Tix.tcl.
|
||||
|
||||
For further info, see:
|
||||
|
||||
* http://tix.sourceforge.net/docs/pdf/TixUser.pdf
|
||||
"""
|
||||
env.set('TIX_LIBRARY', os.path.dirname(find(self.prefix, 'Tix.tcl')[0]))
|
||||
|
5
var/spack/repos/builtin/packages/tix/test/test.tcl
Normal file
5
var/spack/repos/builtin/packages/tix/test/test.tcl
Normal file
@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env tclsh
|
||||
|
||||
package require Tix
|
||||
|
||||
exit
|
@ -3,18 +3,18 @@
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
from spack import *
|
||||
import os
|
||||
|
||||
from spack import *
|
||||
|
||||
|
||||
class Tk(AutotoolsPackage, SourceforgePackage):
|
||||
"""Tk is a graphical user interface toolkit that takes developing
|
||||
desktop applications to a higher level than conventional
|
||||
approaches. Tk is the standard GUI not only for Tcl, but for
|
||||
many other dynamic languages, and can produce rich, native
|
||||
applications that run unchanged across Windows, Mac OS X, Linux
|
||||
and more."""
|
||||
homepage = "http://www.tcl.tk"
|
||||
"""Tk is a graphical user interface toolkit that takes developing desktop
|
||||
applications to a higher level than conventional approaches. Tk is the standard GUI
|
||||
not only for Tcl, but for many other dynamic languages, and can produce rich, native
|
||||
applications that run unchanged across Windows, Mac OS X, Linux and more."""
|
||||
|
||||
homepage = "https://www.tcl.tk"
|
||||
sourceforge_mirror_path = "tcl/tk8.6.5-src.tar.gz"
|
||||
|
||||
version('8.6.11', sha256='5228a8187a7f70fa0791ef0f975270f068ba9557f57456f51eb02d9d4ea31282')
|
||||
@ -25,14 +25,12 @@ class Tk(AutotoolsPackage, SourceforgePackage):
|
||||
version('8.6.3', sha256='ba15d56ac27d8c0a7b1a983915a47e0f635199b9473cf6e10fbce1fc73fd8333')
|
||||
version('8.5.19', sha256='407af1de167477d598bd6166d84459a3bdccc2fb349360706154e646a9620ffa')
|
||||
|
||||
variant('xft', default=True,
|
||||
description='Enable X FreeType')
|
||||
variant('xss', default=True,
|
||||
description='Enable X Screen Saver')
|
||||
variant('xft', default=True, description='Enable X FreeType')
|
||||
variant('xss', default=True, description='Enable X Screen Saver')
|
||||
|
||||
extends('tcl')
|
||||
extends('tcl', type=('build', 'link', 'run'))
|
||||
|
||||
depends_on('tcl@8.6:', when='@8.6:')
|
||||
depends_on('tcl@8.6:', type=('build', 'link', 'run'), when='@8.6:')
|
||||
depends_on('libx11')
|
||||
depends_on('libxft', when='+xft')
|
||||
depends_on('libxscrnsaver', when='+xss')
|
||||
@ -45,6 +43,21 @@ class Tk(AutotoolsPackage, SourceforgePackage):
|
||||
patch('https://raw.githubusercontent.com/macports/macports-ports/master/x11/tk/files/patch-unix-Makefile.in.diff',
|
||||
sha256='54bba3d2b3550b7e2c636881c1a3acaf6e1eb743f314449a132864ff47fd0010',
|
||||
level=0, when='@:8.6.11 platform=darwin')
|
||||
patch('https://raw.githubusercontent.com/macports/macports-ports/master/x11/tk/files/patch-dyld_fallback_library_path.diff',
|
||||
sha256='9ce6512f1928db9987986f4d3540207c39429395d5234bd6489ba9d86a6d9c31',
|
||||
level=0, when='platform=darwin')
|
||||
|
||||
def configure_args(self):
|
||||
spec = self.spec
|
||||
config_args = [
|
||||
'--with-tcl={0}'.format(spec['tcl'].libs.directories[0]),
|
||||
'--x-includes={0}'.format(spec['libx11'].headers.directories[0]),
|
||||
'--x-libraries={0}'.format(spec['libx11'].libs.directories[0])
|
||||
]
|
||||
config_args += self.enable_or_disable('xft')
|
||||
config_args += self.enable_or_disable('xss')
|
||||
|
||||
return config_args
|
||||
|
||||
def install(self, spec, prefix):
|
||||
with working_dir(self.build_directory):
|
||||
@ -64,32 +77,54 @@ def install(self, spec, prefix):
|
||||
stage_src, installed_src,
|
||||
join_path(self.spec['tk'].libs.directories[0], 'tkConfig.sh'))
|
||||
|
||||
@run_after('install')
|
||||
def symlink_wish(self):
|
||||
with working_dir(self.prefix.bin):
|
||||
symlink('wish{0}'.format(self.version.up_to(2)), 'wish')
|
||||
|
||||
def test(self):
|
||||
self.run_test(self.spec['tk'].command.path, ['-h'],
|
||||
purpose='test wish command')
|
||||
|
||||
test_data_dir = self.test_suite.current_test_data_dir
|
||||
test_file = test_data_dir.join('test.tcl')
|
||||
self.run_test(self.spec['tcl'].command.path, test_file,
|
||||
purpose='test that tk can be loaded')
|
||||
|
||||
@property
|
||||
def command(self):
|
||||
"""Returns the wish command.
|
||||
|
||||
Returns:
|
||||
Executable: the wish command
|
||||
"""
|
||||
# Although we symlink wishX.Y to wish, we also need to support external
|
||||
# installations that may not have this symlink, or may have multiple versions
|
||||
# of Tk installed in the same directory.
|
||||
return Executable(os.path.realpath(self.prefix.bin.join(
|
||||
'wish{0}'.format(self.version.up_to(2)))))
|
||||
|
||||
@property
|
||||
def libs(self):
|
||||
return find_libraries(['libtk{0}'.format(self.version.up_to(2))],
|
||||
root=self.prefix, recursive=True)
|
||||
|
||||
def setup_run_environment(self, env):
|
||||
# When using Tkinter from within spack provided python+tkinter, python
|
||||
# will not be able to find Tcl/Tk unless TK_LIBRARY is set.
|
||||
env.set('TK_LIBRARY', self.spec['tk'].libs.directories[0])
|
||||
"""Set TK_LIBRARY to the directory containing tk.tcl.
|
||||
|
||||
For further info, see:
|
||||
|
||||
* https://www.tcl-lang.org/man/tcl/TkCmd/tkvars.htm
|
||||
"""
|
||||
# When using tkinter from within spack provided python+tkinter,
|
||||
# python will not be able to find Tk unless TK_LIBRARY is set.
|
||||
env.set('TK_LIBRARY', os.path.dirname(sorted(find(self.prefix, 'tk.tcl'))[0]))
|
||||
|
||||
def setup_dependent_build_environment(self, env, dependent_spec):
|
||||
env.set('TK_LIBRARY', self.spec['tk'].libs.directories[0])
|
||||
"""Set TK_LIBRARY to the directory containing tk.tcl.
|
||||
|
||||
def configure_args(self):
|
||||
spec = self.spec
|
||||
config_args = [
|
||||
'--with-tcl={0}'.format(spec['tcl'].libs.directories[0]),
|
||||
'--x-includes={0}'.format(spec['libx11'].headers.directories[0]),
|
||||
'--x-libraries={0}'.format(spec['libx11'].libs.directories[0])
|
||||
]
|
||||
config_args += self.enable_or_disable('xft')
|
||||
config_args += self.enable_or_disable('xss')
|
||||
For further info, see:
|
||||
|
||||
return config_args
|
||||
|
||||
@run_after('install')
|
||||
def symlink_wish(self):
|
||||
with working_dir(self.prefix.bin):
|
||||
symlink('wish{0}'.format(self.version.up_to(2)), 'wish')
|
||||
* https://www.tcl-lang.org/man/tcl/TkCmd/tkvars.htm
|
||||
"""
|
||||
env.set('TK_LIBRARY', os.path.dirname(sorted(find(self.prefix, 'tk.tcl'))[0]))
|
||||
|
5
var/spack/repos/builtin/packages/tk/test/test.tcl
Normal file
5
var/spack/repos/builtin/packages/tk/test/test.tcl
Normal file
@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env tclsh
|
||||
|
||||
package require Tk
|
||||
|
||||
exit
|
Loading…
Reference in New Issue
Block a user