背景:我正在开发一种 git 前端,它应该能够启动 gitk 和 git-gui,这两个都是 tcl/tk 程序。它在常规 Linux 上工作正常,但在 snap 容器内工作时会出现问题
在 snap 容器中,文件系统的根目录以 snap 容器路径为前缀,因此该路径 现在到 tck/tk 库:
/snap/multigit/x21/usr/share/tcltk/tcl8.6
/snap/multigit/x21/usr/share/tcltk/tk8.6
理论上,tcl有一个机制来处理这个问题。在实践中,我没能成功。所有示例 列出的内容在 snap 容器内执行。
没有任何调整,看起来像这样:
osboxes@osboxes:/snap/multigit/x21/usr/share/tcltk$ gitk
application-specific initialization failed: Can't find a usable init.tcl in the following directories:
/usr/share/tcltk/tcl8.6 /snap/multigit/x21/usr/lib/tcl8.6 /snap/multigit/x21/lib/tcl8.6 /snap/multigit/x21/usr/library /snap/multigit/x21/library /snap/multigit/x21/tcl8.6.12/library /snap/multigit/tcl8.6.12/library
This probably means that Tcl wasn't installed properly.
Error in startup script: can't find package Tk
while executing
"package require Tk"
(file "/snap/multigit/x21/usr/bin/gitk" line 10)
这个很清楚,我需要将 TCL 指向它的库位置,并且有一个变量:TCL_LIBRARY
让我们将其指向 tcl 和 tk 的公共目录:
osboxes@osboxes:/snap/multigit/x21/usr/share/tcltk$ export TCL_LIBRARY="/snap/multigit/x21/usr/share/tcltk"
然后:
osboxes@osboxes:/snap/multigit/x21/usr/share/tcltk$ gitk
application-specific initialization failed: Can't find a usable init.tcl in the following directories:
/snap/multigit/x21/usr/share/tcltk /snap/multigit/x21/usr/share/tcl8.6 /usr/share/tcltk/tcl8.6 /snap/multigit/x21/usr/lib/tcl8.6 /snap/multigit/x21/lib/tcl8.6 /snap/multigit/x21/usr/library /snap/multigit/x21/library /snap/multigit/x21/tcl8.6.12/library /snap/multigit/tcl8.6.12/library
This probably means that Tcl wasn't installed properly.
Error in startup script: can't find package Tk
while executing
"package require Tk"
(file "/snap/multigit/x21/usr/bin/gitk" line 10)
还不够!
让我们将其指向 tcl 库的目录:
osboxes@osboxes:/snap/multigit/x21/usr/share/tcltk$ export TCL_LIBRARY="/snap/multigit/x21/usr/share/tcltk/tcl8.6"
osboxes@osboxes:/snap/multigit/x21/usr/share/tcltk$ gitk
Error in startup script: can't find package msgcat
while executing
"package require msgcat"
(file "/snap/multigit/x21/usr/bin/gitk" line 12279)
osboxes@osboxes:/snap/multigit/x21/usr/share/tcltk$
好多了,tcl 库已经加载,gitk 可以开始执行了。但它错过了 msgcat。它在哪里?
osboxes@osboxes:/snap/multigit/x21/usr/share/tcltk$ find . | grep msgcat
./tcl8.6/tcl8/msgcat-1.6.1.tm
不明显,它与其他 tcl 库位于同一位置,但位于子目录中
tcl8
.
所以问题是:如何告诉 tcl 在其 TCL_LIBRARY 变量中递归查找,或者如何在 TCL_LIBRARY 中传递多个路径?
我尝试了多种将两个目录放入 TCL_LIBRARY 的组合,所有这些都告诉我它无法考虑多个路径:
export TCL_LIBRARY="/snap/multigit/x21/usr/share/tcltk/tcl8.6;/snap/multigit/x21/usr/share/tcltk/tcl8.6/tcl8"
export TCL_LIBRARY="/snap/multigit/x21/usr/share/tcltk/tcl8.6:/snap/multigit/x21/usr/share/tcltk/tcl8.6/tcl8"
export TCL_LIBRARY="/snap/multigit/x21/usr/share/tcltk/tcl8.6,/snap/multigit/x21/usr/share/tcltk/tcl8.6/tcl8"
export TCL_LIBRARY="/snap/multigit/x21/usr/share/tcltk/tcl8.6 /snap/multigit/x21/usr/share/tcltk/tcl8.6/tcl8"
所有这些都会导致相同的结果:
osboxes@osboxes:/snap/multigit/x21/usr/share/tcltk$ gitk
application-specific initialization failed: Can't find a usable init.tcl in the following directories:
{/snap/multigit/x21/usr/share/tcltk/tcl8.6 /snap/multigit/x21/usr/share/tcltk/tcl8.6/tcl8} {/snap/multigit/x21/usr/share/tcltk/tcl8.6 /snap/multigit/x21/usr/share/tcltk/tcl8.6/tcl8.6} /usr/share/tcltk/tcl8.6 /snap/multigit/x21/usr/lib/tcl8.6 /snap/multigit/x21/lib/tcl8.6 /snap/multigit/x21/usr/library /snap/multigit/x21/library /snap/multigit/x21/tcl8.6.12/library /snap/multigit/tcl8.6.12/library
This probably means that Tcl wasn't installed properly.
Error in startup script: can't find package Tk
while executing
"package require Tk"
(file "/snap/multigit/x21/usr/bin/gitk" line 10)
Tcl 支持包和模块。通过在 auto_path 变量中列出的目录的子目录中查找 pkgIndex.tcl 文件来定位软件包。该变量的初始值会受到 TCLLIBPATH 环境变量的影响。
另一方面,模块是单个文件,其文件名必须类似于name-version.tm。 Tcl 在 tcl::tm::path 上查找模块。这是一个命令而不是一个变量。使用 tcl::tm::path list
查看目录列表。模块路径的初始值也可以通过使用环境变量来修改。 Tcl 8.6 将选取 TCL8_6_TM_PATH、TCL8_5_TM_PATH、TCL8_4_TM_PATH、TCL8_3_TM_PATH、TCL8_2_TM_PATH、TCL8_1_TM_PATH 和 TCL8_0_TM_PATH。模块通常放置在它们可以使用的最低 Tcl 版本的路径上。