Skip to content

Instantly share code, notes, and snippets.

@gromgit
Last active February 18, 2025 15:52
Show Gist options
  • Select an option

  • Save gromgit/a43b69fade5979f0874a9cd4777abdb6 to your computer and use it in GitHub Desktop.

Select an option

Save gromgit/a43b69fade5979f0874a9cd4777abdb6 to your computer and use it in GitHub Desktop.

Revisions

  1. gromgit revised this gist Dec 27, 2024. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions build_sqtcl
    Original file line number Diff line number Diff line change
    @@ -12,9 +12,8 @@ tar xf "$base"-src.tar.gz || fatal "unable to unpack src tarball 'tcl${ver}-src.
    patch -b <sqtcl.patch || fatal "unable to patch src"

    extra_cfg=("--disable-shared")
    sqlite_lib="$(brew --prefix sqlite)/lib/libsqlite3.a"
    sqlite_lib="${sqlite_lib:-$(brew --prefix sqlite)/lib/libsqlite3.a}"
    [[ -s $sqlite_lib ]] || fatal "can't find SQLite static lib '$sqlite_lib'"
    #LDFLAGS=${extra_libs} make -C "$root"/macosx EXTRA_CONFIGURE_FLAGS="${extra_cfg}" INSTALL_ROOT="$(pwd)"/root install
    mkdir build
    ( cd build || fatal "unable to cd to build dir"
    ../"${base}"/unix/configure --prefix="$instroot" "${extra_cfg[@]}"
  2. gromgit created this gist Dec 27, 2024.
    23 changes: 23 additions & 0 deletions build_sqtcl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    #!/usr/bin/env bash
    fatal() {
    printf 'FATAL ERROR: %s' "$*"
    exit 1
    }
    base=tcl${ver:-9.0.1}
    cd "$(dirname "$0")" || fatal "unable to cd to script dir"
    instroot=$(pwd)/inst
    [[ -s ${base}-src.tar.gz ]] || fatal "unable to find src tarball 'tcl${ver}-src.tar.gz'"
    rm -fr build "$instroot" "$base"
    tar xf "$base"-src.tar.gz || fatal "unable to unpack src tarball 'tcl${ver}-src.tar.gz'"
    patch -b <sqtcl.patch || fatal "unable to patch src"

    extra_cfg=("--disable-shared")
    sqlite_lib="$(brew --prefix sqlite)/lib/libsqlite3.a"
    [[ -s $sqlite_lib ]] || fatal "can't find SQLite static lib '$sqlite_lib'"
    #LDFLAGS=${extra_libs} make -C "$root"/macosx EXTRA_CONFIGURE_FLAGS="${extra_cfg}" INSTALL_ROOT="$(pwd)"/root install
    mkdir build
    ( cd build || fatal "unable to cd to build dir"
    ../"${base}"/unix/configure --prefix="$instroot" "${extra_cfg[@]}"
    make SQLITE_A="$sqlite_lib" install
    ) |& tee build.log
    otool -L "$instroot"/bin/*tclsh*
    286 changes: 286 additions & 0 deletions sqtcl.patch
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,286 @@
    *** tcl9.0.1/unix/Makefile.in.orig 2024-12-13 02:07:26.000000000 +0800
    --- tcl9.0.1/unix/Makefile.in 2024-12-27 18:19:30.554064485 +0800
    ***************
    *** 169,174 ****
    --- 169,179 ----
    TCLTEST_EXE = tcltest${EXE_SUFFIX}
    NATIVE_TCLSH = @TCLSH_PROG@

    + # Static SQLite-enabled tclsh
    + SQTCL_EXE = sqtclsh${EXE_SUFFIX}
    + SQTCLSH_OBJS = sqtclAppInit.o
    + SQLITE_A = /opt/homebrew/opt/sqlite/lib/libsqlite.a
    +
    # The symbols below provide support for dynamic loading and shared libraries.
    # See configure.ac for a description of what the symbols mean. The values of
    # the symbols are normally set by the configure script. You shouldn't normally
    ***************
    *** 769,778 ****
    # Start of rules
    #--------------------------------------------------------------------------

    ! all: binaries libraries doc packages

    binaries: ${LIB_FILE} ${TCL_EXE}

    libraries:

    doc:
    --- 774,785 ----
    # Start of rules
    #--------------------------------------------------------------------------

    ! all: binaries libraries doc packages extra-binaries

    binaries: ${LIB_FILE} ${TCL_EXE}

    + extra-binaries: ${SQTCL_EXE}
    +
    libraries:

    doc:
    ***************
    *** 840,845 ****
    --- 847,857 ----
    fi; \
    fi

    + ${SQTCL_EXE}: ${SQTCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${TCL_ZIP_FILE}
    + ${CC} ${CFLAGS} ${LDFLAGS} ${SQTCLSH_OBJS} pkgs/sqlite*/*.o \
    + @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} ${SQLITE_A} @EXTRA_TCLSH_LIBS@ \
    + ${CC_SEARCH_FLAGS} -o ${SQTCL_EXE}
    +
    # Must be empty so it doesn't conflict with rule for ${TCL_EXE} above
    ${NATIVE_TCLSH}:

    ***************
    *** 1000,1006 ****
    INSTALL_DOC_TARGETS = install-doc
    INSTALL_PACKAGE_TARGETS = install-packages
    INSTALL_DEV_TARGETS = install-headers
    ! INSTALL_EXTRA_TARGETS = @EXTRA_INSTALL@
    INSTALL_TARGETS = $(INSTALL_BASE_TARGETS) $(INSTALL_DOC_TARGETS) $(INSTALL_DEV_TARGETS) \
    $(INSTALL_PACKAGE_TARGETS) $(INSTALL_EXTRA_TARGETS)

    --- 1012,1018 ----
    INSTALL_DOC_TARGETS = install-doc
    INSTALL_PACKAGE_TARGETS = install-packages
    INSTALL_DEV_TARGETS = install-headers
    ! INSTALL_EXTRA_TARGETS = @EXTRA_INSTALL@ install-extra-binaries
    INSTALL_TARGETS = $(INSTALL_BASE_TARGETS) $(INSTALL_DOC_TARGETS) $(INSTALL_DEV_TARGETS) \
    $(INSTALL_PACKAGE_TARGETS) $(INSTALL_EXTRA_TARGETS)

    ***************
    *** 1038,1043 ****
    --- 1050,1059 ----
    @$(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/pkgconfig"
    @$(INSTALL_DATA) tcl.pc "$(LIB_INSTALL_DIR)/pkgconfig/tcl.pc"

    + install-extra-binaries: extra-binaries
    + @echo "Installing ${SQTCL_EXE} as $(BIN_INSTALL_DIR)/sqtclsh$(VERSION)${EXE_SUFFIX}"
    + @$(INSTALL_PROGRAM) ${SQTCL_EXE} "$(BIN_INSTALL_DIR)/sqtclsh$(VERSION)${EXE_SUFFIX}"
    +
    install-libraries: libraries
    @for i in "$(SCRIPT_INSTALL_DIR)" "$(MODULE_INSTALL_DIR)"; \
    do \
    ***************
    *** 1278,1283 ****
    --- 1294,1302 ----
    regerror.o: $(REGHDRS) $(GENERIC_DIR)/regerrs.h $(GENERIC_DIR)/regerror.c
    $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/regerror.c

    + sqtclAppInit.o: $(UNIX_DIR)/sqtclAppInit.c
    + $(CC) -c $(APP_CC_SWITCHES) $(UNIX_DIR)/sqtclAppInit.c
    +
    tclAppInit.o: $(UNIX_DIR)/tclAppInit.c
    $(CC) -c $(APP_CC_SWITCHES) $(UNIX_DIR)/tclAppInit.c

    *** tcl9.0.1/unix/sqtclAppInit.c.orig 2024-12-27 18:17:03.822888072 +0800
    --- tcl9.0.1/unix/sqtclAppInit.c 2024-12-27 18:17:03.822976154 +0800
    ***************
    *** 0 ****
    --- 1,184 ----
    + /*
    + * tclAppInit.c --
    + *
    + * Provides a default version of the main program and Tcl_AppInit
    + * procedure for tclsh and other Tcl-based applications (without Tk).
    + *
    + * Copyright (c) 1993 The Regents of the University of California.
    + * Copyright (c) 1994-1997 Sun Microsystems, Inc.
    + * Copyright (c) 1998-1999 Scriptics Corporation.
    + *
    + * See the file "license.terms" for information on usage and redistribution of
    + * this file, and for a DISCLAIMER OF ALL WARRANTIES.
    + */
    +
    + #include "tcl.h"
    + #if TCL_MAJOR_VERSION < 9
    + # if defined(USE_TCL_STUBS)
    + # error "Don't build with USE_TCL_STUBS!"
    + # endif
    + # if TCL_MINOR_VERSION < 7
    + # define Tcl_LibraryInitProc Tcl_PackageInitProc
    + # define Tcl_StaticLibrary Tcl_StaticPackage
    + # endif
    + #endif
    +
    + #ifdef TCL_TEST
    + extern Tcl_LibraryInitProc Tcltest_Init;
    + extern Tcl_LibraryInitProc Tcltest_SafeInit;
    + #endif /* TCL_TEST */
    +
    + #ifdef TCL_XT_TEST
    + extern void XtToolkitInitialize(void);
    + extern Tcl_LibraryInitProc Tclxttest_Init;
    + #endif /* TCL_XT_TEST */
    +
    + /*
    + * The following #if block allows you to change the AppInit function by using
    + * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The
    + * #if checks for that #define and uses Tcl_AppInit if it does not exist.
    + */
    +
    + #ifndef TCL_LOCAL_APPINIT
    + #define TCL_LOCAL_APPINIT Tcl_AppInit
    + #endif
    + #ifndef MODULE_SCOPE
    + # define MODULE_SCOPE extern
    + #endif
    + MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *);
    + MODULE_SCOPE int main(int, char **);
    +
    + /*
    + * The following #if block allows you to change how Tcl finds the startup
    + * script, prime the library or encoding paths, fiddle with the argv, etc.,
    + * without needing to rewrite Tcl_Main()
    + */
    +
    + #ifdef TCL_LOCAL_MAIN_HOOK
    + MODULE_SCOPE int TCL_LOCAL_MAIN_HOOK(int *argc, char ***argv);
    + #endif
    +
    + /*
    + *----------------------------------------------------------------------
    + *
    + * main --
    + *
    + * This is the main program for the application.
    + *
    + * Results:
    + * None: Tcl_Main never returns here, so this procedure never returns
    + * either.
    + *
    + * Side effects:
    + * Just about anything, since from here we call arbitrary Tcl code.
    + *
    + *----------------------------------------------------------------------
    + */
    +
    + int
    + main(
    + int argc, /* Number of command-line arguments. */
    + char *argv[]) /* Values of command-line arguments. */
    + {
    + #ifdef TCL_XT_TEST
    + XtToolkitInitialize();
    + #endif
    +
    + #ifdef TCL_LOCAL_MAIN_HOOK
    + TCL_LOCAL_MAIN_HOOK(&argc, &argv);
    + #elif (TCL_MAJOR_VERSION > 8 || TCL_MINOR_VERSION > 6) && (!defined(_WIN32) || defined(UNICODE))
    + /* New in Tcl 8.7. This doesn't work on Windows without UNICODE */
    + TclZipfs_AppHook(&argc, &argv);
    + #endif
    +
    + Tcl_Main(argc, argv, TCL_LOCAL_APPINIT);
    + return 0; /* Needed only to prevent compiler warning. */
    + }
    +
    + /*
    + *----------------------------------------------------------------------
    + *
    + * Tcl_AppInit --
    + *
    + * This procedure performs application-specific initialization. Most
    + * applications, especially those that incorporate additional packages,
    + * will have their own version of this procedure.
    + *
    + * Results:
    + * Returns a standard Tcl completion code, and leaves an error message in
    + * the interp's result if an error occurs.
    + *
    + * Side effects:
    + * Depends on the startup script.
    + *
    + *----------------------------------------------------------------------
    + */
    +
    + int Sqlite3_Init(Tcl_Interp *interp);
    +
    + int
    + Tcl_AppInit(
    + Tcl_Interp *interp) /* Interpreter for application. */
    + {
    + if (Tcl_Init(interp) == TCL_ERROR) {
    + return TCL_ERROR;
    + }
    +
    + #ifdef TCL_XT_TEST
    + if (Tclxttest_Init(interp) == TCL_ERROR) {
    + return TCL_ERROR;
    + }
    + #endif
    +
    + #ifdef TCL_TEST
    + if (Tcltest_Init(interp) == TCL_ERROR) {
    + return TCL_ERROR;
    + }
    + Tcl_StaticLibrary(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit);
    + #endif /* TCL_TEST */
    +
    + /*
    + * Call the init procedures for included packages. Each call should look
    + * like this:
    + *
    + * if (Mod_Init(interp) == TCL_ERROR) {
    + * return TCL_ERROR;
    + * }
    + *
    + * where "Mod" is the name of the module. (Dynamically-loadable packages
    + * should have the same entry-point name.)
    + */
    + if (Sqlite3_Init(interp) == TCL_ERROR) {
    + return TCL_ERROR;
    + }
    +
    + /*
    + * Call Tcl_CreateObjCommand for application-specific commands, if they
    + * weren't already created by the init procedures called above.
    + */
    +
    + /*
    + * Specify a user-specific startup file to invoke if the application is
    + * run interactively. Typically the startup file is "~/.apprc" where "app"
    + * is the name of the application. If this line is deleted then no
    + * user-specific startup file will be run under any conditions.
    + */
    + #ifdef DJGPP
    + #define INITFILENAME "tclshrc.tcl"
    + #else
    + #define INITFILENAME ".tclshrc"
    + #endif
    +
    + (void) Tcl_EvalEx(interp,
    + "set tcl_rcFileName [file tildeexpand ~/" INITFILENAME "]",
    + -1, TCL_EVAL_GLOBAL);
    + return TCL_OK;
    + }
    +
    + /*
    + * Local Variables:
    + * mode: c
    + * c-basic-offset: 4
    + * fill-column: 78
    + * End:
    + */