diff --git a/.gitignore b/.gitignore
index 9f526dcb0..9d173cd15 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
 .*.swp
-*.pyc
\ No newline at end of file
+*.pyc
+*.zip
+inkstitch-venv
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000..a0c8f0441
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+dist: *.py *.inx inkstitch-venv
+	zip -r inkstitch-$$(git tag -l | grep ^v | tail -n 1)-$$(uname)-$$(uname -m).zip *.py *.inx inkstitch-venv
+
+inkstitch-venv: requirements.txt
+	rm -rf inkstitch-venv
+	virtualenv inkstitch-venv
+	source inkstitch-venv/bin/activate \
+	pip install -r requirements.txt \
+    for file in inkstitch-venv/lib/python*/site-packages/wx/_*.so; do patchelf --set-rpath '$$ORIGIN'; done
diff --git a/embroider.py b/embroider.py
index d5a963dee..8f76391f1 100644
--- a/embroider.py
+++ b/embroider.py
@@ -10,10 +10,11 @@
 # Embroidery file format documentation:
 # http://www.achatina.de/sewing/main/TECHNICL.HTM
 
+execfile('inkstitch_activate_venv.py')
+
 import sys
 import traceback
 sys.path.append("/usr/share/inkscape/extensions")
-import os
 import subprocess
 from copy import deepcopy
 import time
diff --git a/embroider_params.py b/embroider_params.py
index 0c5c52fc6..ce0ec6a96 100644
--- a/embroider_params.py
+++ b/embroider_params.py
@@ -1,6 +1,8 @@
 #!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
+execfile('inkstitch_activate_venv.py')
+
 import os
 import sys
 import json
diff --git a/embroider_simulate.py b/embroider_simulate.py
index f10f39f0a..c1944d40b 100644
--- a/embroider_simulate.py
+++ b/embroider_simulate.py
@@ -1,3 +1,5 @@
+execfile('inkstitch_activate_venv.py')
+
 import sys
 import os
 import numpy
diff --git a/embroider_update.py b/embroider_update.py
index b6821d548..593744547 100644
--- a/embroider_update.py
+++ b/embroider_update.py
@@ -3,6 +3,8 @@
 # Update embroidery parameters stored in XML attributes from old to new
 # format.
 
+execfile('inkstitch_activate_venv.py')
+
 import sys
 sys.path.append("/usr/share/inkscape/extensions")
 import os
diff --git a/inkstitch_activate_venv.py b/inkstitch_activate_venv.py
new file mode 100644
index 000000000..84f2d7b37
--- /dev/null
+++ b/inkstitch_activate_venv.py
@@ -0,0 +1,6 @@
+import os
+
+if __name__ == "__main__":
+    if os.path.isdir("inkstitch-venv"):
+        activate = os.path.join("inkstitch-venv", "bin", "activate_this.py")
+        execfile(activate, dict(__file__=activate))
diff --git a/makefile b/makefile
deleted file mode 100644
index 4c306e116..000000000
--- a/makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-embroider.tgz: makefile index.html embroider.py embroider.inx images/draft1.jpg images/draft2.jpg images/shirt.jpg PyEmb.py
-	ln -fs embroider .
-	tar czf $@ $^
diff --git a/reorder.inx b/reorder.inx
deleted file mode 100644
index 77bf59d70..000000000
--- a/reorder.inx
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
-    <_name>Reorder</_name>
-    <id>lexelby.embroider.reorder</id>
-    <dependency type="executable" location="extensions">reorder.py</dependency>
-    <dependency type="executable" location="extensions">inkex.py</dependency>
-    <effect>
-        <object-type>all</object-type>
-        <effects-menu>
-            <submenu _name="Embroidery"/>
-        </effects-menu>
-    </effect>
-    <script>
-        <command reldir="extensions" interpreter="python">reorder.py</command>
-    </script>
-</inkscape-extension>
diff --git a/reorder.py b/reorder.py
deleted file mode 100644
index a30a0a47a..000000000
--- a/reorder.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/python
-#
-# Remove selected objects from the document and readd them in the order they
-# were selected.
-
-import sys
-sys.path.append("/usr/share/inkscape/extensions")
-import os
-import inkex
-
-
-class Reorder(inkex.Effect):
-
-    def get_selected_in_order(self):
-        selected = []
-
-        for i in self.options.ids:
-            path = '//*[@id="%s"]' % i
-            for node in self.document.xpath(path, namespaces=inkex.NSS):
-                selected.append(node)
-
-        return selected
-
-    def effect(self):
-        objects = self.get_selected_in_order()
-
-        for obj in objects[1:]:
-            obj.getparent().remove(obj)
-
-        insert_parent = objects[0].getparent()
-        insert_pos = insert_parent.index(objects[0])
-
-        insert_parent.remove(objects[0])
-
-        insert_parent[insert_pos:insert_pos] = objects
-
-if __name__ == '__main__':
-    e = Reorder()
-    e.affect()