2017-11-21 4 views

Antwort

1

Da es nicht Teil eines amtlichen spec/doc ist, und, as shown by another Antwort gibt sind Fälle, in denen keine der geeigneten Variablen aus sysconfig/distutils.sysconfig.get_config_var() gesetzt sind,

der einzige Weg, um es in allen Fällen zuverlässig zu bekommen genau als ein Build würde (z.B. selbst für ein Python im Quellbaum) ist es, an die Referenzimplementierung zu delegieren.

In distutils die Logik, die den Bibliothekspfad für einen Compiler setzt. So würde dieser Code es ohne Nebenwirkungen auf der Build erhalten:

import distutils.command.build_ext #imports distutils.core, too 
d = distutils.core.Distribution() 
b = distutils.command.build_ext.build_ext(d) #or `d.get_command_class('build_ext')(d)', 
               # then it's enough to import distutils.core 
b.finalize_options() 
print b.library_dirs 

Beachten Sie, dass:

  • Nicht alle Standorte in der Ergebnisliste unbedingt vorhanden sein.
  • Wenn Ihre setup.pysetuptools -basierte ist, verwenden Sie stattdessen setuptools.Distribution und setuptools.command.build_ext, entsprechend.
  • Wenn Sie Werte an setup() übergeben, die sich auf das Ergebnis auswirken, müssen Sie sie auch hier an Distribution übergeben.

Da gibt es keine Garantien, dass die Menge der zusätzlichen Werte, die Sie übergeben müssen gleich bleiben wird, oder dass der nächste Betreuer schaltet nicht auf einen anderen Builder ; und der Wert wird nur benötigt, wenn ein Erweiterungsbau,

  • es scheint, wie Sie sind nicht wirklich soll diesen Wert erhalten unabhängig überhaupt:
    • Wenn Sie einen anderen Build-Anlage verwenden, Sie sollten eher Unterklasse build_ext und erhalten Sie den Wert von der Basismethode während des Builds.

Okay, ich zugeben, diese besondere man eine ziemlich entfernte Möglichkeit ist

0

Unten ist die (ziemlich lange) subroutine in skbuild.cmaker, die libpythonxx.so/pythonxx.lib für das Ausführen von Python findet. In CMake ist 350-line Modules/FindPythonLibs.cmake für diese Aufgabe gewidmet.

Der Teil der ehemaligen, die nur das Verzeichnis erhält, ist viel obwohl einfacher:

libdir = dustutils.sysconfig.get_config_var('LIBDIR') 
if sysconfig.get_config_var('MULTIARCH'): 
    masd = sysconfig.get_config_var('multiarchsubdir') 
    if masd: 
     if masd.startswith(os.sep): 
      masd = masd[len(os.sep):] 
     libdir = os.path.join(libdir, masd) 

if libdir is None: 
    libdir = os.path.abspath(os.path.join(
     sysconfig.get_config_var('LIBDEST'), "..", "libs")) 

def get_python_library(python_version): 
    """Get path to the python library associated with the current python 
    interpreter.""" 
    # determine direct path to libpython 
    python_library = sysconfig.get_config_var('LIBRARY') 

    # if static (or nonexistent), try to find a suitable dynamic libpython 
    if (python_library is None or 
      os.path.splitext(python_library)[1][-2:] == '.a'): 

     candidate_lib_prefixes = ['', 'lib'] 

     candidate_extensions = ['.lib', '.so', '.a'] 
     if sysconfig.get_config_var('WITH_DYLD'): 
      candidate_extensions.insert(0, '.dylib') 

     candidate_versions = [python_version] 
     if python_version: 
      candidate_versions.append('') 
      candidate_versions.insert(
       0, "".join(python_version.split(".")[:2])) 

     abiflags = getattr(sys, 'abiflags', '') 
     candidate_abiflags = [abiflags] 
     if abiflags: 
      candidate_abiflags.append('') 

     # Ensure the value injected by virtualenv is 
     # returned on windows. 
     # Because calling `sysconfig.get_config_var('multiarchsubdir')` 
     # returns an empty string on Linux, `du_sysconfig` is only used to 
     # get the value of `LIBDIR`. 
     libdir = du_sysconfig.get_config_var('LIBDIR') 
     if sysconfig.get_config_var('MULTIARCH'): 
      masd = sysconfig.get_config_var('multiarchsubdir') 
      if masd: 
       if masd.startswith(os.sep): 
        masd = masd[len(os.sep):] 
       libdir = os.path.join(libdir, masd) 

     if libdir is None: 
      libdir = os.path.abspath(os.path.join(
       sysconfig.get_config_var('LIBDEST'), "..", "libs")) 

     candidates = (
      os.path.join(
       libdir, 
       ''.join((pre, 'python', ver, abi, ext)) 
      ) 
      for (pre, ext, ver, abi) in itertools.product(
       candidate_lib_prefixes, 
       candidate_extensions, 
       candidate_versions, 
       candidate_abiflags 
      ) 
     ) 

     for candidate in candidates: 
      if os.path.exists(candidate): 
       # we found a (likely alternate) libpython 
       python_library = candidate 
       break 

    # TODO(opadron): what happens if we don't find a libpython? 

    return python_library