source: orange/source/orangeqt/setup.py @ 11842:44989ed55fb2

Revision 11842:44989ed55fb2, 9.1 KB checked in by Miha Stajdohar <miha.stajdohar@…>, 3 months ago (diff)

Bugfix: calling module.

  • Property exe set to *
Line 
1#!/usr/bin/env python
2
3import os
4import sys
5import shlex
6from collections import namedtuple
7from ConfigParser import SafeConfigParser
8
9from setuptools import setup
10
11from distutils.core import Extension
12from distutils import dir_util, spawn, log
13
14import glob
15import numpy
16
17import sipdistutils
18
19try:
20    from PyQt4 import pyqtconfig
21except ImportError:
22    pyqtconfig = None
23
24try:
25    from PyQt4.QtCore import PYQT_CONFIGURATION
26except ImportError:
27    PYQT_CONFIGURATION = None
28
29pjoin = os.path.join
30
31NAME                = 'orangeqt-qt'
32DESCRIPTION         = 'orangeqt ploting library'
33URL                 = "http://orange.biolab.si"
34LICENSE             = 'GNU General Public License (GPL)'
35AUTHOR              = "Bioinformatics Laboratory, FRI UL"
36AUTHOR_EMAIL        = "orange@fri.uni-lj.si"
37VERSION             = '0.0.1a'
38
39
40pyqt_conf = namedtuple(
41    "pyqt_conf",
42    ["sip_flags",
43     "sip_dir"]
44)
45
46qt_conf = namedtuple(
47    "qt_conf",
48    ["prefix",
49     "include_dir",
50     "library_dir",
51     "framework",
52     "framework_dir"]
53)
54
55config = namedtuple(
56    "config",
57    ["sip",
58     "pyqt_conf",
59     "qt_conf"]
60)
61
62pyqt_sip_dir = None
63pyqt_sip_flags = None
64
65qt_dir = None
66qt_include_dir = None
67qt_lib_dir = None
68qt_framework = False
69
70# use PyQt4 build time config if provided
71if pyqtconfig is not None:
72    cfg = pyqtconfig.Configuration()
73    pyqt_sip_dir = cfg.pyqt_sip_dir
74    pyqt_sip_flags = cfg.pyqt_sip_flags
75
76    qt_dir = cfg.qt_dir
77    qt_include_dir = cfg.qt_inc_dir
78    qt_lib_dir = cfg.qt_lib_dir
79    qt_framework = bool(cfg.qt_framework)
80    qt_framework_dir = qt_lib_dir
81
82elif PYQT_CONFIGURATION is not None:
83    pyqt_sip_flags = PYQT_CONFIGURATION["sip_flags"]
84
85
86# if QTDIR env is defined use it
87if "QTDIR" in os.environ:
88    qt_dir = os.environ["QTDIR"]
89    if sys.platform == "darwin":
90        if glob.glob(pjoin(qt_dir, "lib", "Qt*.framework")):
91            # This is the standard Qt4 framework layout
92            qt_framework = True
93            qt_framework_dir = pjoin(qt_dir, "lib")
94        elif glob(pjoin(qt_dir, "Frameworks", "Qt*.framework")):
95            # Also worth checking (standard for bundled apps)
96            qt_framework = True
97            qt_framework_dir = pjoin(qt_dir, "Frameworks")
98
99    if not qt_framework:
100        # Assume standard layout
101        qt_framework = False
102        qt_include_dir = pjoin(qt_dir, "include")
103        qt_lib_dir = pjoin(qt_dir, "lib")
104
105
106extra_compile_args = []
107extra_link_args = []
108include_dirs = []
109library_dirs = []
110
111
112def site_config():
113    parser = SafeConfigParser(dict(os.environ))
114    parser.read(["site.cfg",
115                 os.path.expanduser("~/.orangeqt-site.cfg")])
116
117    def get(section, option, default=None, type=None):
118        if parser.has_option(section, option):
119            if type is None:
120                return parser.get(section, option)
121            elif type is bool:
122                return parser.getboolean(section, option)
123            elif type is int:
124                return parser.getint(section, option)
125            else:
126                raise TypeError
127        else:
128            return default
129
130    sip_bin = get("sip", "sip_bin")
131
132    sip_flags = get("pyqt", "sip_flags", default=pyqt_sip_flags)
133    sip_dir = get("pyqt", "sip_dir", default=pyqt_sip_dir)
134
135    if sip_flags is not None:
136        sip_flags = shlex.split(sip_flags)
137    else:
138        sip_flags = []
139
140    prefix = get("qt", "qt_dir", default=qt_dir)
141    include_dir = get("qt", "include_dir", default=qt_include_dir)
142    library_dir = get("qt", "library_dir", default=qt_lib_dir)
143    framework = get("qt", "framework", default=qt_framework, type=bool)
144    framework_dir = get("qt", "framework_dir", default=qt_framework_dir)
145
146    def path_list(path):
147        if path and path.strip():
148            return path.split(os.pathsep)
149        else:
150            return []
151
152    include_dir = path_list(include_dir)
153    library_dir = path_list(library_dir)
154
155    conf = config(
156        sip_bin,
157        pyqt_conf(sip_flags, sip_dir),
158        qt_conf(prefix, include_dir, library_dir,
159                framework, framework_dir)
160    )
161    return conf
162
163site_cfg = site_config()
164
165if sys.platform == "darwin":
166    sip_plaftorm_tag = "WS_MACX"
167elif sys.platform == "win32":
168    sip_plaftorm_tag = "WS_WIN"
169elif sys.platform.startswith("linux"):
170    sip_plaftorm_tag = "WS_X11"
171else:
172    sip_plaftorm_tag = ""
173
174def which(name):
175    """
176    Return the path of program named 'name' on the $PATH.
177    """
178    if os.name == "nt" and not name.endswith(".exe"):
179        name = name + ".exe"
180
181    for path in os.environ["PATH"].split(os.pathsep):
182        path = os.path.join(path, name)
183        if os.path.isfile(path) and os.access(path, os.X_OK):
184            return path
185
186    return None
187
188
189class PyQt4Extension(Extension):
190    pass
191
192
193class build_pyqt_ext(sipdistutils.build_ext):
194    """
195    A build_ext command for building PyQt4 sip based extensions
196    """
197    description = "Build a orangeqt PyQt4 extension."
198
199    def finalize_options(self):
200        sipdistutils.build_ext.finalize_options(self)
201        self.sip_opts = self.sip_opts + \
202                        site_cfg.pyqt_conf.sip_flags + \
203                        ["-j", "1"]  # without -j1 it does not build (??)
204
205    def build_extension(self, ext):
206        if not isinstance(ext, PyQt4Extension):
207            return
208
209        cppsources = [source for source in ext.sources
210                      if source.endswith(".cpp")]
211
212        dir_util.mkpath(self.build_temp, dry_run=self.dry_run)
213
214        # Run moc on all header files.
215        for source in cppsources:
216            header = source.replace(".cpp", ".h")
217            if os.path.exists(header):
218                moc_file = os.path.basename(header).replace(".h", ".moc")
219                out_file = os.path.join(self.build_temp, moc_file)
220                call_arg = ["moc", "-o", out_file, header]
221                spawn.spawn(call_arg, dry_run=self.dry_run)
222
223        # Add the temp build directory to include path, for compiler to find
224        # the created .moc files
225        ext.include_dirs = ext.include_dirs + [self.build_temp]
226
227        sipdistutils.build_ext.build_extension(self, ext)
228
229    def _find_sip(self):
230        if site_cfg.sip:
231            log.info("Using sip at %r (from .cfg file)" % site_cfg.sip)
232            return site_cfg.sip
233
234        # Try the base implementation
235        sip = sipdistutils.build_ext._find_sip(self)
236        if os.path.isfile(sip):
237            return sip
238
239        log.warn("Could not find sip executable at %r." % sip)
240
241        # Find sip on $PATH
242        sip = which("sip")
243
244        if sip:
245            log.info("Found sip on $PATH at: %s" % sip)
246            return sip
247
248        return sip
249
250    # For sipdistutils to find PyQt4's .sip files
251    def _sip_sipfiles_dir(self):
252        if site_cfg.pyqt_conf.sip_dir:
253            return site_cfg.pyqt_conf.sip_dir
254
255        if os.path.isdir(pyqt_sip_dir):
256            return pyqt_sip_dir
257
258        log.warn("The default sip include directory %r does not exist" %
259                 pyqt_sip_dir)
260
261        path = os.path.join(sys.prefix, "share/sip/PyQt4")
262        if os.path.isdir(path):
263            log.info("Found sip include directory at %r" % path)
264            return path
265
266        return "."
267
268
269def get_source_files(path, ext="cpp", exclude=[]):
270    files = glob.glob(os.path.join(path, "*." + ext))
271    files = [file for file in files if os.path.basename(file) not in exclude]
272    return files
273
274
275# Used Qt4 libraries
276qt_libs = ["QtCore", "QtGui"]
277
278if site_cfg.qt_conf.framework:
279    framework_dir = site_cfg.qt_conf.framework_dir
280    extra_compile_args = ["-F%s" % framework_dir]
281    extra_link_args = ["-F%s" % framework_dir]
282    for lib in qt_libs:
283        include_dirs += [os.path.join(framework_dir,
284                                      lib + ".framework", "Headers")]
285        extra_link_args += ["-framework", lib]
286    qt_libs = []
287else:
288    if type(site_cfg.qt_conf.include_dir) == list:
289        include_dirs = site_cfg.qt_conf.include_dir + \
290                [pjoin(d, lib)
291                for lib in qt_libs for d in site_cfg.qt_conf.include_dir]
292    else:
293        include_dirs = [site_cfg.qt_conf.include_dir] + \
294                   [pjoin(site_cfg.qt_conf.include_dir, lib)
295                    for lib in qt_libs]
296    library_dirs += [site_cfg.qt_conf.library_dir]
297
298if sys.platform == "win32":
299    # Qt libs on windows have a 4 added
300    qt_libs = [lib + "4" for lib in qt_libs]
301
302include_dirs += [numpy.get_include(), "./"]
303
304orangeqt_ext = PyQt4Extension(
305    "orangeqt",
306    ["orangeqt.sip"] + get_source_files(
307        "", "cpp",
308        exclude=["canvas3d.cpp", "plot3d.cpp", "glextensions.cpp"]
309     ),
310    include_dirs=include_dirs,
311    extra_compile_args=extra_compile_args + \
312                         ["-DORANGEQT_EXPORTS"],
313    extra_link_args=extra_link_args,
314    libraries=qt_libs,
315    library_dirs=library_dirs
316)
317
318ENTRY_POINTS = {
319    'orange.addons': (
320        'orangeqt = orangeqt',
321    ),
322}
323
324
325def setup_package():
326    setup(name=NAME,
327          description=DESCRIPTION,
328          version=VERSION,
329          author=AUTHOR,
330          author_email=AUTHOR_EMAIL,
331          url=URL,
332          license=LICENSE,
333          ext_modules=[orangeqt_ext],
334          cmdclass={"build_ext": build_pyqt_ext},
335          entry_points=ENTRY_POINTS,
336          )
337
338if __name__ == '__main__':
339    setup_package()
Note: See TracBrowser for help on using the repository browser.