2015-11-30

Build TclBlend

TclBlend 相關文件:
Tcl/Java interoperability with TclBlend 1.4. A new precompiled binary for Window


環境:
Windows XP
MINGW/MSYS
ActiveTcl 8.6.4.1
Java SE 8u65


使用 MINGW/MSYS 參考文章:
Building TclBlend with msys_mingw


下載 Tclblend 1.4.1 以後,加上 Source Forge 的 3 個 patch:
21 allow TclBlend to load Tcl 8.5 into a Java process
22 Compile/​Run against Tcl 8.6
24 Patch for TclJava Bug 2866640


然後加上 tclBlend\src\native\javaInterp.c 的一些小改變(for Tcl/Tk 8.6):

    if (exception) {
        (*env)->DeleteLocalRef(env, exception);
        (void) Tcl_GetStringResult(interp);
        tPtr->errMsg = (char *) 
            ckalloc((unsigned) (strlen(Tcl_GetStringResult(interp)) + 1));
            //ckalloc((unsigned) (strlen(interp->result) + 1));
        //strcpy(tPtr->errMsg, interp->result);
        strcpy(tPtr->errMsg, Tcl_GetStringResult(interp));
        result = tPtr->errMsg;
    }

就 build 出來了。能不能使用則還不知道。

(update) 嘗試使用更加相容其它版本的寫法

        #if TCL_MAJOR_VERSION > 8 || \
           (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 5)
            ckalloc((unsigned) (strlen(Tcl_GetStringResult(interp)) + 1));
        #else
            ckalloc((unsigned) (strlen(interp->result) + 1));
        #endif
        #if TCL_MAJOR_VERSION > 8 || \
           (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 5)
        strcpy(tPtr->errMsg, Tcl_GetStringResult(interp));
        #else
        strcpy(tPtr->errMsg, interp->result);
        #endif



更新:
無法正確執行範例,會發生 crash 的問題。
使用參考文件所提供的檔案可以成功執行,但是我自己編譯的 tclBlend 如果執行範例會 crash,不知道問題出在哪裡。

更新:
使用 TclBlend, Tcl/Tk 8.5.18 and Thread extension 2.7.2 and JDK 8
(單純的 TclBlend 1.4.1,沒有使用 patch)
測試成功

% package require java
1.4.1

% java::import java.net.InetAddress

% puts "My IP Address is: [ [ java::call InetAddress getLocalHost ] getHostAddress ] "
My IP Address is: 192.168.2.105


更新 2015/12/01:
會是 Tcl 8.5.18 與 Tcl 8.6.4 的版本差異所造成的問題嗎?


更新 2015/12/01:
測試 Tcl 8.6.0,
測試成功
看起來跟 Thread Extension 與 JDK 版本無關


更新 2015/12/01:
測試 Tcl 8.6.1, 結果 crash

TCLBLEND_DEBUG: Interp.evalString()
TCLBLEND_DEBUG: cmd is : ->package provide java 1.4.1<- br="">TCLBLEND_DEBUG: JavaInitBlend returning
TCLBLEND_DEBUG: Tclblend_Init finished
TCLBLEND_DEBUG: JavaInitBlend returned TCL_OK
1.4.1
% java::import java.net.InetAddress
TCLBLEND_DEBUG: JavaCmdProc()
% puts "My IP Address is: [ [ java::call InetAddress getLocalHost ] getHostAddre
ss ] "
TCLBLEND_DEBUG: JavaCmdProc()


更新:
記錄我對 TclBlend 在 MinGW/MSYS 與 Tcl 8.6.x 編譯的做法(雖然 TclBlend 在 Tcl 8.6.1 及以後的版本沒辦法用)

1. 使用下列的 script 編譯出 Tcl/Tk 8.6.x

(Tcl 與 Tk 的 source code 放在 /src/tcl 與 /src/tk 的目錄下)

#!/bin/sh
mkdir -p /src
mkdir -p /opt/tcl
mkdir -p /build/tcl
mkdir -p /build/tk
[ -e /src/tcl ] && {
    cd /build/tcl
    /src/tcl/win/configure --prefix=/opt/tcl --enable-threads && make && make install && {
        [ -e /src/tk ] && {
        cd /build/tk
        /src/tk/win/configure --prefix=/opt/tcl --enable-threads --with-tcl=/build/tcl \
            && make && make install
        }
    }
}

2.Build TclBlend

假設已經下載完 source code package,並且放在 /src/tclBlend

2-1 mkdir /build/tclblend
2-2 cd /build/tclblend
2-3 /src/tclBlend/configure --prefix=/opt/tcl --with-tcl=/build/tcl --with-thread=/build/tcl/pkgs/thread2.7.2/ --with-jdk=/c/JDK8/
2-4 make
2-5 make install

在 2-3 的 thread 要看 Tcl/Tk 8.6.x 當時附帶的 Thread extension 版本。因為 8.6.x 已經會附帶一個 Thread extension 而且在第一個步驟就已經編譯完成,所以不用自己再去下載一個來編譯。

要執行 TclBlend 的時候,使用 jtclsh.bat 或者是 jtclsh 啟動。jtclsh.bat 或者是 jtclsh 都是在設定環境變數,主要有下列幾個可以指定的地方:

set PREFIX=C:/MinGW/msys/1.0/opt/tcl
set EXEC_PREFIX=C:/MinGW/msys/1.0/opt/tcl
set TCLSH=C:/MinGW/msys/1.0/opt/tcl/bin/tclsh86

例如說,如果你複製 C:/MinGW/msys/1.0/opt/tcl 目錄下的檔案到 C:/Tcl/ 下,那麼就需要對這幾個環境變數做相對應的修改。


更新:
TclBlend: Tcl core patch

所以預計在 8.6.6 可以修正 crash 問題,8.6.1 ~ 8.6.5 則需要自己 patch Tcl source code。

沒有留言: