我正在尝试重新构建一些最初针对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的宏将被作废,并且不会在这里重新声明。大概我可以在自己的代码中在include语句之后重新定义它们。所以我猜我在想,"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-which是有效的,但我就是不明白为什么他们排在第二位是"#undef“。
发布于 2018-08-07 16:49:23
背景
您没有回应我的评论,但有一些背景:在8.6之前,可以通过Tcl存根表调用Tcl_FindExecutable(),这被证明是一个不想要的循环性问题:Tcl_FindExecutable()必须在创建解释器(Tcl_CreateInterp())之前被调用(callable),但是初始化存根表需要一个正常工作的解释器。例如,请参阅Ticket #8419b6d9ae以获取参考。
所以..。#undef Tcl_FindExecutable将删除该宏(在它刚被添加之后),以减少这种意外使用的可能性(但不会阻止它,如您的补丁所示)。
建议
您的应用程序(xtal.exe)似乎根本不打算作为Tcl扩展来获取存根机制的好处,所以使用-ltcl86将其构建为独立的应用程序,并在编译步骤中省略-DUSE_TCL_STUBS?在任何情况下,为了获得对Tcl_FindExecutable的有效引用,无论是否使用存根,都必须包含-ltcl86。
https://stackoverflow.com/questions/51691236
复制相似问题