Building the Tcl TLS extension on Unix/Linux is straightforward because OpenSSL libraries are already present and installed. It's a different matter on Windows where you need to build OpenSSL yourself. This short article describes the process.
The actual steps required to build OpenSSL and Tcl TLS are very few as you will see below; that is, once you know what to do and more important, what not to do. To get there though took me the better part of an evening, so I'm writing it down. No, not for you, dear reader, but for myself for when I next need to do a build.
These instructions are for building using the Microsoft toolchain, not Cygwin or MinGW. I use Visual C++ 6.0 for my 32-bit builds and the compiler from the February 2003 platform SDK for 64-bit builds. Why such ancient compilers? Well, because I'm kind of ancient myself. Also using older compilers has a major advantage - you do not need to redistribute the C runtime libraries with your extension because the runtimes for those compilers are already present on all Windows systems.
In addition to the compiler, you need to have two additional tools installed:
A suitable Perl interpreter where suitable means an interpreter that will not barf on the Windows OpenSSL build scripts. In particular, do not assume, as I did, that I already have Msys installed so I can just use the Perl that comes with that. I landed up using the ActiveState Perl distribution. And try not to be a bonehead, as I was, and stick the installation directory later in the PATH than the Msys Perl if you have one.
The NASM open source assembler. This is actually optional but you will need it if you are following my steps. Using the assembler allows OpenSSL to be built with some performance optimized x86 assembler crypto routines.
Download the OpenSSL source distribution. The latest version at the time of writing was 1.0.2 which is what I used for my build.
Every time you do an OpenSSL build, do it by extracting the distribution into a new empty directory and working there. Do not rebuild from an existing source directory unless you are absolutely sure that target platform options are exactly the same.
First start a new DOS shell configured for the 32-bit Visual C++
compiler, either from the Windows Program Menu or running the
Then cd to the OpenSSL source directory and start off by configuring
OpenSSL for a 32-bit Windows build using Visual C++.
Note all steps below are done from the toplevel OpenSSL source directory.
In our demonstration, we have extracted to the
cd openssl-src perl Configure VC-WIN32 --prefix=c:\temp\openssl\x86
--prefix option specifies where OpenSSL will be installed. Any
directory will do as long as you do not specify the same directory
for the 64-bit build later.
Next we have to build the Visual C++ makefiles based on the
build configuration in the
Once the makefile are built, invoke nmake to compile and link
nmake -f ms\nt.mak
In the above
nmake commands, we have chosen to run the
makefile because we wanted static libraries to link to our Tcl TLS
extension. We could have run
ms\ntdll.mak instead to build shared DLL
versions of the library. However, I built the static version
because I prefer the Tcl TLS extension to
be one single binary for easy of distribution, inclusion in a TclKit
Once the build is completed, verify it by running the test suite.
Change to the
out32 subdirectory before running the test suite (
out32dll subdirectory if you did the shared DLL build).
cd out32 ..\ms\test
You should see a
passed all tests message at the end of the run.
The final step is to package and install the OpenSSL binaries.
cd .. nmake -f ms\nt.mak install
ntdll.mak if you build the shared DLL version.
If all goes well, you should now have a complete OpenSSL distribution
in the directory you specified through the
The lazy reader might, as lazy people are wont to do, look to avoid all that work by downloading existing Windows binaries instead. There are good reasons I prefer to build from source. First, I prefer using the static OpenSSL libraries for reasons I mentioned above. Second, pre-built binaries do not allow control of build options such as ciphers. Third, and perhaps most important, when you need to update OpenSSL to fix newly discovered vulnerabilities, you are at the mercy of someone else to build an updated binary.
Now that OpenSSL is built, we can move on to building the TLS extension.
The Tcl TLS extension sources can be downloaded from
SourceForge. Extract it into its own directory
and change to the
win subdirectory beneath it.
You may need to edit
makefile.vc to change the OpenSSL library
libeay32.lib respectively. Then run
nmake to build and install
the extension as follows:
nmake -f makefile.vc OPENSSL=c:\temp\openssl\x86 TCLDIR=c:\src\twapi\tcl-tk\85 INSTALLDIR=c:\tcl\863\x86 nmake -f makefile.vc install OPENSSL=c:\temp\openssl\x86 TCLDIR=c:\src\twapi\tcl-tk\85 INSTALLDIR=c:\tcl\863\x86
The TLS extension makefile follows the standard format for Tcl extensions
so the above command should need no explaining. The only unusual thing
is the need to set
OPENSSL to point to the location of the OpenSSL
distribution we just built (matching the
--prefix option passed
to the OpenSSL build).
Building the 64 bit versions follows the same pattern except for slightly different commands so we only summarize here.
To repeat a previous warning, do not build the 64-bit OpenSSL version
from the same directory that the 32-bit version was built from. Not
even if you do a
Start a new DOS command shell to make sure no environment settings
are left over from the 32-bit build. Run the appropriate
for your 64-bit Visual C++ compiler to set up its environment. Then
change to the newly extracted directory and run the following commands:
perl Configure VC-WIN64A --prefix=c:\temp\openssl\x64 ms\do_win64a
Note the platform is now
VC-WIN64A and we are using
ms\do_nasm. Also ensure the directory passed to
--prefix is different from that for the 32-bit builds.
The remaining commands are identical to those for the 32-bit builds.
nmake -f ms\nt.mak cd out32 ..\ms\test cd .. nmake -f ms\nt.mak install
The steps for building the 64-bit TLS extension is the same as before
except that you need to make sure you pass the paths appropriate
for 64-bits. For example,
OPENSSL should point to
To verify the built TLS extension, cd to the tests diectory in the TLS source distribution and run the following command:
You may see two test failures related to ciphers. This is because the test depends on enumerating the number of ciphers built into OpenSSL and can change depending on both the OpenSSL version and build options.
You may notice the built extension is fairly large, around 1 MB.
This is at least in part because the default OpenSSL build probably
includes a whole bunch of ciphers that are not required for the
TLS extension. You can exclude these by specifying options
perl Configure command. However, I have not looked into
which ciphers are actually required.
I am unsure what export restrictions there are on distributing crypto software, both in the US and my country of residence. And I can't be bothered to find out. Thus I have not made binaries available. Also, what's that saying about teaching a man to fish... :-)