Skip to content

Commit

Permalink
Add Nuitka-Python hooks.
Browse files Browse the repository at this point in the history
  • Loading branch information
Maxwell175 committed Jun 16, 2024
1 parent f91fa3d commit 64aef54
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 22 deletions.
10 changes: 8 additions & 2 deletions setuptools/_distutils/_msvccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,17 +265,18 @@ def initialize(self, plat_name=None):
self.rc = _find_exe("rc.exe", paths) # resource compiler
self.mc = _find_exe("mc.exe", paths) # message compiler
self.mt = _find_exe("mt.exe", paths) # message compiler
self.dumpbin = _find_exe("dumpbin.exe", paths)

self.preprocess_options = None
# bpo-38597: Always compile with dynamic linking
# Future releases of Python 3.x will include all past
# versions of vcruntime*.dll for compatibility.
self.compile_options = ['/nologo', '/O2', '/W3', '/GL', '/DNDEBUG', '/MD']
self.compile_options = ['/nologo', '/O2', '/W3', '/GL', '/DNDEBUG', '/MT']

self.compile_options_debug = [
'/nologo',
'/Od',
'/MDd',
'/MTd',
'/Zi',
'/W3',
'/D_DEBUG',
Expand Down Expand Up @@ -457,6 +458,7 @@ def link(
extra_postargs=None,
build_temp=None,
target_lang=None,
extra_midargs=None,
):
if not self.initialized:
self.initialize()
Expand Down Expand Up @@ -498,6 +500,8 @@ def link(

if extra_preargs:
ld_args[:0] = extra_preargs
if extra_midargs:
ld_args.extend(extra_midargs)
if extra_postargs:
ld_args.extend(extra_postargs)

Expand Down Expand Up @@ -552,6 +556,8 @@ def library_option(self, lib):
return self.library_filename(lib)

def find_library_file(self, dirs, lib, debug=0):
if len(dirs) == 1 and os.path.isfile(os.path.join(dirs[0], lib)):
return os.path.join(dirs[0], lib)
# Prefer a debugging library if found (and requested), but deal
# with it if we don't have one.
if debug:
Expand Down
14 changes: 13 additions & 1 deletion setuptools/_distutils/ccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ def link(
extra_postargs=None,
build_temp=None,
target_lang=None,
extra_midargs=None,
):
"""Link a bunch of stuff together to create an executable or
shared library file.
Expand Down Expand Up @@ -718,6 +719,7 @@ def link_shared_lib(
build_temp=None,
target_lang=None,
):
raise NotImplementedError('Building shared libs is disabled for Nuitka-Python')
self.link(
CCompiler.SHARED_LIBRARY,
objects,
Expand Down Expand Up @@ -749,6 +751,7 @@ def link_shared_object(
build_temp=None,
target_lang=None,
):
raise NotImplementedError('Building shared libs is disabled for Nuitka-Python')
self.link(
CCompiler.SHARED_OBJECT,
objects,
Expand Down Expand Up @@ -777,6 +780,7 @@ def link_executable(
extra_preargs=None,
extra_postargs=None,
target_lang=None,
extra_midargs=None,
):
self.link(
CCompiler.EXECUTABLE,
Expand All @@ -792,6 +796,7 @@ def link_executable(
extra_postargs,
None,
target_lang,
extra_midargs,
)

# -- Miscellaneous methods -----------------------------------------
Expand Down Expand Up @@ -1013,6 +1018,9 @@ def library_filename(
fmt = getattr(self, lib_type + "_lib_format")
ext = getattr(self, lib_type + "_lib_extension")

if libname.endswith(ext):
ext = ""

dir, base = os.path.split(libname)
filename = fmt % (base, ext)
if strip_dir:
Expand Down Expand Up @@ -1248,5 +1256,9 @@ def gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries):
"no library file corresponding to '%s' found (skipping)" % lib
)
else:
lib_opts.append(compiler.library_option(lib))
lib_file = compiler.find_library_file(library_dirs, lib_name)
if lib_file is not None and lib_file.endswith('.a'):
lib_opts.append(lib_file)
else:
lib_opts.append(compiler.library_option(lib))
return lib_opts
39 changes: 28 additions & 11 deletions setuptools/_distutils/command/build_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import os
import re
import sys
import json
import shutil
from distutils._log import log
from site import USER_BASE

Expand Down Expand Up @@ -581,18 +583,33 @@ def build_extension(self, ext):
# Detect target language, if not provided
language = ext.language or self.compiler.detect_language(sources)

self.compiler.link_shared_object(
objects,
ext_path,
libraries=self.get_libraries(ext),
library_dirs=ext.library_dirs,
runtime_library_dirs=ext.runtime_library_dirs,
extra_postargs=extra_args,
export_symbols=self.get_export_symbols(ext),
self.compiler.create_static_lib(
objects, ext_path,
output_dir=os.path.abspath("."),
debug=self.debug,
build_temp=self.build_temp,
target_lang=language,
)
target_lang=language)

result_path = self.compiler.library_filename(ext_path,
output_dir=os.path.abspath("."))

with open(result_path + '.link.json', 'w') as f:
json.dump({
'libraries': self.get_libraries(ext),
'library_dirs': ext.library_dirs,
'runtime_library_dirs': ext.runtime_library_dirs,
'extra_postargs': extra_args}, f)

for lib in self.get_libraries(ext):
for dir in ext.library_dirs:
lib_install_dir = os.path.join(os.path.dirname(ext_path), dir)
print(os.path.join(ext_path, dir, lib + '.lib'))
if os.path.isfile(os.path.join(dir, lib + '.lib')):
if not os.path.isabs(dir):
if not os.path.exists(lib_install_dir):
os.makedirs(lib_install_dir)
shutil.copyfile(os.path.join(dir, lib + '.lib'),
os.path.join(lib_install_dir, lib + '.lib'))
break

def swig_sources(self, sources, extension):
"""Walk the list of source files in 'sources', looking for SWIG
Expand Down
8 changes: 4 additions & 4 deletions setuptools/_distutils/msvccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,23 +314,23 @@ def initialize(self):

self.preprocess_options = None
if self.__arch == "Intel":
self.compile_options = ['/nologo', '/O2', '/MD', '/W3', '/GX', '/DNDEBUG']
self.compile_options = ['/nologo', '/O2', '/MT', '/W3', '/GX', '/DNDEBUG']
self.compile_options_debug = [
'/nologo',
'/Od',
'/MDd',
'/MTd',
'/W3',
'/GX',
'/Z7',
'/D_DEBUG',
]
else:
# Win64
self.compile_options = ['/nologo', '/O2', '/MD', '/W3', '/GS-', '/DNDEBUG']
self.compile_options = ['/nologo', '/O2', '/MT', '/W3', '/GS-', '/DNDEBUG']
self.compile_options_debug = [
'/nologo',
'/Od',
'/MDd',
'/MTd',
'/W3',
'/GS-',
'/Z7',
Expand Down
4 changes: 4 additions & 0 deletions setuptools/_distutils/sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,10 @@ def customize_compiler(compiler): # noqa: C901
else:
archiver = ar + ' ' + ar_flags

cflags = ' '.join([x for x in cflags.split(' ') if
not x.startswith('-I') or (
'Nuitka-Python-Deps' not in x and 'dependencies' not in x)])

cc_cmd = cc + ' ' + cflags
compiler.set_executables(
preprocessor=cpp,
Expand Down
19 changes: 16 additions & 3 deletions setuptools/_distutils/unixccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ class UnixCCompiler(CCompiler):
if sys.platform[:6] == "darwin":
executables['ranlib'] = ["ranlib"]

# Nuitka: Make sure to use the original settings
executables["compiler"] = sysconfig.get_config_var("CC")
executables["compiler_so"] = sysconfig.get_config_var("CC")
executables["compiler_cxx"] = sysconfig.get_config_var("CXX")
executables["linker_so"] = sysconfig.get_config_var("CC")
executables["linker_exe"] = sysconfig.get_config_var("CC")

# Needed for the filename generation methods provided by the base
# class, CCompiler. NB. whoever instantiates/uses a particular
# UnixCCompiler instance should set 'shared_lib_ext' -- we set a
Expand Down Expand Up @@ -228,6 +235,7 @@ def link(
extra_postargs=None,
build_temp=None,
target_lang=None,
extra_midargs=None,
):
objects, output_dir = self._fix_object_args(objects, output_dir)
fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)
Expand All @@ -240,11 +248,14 @@ def link(
output_filename = os.path.join(output_dir, output_filename)

if self._need_link(objects, output_filename):
ld_args = objects + self.objects + lib_opts + ['-o', output_filename]
ld_args = objects + self.objects
if debug:
ld_args[:0] = ['-g']
if extra_midargs:
ld_args += extra_midargs
if extra_preargs:
ld_args[:0] = extra_preargs
ld_args += lib_opts + ['-o', output_filename]
if extra_postargs:
ld_args.extend(extra_postargs)
self.mkpath(os.path.dirname(output_filename))
Expand All @@ -253,6 +264,8 @@ def link(
# building an executable or linker_so (with shared options)
# when building a shared library.
building_exe = target_desc == CCompiler.EXECUTABLE
if not building_exe:
raise NotImplemented("No shared libs in Nuitka-Python")
linker = (self.linker_exe if building_exe else self.linker_so)[:]

if target_lang == "c++" and self.compiler_cxx:
Expand Down Expand Up @@ -385,10 +398,10 @@ def find_library_file(self, dirs, lib, debug=0):
>>> compiler.find_library_file(reversed(dirs), 'abc').replace('\\', '/')
'/foo/bar/existing/libabc.a'
"""
lib_names = (
lib_names = [lib] + [
self.library_filename(lib, lib_type=type)
for type in 'dylib xcode_stub shared static'.split()
)
]

roots = map(self._library_root, dirs)

Expand Down
25 changes: 24 additions & 1 deletion setuptools/command/build_ext.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os
import sys
import itertools
import json
import shutil
from importlib.machinery import EXTENSION_SUFFIXES
from importlib.util import cache_from_source as _compiled_file_name
from typing import Dict, Iterator, List, Tuple
Expand Down Expand Up @@ -387,7 +389,7 @@ def _compile_and_remove_stub(self, stub_file: str):
os.unlink(stub_file)


if use_stubs or os.name == 'nt':
if False: # use_stubs or os.name == 'nt':
# Build shared libraries
#
def link_shared_object(
Expand Down Expand Up @@ -455,3 +457,24 @@ def link_shared_object(
basename = basename[3:]

self.create_static_lib(objects, basename, output_dir, debug, target_lang)

result_path = self.library_filename(basename, output_dir=os.path.abspath("."))

with open(result_path + '.link.json', 'w') as f:
json.dump({
'libraries': libraries,
'library_dirs': ext.library_dirs,
'runtime_library_dirs': library_dirs,
'extra_postargs': extra_postargs,
'extra_preargs': extra_preargs}, f)

for lib in libraries:
for dir in library_dirs:
lib_install_dir = os.path.join(output_dir, dir)
if os.path.isfile(os.path.join(dir, lib + '.lib')):
if not os.path.isabs(dir):
if not os.path.exists(lib_install_dir):
os.makedirs(lib_install_dir)
shutil.copyfile(os.path.join(dir, lib + '.lib'),
os.path.join(lib_install_dir, lib + '.lib'))
break

0 comments on commit 64aef54

Please sign in to comment.