首页 > 解决方案 > Tcl8.6.5 USE_TCL_STUBS tclDecls.h # undef Tcl_StaticPackage,

问题描述

我正在尝试重建一些最初针对 Tcl/Tk8.2 构建的软件,这些软件使用了 libtclstubs.a 和 libtkstubs.a 静态库。现在我可以从 Ubuntu Xenial, tcl8.6-dev:amd64 8.6.5+dfsg-2 包中针对 -ltclstub8.6 -ltkstub8.6 重新编译,但我得到了链接器错误:

undefined reference to `Tcl_StaticPackage'
undefined reference to `Tcl_FindExecutable'

我已将其追溯到 tclDecls.h 中的以下代码块

/* !END!: Do not edit above this line. */

#if defined(USE_TCL_STUBS)
#   undef Tcl_CreateInterp
#   undef Tcl_FindExecutable
#   undef Tcl_GetStringResult
#   undef Tcl_Init
#   undef Tcl_SetPanicProc
#   undef Tcl_SetVar
#   undef Tcl_ObjSetVar2
#   undef Tcl_StaticPackage
#   undef TclFSGetNativePath
#   define Tcl_CreateInterp((tclStubsPtr->tcl_CreateInterp())
#   define Tcl_GetStringResult(interp
               (tclStubsPtr->tcl_GetStringResult(interp))
#   define Tcl_Init(interp) (tclStubsPtr->tcl_Init(interp))
#   define Tcl_SetPanicProc(proc)          (tclStubsPtr->tcl_SetPanicProc(proc))
#   define Tcl_SetVar(interp, varName, newValue, flags) \
        (tclStubsPtr->tcl_SetVar(interp, varName, newValue, flags))
#   define Tcl_ObjSetVar2(interp, part1, part2, newValue, flags) \
        (tclStubsPtr->tcl_ObjSetVar2(interp, part1, part2, newValue, flags))
#endif

很明显,前面头文件中重新定义了 Tcl_StaticPackage 和 Tcl_FindExecutable 的宏都被取消了,这里没有重新声明。大概我可以在包含语句之后在我自己的代码中重新定义它们。所以我想我想知道,“undef”声明背后是否有原因,它们将来会消失吗?我只是选择了一个糟糕的版本来构建吗?

作为记录,这是关于一种旧的混合语言 Fortran77 主程序,它通过 C 接口启动几个 tcl 解释器和自定义绘图小部件。

编辑:显示链接命令

    gfortran -O3  -fno-automatic -std=legacy -ffixed-form  -rdynamic \
  -o ../bin/xtal_37.exe             aa.lnx_o ab.lnx_o ad.lnx_o ap.lnx_o \
ar.lnx_o at.lnx_o ax.lnx_o ay.lnx_o az.lnx_o bn.lnx_o bt.lnx_o bu.lnx_o \
by.lnx_o cb.lnx_o cf.lnx_o cg.lnx_o ci.lnx_o cl.lnx_o cn.lnx_o cp.lnx_o \
cr.lnx_o cu.lnx_o dd.lnx_o fb.lnx_o fc.lnx_o fe.lnx_o fr.lnx_o fs.lnx_o \
ge.lnx_o gs.lnx_o gt.lnx_o lc.lnx_o lf.lnx_o ls.lnx_o mh.lnx_o ml.lnx_o \
mp.lnx_o nc.lnx_o nm.lnx_o or.lnx_o pa.lnx_o pb.lnx_o pe.lnx_o pg.lnx_o \
pn.lnx_o po.lnx_o pp.lnx_o px.lnx_o pv.lnx_o rb.lnx_o re.lnx_o rf.lnx_o \
rs.lnx_o rv.lnx_o rw.lnx_o sh.lnx_o si.lnx_o sl.lnx_o sp.lnx_o sr.lnx_o \
sx.lnx_o vu.lnx_o xt.lnx_o mx.lnx_o ed.lnx_o cm.lnx_o os.lnx_o dm.lnx_o \
sf.lnx_o     surfin.lnx_o togl.lnx_o tklib.lnx_o datim.lnx_o bitws.lnx_o \
lnblnk.lnx_o qsort.lnx_o          ciftbx.lnx_o hashfunc.lnx_o clearfp.lnx_o \
         -L/usr/X11R6/lib  -L/usr/lib/x86_64-linux-gnu/   -L/usr/lib  \
    -ltclstub8.6 -ltkstub8.6 -ldl -lX11 -lGL -lXmu 

编辑:通过在#include 之后重新声明defs 来显示修复

#include <tk.h>
#
#if defined(USE_TCL_STUBS)
#define Tcl_FindExecutable \
        (tclStubsPtr->tcl_FindExecutable) /* 144 */
#define Tcl_StaticPackage \
        (tclStubsPtr->tcl_StaticPackage) /* 244 */
#endif

- 这行得通,但我只是不知道为什么它们是“#undef”排在第二位。

标签: tclstubs

解决方案


背景

您没有回复我的评论,但出于某些背景:在 8.6 之前,可以通过 Tcl 存根表调用 Tcl_FindExecutable(),结果证明这是一个不必要的循环问题:Tcl_FindExecutable()必须在解释器之前调用(可调用)已创建(Tcl_CreateInterp()),但初始化存根表假定一个工作解释器。例如,参见Ticket #8419b6d9ae以获取参考。

所以......#undef Tcl_FindExecutable删除宏(在它刚刚添加之后)以减少这种意外使用的可能性(但不会阻止它,如您的补丁所示)。

建议

您的应用xtal.exe程序(无论如何,要获得对 的有效引用,无论是否使用存根,都必须包含。-ltcl86-DUSE_TCL_STUBSTcl_FindExecutable-ltcl86


推荐阅读