Updated 2010-05-17 17:27:50 by AMG

-GPS Tcl'ers feel free to modify this. The original can be found here: http://www.xmission.com/~georgeps/static-executables.html

How to Compile Executables With GCC That Include the Tcl and Tk Libraries

Overview

This tutorial describes how to make executables that do not need Tcl and Tk shared libraries or interpreters to run. This tutorial gives instructions on how to build static Tcl and Tk libraries, create C code from scripts using Mktclapp, compile the C code into a static executable by linking with static Tcl and Tk libraries, verify which libraries are required, and finally methods to distribute extensions.

Mktclapp can be found here: http://www.hwaci.com/sw/mktclapp/

Download the free Tcl and Tk sources, if you don't already have them. See http://www.tcl.tk, the Tcl Developer Xchange.

Extract the sources for Tcl and Tk. Get any extensions you want to use and apply the patches to the Tcl and/or Tk sources.

Add /usr/local/lib to your /etc/ld.so.conf, if the path does not already exist within that file. If the ld.so.conf file does not exist then you may need to create it with ldconfig. You may need to run ldconfig to update the path. See the man page for ldconfig for more information. Note: Tcl and Tk can also be installed to a directory of your choice with a command line option that is listed when ./configure --help is run.

Now change to the tcl8.*.*/unix directory.

Run:

./configure --disable-shared

Now run:

make

to build tclsh8.* and the static libtcl8.*.a library. With root access or root access via su run

make install

Now change to the tk8.*.*/unix directory.

Run:

./configure --disable-shared

Now run:

make

to build wish8.* and the static libtk8.*.a library. With root access or root access via su run

make install

Convert your Tcl script to C code using Mktclapp by following these instructions. http://www.hwaci.com/sw/mktclapp/mktclapp.html

Try building the C code created by Mktclapp with something like this in Linux:

gcc filename.c /usr/local/lib/libtk8.3.a /usr/local/lib/libtcl8.3.a -L/usr/X11R6/lib -lX11 -lm -ldl -o executablename

If you are using BSD the compile command might look like this:

gcc filename.c -I/usr/local/include -I/usr/X11R6/include /usr/local/lib/libtcl83.a /usr/local/lib/libtk83.a -L/usrX11R6/lib -lX11 -lm -o executablename

You will notice how the full path to the library is declared. Hopefully it will compile without any problems.

The ldd program reports what shared libraries are required by an executable. If you run ldd on the executable that you have created it should report something like this in Linux:

libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x4001e000) libm.so.6 => /lib/libm.so.6 (0x400c2000) libdl.so.2 => /lib/libdl.so.2 (0x400e1000) libc.so.6 => /lib/libc.so.6 (0x400e4000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

In BSD ldd executable_name reports:

-lX11.6 => /usr/X11R6/lib/libX11.so.6.1 (0x40127000) -lm.0 => /usr/lib/libm.so.0.1 (0x401bd000) -lc.23 => /usr/lib/libc.so.23.1 (0x401d1000)

If you find that libtcl or libtk is listed in the ldd report of the executable that you have compiled, you will need to make sure that you link with the Tcl and Tk libraries with an .a extension.

If you do have problems, try upgrading to a newer version of Tcl and Tk. I experienced linking problems with Tcl 8.2.1 which were fixed by an upgrade to Tcl 8.2.2. Also try linking only the Tcl library as static and the Tk library as shared and vice versa, so that you can narrow down the problem. You will need to create a shared library for this, by running configure without any options when you build Tcl and Tk. Note: Some systems default to .a libraries rather than .so libraries, in which case you will need to consult the help provided by running ./configure --help.

For example, to link with a shared Tk and static Tcl use something like this: gcc filename.c /usr/local/lib/libtcl8.3.so /usr/local/lib/libtcl8.3.a -L/usr/X11R6/lib -lX11 -lm -ldl -o executablename

It may take some time to learn how to do this. It took me roughly two weeks of off-and-on effort to learn how to do this. I tried using the -static and -shared options while compiling, but when I did that it caused segmentation faults. So, I finally tried just declaring the library and it worked. Do you know why it caused problems? Why does the ld man page list -Bstatic and the gcc man page list -static?

Making Static Executables With Tcl/Tk Extensions (See Update Below)

Well, I am very new at this so correct Me if you know of a better way. First copy the extension shared object library to the executable directory.

For example: cp /usr/local/Img1.2/libimg1.2.so /home/user/my_program/

Now add a line to the top of your Tcl script like this: load ./libimg1.2.so or package require Img

So, now the Img extension library will be loaded from the current directory of the Tcl script. The only problem that might occur with this method is if you start the program from a window manager. It may not find the current directory that you want. However it does work well if you start the executable from the current directory. I have noticed that Quake2 doesn't work if it is started from a window manager. So, Quake2 seems to use a similar method. This could probably be fixed by having a startup script that sets the libimg directory before sourcing the main Tcl script.

Update

I came up with a better way to load extensions in a static executable, by changing the auto_path variable. (Note: This method may not be the best for all cases.)

Copy the extension directory into the directory of your program. Then use lappend auto_path . to add the current directory to the search path. Now, package require package-name can be invoked and the extension should be loaded.

For example:

#This makes it so that the user doesn't need to install Img in /usr/local/lib or /usr/lib. puts "The old auto path is: $auto_path"

lappend auto_path .

puts "The new auto path is: $auto_path"

package require Img

In the case above, the Img1.2 extension directory was copied from /usr/local/lib/ into the directory of the static executable. Then, after that it searches for any directory with Img as the start of the name of the directory. Then, it descends into the directory and looks for pkgIndex.tcl which tells what the package provides.

Well, I hope that this has been useful. If you see a problem that I have overlooked, or have a suggestion to improve the clarity of this please tell Me (George Peter Staplin) about it.

[lem] - 2010-05-17 13:14:48

Hi

About ffmpeg... This is a highly difficult to compile and work how works on windows

Need at least some light to iniciate this project for conversion of videos for portale players... on Unix based OS.

I was think to do any similar app with ffmpeg how do The OPERA web browser for windows (smply static) and more, how The Old web browser EPIPHANY unic executable...

Any Idea???

My email is : [email protected]

AMG: This isn't the right forum to discuss compilation of ffmpeg. I suggest researching, acquiring, and installing ffmpeg's prerequisites, then following any installation instructions that may be included with the ffmpeg sources. Or get a precompiled binary for your platform. If you need further assistance, find an ffmpeg mailing list, forum, or other user support group. If you want this to magically become the right forum to discuss fmpeg, incorporate Tcl into it. :^)