source: docker/msys/py2exe.patch@ 963:35b2e35e9e07

python3
Last change on this file since 963:35b2e35e9e07 was 936:2d2c88cfc74a, checked in by István Váradi <ivaradi@…>, 6 years ago

Programs are produced for the Windows subsysteam (re #347)

File size: 32.2 KB
RevLine 
[920]1diff --git a/py2exe/distutils_buildexe.py b/py2exe/distutils_buildexe.py
2index ae8aca3..d809641 100644
3--- a/py2exe/distutils_buildexe.py
4+++ b/py2exe/distutils_buildexe.py
5@@ -154,6 +154,7 @@ class py2exe(Command):
6 self.ascii = 0
7 self.custom_boot_script = None
8 self.use_assembly = False
9+ self.gi_namespaces = []
10
11 def finalize_options (self):
12 self.optimize = int(self.optimize)
13@@ -239,6 +240,7 @@ class py2exe(Command):
14 excludes = self.excludes,
15 ignores = self.ignores,
16 packages = self.packages,
17+ gi_namespaces = self.gi_namespaces,
18 dist_dist = self.dist_dir,
19 dll_excludes = self.dll_excludes,
20 typelibs = self.typelibs,
21diff --git a/py2exe/dllfinder.py b/py2exe/dllfinder.py
22index 4e5e76c..bb43f9e 100644
23--- a/py2exe/dllfinder.py
24+++ b/py2exe/dllfinder.py
25@@ -68,7 +68,8 @@ class DllFinder:
26 if dll in self._loaded_dlls:
27 continue
28 for dep_dll in self.bind_image(dll):
29- if dep_dll in self._loaded_dlls:
30+ bname = os.path.basename(dep_dll).lower()
31+ if bname in self._loaded_dlls:
32 continue
33 dll_type = self.determine_dll_type(dep_dll)
34 if dll_type is None:
35@@ -144,7 +145,8 @@ class DllFinder:
36 deps = self.bind_image(imagename)
37 if pydll in [d.lower() for d in deps]:
38 return "EXT"
39- if fnm.startswith(windir + os.sep) or fnm.startswith(sysdir + os.sep):
40+ if fnm.startswith(windir + os.sep) or fnm.startswith(sysdir + os.sep) or \
41+ fnm.startswith(windir + '\\') or fnm.startswith(sysdir + '\\'):
42 return None
43 return "DLL"
44
45diff --git a/py2exe/gihelper.py b/py2exe/gihelper.py
46index e69de29..f597692 100644
47--- a/py2exe/gihelper.py
48+++ b/py2exe/gihelper.py
49@@ -0,0 +1,58 @@
50+
51+import cffi
52+
53+class GIHelper(object):
54+ _cdef="""
55+ typedef char gchar;
56+ typedef int gint;
57+ typedef uint32_t guint32;
58+ typedef guint32 GQuark;
59+
60+ typedef struct {
61+ GQuark domain;
62+ gint code;
63+ gchar *message;
64+ } GError;
65+
66+ typedef struct _GITypelib GITypelib;
67+ typedef struct _GIRepository GIRepository;
68+
69+ typedef enum
70+ {
71+ G_IREPOSITORY_LOAD_FLAG_LAZY = 1
72+ } GIRepositoryLoadFlags;
73+
74+ GIRepository *g_irepository_get_default (void);
75+
76+ GITypelib * g_irepository_require (GIRepository *repository,
77+ const gchar *namespace_,
78+ const gchar *version,
79+ GIRepositoryLoadFlags flags,
80+ GError **error);
81+
82+ const gchar * g_irepository_get_shared_library (GIRepository *repository,
83+ const gchar *namespace_);
84+ """
85+
86+ def __init__(self):
87+ self._ffi = cffi.FFI()
88+ self._ffi.cdef(self._cdef)
89+
90+ self._lib = self._ffi.dlopen("libgirepository-1.0-1.dll")
91+
92+ self._repo=self._lib.g_irepository_get_default()
93+
94+ self._error = self._ffi.new("GError**")
95+
96+ def getSharedLibraries(self, namespace, version):
97+ typelib = self._lib.g_irepository_require(self._repo,
98+ bytes(namespace, "utf-8"),
99+ bytes(version, "utf-8"),
100+ 0, self._error)
101+ if typelib == self._ffi.NULL:
102+ return []
103+ else:
104+ return str(
105+ self._ffi.string(
106+ self._lib.g_irepository_get_shared_library(
107+ self._repo, bytes(namespace, "utf-8"))), "utf-8").split(",")
108diff --git a/py2exe/mf3.py b/py2exe/mf3.py
109index f645740..ec1f261 100644
110--- a/py2exe/mf3.py
111+++ b/py2exe/mf3.py
112@@ -5,6 +5,7 @@
113
114 # XXX XXX XXX Does not yet support PEP 452 namespace packages!
115
116+from . import gihelper
117 from collections import defaultdict
118 import dis
119 import importlib
120@@ -21,6 +22,9 @@ LOAD_CONST = dis.opname.index('LOAD_CONST')
121 IMPORT_NAME = dis.opname.index('IMPORT_NAME')
122 STORE_NAME = dis.opname.index('STORE_NAME')
123 STORE_GLOBAL = dis.opname.index('STORE_GLOBAL')
124+LOAD_NAME = dis.opname.index('LOAD_NAME')
125+LOAD_METHOD = dis.opname.index('LOAD_METHOD')
126+CALL_METHOD = dis.opname.index('CALL_METHOD')
127 STORE_OPS = [STORE_NAME, STORE_GLOBAL]
128 HAVE_ARGUMENT = dis.HAVE_ARGUMENT
129
130@@ -63,7 +67,7 @@ class ModuleFinder:
131 self._depgraph = defaultdict(set)
132 self._indent = ""
133 self._package_paths = defaultdict(list)
134-
135+ self._gihelper = gihelper.GIHelper()
136
137 def add_packagepath(self, packagename, path):
138 """ModuleFinder can not handle __path__ modifications packages
139@@ -416,7 +420,6 @@ class ModuleFinder:
140 We also take note of 'static' global symbols in the module and
141 add them to __globalnames__.
142 """
143-
144 for what, args in self._scan_opcodes(code):
145 if what == "store":
146 name, = args
147@@ -424,6 +427,11 @@ class ModuleFinder:
148 elif what == "import":
149 level, fromlist, name = args
150 self.safe_import_hook(name, mod, fromlist, level)
151+ elif what == "gi_request":
152+ for sharedLibrary in \
153+ self._gihelper.getSharedLibraries(args[0], args[1]):
154+ from . dllfinder import SearchPath
155+ self.add_dll(SearchPath(sharedLibrary))
156 else:
157 # We don't expect anything else from the generator.
158 raise RuntimeError(what)
159@@ -442,10 +450,15 @@ class ModuleFinder:
160 # dis.get_instructions() is only available in python 3.4
161 # and higher
162 instructions = []
163+
164+ requireCallLevel = 0
165+ requiredNamespace = None
166+ requiredVersion = None
167 for inst in dis.get_instructions(co):
168 instructions.append(inst)
169 c = inst.opcode
170 if c == IMPORT_NAME:
171+ requireCallLevel = 0
172 assert instructions[-3].opcode == LOAD_CONST
173 level = instructions[-3].argval
174 assert instructions[-2].opcode == LOAD_CONST
175@@ -453,7 +466,34 @@ class ModuleFinder:
176 name = inst.argval
177 yield "import", (level, fromlist, name)
178 elif c in STORE_OPS:
179+ requireCallLevel = 0
180 yield "store", (inst.argval,)
181+ elif c == LOAD_NAME:
182+ if requireCallLevel==0 and inst.argval=="gi":
183+ requireCallLevel += 1
184+ else:
185+ requireCallLevel = 0
186+ elif c == LOAD_METHOD:
187+ if requireCallLevel==1 and inst.argval=="require_version":
188+ requireCallLevel += 1
189+ else:
190+ requireCallLevel = 0
191+ elif c==LOAD_CONST:
192+ if requireCallLevel==2:
193+ requiredNamespace = inst.argval
194+ requireCallLevel += 1
195+ elif requireCallLevel==3:
196+ requiredVersion = inst.argval
197+ requireCallLevel += 1
198+ else:
199+ requireCallLevel = 0
200+ elif c==CALL_METHOD:
201+ if requireCallLevel==4:
202+ yield ("gi_request", (requiredNamespace, requiredVersion))
203+ requireCallLevel = 0
204+ requiredNamespace = None
205+ requiredVersion = None
206+
207 else:
208 code = co.co_code
209 names = co.co_names
210diff --git a/py2exe/py2exe_distutils.py b/py2exe/py2exe_distutils.py
211index 3918849..fe97b90 100644
212--- a/py2exe/py2exe_distutils.py
213+++ b/py2exe/py2exe_distutils.py
214@@ -1,5 +1,5 @@
215 # This file is only used when BUILDING py2exe.
216-import os, sys
217+import os, sys, types, copy
218
219 from distutils.core import Extension
220 from distutils.dist import Distribution
221@@ -8,12 +8,17 @@ from distutils.sysconfig import customize_compiler
222 from distutils.dep_util import newer_group
223 from distutils.errors import DistutilsError, DistutilsSetupError, DistutilsPlatformError
224 from distutils.errors import CCompilerError, CompileError
225+from distutils.file_util import write_file
226 from distutils.util import get_platform
227 from distutils import log
228
229-# We don't need a manifest in the executable, so monkeypatch the code away:
230-from distutils.msvc9compiler import MSVCCompiler
231-MSVCCompiler.manifest_setup_ldargs = lambda *args: None
232+from distutils import ccompiler
233+isMingw32 = ccompiler.get_default_compiler()=='mingw32'
234+
235+if not isMingw32:
236+ # We don't need a manifest in the executable, so monkeypatch the code away:
237+ from distutils.msvc9compiler import MSVCCompiler
238+ MSVCCompiler.manifest_setup_ldargs = lambda *args: None
239
240 class Interpreter(Extension):
241 def __init__(self, *args, **kw):
242@@ -38,6 +43,82 @@ class Dist(Distribution):
243 def has_extensions(self):
244 return False
245
246+def mingw32_link(self, target_desc, objects, output_filename, output_dir=None,
247+ libraries=None, library_dirs=None, runtime_library_dirs=None,
248+ export_symbols=None, debug=0, extra_preargs=None,
249+ extra_postargs=None, build_temp=None, target_lang=None):
250+ """Link the objects."""
251+ from distutils.unixccompiler import UnixCCompiler
252+
253+ # use separate copies, so we can modify the lists
254+ extra_preargs = copy.copy(extra_preargs or [])
255+ libraries = copy.copy(libraries or [])
256+ objects = copy.copy(objects or [])
257+
258+ # Additional libraries
259+ libraries.extend(self.dll_libraries)
260+
261+ # handle export symbols by creating a def-file
262+ # with executables this only works with gcc/ld as linker
263+ if ((export_symbols is not None) and
264+ (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
265+ # (The linker doesn't do anything if output is up-to-date.
266+ # So it would probably better to check if we really need this,
267+ # but for this we had to insert some unchanged parts of
268+ # UnixCCompiler, and this is not what we want.)
269+
270+ # we want to put some files in the same directory as the
271+ # object files are, build_temp doesn't help much
272+ # where are the object files
273+ temp_dir = os.path.dirname(objects[0])
274+ # name of dll to give the helper files the same base name
275+ (dll_name, dll_extension) = os.path.splitext(
276+ os.path.basename(output_filename))
277+
278+ # generate the filenames for these files
279+ def_file = os.path.join(temp_dir, dll_name + ".def")
280+ lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a")
281+
282+ # Generate .def file
283+ contents = ["EXPORTS"]
284+ for sym in export_symbols:
285+ contents.append(sym)
286+ self.execute(write_file, (def_file, contents),
287+ "writing %s" % def_file)
288+
289+ # next add options for def-file and to creating import libraries
290+
291+ # dllwrap uses different options than gcc/ld
292+ if self.linker_dll == "dllwrap":
293+ extra_preargs.extend(["--output-lib", lib_file])
294+ # for dllwrap we have to use a special option
295+ extra_preargs.extend(["--def", def_file])
296+ # we use gcc/ld here and can be sure ld is >= 2.9.10
297+ else:
298+ # doesn't work: bfd_close build\...\libfoo.a: Invalid operation
299+ #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
300+ # for gcc/ld the def-file is specified as any object files
301+ objects.append(def_file)
302+
303+ #end: if ((export_symbols is not None) and
304+ # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
305+
306+ # who wants symbols and a many times larger output file
307+ # should explicitly switch the debug mode on
308+ # otherwise we let dllwrap/ld strip the output file
309+ # (On my machine: 10KiB < stripped_file < ??100KiB
310+ # unstripped_file = stripped_file + XXX KiB
311+ # ( XXX=254 for a typical python extension))
312+ if not debug and not hasattr(sys, 'gettotalrefcount'):
313+ extra_preargs.append("-s")
314+
315+ UnixCCompiler.link(self, target_desc, objects, output_filename,
316+ output_dir, libraries, library_dirs,
317+ runtime_library_dirs,
318+ None, # export_symbols, we do this in our def-file
319+ debug, extra_preargs, extra_postargs, build_temp,
320+ target_lang)
321+
322 class BuildInterpreters(build_ext.build_ext):
323 description = "build special python interpreter stubs"
324
325@@ -67,6 +148,9 @@ class BuildInterpreters(build_ext.build_ext):
326 if os.name == 'nt' and self.plat_name != get_platform():
327 self.compiler.initialize(self.plat_name)
328
329+ if isMingw32:
330+ self.compiler.link = types.MethodType(mingw32_link, self.compiler)
331+
332 # And make sure that any compile/link-related options (which might
333 # come from the command-line or from the setup script) are set in
334 # that CCompiler object -- that way, they automatically apply to
335@@ -190,7 +274,7 @@ class BuildInterpreters(build_ext.build_ext):
336 libraries=self.get_libraries(ext),
337 library_dirs=ext.library_dirs,
338 runtime_library_dirs=ext.runtime_library_dirs,
339- export_symbols=ext.export_symbols,
340+ export_symbols=ext.export_symbols if ext.export_symbols else None,
341 extra_postargs=extra_args,
342 debug=self.debug)
343
344diff --git a/py2exe/runtime.py b/py2exe/runtime.py
345index 10b0fa9..d154ff7 100644
346--- a/py2exe/runtime.py
347+++ b/py2exe/runtime.py
348@@ -19,8 +19,8 @@ from .icons import BuildIcons
349
350 logger = logging.getLogger("runtime")
351
352-#from importlib.machinery import EXTENSION_SUFFIXES
353-EXTENSION_SUFFIXES = ['.pyd']
354+from importlib.machinery import EXTENSION_SUFFIXES
355+#EXTENSION_SUFFIXES = ['.pyd']
356 from importlib.machinery import DEBUG_BYTECODE_SUFFIXES, OPTIMIZED_BYTECODE_SUFFIXES
357
358 RT_MANIFEST = 24
359@@ -248,12 +248,15 @@ class Runtime(object):
360 if os.path.isfile(libpath):
361 os.remove(libpath)
362
363- if not os.path.exists(os.path.dirname(libpath)):
364- os.mkdir(os.path.dirname(libpath))
365-
366- dll_bytes = pkgutil.get_data("py2exe", "resources.dll")
367- with open(libpath, "wb") as ofi:
368- ofi.write(dll_bytes)
369+ if self.options.skip_archive:
370+ if not os.path.exists(libpath):
371+ os.makedirs(libpath)
372+ else:
373+ if not os.path.exists(os.path.dirname(libpath)):
374+ os.mkdir(os.path.dirname(libpath))
375+ dll_bytes = pkgutil.get_data("py2exe", "resources.dll")
376+ with open(libpath, "wb") as ofi:
377+ ofi.write(dll_bytes)
378 if options.verbose:
379 print("Building shared code archive '%s'." % libpath)
380 # Archive is appended to resources.dll; remove the icon
381@@ -263,7 +266,7 @@ class Runtime(object):
382
383 self.copy_files(destdir)
384
385- # data directories from modulefinder
386+ # data directories from modulefinder
387 for name, (src, recursive) in self.mf._data_directories.items():
388 if recursive:
389 dst = os.path.join(destdir, name)
390@@ -274,11 +277,11 @@ class Runtime(object):
391 else:
392 raise RuntimeError("not yet supported")
393
394- # data files from modulefinder
395- for name, src in self.mf._data_files.items():
396- dst = os.path.join(destdir, name)
397- shutil.copy2(src, dst)
398-
399+ # data files from modulefinder
400+ for name, src in self.mf._data_files.items():
401+ dst = os.path.join(destdir, name)
402+ shutil.copy2(src, dst)
403+
404 # other data files
405 if self.options.data_files:
406 for subdir, files in self.options.data_files:
407@@ -410,46 +413,38 @@ class Runtime(object):
408 compression = zipfile.ZIP_STORED
409
410 # Create a zipfile and append it to the library file
411- arc = zipfile.ZipFile(libpath, "a",
412- compression=compression)
413-
414- # The same modules may be in self.ms.modules under different
415- # keys; we only need one of them in the archive.
416- for mod in set(self.mf.modules.values()):
417- if mod.__code__:
418- if hasattr(mod, "__path__"):
419- path = mod.__name__.replace(".", "\\") + "\\__init__" + bytecode_suffix
420- else:
421- path = mod.__name__.replace(".", "\\") + bytecode_suffix
422- stream = io.BytesIO()
423- stream.write(imp.get_magic())
424- if sys.version_info >= (3,7,0):
425- stream.write(b"\0\0\0\0") # null flags
426- stream.write(b"\0\0\0\0") # null timestamp
427- stream.write(b"\0\0\0\0") # null size
428- marshal.dump(mod.__code__, stream)
429- arc.writestr(path, stream.getvalue())
430-
431- elif hasattr(mod, "__file__"):
432- #assert mod.__file__.endswith(EXTENSION_SUFFIXES[0])
433- if self.options.bundle_files <= 2:
434- # put .pyds into the archive
435- arcfnm = mod.__name__.replace(".", "\\") + EXTENSION_SUFFIXES[0]
436- if self.options.verbose > 1:
437- print("Add %s to %s" % (os.path.basename(mod.__file__), libpath))
438- arc.write(mod.__file__, arcfnm)
439- else:
440- # The extension modules will be copied into
441- # dlldir. To be able to import it without dlldir
442- # being on sys.path, create a loader module and
443- # put that into the archive.
444- pydfile = mod.__name__ + EXTENSION_SUFFIXES[0]
445- if self.options.verbose > 1:
446- print("Add Loader for %s to %s" % (os.path.basename(mod.__file__), libpath))
447- loader = LOAD_FROM_DIR.format(pydfile)
448-
449- code = compile(loader, "<loader>", "exec",
450- optimize=self.options.optimize)
451+ if self.options.skip_archive:
452+ for mod in set(self.mf.modules.values()):
453+ if hasattr(mod, "__file__"):
454+ path = os.path.join(*mod.__name__.split("."))
455+ if hasattr(mod, "__path__"):
456+ path = os.path.join(path, "__init__")
457+ path += bytecode_suffix if mod.__code__ else EXTENSION_SUFFIXES[0]
458+ path = os.path.join(libpath, path)
459+ dirpath = os.path.dirname(path)
460+ if not os.path.isdir(dirpath):
461+ os.makedirs(dirpath)
462+ if mod.__code__:
463+ with open(mod.__file__, "rt") as fin:
464+ code = compile(fin.read(), mod.__file__, "exec",
465+ optimize=self.options.optimize)
466+ with open(path, "wb") as fout:
467+ fout.write(imp.get_magic())
468+ if sys.version_info >= (3,7,0):
469+ fout.write(b"\0\0\0\0") # null flags
470+ fout.write(b"\0\0\0\0") # null timestamp
471+ fout.write(b"\0\0\0\0") # null size
472+ marshal.dump(code, fout)
473+ else:
474+ shutil.copy2(mod.__file__, path)
475+ else:
476+ arc = zipfile.ZipFile(libpath, "a",
477+ compression=compression)
478+
479+ # The same modules may be in self.ms.modules under different
480+ # keys; we only need one of them in the archive.
481+ for mod in set(self.mf.modules.values()):
482+ if mod.__code__:
483 if hasattr(mod, "__path__"):
484 path = mod.__name__.replace(".", "\\") + "\\__init__" + bytecode_suffix
485 else:
486@@ -457,28 +452,61 @@ class Runtime(object):
487 stream = io.BytesIO()
488 stream.write(imp.get_magic())
489 if sys.version_info >= (3,7,0):
490- stream.write(b"\0\0\0\0") # null flags
491+ stream.write(b"\0\0\0\0") # null flags
492 stream.write(b"\0\0\0\0") # null timestamp
493 stream.write(b"\0\0\0\0") # null size
494- marshal.dump(code, stream)
495+ marshal.dump(mod.__code__, stream)
496 arc.writestr(path, stream.getvalue())
497
498- if self.options.bundle_files == 0:
499- # put everything into the arc
500- files = self.mf.all_dlls()
501- elif self.options.bundle_files in (1, 2):
502- # put only extension dlls into the arc
503- files = self.mf.extension_dlls()
504- else:
505- arc.close()
506- return
507+ elif hasattr(mod, "__file__"):
508+ #assert mod.__file__.endswith(EXTENSION_SUFFIXES[0])
509+ if self.options.bundle_files <= 2:
510+ # put .pyds into the archive
511+ arcfnm = mod.__name__.replace(".", "\\") + EXTENSION_SUFFIXES[0]
512+ if self.options.verbose > 1:
513+ print("Add %s to %s" % (os.path.basename(mod.__file__), libpath))
514+ arc.write(mod.__file__, arcfnm)
515+ else:
516+ # The extension modules will be copied into
517+ # dlldir. To be able to import it without dlldir
518+ # being on sys.path, create a loader module and
519+ # put that into the archive.
520+ pydfile = mod.__name__ + EXTENSION_SUFFIXES[0]
521+ if self.options.verbose > 1:
522+ print("Add Loader for %s to %s" % (os.path.basename(mod.__file__), libpath))
523+ loader = LOAD_FROM_DIR.format(pydfile)
524+
525+ code = compile(loader, "<loader>", "exec",
526+ optimize=self.options.optimize)
527+ if hasattr(mod, "__path__"):
528+ path = mod.__name__.replace(".", "\\") + "\\__init__" + bytecode_suffix
529+ else:
530+ path = mod.__name__.replace(".", "\\") + bytecode_suffix
531+ stream = io.BytesIO()
532+ stream.write(imp.get_magic())
533+ if sys.version_info >= (3,7,0):
534+ stream.write(b"\0\0\0\0") # null flags
535+ stream.write(b"\0\0\0\0") # null timestamp
536+ stream.write(b"\0\0\0\0") # null size
537+ marshal.dump(code, stream)
538+ arc.writestr(path, stream.getvalue())
539+
540+ if self.options.bundle_files == 0:
541+ # put everything into the arc
542+ files = self.mf.all_dlls()
543+ elif self.options.bundle_files in (1, 2):
544+ # put only extension dlls into the arc
545+ files = self.mf.extension_dlls()
546+ else:
547+ arc.close()
548+ return
549
550- for src in files:
551- if self.options.verbose > 1:
552- print("Add DLL %s to %s" % (os.path.basename(src), libpath))
553- arc.write(src, os.path.basename(src))
554+ for src in files:
555+ if self.options.verbose > 1:
556+ print("Add DLL %s to %s" % (os.path.basename(src), libpath))
557+ arc.write(src, os.path.basename(src))
558
559- arc.close()
560+ arc.close()
561
562 def copy_files(self, destdir):
563 """Copy files (pyds, dlls, depending on the bundle_files value,
564@@ -498,17 +526,19 @@ class Runtime(object):
565 with UpdateResources(dst, delete_existing=False) as resource:
566 resource.add_string(1000, "py2exe")
567
568- if self.options.bundle_files == 3:
569+ if not self.options.skip_archive and self.options.bundle_files == 3:
570 # copy extension modules; they go to libdir
571 for mod in self.mf.modules.values():
572 if mod.__code__:
573 # nothing to do for python modules.
574 continue
575 if hasattr(mod, "__file__"):
576- assert mod.__file__.endswith(EXTENSION_SUFFIXES[0])
577- pydfile = mod.__name__ + EXTENSION_SUFFIXES[0]
578+ if mod.__file__.endswith(EXTENSION_SUFFIXES[0]):
579+ pydfile = mod.__name__ + EXTENSION_SUFFIXES[0]
580
581- dst = os.path.join(libdir, pydfile)
582+ dst = os.path.join(libdir, pydfile)
583+ else:
584+ dst = os.path.join(libdir, os.path.basename(mod.__file__))
585 if self.options.verbose:
586 print("Copy %s to %s" % (mod.__file__, dst))
587 shutil.copy2(mod.__file__, dst)
588@@ -638,9 +668,11 @@ def __load():
589 dllpath = os.path.join(os.path.dirname(__loader__.archive), r'{0}')
590 try:
591 mod = imp.load_dynamic(__name__, dllpath)
592+ mod.frozen = 1
593 except ImportError as details:
594 raise ImportError('(%s) %r' % (details, dllpath)) from None
595- mod.frozen = 1
596+ except AttributeError:
597+ pass
598 __load()
599 del __load
600 """
601diff --git a/setup.py b/setup.py
602index 342d194..5fb5a9a 100644
603--- a/setup.py
604+++ b/setup.py
605@@ -12,6 +12,8 @@ if sys.version_info < (3, 3):
606 ############################################################################
607
608 from setuptools import setup
609+from distutils import ccompiler
610+isMingw32 = ccompiler.get_default_compiler()=='mingw32'
611 ##from distutils.core import setup
612
613 from py2exe.py2exe_distutils import Dist, Interpreter, BuildInterpreters
614@@ -26,11 +28,11 @@ def _is_debug_build():
615 return False
616
617 if _is_debug_build():
618- macros = [("PYTHONDLL", '\\"python%d%d_d.dll\\"' % sys.version_info[:2]),
619+ macros = [("PYTHONDLL", ('"libpython%d.%dm_d.dll"' if isMingw32 else '"\\python%d%d_d.dll\\"') % sys.version_info[:2]),
620 ## ("PYTHONCOM", '\\"pythoncom%d%d_d.dll\\"' % sys.version_info[:2]),
621 ("_CRT_SECURE_NO_WARNINGS", '1')]
622 else:
623- macros = [("PYTHONDLL", '\\"python%d%d.dll\\"' % sys.version_info[:2]),
624+ macros = [("PYTHONDLL", ('"libpython%d.%dm.dll"' if isMingw32 else '"\\python%d%d.dll\\"') % sys.version_info[:2]),
625 ## ("PYTHONCOM", '\\"pythoncom%d%d.dll\\"' % sys.version_info[:2]),
626 ("_CRT_SECURE_NO_WARNINGS", '1'),]
627
628@@ -39,9 +41,10 @@ macros.append(("Py_BUILD_CORE", '1'))
629 extra_compile_args = []
630 extra_link_args = []
631
632-extra_compile_args.append("-IC:\\Program Files\\Microsoft SDKs\\Windows\\v7.0\\Include")
633-extra_compile_args.append("-IC:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\include")
634-extra_compile_args.append("-IC:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.10586.0\\ucrt")
635+if not isMingw32:
636+ extra_compile_args.append("-IC:\\Program Files\\Microsoft SDKs\\Windows\\v7.0\\Include")
637+ extra_compile_args.append("-IC:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\include")
638+ extra_compile_args.append("-IC:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.10586.0\\ucrt")
639
640 if 0:
641 # enable this to debug a release build
642@@ -63,7 +66,11 @@ run_ctypes_dll = Interpreter("py2exe.run_ctypes_dll",
643 "source/python-dynload.c",
644 ],
645 libraries=["user32", "shell32"],
646- export_symbols=["DllCanUnloadNow,PRIVATE",
647+ export_symbols=["DllCanUnloadNow",
648+ "DllGetClassObject",
649+ "DllRegisterServer",
650+ "DllUnregisterServer",
651+ ] if isMingw32 else ["DllCanUnloadNow,PRIVATE",
652 "DllGetClassObject,PRIVATE",
653 "DllRegisterServer,PRIVATE",
654 "DllUnregisterServer,PRIVATE",
655@@ -71,7 +78,7 @@ run_ctypes_dll = Interpreter("py2exe.run_ctypes_dll",
656 target_desc = "shared_library",
657 define_macros=macros,
658 extra_compile_args=extra_compile_args,
659- extra_link_args=extra_link_args + ["/DLL"],
660+ extra_link_args=extra_link_args + ([] if isMingw32 else ["/DLL"]),
661 )
662
663 run = Interpreter("py2exe.run",
664@@ -123,7 +130,7 @@ resource_dll = Interpreter("py2exe.resources",
665 ["source/dll.c",
666 "source/icon.rc"],
667 target_desc = "shared_library",
668- extra_link_args=["/DLL"],
669+ extra_link_args=[] if isMingw32 else ["/DLL"],
670 )
671
672 interpreters = [run, run_w, resource_dll,
673diff --git a/source/python-dynload.c b/source/python-dynload.c
674index 2a60b86..373bb62 100644
675--- a/source/python-dynload.c
676+++ b/source/python-dynload.c
677@@ -31,7 +31,7 @@ static HMODULE hmod_pydll;
678
679 #define FUNC(res, name, args) \
680 static res(*proc)args; \
681- if (!proc) (FARPROC)proc = MyGetProcAddress(hmod_pydll, #name)
682+ if (!proc) proc = (res (*)args)MyGetProcAddress(hmod_pydll, #name)
683
684 #define DATA(type, name) \
685 static type pflag; \
686@@ -158,7 +158,7 @@ void PyErr_Print(void)
687 proc();
688 }
689
690-void Py_SetProgramName(wchar_t *name)
691+void Py_SetProgramName(const wchar_t *name)
692 {
693 FUNC(void, Py_SetProgramName, (wchar_t *));
694 proc(name);
695diff --git a/source/run.c b/source/run.c
696index e1f630e..933ae77 100644
697--- a/source/run.c
698+++ b/source/run.c
699@@ -54,7 +54,11 @@ extern int start(int argc, wchar_t **argv);
700 /*
701 The main function for our exe.
702 */
703+#if defined(__MINGW32__)
704+int main (int argc, wchar_t **argv)
705+#else
706 int wmain (int argc, wchar_t **argv)
707+#endif
708 {
709 int result;
710 result = init("console_exe");
711diff --git a/source/start.c b/source/start.c
712index e894ae6..6b61624 100644
713--- a/source/start.c
714+++ b/source/start.c
715@@ -128,7 +128,7 @@ BOOL locate_script(HMODULE hmod)
716 SystemError(GetLastError(), "Could not load script resource:");
717 return FALSE;
718 }
719- p_script_info = (struct scriptinfo *)pScript = LockResource(hgbl);
720+ p_script_info = (struct scriptinfo *)(pScript = LockResource(hgbl));
721 if (!pScript) {
722 SystemError(GetLastError(), "Could not lock script resource:");
723 return FALSE;
[936]724diff --git a/setup.py b/setup.py
725index 342d194..1fe1e43 100644
726--- a/setup.py
727+++ b/setup.py
728@@ -107,7 +107,7 @@ run_w = Interpreter("py2exe.run_w",
729 libraries=["user32", "shell32"],
730 define_macros=macros,
731 extra_compile_args=extra_compile_args,
732- extra_link_args=extra_link_args,
733+ extra_link_args=extra_link_args + (["-Wl,--subsystem,windows"] if isMingw32 else []),
734 )
735
736 # The py2exe.resources name is special handled in BuildInterpreters;
Note: See TracBrowser for help on using the repository browser.