diff --git a/Demos/freeze/Makefile b/Demos/freeze/Makefile
index d108182789f78fac569ddd02fc070ec0d147d169..51ab3bd80528c458a83158e1d3a7fcc45d224d6b 100644
--- a/Demos/freeze/Makefile
+++ b/Demos/freeze/Makefile
@@ -1,17 +1,20 @@
 CC = gcc
-CYTHON = ../../bin/cython
-CYTHON_FREEZE = ../../bin/cython_freeze
+CYTHON = cython
+CYTHON_FREEZE = ./cython_freeze
 PYTHON = python
 RST2HTML = rst2html
 
 PY_LDFLAGS = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_config_var as g; import sys; sys.stdout.write(" ".join([g("LINKFORSHARED"), "-L"+g("LIBPL")]) + "\n")')
 PY_CPPFLAGS = $(shell $(PYTHON) -c 'from distutils.sysconfig import *; import sys; sys.stdout.write("-I"+get_python_inc() + "\n")')
-PY_LDLIBS = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_config_var as g; import sys; sys.stdout.write(" ".join(["-lpython"+g("VERSION"), g("SYSLIBS"), g("LIBS"), g("LOCALMODLIBS")]) + "\n")')
+LIBDIR1 := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBDIR'))")
+LIBDIR2 := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBPL'))")
+PYLIB := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBRARY')[3:-2])")
+LIBS := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LIBS'))")
 
 CFLAGS = -fPIC -fno-strict-aliasing -g -O2 -Wall -Wextra
 CPPFLAGS = $(PY_CPPFLAGS)
 LDFLAGS = $(PY_LDFLAGS)
-LDLIBS = $(PY_LDLIBS)
+LDLIBS = -L$(LIBDIR1) -L$(LIBDIR2) -l$(PYLIB)
 
 
 # Name of executable
diff --git a/Demos/freeze/cython_freeze b/Demos/freeze/cython_freeze
new file mode 100755
index 0000000000000000000000000000000000000000..4be33b69a2cad41ba988d1ac48d3de911958fbf4
--- /dev/null
+++ b/Demos/freeze/cython_freeze
@@ -0,0 +1,258 @@
+#!/usr/bin/env python
+"""
+Create a C file for embedding one or more Cython source files.
+Requires Cython 0.11.2 (or perhaps newer).
+
+See Demos/freeze/README.txt for more details.
+"""
+from __future__ import print_function
+
+import optparse
+from os.path import splitext, basename
+
+usage= '%prog [-o outfile] [-p] module [module ...]'
+description = 'Create a C file for embedding Cython modules.'
+p = optparse.OptionParser(usage=usage, description=description)
+p.add_option('-o', '--output', metavar='FILE',
+        help='write output to FILE instead of standard output')
+p.add_option('-p', '--pymain', action='store_true', default=False,
+        help='do not automatically run the first module as __main__')
+
+options, args = p.parse_args()
+
+if len(args) < 1:
+    p.print_help()
+    p.exit(1)
+
+if options.output:
+    import sys
+    old_stdout = sys.stdout
+    sys.stdout = open(options.output, 'w')
+
+modules = [basename(splitext(x)[0]).replace('.', '_') for x in args]
+
+print("""\
+#include <Python.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __FreeBSD__
+#include <floatingpoint.h>
+#endif
+
+#if PY_MAJOR_VERSION < 3
+# define MODINIT(name)  init ## name
+#else
+# define MODINIT(name)  PyInit_ ## name
+#endif
+""")
+
+for name in modules:
+    print("PyMODINIT_FUNC MODINIT(%s) (void);" % name)
+
+print("""
+static struct _inittab inittab[] = {""")
+
+for name in modules:
+    print('    {"%(name)s", MODINIT(%(name)s)},' % {'name' : name})
+
+print("""    {NULL, NULL}
+};
+""", end=' ')
+
+if not options.pymain:
+    print("\nextern int __pyx_module_is_main_%s;" % modules[0])
+
+print("""
+#if PY_MAJOR_VERSION < 3
+int main(int argc, char** argv) {
+#elif defined(WIN32) || defined(MS_WINDOWS)
+int wmain(int argc, wchar_t **argv) {
+#else
+static int python_main(int argc, wchar_t **argv) {
+#endif
+""", end=' ')
+if not options.pymain:
+    print("""\
+    PyObject *m = NULL;
+    int r = 0;
+""", end=' ')
+print("""\
+    /* 754 requires that FP exceptions run in "no stop" mode by default,
+     * and until C vendors implement C99's ways to control FP exceptions,
+     * Python requires non-stop mode.  Alas, some platforms enable FP
+     * exceptions by default.  Here we disable them.
+     */
+#ifdef __FreeBSD__
+    fp_except_t m;
+
+    m = fpgetmask();
+    fpsetmask(m & ~FP_X_OFL);
+#endif
+    if (PyImport_ExtendInittab(inittab)) {
+        fprintf(stderr, "No memory\\n");
+        exit(1);
+    }
+""", end=' ')
+if options.pymain:
+    print("""\
+    return Py_Main(argc, argv);
+}
+""")
+else:
+    print("""\
+    Py_SetProgramName(argv[0]);
+    Py_Initialize();
+    PySys_SetArgv(argc, argv);
+    __pyx_module_is_main_%(main)s = 1;
+    m = PyImport_ImportModule(inittab[0].name);
+    if (!m) {
+        r = 1;
+        PyErr_Print(); /* This exits with the right code if SystemExit. */
+#if PY_MAJOR_VERSION < 3
+        if (Py_FlushLine())
+            PyErr_Clear();
+#endif
+    }
+    Py_XDECREF(m);
+    Py_Finalize();
+    return r;
+}
+""" % {'main' : modules[0]}, end=' ')
+
+print(r"""
+#if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS)
+static wchar_t*
+char2wchar(char* arg)
+{
+	wchar_t *res;
+#ifdef HAVE_BROKEN_MBSTOWCS
+	/* Some platforms have a broken implementation of
+	 * mbstowcs which does not count the characters that
+	 * would result from conversion.  Use an upper bound.
+	 */
+	size_t argsize = strlen(arg);
+#else
+	size_t argsize = mbstowcs(NULL, arg, 0);
+#endif
+	size_t count;
+	unsigned char *in;
+	wchar_t *out;
+#ifdef HAVE_MBRTOWC
+	mbstate_t mbs;
+#endif
+	if (argsize != (size_t)-1) {
+		res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t));
+		if (!res)
+			goto oom;
+		count = mbstowcs(res, arg, argsize+1);
+		if (count != (size_t)-1) {
+			wchar_t *tmp;
+			/* Only use the result if it contains no
+			   surrogate characters. */
+			for (tmp = res; *tmp != 0 &&
+				     (*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
+				;
+			if (*tmp == 0)
+				return res;
+		}
+		free(res);
+	}
+	/* Conversion failed. Fall back to escaping with surrogateescape. */
+#ifdef HAVE_MBRTOWC
+	/* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
+
+	/* Overallocate; as multi-byte characters are in the argument, the
+	   actual output could use less memory. */
+	argsize = strlen(arg) + 1;
+	res = malloc(argsize*sizeof(wchar_t));
+	if (!res) goto oom;
+	in = (unsigned char*)arg;
+	out = res;
+	memset(&mbs, 0, sizeof mbs);
+	while (argsize) {
+		size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
+		if (converted == 0)
+			/* Reached end of string; null char stored. */
+			break;
+		if (converted == (size_t)-2) {
+			/* Incomplete character. This should never happen,
+			   since we provide everything that we have -
+			   unless there is a bug in the C library, or I
+			   misunderstood how mbrtowc works. */
+			fprintf(stderr, "unexpected mbrtowc result -2\n");
+			return NULL;
+		}
+		if (converted == (size_t)-1) {
+			/* Conversion error. Escape as UTF-8b, and start over
+			   in the initial shift state. */
+			*out++ = 0xdc00 + *in++;
+			argsize--;
+			memset(&mbs, 0, sizeof mbs);
+			continue;
+		}
+		if (*out >= 0xd800 && *out <= 0xdfff) {
+			/* Surrogate character.  Escape the original
+			   byte sequence with surrogateescape. */
+			argsize -= converted;
+			while (converted--)
+				*out++ = 0xdc00 + *in++;
+			continue;
+		}
+		/* successfully converted some bytes */
+		in += converted;
+		argsize -= converted;
+		out++;
+	}
+#else
+	/* Cannot use C locale for escaping; manually escape as if charset
+	   is ASCII (i.e. escape all bytes > 128. This will still roundtrip
+	   correctly in the locale's charset, which must be an ASCII superset. */
+	res = malloc((strlen(arg)+1)*sizeof(wchar_t));
+	if (!res) goto oom;
+	in = (unsigned char*)arg;
+	out = res;
+	while(*in)
+		if(*in < 128)
+			*out++ = *in++;
+		else
+			*out++ = 0xdc00 + *in++;
+	*out = 0;
+#endif
+	return res;
+oom:
+	fprintf(stderr, "out of memory\n");
+	return NULL;
+}
+
+int
+main(int argc, char **argv)
+{
+	wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
+	/* We need a second copies, as Python might modify the first one. */
+	wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
+	int i, res;
+	char *oldloc;
+	if (!argv_copy || !argv_copy2) {
+		fprintf(stderr, "out of memory\n");
+		return 1;
+	}
+	oldloc = strdup(setlocale(LC_ALL, NULL));
+	setlocale(LC_ALL, "");
+	for (i = 0; i < argc; i++) {
+		argv_copy2[i] = argv_copy[i] = char2wchar(argv[i]);
+		if (!argv_copy[i])
+			return 1;
+	}
+	setlocale(LC_ALL, oldloc);
+	free(oldloc);
+	res = python_main(argc, argv_copy);
+	for (i = 0; i < argc; i++) {
+		free(argv_copy2[i]);
+	}
+	free(argv_copy);
+	free(argv_copy2);
+	return res;
+}
+#endif""")