[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor-browser-bundle/master] Add gcc, dllwrap, and swig wrappers for Wine.
commit 87142112db32e1999de9ab2a213f5521d37a1e94
Author: David Fifield <david@xxxxxxxxxxxxxxx>
Date: Fri Nov 22 17:22:42 2013 +0000
Add gcc, dllwrap, and swig wrappers for Wine.
Python distutils, with the "mingw32" compiler profile, is inflexible. It
hardcodes the names "gcc.exe" and "dllwrap.exe", and passes them fixed
options. It's not possible to control it with environment variables like
CC and CFLAGS.
Before Python 2.7.6, distutils always passes the option -mno-cygwin to
gcc, which causes an error. Additionally, when distutils is run under
Wine, it passes Windows-style paths with backslashes to our unsuspecting
i686-w64-mingw32-gcc.
These wrapper programs strip -mno-cygwin, and convert Windows paths to
Unix paths. They also set LD_PRELOAD and FAKETIME, because those can't
be set for the outer Wine process.
Doing a subprocess.Popen of a Unix program from within Wine mostly
works. For example, subprocess.Popen(["/usr/bin/i686-w64-mingw32-gcc"])
starts a new compiler process. However, if you .wait() on the process
object, you get a "WindowsError: [Error 6] Invalid handle". The same
goes for the implicit wait in subprocess.call and
subprocess.check_output. The .pid of such processes is 0.
What you can do, however, is read from one of the process's output
streams--it will be closed when the process terminates. Because we know
we are dealing with gcc subprocesses, we read its stderr and look for
the string " error: ". If it appears, we return a non-zero status code.
We don't return non-zero merely on a non-empty stderr, because warnings
don't usually cause that.
The difficulty doesn't exist when running native Windows binaries.
That's why we can do subprocess.call(["winepath", ...]): because
winepath.exe is a native binary that comes with Wine.
---
gitian/build-helpers/wine-wrappers/common.py | 27 ++++++++++++++++++
gitian/build-helpers/wine-wrappers/dllwrap.py | 36 ++++++++++++++++++++++++
gitian/build-helpers/wine-wrappers/gcc.py | 36 ++++++++++++++++++++++++
gitian/build-helpers/wine-wrappers/settings.py | 2 ++
gitian/build-helpers/wine-wrappers/setup.py | 7 +++++
gitian/build-helpers/wine-wrappers/swig.py | 33 ++++++++++++++++++++++
gitian/mkbundle-linux.sh | 2 +-
gitian/mkbundle-mac.sh | 2 +-
gitian/mkbundle-windows.sh | 2 +-
9 files changed, 144 insertions(+), 3 deletions(-)
diff --git a/gitian/build-helpers/wine-wrappers/common.py b/gitian/build-helpers/wine-wrappers/common.py
new file mode 100644
index 0000000..19e994b
--- /dev/null
+++ b/gitian/build-helpers/wine-wrappers/common.py
@@ -0,0 +1,27 @@
+import os
+import subprocess
+
+import settings
+
+def winepath(windowspath):
+ """Convert a Windows path to a Unix path."""
+ return subprocess.check_output(["winepath", "-u", windowspath])[:-1]
+
+def search_startswith(a, elems):
+ """Search for the first element of the array a that startswith any of the
+ members of elems, and return it. Return None if no match was found."""
+ for e in elems:
+ if a.startswith(e):
+ return e
+ return None
+
+def popen_faketime(*args, **kwargs):
+ """Does subprocess.Popen after setting faketime environment variables."""
+ ld_preload = os.getenv("LD_PRELOAD")
+ if ld_preload:
+ # ld.so(8): "The items of [LD_PRELOAD] can be separated by spaces or colons."
+ ld_preload += ":"
+ ld_preload += settings.LD_PRELOAD
+ os.putenv("LD_PRELOAD", ld_preload)
+ os.putenv("FAKETIME", settings.FAKETIME)
+ return subprocess.Popen(*args, **kwargs)
diff --git a/gitian/build-helpers/wine-wrappers/dllwrap.py b/gitian/build-helpers/wine-wrappers/dllwrap.py
new file mode 100755
index 0000000..fdff035
--- /dev/null
+++ b/gitian/build-helpers/wine-wrappers/dllwrap.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+
+# A wrapper for i686-w64-mingw32-dllwrap that removes -mno-cygwin and converts
+# Windows paths to Unix paths, so that the w64-mingw32 dllwrap can be called by
+# Python distutils.
+
+import os
+import subprocess
+import sys
+
+import common
+
+args = ["/usr/bin/i686-w64-mingw32-dllwrap"]
+sys.argv.pop(0)
+while sys.argv:
+ a = sys.argv.pop(0)
+ if not a.startswith("-"):
+ args.append(common.winepath(a))
+ continue
+ if a == "-mno-cygwin":
+ continue
+ if a in ("-I", "-L", "-s", "--def", "--output-lib"):
+ args.append(a)
+ args.append(common.winepath(sys.argv.pop(0)))
+ continue
+ o = common.search_startswith(a, ("-I", "-L", "--def=", "--output-lib="))
+ if o is not None:
+ path = a[len(o):]
+ args.append("%s%s" % (o, common.winepath(path)))
+ continue
+ args.append(a)
+p = common.popen_faketime(args, stderr=subprocess.PIPE)
+stderr = p.stderr.read()
+sys.stderr.write(stderr)
+if " error: " in stderr:
+ sys.exit(1)
diff --git a/gitian/build-helpers/wine-wrappers/gcc.py b/gitian/build-helpers/wine-wrappers/gcc.py
new file mode 100755
index 0000000..493b27b
--- /dev/null
+++ b/gitian/build-helpers/wine-wrappers/gcc.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+
+# A wrapper for i686-w64-mingw32-gcc that removes -mno-cygwin and converts
+# Windows paths to Unix paths, so that the w64-mingw32 gcc can be called by
+# Python distutils.
+
+import os
+import subprocess
+import sys
+
+import common
+
+args = ["/usr/bin/i686-w64-mingw32-gcc"]
+sys.argv.pop(0)
+while sys.argv:
+ a = sys.argv.pop(0)
+ if not a.startswith("-"):
+ args.append(common.winepath(a))
+ continue
+ if a == "-mno-cygwin":
+ continue
+ if a in ("-I", "-L"):
+ args.append(a)
+ args.append(common.winepath(sys.argv.pop(0)))
+ continue
+ o = common.search_startswith(a, ("-I", "-L"))
+ if o is not None:
+ path = a[len(o):]
+ args.append("%s%s" % (o, common.winepath(path)))
+ continue
+ args.append(a)
+p = common.popen_faketime(args, stderr=subprocess.PIPE)
+stderr = p.stderr.read()
+sys.stderr.write(stderr)
+if " error: " in stderr:
+ sys.exit(1)
diff --git a/gitian/build-helpers/wine-wrappers/settings.py b/gitian/build-helpers/wine-wrappers/settings.py
new file mode 100644
index 0000000..f395433
--- /dev/null
+++ b/gitian/build-helpers/wine-wrappers/settings.py
@@ -0,0 +1,2 @@
+LD_PRELOAD = "/usr/lib/faketime/libfaketime.so.1"
+FAKETIME = "2000-01-01 00:00:00"
diff --git a/gitian/build-helpers/wine-wrappers/setup.py b/gitian/build-helpers/wine-wrappers/setup.py
new file mode 100644
index 0000000..797015e
--- /dev/null
+++ b/gitian/build-helpers/wine-wrappers/setup.py
@@ -0,0 +1,7 @@
+from distutils.core import setup
+import py2exe
+setup(
+ console=["gcc.py", "dllwrap.py", "swig.py"],
+ zipfile=None,
+ options={"py2exe": {"bundle_files": 1, "compressed": True}}
+)
diff --git a/gitian/build-helpers/wine-wrappers/swig.py b/gitian/build-helpers/wine-wrappers/swig.py
new file mode 100755
index 0000000..45941f4
--- /dev/null
+++ b/gitian/build-helpers/wine-wrappers/swig.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+# A wrapper for swig that converts Windows paths to Unix paths, so that swig can
+# be called by Python distutils.
+
+import os
+import subprocess
+import sys
+
+import common
+
+args = ["/usr/bin/swig"]
+sys.argv.pop(0)
+while sys.argv:
+ a = sys.argv.pop(0)
+ if not a.startswith("-"):
+ args.append(common.winepath(a))
+ continue
+ if a in ("-I",):
+ args.append(a)
+ args.append(common.winepath(sys.argv.pop(0)))
+ continue
+ o = common.search_startswith(a, ("-I",))
+ if o is not None:
+ path = a[len(o):]
+ args.append("%s%s" % (o, common.winepath(path)))
+ continue
+ args.append(a)
+p = common.popen_faketime(args, stderr=subprocess.PIPE)
+stderr = p.stderr.read()
+sys.stderr.write(stderr)
+if " Error: " in stderr:
+ sys.exit(1)
diff --git a/gitian/mkbundle-linux.sh b/gitian/mkbundle-linux.sh
index 9ef0910..3b92216 100755
--- a/gitian/mkbundle-linux.sh
+++ b/gitian/mkbundle-linux.sh
@@ -41,7 +41,7 @@ echo "pref(\"torbrowser.version\", \"$TORBROWSER_VERSION-Linux\");" > $GITIAN_DI
echo "$TORBROWSER_VERSION" > $GITIAN_DIR/inputs/bare-version
cp -a $WRAPPER_DIR/$VERSIONS_FILE $GITIAN_DIR/inputs/versions
-cp $WRAPPER_DIR/build-helpers/* $GITIAN_DIR/inputs/
+cp -r $WRAPPER_DIR/build-helpers/* $GITIAN_DIR/inputs/
cd $WRAPPER_DIR/..
rm -f $GITIAN_DIR/inputs/relativelink-src.zip
diff --git a/gitian/mkbundle-mac.sh b/gitian/mkbundle-mac.sh
index 8e4da79..69ef3ed 100755
--- a/gitian/mkbundle-mac.sh
+++ b/gitian/mkbundle-mac.sh
@@ -41,7 +41,7 @@ echo "pref(\"torbrowser.version\", \"$TORBROWSER_VERSION-MacOS\");" > $GITIAN_DI
echo "$TORBROWSER_VERSION" > $GITIAN_DIR/inputs/bare-version
cp -a $WRAPPER_DIR/$VERSIONS_FILE $GITIAN_DIR/inputs/versions
-cp $WRAPPER_DIR/build-helpers/* $GITIAN_DIR/inputs/
+cp -r $WRAPPER_DIR/build-helpers/* $GITIAN_DIR/inputs/
cd $WRAPPER_DIR/..
rm -f $GITIAN_DIR/inputs/relativelink-src.zip
diff --git a/gitian/mkbundle-windows.sh b/gitian/mkbundle-windows.sh
index 33e8a2b..9542604 100755
--- a/gitian/mkbundle-windows.sh
+++ b/gitian/mkbundle-windows.sh
@@ -42,7 +42,7 @@ echo "pref(\"torbrowser.version\", \"$TORBROWSER_VERSION-Windows\");" > $GITIAN_
echo "$TORBROWSER_VERSION" > $GITIAN_DIR/inputs/bare-version
cp -a $WRAPPER_DIR/$VERSIONS_FILE $GITIAN_DIR/inputs/versions
-cp $WRAPPER_DIR/build-helpers/* $GITIAN_DIR/inputs/
+cp -r $WRAPPER_DIR/build-helpers/* $GITIAN_DIR/inputs/
cp $WRAPPER_DIR/gpg/ubuntu-wine.gpg $GITIAN_DIR/inputs/
cd $WRAPPER_DIR/..
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits