[pypy-commit] pypy default: Support for Windows icons

arigo noreply at buildbot.pypy.org
Mon May 4 19:25:17 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r77049:72e7058957d1
Date: 2015-05-04 19:20 +0200
http://bitbucket.org/pypy/pypy/changeset/72e7058957d1/

Log:	Support for Windows icons

diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py
--- a/rpython/config/translationoption.py
+++ b/rpython/config/translationoption.py
@@ -189,6 +189,7 @@
     BoolOption("lldebug0",
                "If true, makes an lldebug0 build", default=False,
                cmdline="--lldebug0"),
+    StrOption("icon", "Path to the (Windows) icon to use for the executable"),
 
     OptionDescription("backendopt", "Backend Optimization Options", [
         # control inlining
diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py
--- a/rpython/translator/c/genc.py
+++ b/rpython/translator/c/genc.py
@@ -391,7 +391,8 @@
             path=targetdir, exe_name=exe_name,
             headers_to_precompile=headers_to_precompile,
             no_precompile_cfiles = module_files,
-            shared=self.config.translation.shared)
+            shared=self.config.translation.shared,
+            icon=self.config.translation.icon)
 
         if self.has_profopt():
             profopt = self.config.translation.profopt
diff --git a/rpython/translator/c/test/test_standalone.py b/rpython/translator/c/test/test_standalone.py
--- a/rpython/translator/c/test/test_standalone.py
+++ b/rpython/translator/c/test/test_standalone.py
@@ -22,13 +22,14 @@
         # Do not open dreaded dialog box on segfault
         import ctypes
         SEM_NOGPFAULTERRORBOX = 0x0002 # From MSDN
-        old_err_mode = ctypes.windll.kernel32.GetErrorMode()
-        new_err_mode = old_err_mode | SEM_NOGPFAULTERRORBOX
-        ctypes.windll.kernel32.SetErrorMode(new_err_mode)
-        module.old_err_mode = old_err_mode
+        if hasattr(ctypes.windll.kernel32, 'GetErrorMode'):
+            old_err_mode = ctypes.windll.kernel32.GetErrorMode()
+            new_err_mode = old_err_mode | SEM_NOGPFAULTERRORBOX
+            ctypes.windll.kernel32.SetErrorMode(new_err_mode)
+            module.old_err_mode = old_err_mode
 
 def teardown_module(module):
-    if os.name == 'nt':
+    if os.name == 'nt' and hasattr(module, 'old_err_mode'):
         import ctypes
         ctypes.windll.kernel32.SetErrorMode(module.old_err_mode)
 
@@ -36,7 +37,7 @@
     config = None
 
     def compile(self, entry_point, debug=True, shared=False,
-                stackcheck=False, entrypoints=None):
+                stackcheck=False, entrypoints=None, local_icon=None):
         t = TranslationContext(self.config)
         ann = t.buildannotator()
         ann.build_types(entry_point, [s_list_of_strings])
@@ -53,6 +54,9 @@
             insert_ll_stackcheck(t)
 
         t.config.translation.shared = shared
+        if local_icon:
+            t.config.translation.icon = os.path.join(os.path.dirname(__file__),
+                                                     local_icon)
 
         if entrypoints is not None:
             kwds = {'secondary_entrypoints': [(i, None) for i in entrypoints]}
@@ -110,7 +114,7 @@
                 os.write(1, "   '" + str(s) + "'\n")
             return 0
 
-        t, cbuilder = self.compile(entry_point)
+        t, cbuilder = self.compile(entry_point, local_icon='red.ico')
         data = cbuilder.cmdexec('hi there')
         assert data.startswith('''hello world\nargument count: 2\n   'hi'\n   'there'\n''')
 
@@ -1407,7 +1411,7 @@
             return 0
 
         t, cbuilder = self.compile(entry_point, shared=True,
-                                   entrypoints=[f])
+                                   entrypoints=[f], local_icon='red.ico')
         ext_suffix = '.so'
         if cbuilder.eci.platform.name == 'msvc':
             ext_suffix = '.dll'
diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py
--- a/rpython/translator/platform/__init__.py
+++ b/rpython/translator/platform/__init__.py
@@ -101,7 +101,7 @@
 
     def gen_makefile(self, cfiles, eci, exe_name=None, path=None,
                      shared=False, headers_to_precompile=[],
-                     no_precompile_cfiles = []):
+                     no_precompile_cfiles = [], icon=None):
         raise NotImplementedError("Pure abstract baseclass")
 
     def __repr__(self):
diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py
--- a/rpython/translator/platform/posix.py
+++ b/rpython/translator/platform/posix.py
@@ -99,7 +99,7 @@
 
     def gen_makefile(self, cfiles, eci, exe_name=None, path=None,
                      shared=False, headers_to_precompile=[],
-                     no_precompile_cfiles = []):
+                     no_precompile_cfiles = [], icon=None):
         cfiles = self._all_cfiles(cfiles, eci)
 
         if path is None:
diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py
--- a/rpython/translator/platform/windows.py
+++ b/rpython/translator/platform/windows.py
@@ -1,6 +1,6 @@
 """Support for Windows."""
 
-import py, os, sys, re
+import py, os, sys, re, shutil
 
 from rpython.translator.platform import CompilationError
 from rpython.translator.platform import log, _run_subprocess
@@ -244,7 +244,7 @@
 
     def gen_makefile(self, cfiles, eci, exe_name=None, path=None,
                      shared=False, headers_to_precompile=[],
-                     no_precompile_cfiles = []):
+                     no_precompile_cfiles = [], icon=None):
         cfiles = self._all_cfiles(cfiles, eci)
 
         if path is None:
@@ -361,6 +361,13 @@
                           '/Fo$@ /c $< $(INCLUDEDIRS)'))
 
 
+        if icon:
+            shutil.copyfile(icon, str(path.join('icon.ico')))
+            rc_file = path.join('icon.rc')
+            rc_file.write('IDI_ICON1 ICON DISCARDABLE "icon.ico"')
+            rules.append(('icon.res', 'icon.rc', 'rc icon.rc'))
+
+
         for args in definitions:
             m.definition(*args)
 
@@ -374,19 +381,23 @@
         else:
             linkobjs = '@<<\n$(OBJECTS)\n<<'
 
+        extra_deps = []
+        if icon and not shared:
+            extra_deps.append('icon.res')
+            linkobjs = 'icon.res ' + linkobjs
         if self.version < 80:
-            m.rule('$(TARGET)', '$(OBJECTS)',
+            m.rule('$(TARGET)', ['$(OBJECTS)'] + extra_deps,
                     [ '$(CC_LINK) /nologo $(LDFLAGS) $(LDFLAGSEXTRA) /out:$@' +\
                       ' $(LIBDIRS) $(LIBS) ' + linkobjs,
                    ])
         else:
-            m.rule('$(TARGET)', '$(OBJECTS)',
+            m.rule('$(TARGET)', ['$(OBJECTS)'] + extra_deps,
                     [ '$(CC_LINK) /nologo $(LDFLAGS) $(LDFLAGSEXTRA)' + \
                       ' $(LINKFILES) /out:$@ $(LIBDIRS) $(LIBS) /MANIFEST' + \
                       ' /MANIFESTFILE:$*.manifest ' + linkobjs,
                     'mt.exe -nologo -manifest $*.manifest -outputresource:$@;1',
                     ])
-        m.rule('debugmode_$(TARGET)', '$(OBJECTS)',
+        m.rule('debugmode_$(TARGET)', ['$(OBJECTS)'] + extra_deps,
                 [ '$(CC_LINK) /nologo /DEBUG $(LDFLAGS) $(LDFLAGSEXTRA)' + \
                   ' $(LINKFILES) /out:$@ $(LIBDIRS) $(LIBS) ' + linkobjs,
                 ])
@@ -399,12 +410,18 @@
                    'int $(PYPY_MAIN_FUNCTION)(int, char*[]); '
                    'int main(int argc, char* argv[]) '
                    '{ return $(PYPY_MAIN_FUNCTION)(argc, argv); } > $@')
-            m.rule('$(DEFAULT_TARGET)', ['$(TARGET)', 'main.obj'],
-                   ['$(CC_LINK) /nologo /debug main.obj $(SHARED_IMPORT_LIB) /out:$@ /MANIFEST /MANIFESTFILE:$*.manifest',
+            deps = ['main.obj']
+            if icon:
+                deps.append('icon.res')
+            m.rule('$(DEFAULT_TARGET)', ['$(TARGET)'] + deps,
+                   ['$(CC_LINK) /nologo /debug %s ' % (' '.join(deps),) + \
+                    '$(SHARED_IMPORT_LIB) /out:$@ ' + \
+                    '/MANIFEST /MANIFESTFILE:$*.manifest',
                     'mt.exe -nologo -manifest $*.manifest -outputresource:$@;1',
                     ])
-            m.rule('debugmode_$(DEFAULT_TARGET)', ['debugmode_$(TARGET)', 'main.obj'],
-                   ['$(CC_LINK) /nologo /DEBUG main.obj debugmode_$(SHARED_IMPORT_LIB) /out:$@'
+            m.rule('debugmode_$(DEFAULT_TARGET)', ['debugmode_$(TARGET)']+deps,
+                   ['$(CC_LINK) /nologo /DEBUG %s ' % (' '.join(deps),) + \
+                    'debugmode_$(SHARED_IMPORT_LIB) /out:$@',
                     ])
 
         return m


More information about the pypy-commit mailing list