cross-building a starkit

JOB It is possible to "cross compile" starkits for a specific platform! The following Makefile shows how it works.

Some further explanations: For cross compilation, we need both: a binary (tclkit) for the current platform, we are running the Makefile on (which is used to create a working sdx utility) and another pre-compiled binary for the target platform. The sdx utility in turn is capable to maintain any tclkit binary regardless which binary it belongs to!

I am using a similar Makefile to create binaries for win* although the development platform is a mac - which works pretty well!

# Makefile ---
# -------------------------------------------------------------------------
#   Purpose:
#       Create (*)starkit and application binaries
#       for unix and windows. This makefile might be used to
#       "cross compile" binaries for any target OS.
#   Copyright(c) 2008,  Johann Oberdorfer
#                       mail-to: [email protected]
# -------------------------------------------------------------------------
# This source file is distributed under the BSD license.

# main entry point:

# unix / win / osx ...

# the sdx utility:

# *edit* to reflect your build platform
# you are currently running on:
# -------------------------------------


all:         aix win ls
devel:         aix win kit ls

aix:        $(APP).aix
win:        $(APP).exe
osx:        $(APP).osx
kit:    $(APP).kit

        cp $(TCL_KIT) kitbin
        cp $(SDXUTIL) sdx.kit
        $(TCL_KIT) $(SDXUTIL) unwrap sdx.kit
        $(TCL_KIT) $(SDXUTIL) wrap sdx -runtime kitbin
        rm -rf sdx.vfs
        rm -r  sdx.kit
        rm -f  kitbin

$(APP).kit: $(VER)
        $(TCL_KIT) $(SDXUTIL) wrap $@ -vfs $(VER)

$(APP).aix: $(VER)
        cp $(AIX_KIT) aixkitbin
        $(TCL_KIT) $(SDXUTIL) wrap $@ -vfs $(VER) -runtime aixkitbin
        rm -f aixkitbin

$(APP).exe: $(VER)
        cp $(WIN_KIT) winkitbin.exe
        $(TCL_KIT) $(SDXUTIL) wrap $@ -vfs $(VER) -runtime winkitbin.exe
        rm -f winkitbin.exe

$(APP).osx: $(VER)
        cp $(OSX_KIT) osxkitbin
        $(OSX_KIT) $(SDXUTIL) wrap $@ -vfs $(VER) -runtime osxkitbin
        rm -f osxkitbin

        ls -ltr        

        @if [ -f $(APP).aix ]; then \
          echo "Moving file: $(APP).aix to: $(INSTALL_DIR)" ; \
          mv $(APP).aix $(INSTALL_DIR) ; \
        @if [ -f $(APP).exe ]; then \
          echo "Moving file: $(APP).exe to: $(INSTALL_DIR)" ; \
          mv $(APP).exe $(INSTALL_DIR) ; \
        @if [ -f $(APP).osx ]; then \
          echo "Moving file: $(APP).osx to: $(INSTALL_DIR)" ; \
          mv $(APP).osx $(INSTALL_DIR) ; \

        rm -f aixkitbin
        rm -f winkitbin.exe
        rm -f osxkitbin
        rm -f kitbin
        rm -f $(APP).kit
        rm -f $(APP).aix
        rm -f $(APP).exe


Just a word of caution about this makefile.

It renames the windows kit and the new name does *not* finish with .exe and this has a side effect: sdx *will ignore* the tclkit.ico you may have inserted in your vfs.

If you do mind about making a custom icon, rename the windows kit with a trailing .exe and consider reading Pat Thoyts web page detailing the process of adding an icon to a Windows Starkit: [L1 ]

JOB Thank you lyon for your remark (looks as I am heavily influenced by unix driven boxes, where the file extension for executables isn't relevant at all). Next time I am going to try to extend the Makefile to handle custom icons as well. The main purpose of the Makefile although is the fact that - with starkit technology - you can freely choose your development platform - a kind of freedom for developers! -> Changed the Makefile accordingly.

dcd See Building Starkits and Starpacks using a Makefile 2 for a way to generalize the makefile for different platforms, including getting the extension right. The makefile there will handle cross-compiling as well. When I get around to it, kbskit looks like it could also be useful.

RZ If you are already using kbskit you can put the creation in a package definition. But it works like your Makefile only for tcl only extensions. May be an idea for the next version.

 Package my_program0.1 {
   Require { Use kbskit8.5 sdx.kit my_lib0.1 }
   Source { Link my_program0.1 }
   Configure { Kit {source $::starkit::topdir/my_program.tcl} Tk }
   Make { Kit my_program my_lib0.1}
   Install {
     Kit my_program kbskit85-gui_aix
     file rename -force [Get builddir]/bin/my_program [Get builddir]/bin/aix_my_program
     Kit my_program kbskit85-gui_win.exe
     file rename -force [Get builddir]/bin/my_program.exe [Get builddir]/bin/win_my_program.exe

JOB Yes, kbskit is great - an additional rule for kbskit would also be a neat idea!

With the following additional rule, the above makefile can be used to create a MacOS executable bundle:

# minimum app structure:
#     ./Contents/Info.plist
#     ./Contents/MacOS/myCoolApp.osx
#     ./Contents/Resources/mycoolicon.icns

$(APP).app: $(VFS)
        @echo "Establishing required bundle directory structure ..." ; \
        mkdir -p $(APP).app ; cd  $(APP).app ; \
        mkdir -p Contents   ; cd Contents ; \
        echo "Creating application specific Info.plist ..." ; \
        cp ../../macbundle/Info.plist . ; \
        /usr/bin/sed s/AppName/$(APP)/g Info.plist > tmp ; mv tmp Info.plist ; \
        /usr/bin/sed s/AppVer/$(VER)/g  Info.plist > tmp ; mv tmp Info.plist ; \
        mkdir -p MacOS ; cp ../../$(APP).osx ./MacOS ; \
        mkdir -p Resources ; cp ../../macbundle/$(APP).icns ./Resources ; \
        cd ../.. ; \
        echo "Done."

In addition the following Info.plist template is required, stored in a sibling directory named as "macbundle", plus the application's image file (*.icns).

Info.plist - template with minimum required settings:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "">
<plist version="1.0">
        <string>AppName Starpack Application AppVer</string>

JOB 17-04-09,

I just like to post the actual Makefile.tcl which I am using to build executables from source for WIN and OSX.

# Makefile.tcl ---
# ------------------------------------------------------------------------
# (c) 2016, Johann Oberdorfer - Engineering Support | CAD | Software
#     johann.oberdorfer [at] gmail <dot> com
# ------------------------------------------------------------------------
# This source file is distributed under the BSD license.
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   See the BSD License for more details.
# ------------------------------------------------------------------------
# Purpose:
#   Create (*)starkit and application binaries for unix and windows.
#        This makefile might be used to "cross compile" binaries
#        for any target OS.
# ------------------------------------------------------------------------
#   There are various tclkit binaries available, but not all are
#   fully compatible with Tkhtml 3.0 loadable dll ?!
#   Tkhtml 3.0 is downloaded from ActiveState, which provides
#   binaries for Win as well as OSX !
#   If there is a version conflict:
#     as a side effect (without waring), images are not shown in the
#     html window !!!
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------

# main entry point:
set THIS_APP    [file normalize [file dirname [info script]]]
set TCLKIT_DIR  [file join $THIS_APP "../tclkit"]
set INSTALL_DIR [file join $THIS_APP "../Apps"]

# unix / win / osx ...
set OSX_KIT [file join $TCLKIT_DIR "Darwin_kbsvq8.6-gui"]
set WIN_KIT [file join $TCLKIT_DIR "WindowsNT_kbsvq8.6-gui.exe"]
set SDXUTIL [file join $TCLKIT_DIR "sdx.exe"]
set UPXUTIL [file join $TCLKIT_DIR "upx.exe"]

# -------------------------------------
# *edit* to reflect your build platform
# you are currently running on:
# -------------------------------------

if {$::tcl_version >= 8.4} {
        set plat [tk windowingsystem]
} else {
        set plat $::tcl_platform(platform)

switch -exact $plat {
        "aqua" {
                set TCL_KIT $OSX_KIT
        "win32" -
        "windows" {

                # show the console window
                package require Tk
                wm withdraw .
                console show
                console eval {wm protocol . WM_DELETE_WINDOW {exit 0}}

                set TCL_KIT $WIN_KIT
        "x11" -
        default {
                tk_messageBox \
                -title "Message:" \
                -message \
"Sorry, your platform: $plat you are currently working on
is not supported (due to missing kit file binaries)!
Please edit [info script] and try again!" \
                -icon info
                exit 0

# -------------------------------------
set APPNAME "XXX Put your name here... XXX"
set VER "2.0.3"
set APP "${APPNAME}${VER}"
set VFS "Release_${VER}"
# -------------------------------------

# default operation mode
if {$argc == 0} {
        set argv "all"

set t0 [clock milliseconds]

proc build_win {} {


        puts "Creating windows executable: ${APP}.exe ..."; update

        file delete -force ${APP}.exe
        exec $SDXUTIL wrap ${APP}.exe -vfs $VFS -runtime $TCL_KIT
        # compressing the exe...
        puts "Running UPX to compress executable ..."; update
        exec $UPXUTIL ${APP}.exe

proc build_osx {} {


        puts "Creating osx executable: ${APP}.osx ..."; update

        file delete -force ${APP}.osx
        exec $SDXUTIL wrap ${APP}.osx -vfs $VFS -runtime $OSX_KIT
        puts "Establishing required bundle directory structure ..."
        file mkdir ${APP}.app
        cd ${APP}.app
        file mkdir Contents
        cd Contents
        puts "Creating application specific Info.plist ..."
        file copy -force ../../macbundle/Info.plist ./Info.plist

        file mkdir MacOS
        file copy -force ../../${APP}.osx ./MacOS
        file mkdir Resources
        file copy -force ../../macbundle/${APPNAME}.icns ./Resources
        cd ../..
        file delete -force ${APP}.osx

proc build_sdx {} {

        global TCL_KIT SDXUTIL TCL_KIT

        puts "Creating windows executable: sdx.exe ..."; update

        file delete -force sdx.exe
        exec $TCL_KIT $SDXUTIL wrap sdx.exe -vfs $SDXUTIL -runtime $TCL_KIT

set t0 [clock milliseconds]

switch -- $argv {
        "win" {        build_win }
        "osx" {        build_osx }
        "sdx" {        build_sdx }

        "all" {
        default {
                puts "Unknown or missing argument!"

puts "Done - [expr ( [clock milliseconds] - $t0 ) / 1000.0] sec."

# -------------------------------------