702 lines
28 KiB
Diff
702 lines
28 KiB
Diff
diff --git a/setup.py b/setup.py
|
|
index 37d536a..3e9d270 100644
|
|
--- a/setup.py
|
|
+++ b/setup.py
|
|
@@ -124,7 +124,8 @@ class WinExt(Extension):
|
|
|
|
extra_link_args = extra_link_args or []
|
|
if export_symbol_file:
|
|
- extra_link_args.append("/DEF:" + export_symbol_file)
|
|
+ if "MSC" in sys.version:
|
|
+ extra_link_args.append("/DEF:" + export_symbol_file)
|
|
|
|
# Some of our swigged files behave differently in distutils vs
|
|
# MSVC based builds. Always define DISTUTILS_BUILD so they can tell.
|
|
@@ -162,7 +163,7 @@ class WinExt(Extension):
|
|
def finalize_options(self, build_ext):
|
|
# distutils doesn't define this function for an Extension - it is
|
|
# our own invention, and called just before the extension is built.
|
|
- if not build_ext.mingw32:
|
|
+ if "MSC" in sys.version:
|
|
if self.pch_header:
|
|
self.extra_compile_args = self.extra_compile_args or []
|
|
|
|
@@ -218,6 +219,61 @@ class WinExt(Extension):
|
|
break
|
|
if found_mfc:
|
|
break
|
|
+ else:
|
|
+ # Set our C++ standard
|
|
+ self.extra_compile_args.append("-std=c++17")
|
|
+ # This is needed for pythoncom
|
|
+ self.extra_compile_args.append("-fpermissive")
|
|
+
|
|
+ # MinGW-w64 doesn't define these.
|
|
+ self.extra_compile_args.append("-D__WIN32__")
|
|
+ # Extra compile args
|
|
+ if "AMD64" in sys.version:
|
|
+ self.extra_compile_args.append("-D_M_X64") # pythoncom & win32ui
|
|
+ self.extra_compile_args.append("-D_AMD64_") # mapi
|
|
+ elif "ARM64" in sys.version:
|
|
+ self.extra_compile_args.append("-D_M_ARM64") # pythoncom & win32ui
|
|
+ self.extra_compile_args.append("-D_ARM64_") # mapi
|
|
+ else:
|
|
+ self.extra_compile_args.append("-D_M_IX86") # pythoncom & win32ui
|
|
+ self.extra_compile_args.append("-D_X86_") # mapi
|
|
+
|
|
+ # If someone needs a specially named implib created, handle that
|
|
+ if self.implib_name:
|
|
+ implib = os.path.join(build_ext.build_temp, self.implib_name)
|
|
+ suffix = "_d" if build_ext.debug else ""
|
|
+ self.extra_link_args.append(
|
|
+ "-Wl,--out-implib,%s%s.dll.a" % (implib, suffix)
|
|
+ )
|
|
+
|
|
+ if "64 bit" in sys.version:
|
|
+ self.extra_link_args.append("-m64")
|
|
+ else:
|
|
+ self.extra_link_args.append("-m32")
|
|
+
|
|
+ # Silenced some annoying warnings
|
|
+ self.extra_compile_args.append("-Wno-attributes")
|
|
+ self.extra_compile_args.append("-Wno-conversion-null")
|
|
+ self.extra_compile_args.append("-Wno-deprecated-declarations")
|
|
+ self.extra_compile_args.append("-Wno-invalid-offsetof")
|
|
+ self.extra_compile_args.append("-Wno-return-type")
|
|
+ self.extra_compile_args.append("-Wno-sign-compare")
|
|
+ self.extra_compile_args.append("-Wno-strict-aliasing")
|
|
+ self.extra_compile_args.append("-Wno-uninitialized")
|
|
+ self.extra_compile_args.append("-Wno-unknown-pragmas")
|
|
+ self.extra_compile_args.append("-Wno-unused")
|
|
+ self.extra_compile_args.append("-Wno-write-strings")
|
|
+
|
|
+ if "Clang" in sys.version:
|
|
+ self.extra_compile_args.append("-Wno-missing-braces")
|
|
+ self.extra_compile_args.append("-Wno-missing-exception-spec")
|
|
+ self.extra_compile_args.append("-Wno-nonportable-include-path")
|
|
+ self.extra_compile_args.append("-Wno-self-assign")
|
|
+ else:
|
|
+ self.extra_compile_args.append("-Wno-class-memaccess")
|
|
+ self.extra_compile_args.append("-Wno-nonnull-compare")
|
|
+ self.extra_compile_args.append("-Wno-pointer-arith")
|
|
+ self.extra_compile_args.append("-Wno-sequence-point")
|
|
|
|
self.extra_compile_args.append("-DUNICODE")
|
|
self.extra_compile_args.append("-D_UNICODE")
|
|
@@ -228,6 +284,19 @@ class WinExt_pythonwin(WinExt):
|
|
def __init__(self, name, **kw):
|
|
kw.setdefault("extra_compile_args", []).extend(["-D_AFXDLL", "-D_AFXEXT"])
|
|
|
|
+ if "GCC" in sys.version:
|
|
+ kw.setdefault("extra_compile_args", []).extend(
|
|
+ ["-DMINGW_HAS_SECURE_API=1"])
|
|
+
|
|
+ kw["libraries"] = kw.get("libraries", "") + " mfc100u"
|
|
+ if name == "win32ui":
|
|
+ kw["libraries"] = kw.get("libraries", "") + " winspool"
|
|
+ elif name == "win32uiole":
|
|
+ kw["libraries"] = kw.get("libraries", "") + " win32ui pythoncom"
|
|
+ elif name == "dde":
|
|
+ kw["libraries"] = kw.get("libraries", "") + " win32ui"
|
|
+ kw["libraries"] = kw.get("libraries", "") + " pywintypes"
|
|
+
|
|
WinExt.__init__(self, name, **kw)
|
|
|
|
def get_pywin32_dir(self):
|
|
@@ -238,7 +307,7 @@ class WinExt_pythonwin_subsys_win(WinExt_pythonwin):
|
|
def finalize_options(self, build_ext):
|
|
WinExt_pythonwin.finalize_options(self, build_ext)
|
|
|
|
- if build_ext.mingw32:
|
|
+ if "GCC" in sys.version:
|
|
self.extra_link_args.append("-mwindows")
|
|
else:
|
|
self.extra_link_args.append("/SUBSYSTEM:WINDOWS")
|
|
@@ -249,6 +318,9 @@ class WinExt_pythonwin_subsys_win(WinExt_pythonwin):
|
|
|
|
class WinExt_win32(WinExt):
|
|
def __init__(self, name, **kw):
|
|
+ if "GCC" in sys.version:
|
|
+ if name not in ["_win32sysloader"]:
|
|
+ kw["libraries"] = kw.get("libraries", "") + " pywintypes"
|
|
WinExt.__init__(self, name, **kw)
|
|
|
|
def get_pywin32_dir(self):
|
|
@@ -265,6 +337,8 @@ class WinExt_ISAPI(WinExt):
|
|
class WinExt_win32com(WinExt):
|
|
def __init__(self, name, **kw):
|
|
kw["libraries"] = kw.get("libraries", "") + " oleaut32 ole32"
|
|
+ if "GCC" in sys.version:
|
|
+ kw["libraries"] = kw.get("libraries", "") + " uuid pythoncom pywintypes"
|
|
|
|
# COM extensions require later windows headers.
|
|
if not kw.get("windows_h_version"):
|
|
@@ -331,11 +405,16 @@ class WinExt_system32(WinExt):
|
|
|
|
|
|
class WinExt_pythonservice(WinExt):
|
|
+ def __init__(self, name, **kw):
|
|
+ if "GCC" in sys.version:
|
|
+ kw["libraries"] = kw.get("libraries", "") + " pywintypes"
|
|
+ WinExt.__init__(self, name, **kw)
|
|
+
|
|
# special handling because it's a "console" exe.
|
|
def finalize_options(self, build_ext):
|
|
WinExt.finalize_options(self, build_ext)
|
|
|
|
- if build_ext.mingw32:
|
|
+ if "GCC" in sys.version:
|
|
self.extra_link_args.append("-mconsole")
|
|
self.extra_link_args.append("-municode")
|
|
else:
|
|
@@ -880,6 +959,395 @@ class my_build_ext(build_ext):
|
|
return new_sources
|
|
|
|
|
|
+class mingw_build_ext(build_ext):
|
|
+ def finalize_options(self):
|
|
+ build_ext.finalize_options(self)
|
|
+ self.windows_h_version = None
|
|
+ # The pywintypes library is created in the build_temp directory,
|
|
+ # so we need to add this to library_dirs
|
|
+ self.library_dirs.append(self.build_temp)
|
|
+
|
|
+ # Add extra VC++ SDK library dir
|
|
+ if "64 bit" in sys.version:
|
|
+ x64_dir = "/x64"
|
|
+ else:
|
|
+ x64_dir = ""
|
|
+
|
|
+ # VC++ custom dirs for ATL/MFC
|
|
+ if "SDKDIR" in os.environ:
|
|
+ sdk_info = os.environ.get("SDKDIR")
|
|
+ else:
|
|
+ sdk_info = "."
|
|
+ #self.include_dirs.append(sdk_info + "/atlmfc/include")
|
|
+ #self.library_dirs.append(sdk_info + "/atlmfc/lib" + x64_dir)
|
|
+
|
|
+ self.excluded_extensions = [] # list of (ext, why)
|
|
+ self.swig_cpp = True
|
|
+
|
|
+ def _why_cant_build_extension(self, ext):
|
|
+ # Return None, or a reason it can't be built.
|
|
+ if ext.name in ["exchange", "exchdapi"]:
|
|
+ return "No library for utility functions available."
|
|
+
|
|
+ # Comment out below to enable Pythonwin extensions
|
|
+ if ext.name in ["win32ui", "win32uiole", "dde", "Pythonwin"]:
|
|
+ return "Unsupported due to ATL/MFC usage."
|
|
+
|
|
+ # axdebug fails to build on 3.11 due to Python "frame" objects changing.
|
|
+ # This could be fixed, but is almost certainly not in use any more, so
|
|
+ # just skip it.
|
|
+ if ext.name == "axdebug" and sys.version_info > (3, 10):
|
|
+ return "AXDebug no longer builds on 3.11 and up"
|
|
+
|
|
+ def _build_scintilla(self):
|
|
+ path = "Pythonwin/Scintilla/win32"
|
|
+ makefile = "scintilla_mingw.mak"
|
|
+ makeargs = []
|
|
+
|
|
+ if self.debug:
|
|
+ makeargs.append("DEBUG=1")
|
|
+ if not self.verbose:
|
|
+ makeargs.append("QUIET=1")
|
|
+ # We build the DLL into our own temp directory, then copy it to the
|
|
+ # real directory - this avoids the generated .lib/.exp
|
|
+ build_temp = os.path.abspath(os.path.join(self.build_temp, "scintilla"))
|
|
+ self.mkpath(build_temp)
|
|
+ makeargs.append("SUB_DIR_O=%s" % build_temp)
|
|
+ makeargs.append("SUB_DIR_BIN=%s" % build_temp)
|
|
+
|
|
+ # Deliberately not using self.spawn() to avoid stdout from always
|
|
+ # printing the parsed arguments for the makefile.
|
|
+ cwd = os.getcwd()
|
|
+ os.chdir(path)
|
|
+ try:
|
|
+ import subprocess
|
|
+
|
|
+ cmd = subprocess.call(["make", "-f", makefile] + makeargs)
|
|
+ finally:
|
|
+ os.chdir(cwd)
|
|
+
|
|
+ # The DLL goes into the Pythonwin directory.
|
|
+ if self.debug:
|
|
+ base_name = "scintilla_d.dll"
|
|
+ else:
|
|
+ base_name = "scintilla.dll"
|
|
+ self.copy_file(
|
|
+ os.path.join(self.build_temp, "scintilla", base_name),
|
|
+ os.path.join(self.build_lib, "pythonwin"),
|
|
+ )
|
|
+
|
|
+ def build_extensions(self):
|
|
+ # First, sanity-check the 'extensions' list
|
|
+ self.check_extensions_list(self.extensions)
|
|
+
|
|
+ self.found_libraries = {}
|
|
+
|
|
+ if not hasattr(self.compiler, "initialized"):
|
|
+ # 2.3 and earlier initialized at construction
|
|
+ self.compiler.initialized = True
|
|
+ else:
|
|
+ if not self.compiler.initialized:
|
|
+ self.compiler.initialize()
|
|
+
|
|
+ # Here we hack a "pywin32" directory,
|
|
+ # as distutils doesn't seem to like the concept
|
|
+ # of multiple top-level directories.
|
|
+ assert self.package is None
|
|
+ for ext in self.extensions:
|
|
+ try:
|
|
+ self.package = ext.get_pywin32_dir()
|
|
+ except AttributeError:
|
|
+ raise RuntimeError("Not a win32 package!")
|
|
+ self.build_extension(ext)
|
|
+
|
|
+ for ext in W32_exe_files:
|
|
+ ext.finalize_options(self)
|
|
+ why = self._why_cant_build_extension(ext)
|
|
+ if why is not None:
|
|
+ self.excluded_extensions.append((ext, why))
|
|
+ assert why, "please give a reason, or None"
|
|
+ print(f"Skipping {ext.name}: {why}")
|
|
+ continue
|
|
+
|
|
+ try:
|
|
+ self.package = ext.get_pywin32_dir()
|
|
+ except AttributeError:
|
|
+ raise RuntimeError("Not a win32 package!")
|
|
+ self.build_exefile(ext)
|
|
+
|
|
+ # Only build scintilla if Pythonwin extensions are enabled
|
|
+ pythonwin_dir = os.path.join(self.build_temp, "pythonwin")
|
|
+ if os.path.exists(pythonwin_dir):
|
|
+ self._build_scintilla()
|
|
+ # Copy cpp lib files needed to create Python COM extensions
|
|
+ clib_files = (
|
|
+ ["win32", "pywintypes%s.dll.a"],
|
|
+ ["win32com", "pythoncom%s.dll.a"],
|
|
+ ["win32com", "axscript%s.dll.a"],
|
|
+ )
|
|
+ for clib_file in clib_files:
|
|
+ target_dir = os.path.join(self.build_lib, clib_file[0], "libs")
|
|
+ if not os.path.exists(target_dir):
|
|
+ self.mkpath(target_dir)
|
|
+ suffix = "_d" if self.debug else ""
|
|
+ fname = clib_file[1] % suffix
|
|
+ self.copy_file(os.path.join(self.build_temp, fname), target_dir)
|
|
+
|
|
+ # Search the MFC dll.
|
|
+ try:
|
|
+ target_dir = os.path.join(self.build_lib, "pythonwin")
|
|
+ mfc_files = ["libmfc100u.dll"]
|
|
+
|
|
+ if "64 bit" in sys.version:
|
|
+ plat_dir = "x64"
|
|
+ else:
|
|
+ plat_dir = "x86"
|
|
+
|
|
+ # Locate the redist directory.
|
|
+ target_file = os.path.join(target_dir, "Pythonwin.exe")
|
|
+ if os.path.exists(target_file):
|
|
+ mfcdll_dir = os.path.join(sdk_info, "redist", plat_dir)
|
|
+ if not os.path.isdir(mfcdll_dir):
|
|
+ raise RuntimeError("Can't find the redist dir at %r" % (mfcdll_dir))
|
|
+ for f in mfc_files:
|
|
+ self.copy_file(os.path.join(mfcdll_dir, f), target_dir)
|
|
+ except (EnvironmentError, RuntimeError) as exc:
|
|
+ if os.path.exists(target_file):
|
|
+ print("Can't find the requested MFC DLL:", exc)
|
|
+ pass
|
|
+
|
|
+ def build_exefile(self, ext):
|
|
+ sources = list(ext.sources)
|
|
+
|
|
+ fullname = self.get_ext_fullname(ext.name)
|
|
+ if self.inplace:
|
|
+ # ignore build-lib -- put the compiled extension into
|
|
+ # the source tree along with pure Python modules
|
|
+ modpath = string.split(fullname, ".")
|
|
+ package = string.join(modpath[0:-1], ".")
|
|
+ base = modpath[-1]
|
|
+
|
|
+ build_py = self.get_finalized_command("build_py")
|
|
+ package_dir = build_py.get_package_dir(package)
|
|
+ ext_filename = os.path.join(package_dir, self.get_ext_filename(base))
|
|
+ else:
|
|
+ ext_filename = os.path.join(self.build_lib, self.get_ext_filename(fullname))
|
|
+ depends = sources + ext.depends
|
|
+ if not (self.force or newer_group(depends, ext_filename, "newer")):
|
|
+ logging.debug("skipping '%s' executable (up-to-date)", ext.name)
|
|
+ return
|
|
+ else:
|
|
+ logging.info("building '%s' executable", ext.name)
|
|
+
|
|
+ # First, scan the sources for SWIG definition files (.i), run
|
|
+ # SWIG on 'em to create .c files, and modify the sources list
|
|
+ # accordingly.
|
|
+ sources = self.swig_sources(sources, ext)
|
|
+ extra_args = ext.extra_compile_args or []
|
|
+
|
|
+ macros = ext.define_macros[:]
|
|
+ for undef in ext.undef_macros:
|
|
+ macros.append((undef,))
|
|
+ # Note: custom 'output_dir' needed due to servicemanager.pyd and
|
|
+ # pythonservice.exe being built from the same .cpp file - without
|
|
+ # this, distutils gets confused, as they both try and use the same
|
|
+ # .obj.
|
|
+ output_dir = os.path.join(self.build_temp, ext.name)
|
|
+ kw = {
|
|
+ "output_dir": output_dir,
|
|
+ "macros": macros,
|
|
+ "include_dirs": ext.include_dirs,
|
|
+ "debug": self.debug,
|
|
+ "extra_postargs": extra_args,
|
|
+ "depends": ext.depends,
|
|
+ }
|
|
+ objects = self.compiler.compile(sources, **kw)
|
|
+
|
|
+ self._built_objects = objects[:]
|
|
+
|
|
+ # Now link the object files together into a "shared object" --
|
|
+ # of course, first we have to figure out all the other things
|
|
+ # that go into the mix.
|
|
+ if ext.extra_objects:
|
|
+ objects.extend(ext.extra_objects)
|
|
+ extra_args = ext.extra_link_args or []
|
|
+
|
|
+ # 2.2 has no 'language' support
|
|
+ kw = {
|
|
+ "libraries": self.get_libraries(ext),
|
|
+ "library_dirs": ext.library_dirs,
|
|
+ "runtime_library_dirs": ext.runtime_library_dirs,
|
|
+ "extra_postargs": extra_args,
|
|
+ "debug": self.debug,
|
|
+ "build_temp": self.build_temp,
|
|
+ }
|
|
+
|
|
+ # Detect target language, if not provided
|
|
+ language = ext.language or self.compiler.detect_language(sources)
|
|
+ kw["target_lang"] = language
|
|
+
|
|
+ self.compiler.link("executable", objects, ext_filename, **kw)
|
|
+
|
|
+ def build_extension(self, ext):
|
|
+ # It is well known that some of these extensions are difficult to
|
|
+ # build, requiring various hard-to-track libraries etc. So we
|
|
+ # check the extension list for the extra libraries explicitly
|
|
+ # listed. We then search for this library the same way the C
|
|
+ # compiler would - if we can't find a library, we exclude the
|
|
+ # extension from the build.
|
|
+ # Note we can't do this in advance, as some of the .lib files
|
|
+ # we depend on may be built as part of the process - thus we can
|
|
+ # only check an extension's lib files as we are building it.
|
|
+ why = self._why_cant_build_extension(ext)
|
|
+ if why is not None:
|
|
+ assert why, "please give a reason, or None"
|
|
+ self.excluded_extensions.append((ext, why))
|
|
+ print(f"Skipping {ext.name}: {why}")
|
|
+ return
|
|
+ self.current_extension = ext
|
|
+
|
|
+ ext.finalize_options(self)
|
|
+
|
|
+ # Ensure the SWIG .i files are treated as dependencies.
|
|
+ for source in ext.sources:
|
|
+ if source.endswith(".i"):
|
|
+ self.find_swig() # for the side-effect of the environment value.
|
|
+ # Find the swig_lib .i files we care about for dependency tracking.
|
|
+ ext.swig_deps = glob.glob(
|
|
+ os.path.join(os.environ["SWIG_LIB"], "python", "*.i")
|
|
+ )
|
|
+ ext.depends.extend(ext.swig_deps)
|
|
+ break
|
|
+ else:
|
|
+ ext.swig_deps = None
|
|
+
|
|
+ try:
|
|
+ build_ext.build_extension(self, ext)
|
|
+ except:
|
|
+ print()
|
|
+ print("WARNING: building of extension '%s' failed" % (ext.name))
|
|
+ print()
|
|
+ return
|
|
+
|
|
+ def get_ext_filename(self, name):
|
|
+ # The pywintypes and pythoncom extensions have special names
|
|
+ extra_dll = self.debug and "_d.dll" or ".dll"
|
|
+ extra_exe = self.debug and "_d.exe" or ".exe"
|
|
+ # *sob* - python fixed this bug in python 3.1 (bug 6403)
|
|
+ # So in the fixed versions we only get the base name, and if the
|
|
+ # output name is simply 'dir\name' we need to nothing.
|
|
+
|
|
+ if name in ["pywintypes", "pythoncom"]:
|
|
+ return name + "%d%d%s" % (
|
|
+ sys.version_info[0],
|
|
+ sys.version_info[1],
|
|
+ extra_dll,
|
|
+ )
|
|
+ elif name in ["perfmondata", "PyISAPI_loader"]:
|
|
+ return name + extra_dll
|
|
+ elif name.endswith("win32.pythonservice"):
|
|
+ return "win32/pythonservice" + extra_exe
|
|
+ elif name.endswith("pythonwin.Pythonwin"):
|
|
+ return "pythonwin/Pythonwin" + extra_exe
|
|
+ return build_ext.get_ext_filename(self, name)
|
|
+
|
|
+ def get_export_symbols(self, ext):
|
|
+ if ext.is_regular_dll:
|
|
+ return None
|
|
+ return build_ext.get_export_symbols(self, ext)
|
|
+
|
|
+ def find_swig(self):
|
|
+ if "SWIG" in os.environ:
|
|
+ swig = os.environ["SWIG"]
|
|
+ else:
|
|
+ # We know where our swig is
|
|
+ swig = os.path.abspath("swig/swig.exe")
|
|
+ lib = os.path.join(os.path.dirname(swig), "swig_lib")
|
|
+ os.environ["SWIG_LIB"] = lib
|
|
+ return swig
|
|
+
|
|
+ def swig_sources(self, sources, ext=None):
|
|
+ new_sources = []
|
|
+ swig_sources = []
|
|
+ swig_targets = {}
|
|
+
|
|
+ target_ext = ".cpp"
|
|
+ for source in sources:
|
|
+ (base, sext) = os.path.splitext(source)
|
|
+ if sext == ".i":
|
|
+ if os.path.split(base)[1] in swig_include_files:
|
|
+ continue
|
|
+ swig_sources.append(source)
|
|
+ # Patch up the filenames for various special cases...
|
|
+ if os.path.basename(base) in swig_interface_parents:
|
|
+ swig_targets[source] = base + target_ext
|
|
+ else:
|
|
+ new_target = "%s_swig%s" % (base, target_ext)
|
|
+ new_sources.append(new_target)
|
|
+ swig_targets[source] = new_target
|
|
+ else:
|
|
+ new_sources.append(source)
|
|
+
|
|
+ if not swig_sources:
|
|
+ return new_sources
|
|
+
|
|
+ swig = self.find_swig()
|
|
+ for source in swig_sources:
|
|
+ swig_cmd = [swig, "-python", "-c++", "-dnone"]
|
|
+ swig_cmd.extend(self.current_extension.extra_swig_commands)
|
|
+
|
|
+ if "64 bit" in sys.version:
|
|
+ swig_cmd.append("-DSWIG_PY64BIT")
|
|
+ else:
|
|
+ swig_cmd.append("-DSWIG_PY32BIT")
|
|
+ target = swig_targets[source]
|
|
+ try:
|
|
+ interface_parent = swig_interface_parents[
|
|
+ os.path.basename(os.path.splitext(source)[0])
|
|
+ ]
|
|
+ except KeyError:
|
|
+ # "normal" swig file - no special win32 issues.
|
|
+ pass
|
|
+ else:
|
|
+ # Using win32 extensions to SWIG for generating COM classes.
|
|
+ if interface_parent is not None:
|
|
+ # generating a class, not a module.
|
|
+ swig_cmd.append("-pythoncom")
|
|
+ if interface_parent:
|
|
+ # A class deriving from other than the default
|
|
+ swig_cmd.extend(["-com_interface_parent", interface_parent])
|
|
+
|
|
+ # This 'newer' check helps python 2.2 builds, which otherwise
|
|
+ # *always* regenerate the .cpp files, meaning every future
|
|
+ # build for any platform sees these as dirty.
|
|
+ # This could probably go once we generate .cpp into the temp dir.
|
|
+ fqsource = os.path.abspath(source)
|
|
+ fqtarget = os.path.abspath(target)
|
|
+ rebuild = self.force or (
|
|
+ ext and newer_group(ext.swig_deps + [fqsource], fqtarget)
|
|
+ )
|
|
+
|
|
+ # can remove once edklib is no longer used for 32-bit builds
|
|
+ if source == "com/win32comext/mapi/src/exchange.i":
|
|
+ rebuild = True
|
|
+
|
|
+ logging.debug("should swig %s->%s=%s", source, target, rebuild)
|
|
+ if rebuild:
|
|
+ swig_cmd.extend(["-o", fqtarget, fqsource])
|
|
+ logging.info("swigging %s to %s", source, target)
|
|
+ out_dir = os.path.dirname(source)
|
|
+ cwd = os.getcwd()
|
|
+ os.chdir(out_dir)
|
|
+ try:
|
|
+ self.spawn(swig_cmd)
|
|
+ finally:
|
|
+ os.chdir(cwd)
|
|
+ else:
|
|
+ logging.info("skipping swig of %s", source)
|
|
+
|
|
+ return new_sources
|
|
+
|
|
+
|
|
class my_install(install):
|
|
def run(self):
|
|
install.run(self)
|
|
@@ -895,7 +1363,7 @@ class my_install(install):
|
|
# some other directory than Python itself (eg, into a temp directory
|
|
# for bdist_wininst to use) - in which case we must *not* run our
|
|
# installer
|
|
- if not self.dry_run and not self.root:
|
|
+ if "MSC" in sys.version and not self.dry_run and not self.root:
|
|
# We must run the script we just installed into Scripts, as it
|
|
# may have had 2to3 run over it.
|
|
filename = os.path.join(self.install_scripts, "pywin32_postinstall.py")
|
|
@@ -945,14 +1413,21 @@ def my_new_compiler(**kw):
|
|
orig_new_compiler = ccompiler.new_compiler
|
|
ccompiler.new_compiler = my_new_compiler # type: ignore[assignment] # Assuming the caller will always use only kwargs
|
|
|
|
+if "MSC" in sys.version:
|
|
+ base_compiler = MSVCCompiler
|
|
+else:
|
|
+ from distutils.cygwinccompiler import Mingw32CCompiler
|
|
+ base_compiler = Mingw32CCompiler
|
|
+
|
|
|
|
-class my_compiler(MSVCCompiler):
|
|
+class my_compiler(base_compiler):
|
|
# Just one GUIDS.CPP and it gives trouble on mainwin too. Maybe I
|
|
# should just rename the file, but a case-only rename is likely to be
|
|
# worse! This can probably go away once we kill the VS project files
|
|
# though, as we can just specify the lowercase name in the module def.
|
|
- _cpp_extensions = MSVCCompiler._cpp_extensions + [".CPP"]
|
|
- src_extensions = MSVCCompiler.src_extensions + [".CPP"]
|
|
+ if "MSC" in sys.version:
|
|
+ _cpp_extensions = base_compiler._cpp_extensions + [".CPP"]
|
|
+ src_extensions = base_compiler.src_extensions + [".CPP"]
|
|
|
|
def link(
|
|
self,
|
|
@@ -1025,7 +1500,7 @@ class my_compiler(MSVCCompiler):
|
|
return (e, b)
|
|
|
|
sources = sorted(sources, key=key_reverse_mc)
|
|
- return MSVCCompiler.compile(self, sources, **kwargs)
|
|
+ return base_compiler.compile(self, sources, **kwargs)
|
|
|
|
def spawn(self, cmd):
|
|
is_link = cmd[0].endswith("link.exe") or cmd[0].endswith('"link.exe"')
|
|
@@ -1085,6 +1560,10 @@ class my_install_data(install_data):
|
|
|
|
################################################################
|
|
|
|
+pywintypes_lib = ""
|
|
+if "GCC" in sys.version:
|
|
+ pywintypes_lib = "pywintypes"
|
|
+
|
|
pywintypes = WinExt_system32(
|
|
"pywintypes",
|
|
sources=[
|
|
@@ -1110,6 +1589,7 @@ pywintypes = WinExt_system32(
|
|
],
|
|
extra_compile_args=["-DBUILD_PYWINTYPES"],
|
|
libraries="advapi32 user32 ole32 oleaut32",
|
|
+ implib_name=pywintypes_lib,
|
|
pch_header="PyWinTypes.h",
|
|
)
|
|
|
|
@@ -1151,7 +1631,7 @@ for info in (
|
|
("win32cred", "AdvAPI32 credui", 0x0501, "win32/src/win32credmodule.cpp"),
|
|
(
|
|
"win32crypt",
|
|
- "Crypt32 Advapi32",
|
|
+ "advapi32 crypt32",
|
|
0x0500,
|
|
"""
|
|
win32/src/win32crypt/win32cryptmodule.cpp
|
|
@@ -1269,7 +1749,7 @@ win32_extensions += [
|
|
WinExt_win32(
|
|
"win32evtlog",
|
|
sources="""
|
|
- win32\\src\\win32evtlog_messages.mc win32\\src\\win32evtlog.i
|
|
+ win32/src/win32evtlog_messages.mc win32/src/win32evtlog.i
|
|
""".split(),
|
|
libraries="advapi32 oleaut32",
|
|
delay_load_libraries="wevtapi",
|
|
@@ -1338,6 +1818,13 @@ dirs = {
|
|
"win32com": "com/win32com/src",
|
|
}
|
|
|
|
+pythoncom_lib = pythoncom_dep = ""
|
|
+win32ui_lib = ""
|
|
+if "GCC" in sys.version:
|
|
+ pythoncom_lib = "pythoncom"
|
|
+ pythoncom_dep = " uuid pywintypes"
|
|
+ win32ui_lib = "win32ui"
|
|
+
|
|
# The COM modules.
|
|
pythoncom = WinExt_system32(
|
|
"pythoncom",
|
|
@@ -1417,9 +1904,10 @@ pythoncom = WinExt_system32(
|
|
**dirs
|
|
)
|
|
).split(),
|
|
- libraries="oleaut32 ole32 user32 urlmon",
|
|
+ libraries="oleaut32 ole32 user32 urlmon" + pythoncom_dep,
|
|
export_symbol_file="com/win32com/src/PythonCOM.def",
|
|
extra_compile_args=["-DBUILD_PYTHONCOM"],
|
|
+ implib_name=pythoncom_lib,
|
|
pch_header="stdafx.h",
|
|
windows_h_version=0x500,
|
|
base_address=dll_base_address,
|
|
@@ -1429,7 +1917,7 @@ com_extensions = [
|
|
pythoncom,
|
|
WinExt_win32com(
|
|
"adsi",
|
|
- libraries="ACTIVEDS ADSIID user32 advapi32",
|
|
+ libraries="activeds adsiid user32 advapi32",
|
|
sources=(
|
|
"""
|
|
{adsi}/adsi.i {adsi}/adsi.cpp
|
|
@@ -1948,6 +2436,7 @@ pythonwin_extensions = [
|
|
"Pythonwin/Win32uiHostGlue.h",
|
|
"Pythonwin/win32win.h",
|
|
],
|
|
+ implib_name=win32ui_lib,
|
|
optional_headers=["afxres.h"],
|
|
),
|
|
WinExt_pythonwin(
|
|
@@ -2188,6 +2677,12 @@ ext_modules = (
|
|
win32_extensions + com_extensions + pythonwin_extensions + other_extensions
|
|
)
|
|
|
|
+if "GCC" in sys.version:
|
|
+ my_build_ext = mingw_build_ext
|
|
+ install_scripts = []
|
|
+else:
|
|
+ install_scripts = ["pywin32_postinstall.py", "pywin32_testall.py"]
|
|
+
|
|
cmdclass = {
|
|
"install": my_install,
|
|
"build": my_build,
|
|
@@ -2272,7 +2767,7 @@ dist = setup(
|
|
"user_access_control": "auto",
|
|
},
|
|
},
|
|
- scripts=["pywin32_postinstall.py", "pywin32_testall.py"],
|
|
+ scripts=install_scripts,
|
|
ext_modules=ext_modules,
|
|
package_dir={
|
|
"win32com": "com/win32com",
|
|
@@ -2381,7 +2876,7 @@ if "build_ext" in dist.command_obj:
|
|
print("*** NOTE: The following extensions were NOT %s:" % what_string)
|
|
for ext, why in excluded_extensions:
|
|
print(f" {ext.name}: {why}")
|
|
- if ext.name not in skip_whitelist:
|
|
+ if "MSC" in sys.version and ext.name not in skip_whitelist:
|
|
skipped_ex.append(ext.name)
|
|
print("For more details on installing the correct libraries and headers,")
|
|
print("please execute this script with no arguments (or see the docstring)")
|