summaryrefslogtreecommitdiffstats
path: root/setup.py
blob: 36fb10d84d93aa3962876ddebb0113ed36c1e62f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
#!/usr/bin/python
###########################################################################
# setup - description                                                     #
# ------------------------------                                          #
# begin     : Thu Apr 21 2005                                             #
# copyright : (C) 2005 by Simon Edwards                                   #
# email     : simon@simonzone.com                                         #
#                                                                         #
###########################################################################
#                                                                         #
#   This program is free software; you can redistribute it and/or modify  #
#   it under the terms of the GNU Library General Public License as       #
#   published by the Free Software Foundation; either version 2 of the    #
#   License, or (at your option) any later version.                       #
#                                                                         #
###########################################################################
from distutils.cmd import Command
from distutils import sysconfig
from distutils.spawn import find_executable,spawn
from distutils import dir_util
import sys
import os
import glob

sys.path.insert(0,"src") # We need this for the import statement below.
import tdedistutils

def main():
    tdedistutils.setup(name="pytdeextensions",
        version="0.4.0",
        author="Simon Edwards",
        author_email="simon@simonzone.com",
        url="http://www.simonzone.com/software/pykdeextensions/",
        min_kde_version = "3.0.0",
        min_qt_version = "3.0.0",
        license = "LGPL",
        package_dir = {'': 'src'},
        py_modules = ["tdedistutils","qtuicompiler","tqtdesigner","tdedesigner"],
        application_data = ["app_templates","AUTHORS","ChangeLog","COPYING","INSTALL","NEWS"],
        docbooks = [ ('doc/en','en') ],
        cmdclass = {
            'install' : InstallPyKDEExtensions,
            'build_libpythonize' : BuildLibpythonize,
            'install_libpythonize' : InstallLibpythonize
        }
        )

###########################################################################
class InstallPyKDEExtensions(tdedistutils.InstallKDE):
    sub_commands = tdedistutils.InstallKDE.sub_commands[:]
    sub_commands.append( ('install_libpythonize',None) )
    
    user_options = tdedistutils.InstallKDE.user_options
    user_options.append( ('install-clib=', None, "installation directory for shared libraries") )
    user_options.append( ('install-cheaders=', None, "installation directory for C header files") )
            
    def initialize_options(self):
        self.install_clib = None
        self.install_cheaders = None
        tdedistutils.InstallKDE.initialize_options(self)

    def finalize_options(self):
        if self.install_clib is None:
            if self.prefix is not None:
                self.install_clib = os.path.join(self.prefix,'lib')
            else:
                self.announce("Detecting KDE library directory...")
                self.install_clib = tdedistutils.ask_kde_config('--install lib --expandvars').strip()
                self.announce("  ...KDE library directory is %s" % self.install_clib)
                
        if self.install_cheaders is None:
            if self.prefix is not None:
                self.install_cheaders = os.path.join(self.prefix,'include')
            else:
                self.announce("Detecting KDE headers directory...")
                self.install_cheaders = os.path.normpath(os.path.join(tdedistutils.ask_kde_config('--install lib --expandvars').strip(),"../include"))
                self.announce("  ...KDE library headers is %s" % self.install_cheaders)

        tdedistutils.InstallKDE.finalize_options(self)

        if self.root is not None:
            self.change_roots('clib','cheaders')
    
###########################################################################
class BuildLibpythonize(Command):
    description = "Build libpythonize"

    user_options = [
                    ('install-dir=', 'd',"Directory for the libpythonize shared library."),
                    ('no-libpythonize',None,"Don't build libpythonize"),
                    ('build-dir=','b', "build directory (where to install from)"),
                    ('python-dir=',None,'Directory containing the Python installation'),
                    ('python-inc-dir=',None,'Directory containing C Header files for Python'),
                    ('clib=',None,'gcc library and path'),
                    ]
    
    def initialize_options(self):
        self.build_dir = None
        self.install_dir = None
        self.no_libpythonize = 0
        self.python_inc_dir = None
        self.python_dir = None
        self.clib = None
        
    def finalize_options(self):
        if self.no_libpythonize==0:
            own_install_dir = self.install_dir is not None

            self.set_undefined_options('install',\
                                ('build_base', 'build_dir'),
                                ('install_clib', 'install_dir') )

            install = self.get_finalized_command('install')
            self.install_prefix = install.prefix
                    
            # Python dir
            if self.python_dir is None:
                self.python_dir = os.path.split(sysconfig.get_config_var("LIBPL"))[0]
            self.announce("Using %s for the python directory" % self.python_dir)
            
            # Python include dir.
            if self.python_inc_dir is None:
                # Find the Python include directory.
                self.python_inc_dir = sysconfig.get_config_var("INCLUDEPY")
            self.announce("Using %s for Python header files" % self.python_inc_dir)
                
            # Find the C library (libgcc, libgcc_s or some other variation).
            if self.clib is None:
                canidatepaths = ["/usr/"+tdedistutils.get_libdir_name(), "/usr/local/"+tdedistutils.get_libdir_name(), "/usr/lib" ]
                self.clib = tdedistutils.FindFileInPaths("libgcc*.so",canidatepaths)
                if self.clib!=None:
                    self.clib = glob.glob(os.path.join(self.clib,'libgcc*.so'))[0]
                else:
                    self.clib = tdedistutils.FindFileInPaths("libgcc*.a",canidatepaths)
                    if self.clib!=None:
                        self.clib = glob.glob(os.path.join(self.clib,'libgcc*.a'))[0]
            if self.clib is None:
                raise SystemExit("setup.py: Failed to find a suitable libgcc library")
            self.announce("Using %s for clib" % self.clib)
    
            # Make a list of places to look for python .so modules
            self.python_sub_dirs = sysconfig.get_config_var("LIBSUBDIRS").split()
            base = sysconfig.get_config_var("LIBPL")
            self.python_sub_dirs = [ os.path.join(base,item) for item in self.python_sub_dirs ]
            self.python_sub_dirs.append(base)

    def get_command_name(self):
        return 'build_libpythonize'

    def run(self):
        if self.no_libpythonize:
            self.announce("Skipping libpythonize")
            return
    
        self.announce("Building libpythonize.")
        
        cppfile = "src/pythonize.cpp"
        # Compile the library.
        cmdlist = ['libtool']

        # Couldn't get it to pass without this ...
        cmdlist.append("--mode=compile")
        cmdlist.append("--tag=CXX")
        
        # Find the compiler flags and options
        # CXX is empty on some Systems, let's do it 'the hard way'.
        # FIXME :: get CXX from make.conf for Gentoo.
        if len(sysconfig.get_config_var("CXX").split()) >= 2:
            cmdlist.extend(sysconfig.get_config_var("CXX").split())
        else:
            cmdlist.extend(['g++', '-pthread'])
        
        # cc_flags
        cmdlist.append("-c")
        cmdlist.append("-g")
        
        # The 4 is randomly chosen!
        # FIXME :: get CFLAGS from make.conf for Gentoo.
        if len(sysconfig.get_config_var("CFLAGS").split()) >=4:
            cmdlist.extend(sysconfig.get_config_var("CFLAGS").split())
        else:
            # On Gentoo systems, CFLAGS are not in the environment.
            raw = os.popen('emerge info 2> /dev/null|grep CFLAGS')
            lines = raw.readlines()
            if len(lines):
                cflags = lines[0].split('"')[1].split()
                print("Got CFLAGS from emerge info.")
                cmdlist.extend(cflags)
            else:
                # Still no CFLAGS found, use these ...
                cmdlist.extend(['-fno-strict-aliasing', '-DNDEBUG', '-g', '-O3', '-Wall', '-Wstrict-prototypes'])
            
        # includes
        cmdlist.append("-I" + sysconfig.get_config_var("INCLUDEDIR"))
        cmdlist.append("-I" + sysconfig.get_config_var("INCLUDEPY"))
        cmdlist.append("-I" + self.python_inc_dir)
        cmdlist.append("-Isrc")
        # input
        cmdlist.append(cppfile)
        # output
        outputfile = os.path.join(self.build_dir,'libpythonize.lo')
        cmdlist.append("-o")
        cmdlist.append(outputfile)
        spawn(cmdlist) # Execute!!!
        print()
        
        # Link the resulting object file to create a shared library.
        cmdlist = ['libtool']
        cmdlist.append("--mode=link")
        cmdlist.append("--tag=LD")
        
        # Grab the linker command name
        cmdlist.append(sysconfig.get_config_var("LDSHARED").split()[0])
        # link_flags
        cmdlist.append("-module")
        cmdlist.append("-export-dynamic")
        # object
        cmdlist.append(outputfile)
        cmdlist.append("-rpath"); cmdlist.append(self.install_dir)
        cmdlist.append("-o"); cmdlist.append(os.path.join(self.build_dir,'libpythonize.la'))
        # Link libs
        linklist = []
        linklist.append("-lpython%i.%i%s" % (sys.version_info[0], sys.version_info[1], sys.abiflags) )
        linklist.extend(sysconfig.get_config_var("LIBS").split())
        
        linklist.append("-lm")
        linklist.append("-lc")
        linklist.append(self.clib)

        linklist.append("-R"); linklist.append(self.python_dir)

        cmdlist.extend(linklist)
        spawn(cmdlist) # Execute!!
        print()

###########################################################################
class InstallLibpythonize(Command):
    description = "Install libpythonize"

    user_options = [
        ('install-dir=', 'd',"Directory for the libpythonize shared library."),
        ('build-dir=','b', "build directory (where to install from)"),
        ('cheader-dir=', 'h',"Directory for the pythonize.h C header file."),
        ('install-cmd=', None, "Command to use to install the files"),
        ('root=', None, "install everything relative to this alternate root directory"),
        ('force', 'f', "force installation (overwrite existing files)"),
        ('skip-build', None, "skip the build steps"),
        ]
        
    boolean_options = ['force', 'skip-build']
    
    def initialize_options(self):
        self.install_dir = None
        self.build_dir = None
        self.install_cmd = None
        self.cheader_dir = None
        self.outfiles = []
        self.root = None
        self.force = 0
        self.warn_dir = 1
        self.skip_build = None

    def finalize_options(self):
        own_install_dir = self.install_dir is not None
        own_cheader_dir = self.cheader_dir is not None
        
        self.set_undefined_options('install',
                                ('build_base','build_dir'),
                                ('install_clib', 'install_dir'),
                                ('install_cheaders', 'cheader_dir'),
                                ('install_cmd', 'install_cmd'),
                                ('root', 'root'),
                                ('force', 'force'),
                                ('skip_build', 'skip_build')
                                )

        if own_install_dir and self.root is not None:
            self.install_dir = change_root(self.root,self.install_dir)
        if own_cheader_dir and self.root is not None:
            self.cheader_dir = change_root(self.root,self.cheader_dir)

    def get_command_name(self):
        return 'install_libpythonize'
        
    def run(self):
        if not self.skip_build:
            self.run_command('build_libpythonize')
    
        self.announce("Installing libpythonize...")
        
        self.outfiles.extend(self.mkpath(self.install_dir))
        
        # Install the library.
        cmdlist = ['libtool']
        cmdlist.append("--mode=install")
        cmdlist.append(self.install_cmd)
        cmdlist.append("-c")
        cmdlist.append(os.path.join(self.build_dir,"libpythonize.la"))
        cmdlist.append(os.path.join(self.install_dir,"libpythonize.la"))
        spawn(cmdlist) # Execute!!
        print()

        # Work the names of the files that were installed.
        self.outfiles = []
        for file in glob.glob(os.path.join(self.build_dir,'.libs/libpythonize*')):
            self.outfiles.append(os.path.join(self.install_dir,os.path.basename(file)))

        # Create a directory for the C header file.
        self.outfiles.extend(self.mkpath(self.cheader_dir))
        
        # Install the header file.
        (out, _) = self.copy_file("src/pythonize.h", os.path.join(self.cheader_dir,'pythonize.h'))
        self.outfiles.append(out)

        self.announce("Done installing libpythonize.")

    def get_outputs(self):
        return self.outfiles

    def mkpath(self, name, mode=0o777):
        return dir_util.mkpath(name, mode, dry_run=self.dry_run)
        
main()