sip_configure.py
Go to the documentation of this file.
1 from copy import copy
2 from distutils.spawn import find_executable
3 import os
4 import re
5 import subprocess
6 import sys
7 
8 import sipconfig
9 from PyQt5 import QtCore
10 
11 
12 class Configuration(sipconfig.Configuration):
13 
14  def __init__(self):
15  env = copy(os.environ)
16  env['QT_SELECT'] = '5'
17  qmake_exe = 'qmake-qt5' if find_executable('qmake-qt5') else 'qmake'
18  qtconfig = subprocess.check_output(
19  [qmake_exe, '-query'], env=env, universal_newlines=True)
20  qtconfig = dict(line.split(':', 1) for line in qtconfig.splitlines())
21  pyqtconfig = {
22  'qt_archdata_dir': qtconfig['QT_INSTALL_DATA'],
23  'qt_data_dir': qtconfig['QT_INSTALL_DATA'],
24  'qt_dir': qtconfig['QT_INSTALL_PREFIX'],
25  'qt_inc_dir': qtconfig['QT_INSTALL_HEADERS'],
26  'qt_lib_dir': qtconfig['QT_INSTALL_LIBS'],
27  'qt_threaded': 1,
28  'qt_version': QtCore.QT_VERSION,
29  'qt_winconfig': 'shared exceptions',
30  }
31  if sys.platform == 'darwin':
32  pyqtconfig['qt_framework'] = 1
33  sipconfig.Configuration.__init__(self, [pyqtconfig])
34 
35  macros = sipconfig._default_macros.copy()
36  macros['INCDIR_QT'] = qtconfig['QT_INSTALL_HEADERS']
37  macros['LIBDIR_QT'] = qtconfig['QT_INSTALL_LIBS']
38  macros['MOC'] = 'moc-qt5'
39  self.set_build_macros(macros)
40 
41 
42 def get_sip_dir_flags(config):
43  """
44  Get the extra SIP flags needed by the imported qt module, and locate PyQt5 sip install files.
45 
46  Note that this normally only includes those flags (-x and -t) that relate to SIP's versioning
47  system.
48  """
49  try:
50  sip_dir = config.pyqt_sip_dir
51  sip_flags = config.pyqt_sip_flags
52  return sip_dir, sip_flags
53  except AttributeError:
54  # sipconfig.Configuration does not have a pyqt_sip_dir or pyqt_sip_flags AttributeError
55  sip_flags = QtCore.PYQT_CONFIGURATION['sip_flags']
56 
57  default_sip_dir = os.path.join(sipconfig._pkg_config['default_sip_dir'], 'PyQt5')
58  if os.path.exists(default_sip_dir):
59  return default_sip_dir, sip_flags
60 
61  # Homebrew installs sip files here by default
62  default_sip_dir = os.path.join(sipconfig._pkg_config['default_sip_dir'], 'Qt5')
63  if os.path.exists(default_sip_dir):
64  return default_sip_dir, sip_flags
65  raise FileNotFoundError('The sip directory for PyQt5 could not be located. Please ensure' +
66  ' that PyQt5 is installed')
67 
68 
69 if len(sys.argv) != 8:
70  print('usage: %s build-dir sip-file output_dir include_dirs libs lib_dirs ldflags' %
71  sys.argv[0])
72  sys.exit(1)
73 
74 # The SIP build folder, the SIP file, the output directory, the include
75 # directories, the libraries, the library directories and the linker
76 # flags.
77 build_dir, sip_file, output_dir, include_dirs, libs, lib_dirs, ldflags = sys.argv[1:]
78 
79 # The name of the SIP build file generated by SIP and used by the build system.
80 build_file = 'pyqtscripting.sbf'
81 
82 # Get the PyQt configuration information.
83 config = Configuration()
84 
85 sip_dir, sip_flags = get_sip_dir_flags(config)
86 
87 try:
88  os.makedirs(build_dir)
89 except OSError:
90  pass
91 
92 # Run SIP to generate the code. Note that we tell SIP where to find the qt
93 # module's specification files using the -I flag.
94 
95 sip_bin = config.sip_bin
96 # Without the .exe, this might actually be a directory in Windows
97 if sys.platform == 'win32' and os.path.isdir(sip_bin):
98  sip_bin += '.exe'
99 
100 cmd = [
101  sip_bin,
102  '-c', build_dir,
103  '-b', os.path.join(build_dir, build_file),
104  '-I', sip_dir,
105  '-w'
106 ]
107 cmd += sip_flags.split(' ')
108 cmd.append(sip_file)
109 subprocess.check_call(cmd)
110 
111 # Create the Makefile. The QtModuleMakefile class provided by the
112 # pyqtconfig module takes care of all the extra preprocessor, compiler and
113 # linker flags needed by the Qt library.
114 makefile = sipconfig.SIPModuleMakefile(
115  dir=build_dir,
116  configuration=config,
117  build_file=build_file,
118  qt=['QtCore', 'QtGui']
119 )
120 
121 # hack to override makefile behavior which always prepend -l to libraries
122 # which is wrong for absolute paths
123 default_platform_lib_function = sipconfig.SIPModuleMakefile.platform_lib
124 
125 
126 def custom_platform_lib_function(self, clib, framework=0):
127  if not clib or clib.isspace():
128  return None
129  # Only add '-l' if a library doesn't already start with '-l' and is not an absolute path
130  if os.path.isabs(clib) or clib.startswith('-l'):
131  return clib
132  return default_platform_lib_function(self, clib, framework)
133 
134 
135 sipconfig.SIPModuleMakefile.platform_lib = custom_platform_lib_function
136 
137 
138 # split paths on whitespace
139 # while dealing with whitespaces within the paths if they are escaped with backslashes
140 def split_paths(paths):
141  paths = re.split('(?<=[^\\\\]) ', paths)
142  return paths
143 
144 
145 for include_dir in split_paths(include_dirs):
146  include_dir = include_dir.replace('\\', '')
147  makefile.extra_include_dirs.append(include_dir)
148 for lib in split_paths(libs):
149  makefile.extra_libs.append(lib)
150 for lib_dir in split_paths(lib_dirs):
151  lib_dir = lib_dir.replace('\\', '')
152  makefile.extra_lib_dirs.append(lib_dir)
153 for ldflag in ldflags.split('\\ '):
154  makefile.LFLAGS.append(ldflag)
155 
156 # redirect location of generated library
157 makefile._target = '"%s"' % os.path.join(output_dir, makefile._target)
158 
159 # Force c++14
160 if sys.platform == 'win32':
161  makefile.extra_cxxflags.append('/std:c++14')
162  # The __cplusplus flag is not properly set on Windows for backwards
163  # compatibilty. This flag sets it correctly
164  makefile.CXXFLAGS.append('/Zc:__cplusplus')
165 else:
166  makefile.extra_cxxflags.append('-std=c++14')
167 
168 # Finalise the Makefile, preparing it to be saved to disk
169 makefile.finalise()
170 
171 # Replace Qt variables from libraries
172 libs = makefile.LIBS.as_list()
173 for i in range(len(libs)):
174  libs[i] = libs[i].replace('$$[QT_INSTALL_LIBS]', config.build_macros()['LIBDIR_QT'])
175 makefile.LIBS.set(libs)
176 
177 # Generate the Makefile itself
178 makefile.generate()
def get_sip_dir_flags(config)
def custom_platform_lib_function(self, clib, framework=0)
def split_paths(paths)


python_qt_binding
Author(s): Dave Hershberger, Dorian Scholz, Dirk Thomas
autogenerated on Tue Apr 13 2021 02:23:57