API_Py  0.0.2
API_Py exporte le projet API vers un module python dans l’environnement python choisi. Le module python se nomme wxcpppy.
setup.py
1 # Copyright 20018-2019 wxCppPy. All Rights Reserved.
2 # Licensed to MIT see LICENSE.txt
3 
4 # Thanks to Sylvain Corlay see https://github.com/pybind/python_example'
5 
6 # N'installer pas wheel sinon setuptools.setup essaiera de l'utiliser et je n'ai pas réussi à le configurer sur Mageia6.
7 # Le tag de la plateforme lui est inconnu.
8 
9 from setuptools import setup, Extension
10 from setuptools.command.build_ext import build_ext
11 import os
12 import sys
13 import setuptools
14 
15 import wxcpppyconfig
16 
17 # https://setuptools.readthedocs.io/en/latest/setuptools.html#developer-s-guide
18 # https://setuptools.readthedocs.io/en/latest/history.html?highlight=ext_modules
19 
20 __version__ = '0.0.2'
21 
22 module_name = 'wxcpppy'
23 
24 
25 class Directories(object):
26  wxcpppy_path = os.environ["PWD"] + "/.."
27  """C'est la seul variable qui permet de retrouver par défaut le répertoire d'éxécution du script. Pip exécute le
28  tout dans un répertoire temporaire.
29  """
30 
31  wxcpppy_config = wxcpppyconfig.WXCppPyConfig()
32  """Liste des chemins pour compiler le projet wxCppPy::API_Py"""
33 
34  @staticmethod
35  def get_includes_directories():
36 
37  result = [Directories.wxcpppy_path + "/API_Py/include",
38  Directories.wxcpppy_path + "/API/include",
40  GetPybindInclude(user=True),
41  Directories.wxcpppy_config.pyenv_include_path,
42  Directories.wxcpppy_config.cppclay_path + "/include",
43  Directories.wxcpppy_config.wxpython_path + "/ext/wxWidgets/include",
44  Directories.wxcpppy_config.wxpython_path + "/build/wxbld/gtk3/lib/wx/include/gtk3-unicode-3.0",
45  Directories.wxcpppy_config.wxpython_path + "/sip/siplib",
46  Directories.wxcpppy_config.wxpython_path + "/wx/include",
47  Directories.wxcpppy_config.pyenv_path,
48  Directories.wxcpppy_config.pyenv_sp_path,
49  Directories.wxcpppy_config.pyenv_include_path,
50  Directories.wxcpppy_config.pybind11_path,
51  Directories.wxcpppy_config.wxpython_path,
52  Directories.wxcpppy_config.cppclay_path,
53  Directories.wxcpppy_config.cppclaydll_path]
54 
55  return result
56 
57  @staticmethod
58  def get_macros():
59  result = [
60  ('PYTHONENV_PATH', Directories.wxcpppy_config.pyenv_path),
61  ('PYTHONENV_SP_PATH', Directories.wxcpppy_config.pyenv_sp_path),
62  ('PYTHONENV_INCLUDE_PATH', Directories.wxcpppy_config.pyenv_include_path),
63  ('PYBIND11_PATH', Directories.wxcpppy_config.pybind11_path),
64  ('WXPYTHON_PATH', Directories.wxcpppy_config.wxpython_path),
65  ('CPPCLAY_PATH', Directories.wxcpppy_config.cppclay_path),
66  ('CPPCLAYDLL_PATH', Directories.wxcpppy_config.cppclaydll_path),
67  ('WXCPPPY_PATH', Directories.wxcpppy_path)]
68 
69  for define in Directories.get_defines():
70  result.append((define, None))
71 
72  return result
73 
74  @staticmethod
75  def get_libraries():
76  path_wx_python = Directories.wxcpppy_config.pyenv_sp_path + '/wx/'
77 
78  prefix_wx = path_wx_python + 'lib'
79  suffix_wx = '.so'
80 
81  prefix_wx_cpython = path_wx_python
82  suffix_wx_cpython = Directories.wxcpppy_config.pyenv_ext_suffix
83 
84  wx_paths = ['wx_gtk3u_xrc-3.0',
85  'wx_gtk3u_webview-3.0',
86  'wx_gtk3u_html-3.0',
87  'wx_gtk3u_adv-3.0',
88  'wx_gtk3u_core-3.0',
89  'wx_baseu_xml-3.0',
90  'wx_baseu_net-3.0',
91  'wx_baseu-3.0',
92  'wx_gtk3u_aui-3.0']
93 
94  for i in range(0, len(wx_paths)):
95  wx_paths[i] = prefix_wx + wx_paths[i] + suffix_wx
96 
97  wx_cpython_path = ['_aui',
98  '_propgrid',
99  '_ribbon',
100  '_richtext',
101  '_xrc',
102  '_xml',
103  '_html2',
104  '_html',
105  '_glcanvas',
106  '_stc',
107  '_grid',
108  '_dataview',
109  '_adv',
110  '_core',
111  'siplib']
112 
113  for i in range(0, len(wx_cpython_path)):
114  wx_cpython_path[i] = prefix_wx_cpython + wx_cpython_path[i] + suffix_wx_cpython
115 
116  result = wx_paths.copy()
117  result.extend(wx_cpython_path)
118 
119  for i in range(0, len(result)):
120  path = result[i]
121  assert os.path.exists(path), path + " doesn't exist"
122  result[i] = os.path.normpath(path)
123 
124  result.extend([Directories.wxcpppy_path + "/API/bin/Debug/libAPI.so",
125  Directories.wxcpppy_config.cppclaydll_path + '/libclay.so', 'pthread'])
126 
127  return result
128 
129  @staticmethod
130  def get_libraries_directories():
131  return [Directories.wxcpppy_config.cppclaydll_path,
132  Directories.wxcpppy_config.pyenv_sp_path + "/wx",
133  Directories.wxcpppy_path + "/API/bin/Debug"]
134 
135  @staticmethod
136  def get_compiler_options():
137  return ['-O3',
138  '-s',
139  '-fexceptions',
140  '-fpic'] # todo voir -rpath et -rpath-link
141 
142  @staticmethod
143  def get_defines():
144  return ['_FILE_OFFSET_BITS=64',
145  'WXUSINGDLL',
146  '__WXGTK__',
147  'wxUSE_UNICODE',
148  'wxUSE_MENUS',
149  'wxUSE_CMDLINE_PARSER']
150 
151 
152 class GetPybindInclude(object):
153  """Helper class to determine the pybind11 include path
154 
155  The purpose of this class is to postpone importing pybind11
156  until it is actually installed, so that the ``get_include()``
157  method can be invoked. """
158 
159  def __init__(self, user=False):
160  self.user = user
161 
162  def __str__(self):
163  import pybind11
164  return pybind11.get_include(self.user)
165 
166 
167 ext_modules = [
168  # https://docs.python.org/3/extending/building.html
169  Extension(
170  module_name,
171  sources=['src/Module.cpp', 'src/Vector.cpp', 'src/wxAccess.cpp'],
172  define_macros=Directories.get_macros(),
173  include_dirs=Directories.get_includes_directories(),
174  libraries=Directories.get_libraries(),
175  library_dirs=Directories.get_libraries_directories(),
176  language='c++'
177  ),
178 ]
179 
180 
181 # As of Python 3.6, CCompiler has a `has_flag` method.
182 # cf http://bugs.python.org/issue26689
183 def has_flag(compiler, flag_name):
184  """Return a boolean indicating whether a flag name is supported on
185  the specified compiler.
186  """
187  import tempfile
188  with tempfile.NamedTemporaryFile('w', suffix='.cpp') as f:
189  f.write('int main (int argc, char **argv) { return 0; }')
190  try:
191  compiler.compile([f.name], extra_postargs=[flag_name])
192  except setuptools.distutils.errors.CompileError:
193  return False
194  return True
195 
196 
197 def cpp_flag(compiler):
198  """Return the -std=c++[11/14/17] compiler flag.
199 
200  The c++17 is prefered over c++14/11 (when it is available).
201  """
202  if has_flag(compiler, '-std=c++17'):
203  return '-std=c++17'
204  elif has_flag(compiler, '-std=c++1z'): # gcc / clang
205  return '-std=c++11'
206  elif has_flag(compiler, '-std=c++1atest'): # MSVC
207  return '-std=c++11'
208  elif has_flag(compiler, '-std=c++11'):
209  return '-std=c++11'
210  elif has_flag(compiler, '-std=c++14'):
211  return '-std=c++14'
212  elif has_flag(compiler, '-std=c++11'):
213  return '-std=c++11'
214  else:
215  raise RuntimeError('Unsupported compiler -- at least C++11 support is needed!')
216 
217 
218 class BuildExt(build_ext):
219  """A custom build extension for adding compiler-specific options."""
220  c_opts = {
221  'msvc': ['/EHsc'],
222  'unix': [],
223  }
224 
225  if sys.platform == 'darwin':
226  c_opts['unix'] += ['-stdlib=libc++', '-mmacosx-version-min=10.7']
227 
228  def build_extensions(self):
229  ct = self.compiler.compiler_type
230  opts = self.c_opts.get(ct, [])
231 
232  if ct == 'unix':
233  opts.append('-DVERSION_INFO="%s"' % self.distribution.get_version())
234  opts.append(cpp_flag(self.compiler))
235 
236  if has_flag(self.compiler, '-fvisibility=hidden'):
237  opts.append('-fvisibility=hidden')
238 
239  elif ct == 'msvc':
240  opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version())
241 
242  for option in Directories.get_compiler_options():
243  opts.append(option)
244 
245  for ext in self.extensions:
246  ext.extra_compile_args = opts
247 
248  build_ext.build_extensions(self)
249 
250 
251 setup(
252  name=module_name,
253  version=__version__,
254  author='Pierre Pontier',
255  author_email='http://www.suryavarman.fr/contact/',
256  url='http://www.suryavarman.fr/python_cpp_pybind_wx/',
257  license='MIT',
258  description='A tutorial project using pybind11 and wxWidgets',
259  # long_description=open(os.path.dirname(os.path.abspath(__file__)) + '/../README.md').read(),
260  ext_modules=ext_modules,
261  install_requires=['pybind11>=2.2', 'wxPython>=4'],
262  setup_requires=['wxPython>=4'],
263  include_package_data=True,
264  cmdclass={'build_ext': BuildExt},
265  zip_safe=False,
266 )
Definition: setup.py:1
dictionary c_opts
Definition: setup.py:220