You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pytdeextensions/src/tdedistutils.py

2256 lines
92 KiB

#!/usr/bin/python
###########################################################################
# tdedistutils - 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. #
# #
###########################################################################
import distutils.core
from distutils.core import Extension
from distutils.cmd import Command
from distutils.dist import Distribution
from distutils.command.build import build
from distutils.command.install import install
from distutils.command.install_scripts import install_scripts
from distutils.command.install_data import install_data
from distutils.command.install_lib import install_lib
from distutils.util import change_root, convert_path
from distutils.spawn import find_executable,spawn
from distutils import sysconfig
from distutils import log
from distutils import file_util
from distutils import dir_util
from distutils.util import byte_compile
import tqtuicompiler
import stat
import os,os.path,imp,glob
import sys
from types import *
INSTALL_LIST = 'install_log.txt'
###########################################################################
def setup(**arg_dict):
if 'cmdclass' not in arg_dict:
arg_dict['cmdclass'] = {}
cmdclass = arg_dict['cmdclass']
arg_dict.setdefault('data_files',[])
kdecmdclass = {'install' : InstallKDE,
'install_executable_links' : InstallExecutableLinks,
'install_application_data' : InstallApplicationDataAndLinks,
'build_messages' : BuildI18NMessages,
'install_messages' : InstallI18NMessages,
'update_messages' : UpdateI18NMessages,
'checkpytqt' : CheckPyTQt,
'checkpytde' : CheckPyTDE,
'uninstall' : Uninstall,
'build' : BuildKDE,
'build_kcm' : BuildKControlModule,
'install_kcm' : InstallKControlModule,
'build_html' : BuildDocbookHTML,
'install_html' : InstallDocbookHTML,
'install_lib' : InstallLibWithRoot,
'build_tdeioslave' : BuildTdeioslave,
'install_tdeioslave' : InstallTdeioslave}
for key in kdecmdclass.keys():
cmdclass.setdefault(key,kdecmdclass[key])
arg_dict.setdefault('distclass',KDEDistribution)
distutils.core.setup(*[], **arg_dict)
###########################################################################
class KDEDistribution(Distribution):
def __init__(self,attrs=None):
self.min_kde_version = None
self.min_tqt_version = None
self.kcontrol_modules = None
self.tdeioslaves = None
self.executable_links = None
self.docbooks = None
self.application_data = None
self.i18n = None
Distribution.__init__(self,attrs)
###########################################################################
def has_kcms(self):
if self.distribution.kcontrol_modules is None:
return 0
return len(self.distribution.kcontrol_modules)!=0
def has_docbook_html(self):
if self.distribution.docbooks is None:
return 0
return len(self.distribution.docbooks)!=0
def has_messages(self):
if self.distribution.i18n is None:
return 0
return len(self.distribution.i18n)!=0
def has_application_data(self):
if self.distribution.application_data is None:
return 0
return len(self.distribution.application_data)!=0
def has_tdeioslaves(self):
if self.distribution.tdeioslaves is None:
return 0
return len(self.distribution.tdeioslaves)!=0
###########################################################################
# Our slightly extended build command. This also does kcontrol modules.
class BuildKDE(build):
user_options = build.user_options[:]
user_options.append( ('msgfmt-exe=',None,'Path to the msgfmt executable') )
user_options.append( ('meinproc-exe=',None,'Path to the meinproc executable') )
sub_commands = build.sub_commands[:]
sub_commands.append( ('build_kcm',has_kcms) )
sub_commands.append( ('build_tdeioslave',has_tdeioslaves) )
sub_commands.append( ('build_html',has_docbook_html) )
sub_commands.append( ('build_messages',has_messages) )
def __init__(self,dist):
build.__init__(self,dist)
self.has_kcms = has_kcms
self.has_tdeioslaves = has_tdeioslaves
self.has_docbook_html = has_docbook_html
self.has_messages = has_messages
def initialize_options(self):
self.msgfmt_exe = None
self.meinproc_exe = None
build.initialize_options(self)
def finalize_options(self):
build.finalize_options(self)
if self.msgfmt_exe is None:
# Find msgfmt
canidatepaths = []
canidatepaths.append( ask_kde_config('--install exe --expandvars').strip() )
self.msgfmt_exe = FindExeOnPath('msgfmt',canidatepaths)
if self.msgfmt_exe is None:
raise SystemExit("Unable to find 'msgfmt', needed to build i18n messages.")
if self.meinproc_exe is None:
# Find meinproc
canidatepaths = []
canidatepaths.append( ask_kde_config('--install exe --expandvars').strip() )
self.meinproc_exe = FindExeOnPath('meinproc',canidatepaths)
if self.meinproc_exe is None:
raise SystemExit("Unable to find 'meinproc', needed to generate Docbook HTML documentation.")
###########################################################################
def has_executable_links(self):
if self.distribution.executable_links is None:
return 0
return len(self.distribution.executable_links)!=0
###########################################################################
class InstallKDE(install):
user_options = install.user_options[:]
user_options.append( ('kde-prefix=',None,"TDE installation prefix") )
user_options.append( ('install-messages=',None,"installation directory for i18n message files") )
user_options.append( ('install-html=',None,"installation directory for Docbook HTML files") )
user_options.append( ('install-cmd=',None,"Command to use to install the files") )
user_options.append( ('install-xdg-apps=',None,"directory for XDG app files") )
user_options.append( ('install-kcm=',None,"directory for kcm library files") )
user_options.append( ('install-tdeioslave',None,"directory for tdeioslave library files") )
user_options.append( ('install-protocol',None,"directory for tdeioslave protocol files") )
sub_commands = install.sub_commands[:]
sub_commands.insert(0, ('checkpytde',None) )
sub_commands.insert(0, ('checkpytqt',None) )
sub_commands.append( ('install_executable_links',has_executable_links) )
sub_commands.append( ('install_messages',has_messages) )
sub_commands.append( ('install_html',has_docbook_html) )
sub_commands.append( ('install_kcm',has_kcms) )
sub_commands.append( ('install_tdeioslave',has_tdeioslaves) )
sub_commands.append( ('install_application_data',has_application_data) )
def initialize_options(self):
self.kde_prefix = None
self.install_messages = None
self.install_html = None
self.install_cmd = None
self.install_xdg_apps = None
self.install_kcm = None
self.install_tdeioslave = None
self.install_protocol = None
self.install_application_data = None
install.initialize_options(self)
def finalize_options(self):
# If no install prefix was provided, then we try to detect the KDE install prefix.
self.user_supplied_kde_prefix = True
if self.install_scripts is None:
if self.kde_prefix is not None:
self.install_scripts = os.path.join(self.kde_prefix,'bin')
else:
self.announce("Detecting TDE 'bin' directory...")
self.install_scripts = ask_kde_config('--install exe --expandvars').strip()
self.announce(" ...TDE 'bin' directory is %s" % self.install_scripts)
if self.install_application_data is None:
if self.kde_prefix is not None:
self.install_application_data = os.path.join(self.kde_prefix,'share/apps',self.distribution.metadata.name)
else:
self.announce("Detecting TDE application directory...")
kdeappdir = ask_kde_config('--install data --expandvars').strip()
self.announce(" ...TDE application directory is %s" % self.install_application_data)
self.install_application_data = os.path.join(kdeappdir,self.distribution.metadata.name)
if self.install_messages is None:
if self.kde_prefix is not None:
self.install_messages = os.path.join(self.kde_prefix,'share/locale')
else:
self.announce("Detecting TDE messages directory...")
self.install_messages = ask_kde_config('--install locale --expandvars').strip()
self.announce(" ...TDE messages directory is %s" % self.install_messages)
if self.install_html is None:
if self.kde_prefix is not None:
self.install_html = os.path.join(self.kde_prefix,'share/doc/tde/HTML')
else:
self.announce("Detecting TDE HTML directory...")
self.install_html = ask_kde_config('--install html --expandvars').strip()
self.announce(" ...TDE HTML directory is %s" % self.install_html)
if self.kde_prefix is None:
self.announce("Detecting TDE install prefix...")
self.kde_prefix = ask_kde_config('--prefix').strip()
self.announce(" ...TDE install prefix is %s" % self.kde_prefix)
self.user_supplied_kde_prefix = False
if self.install_cmd is None:
self.announce("Detecting 'install' command...")
# Ok, time to find the install command.
self.install_cmd = find_executable('install')
if self.install_cmd is None:
raise SystemExit("Unable to find the 'install' command, needed to install libraries.")
self.announce(" ...'install' command is %s" % self.install_cmd)
if self.install_xdg_apps is None:
self.announce("Detecting XDG apps directory...")
self.install_xdg_apps = ask_kde_config('--install xdgdata-apps --expandvars').strip()
self.announce(" ...XDG apps directory is %s" % self.install_xdg_apps)
if self.install_kcm is None:
self.announce("Detecting kcm library directory...")
self.install_kcm = ask_kde_config('--install module --expandvars').strip()
self.announce(" ...kcm library directory is %s" % self.install_kcm)
if self.install_tdeioslave is None:
self.announce("Detecting tdeioslave library directory...")
self.install_tdeioslave = ask_kde_config('--install module --expandvars').strip()
self.announce(" ...tdeioslave library directory is %s" % self.install_tdeioslave)
if self.install_protocol is None:
self.announce("Detecting tdeioslave protocol directory...")
self.install_protocol = ask_kde_config('--install services --expandvars').strip()
self.announce(" ...tdeioslave protocol directory is %s" % self.install_protocol)
install.finalize_options(self)
if self.root is not None:
self.change_roots('application_data','html','messages','xdg_apps','kcm')
def get_command_name(self):
return 'install'
def run(self):
global INSTALL_LIST
install.run(self)
# Write out the uninstall list.
fhandle = open(INSTALL_LIST,'w')
for item in self.get_outputs():
fhandle.write(item)
fhandle.write('\n')
fhandle.close()
###########################################################################
class InstallApplicationDataAndLinks(install_data):
def get_command_name(self):
return 'install_application_data'
def initialize_options(self):
install_data.initialize_options(self)
self.data_files = self.distribution.application_data
def finalize_options(self):
self.set_undefined_options('install',
('install_application_data', 'install_dir'),
('root', 'root'),
('force', 'force'),
)
def run(self):
self.outfiles.extend(self.mkpath(self.install_dir))
for f in self.data_files:
if type(f) is type('String'):
# it's a simple file, so copy it
f = convert_path(f)
if self.warn_dir:
self.warn("setup script did not provide a directory for "
"'%s' -- installing right in '%s'" %
(f, self.install_dir))
if os.path.isfile(f):
(out, _) = self.copy_file(f, self.install_dir)
self.outfiles.append(out)
elif os.path.isdir(f):
out = self.copy_tree(f,os.path.join(self.install_dir,f))
self.outfiles.extend(out)
else:
self.warn("Setup script can't find file or directory %s needed for installation." % f)
else:
# it's a tuple with path to install to and a list of files
dir = convert_path(f[0])
if not os.path.isabs(dir):
dir = change_root(self.install_dir, dir)
elif self.root:
dir = change_root(self.root, dir)
self.outfiles.extend(self.mkpath(dir))
if f[1] == []:
# If there are no files listed, the user must be
# trying to create an empty directory, so add the
# directory to the list of output files.
self.outfiles.append(dir)
else:
# Copy files, adding them to the list of output files.
for data in f[1]:
data = convert_path(data)
if os.path.islink(data):
# Transplant the link to the new location without changing
# where it points to. (ie it is _not_ relocated).
dest = os.path.join(dir, os.path.basename(data))
if os.path.exists(dest):
os.remove(dest)
os.symlink(os.readlink(data),dest)
log.info("moving link %s -> %s" % (data,dest) )
#os.chmod(dest, os.stat(data)[stat.ST_MODE])
elif os.path.isdir(data):
out = self.copy_tree(data,dir)
self.outfiles.extend(out)
else:
(out, _) = self.copy_file(data, dir)
self.outfiles.append(out)
# Compile the .ui files
install_cmd = self.get_finalized_command('install')
prefix = self.install_dir
if prefix[-1] != os.sep:
prefix = prefix + os.sep
self.outfiles.extend(compile_tqtdesigner(self.outfiles, force=1, prefix=prefix, base_dir=install_cmd.prefix, dry_run=self.dry_run))
# Byte compile the .py files
from distutils.util import byte_compile
byte_compile(self.outfiles, optimize=0, force=1, prefix=prefix, base_dir=install_cmd.prefix, dry_run=self.dry_run)
# Add the .pyc files to the list of outfiles.
self.outfiles.extend( [item+'c' for item in self.outfiles if item.endswith('.py')] )
def mkpath(self, name, mode=0o777):
return dir_util.mkpath(name, mode, dry_run=self.dry_run)
###########################################################################
class InstallExecutableLinks(Command):
description = "Install symlinks"
user_options = []
def initialize_options(self):
self.outfiles = []
def finalize_options(self):
pass
def get_command_name(self):
return 'install_executable_links'
def run(self):
# FIXME add cmd options?
install_script_cmd = self.get_finalized_command('install_scripts')
install_data_cmd = self.get_finalized_command('install_application_data')
destination_dir = install_data_cmd.install_dir
if not os.path.exists(install_script_cmd.install_dir):
self.outfiles.extend(self.mkpath(install_script_cmd.install_dir))
if self.distribution.executable_links is not None:
for link in self.distribution.executable_links:
symname = os.path.join(install_script_cmd.install_dir,link[0])
target = os.path.join(destination_dir,link[1])
log.info("symlinking %s -> %s", symname, target)
if not self.dry_run:
if os.path.islink(symname):
os.remove(symname)
os.symlink(target,symname)
self.outfiles.append(symname)
def get_outputs(self):
return self.outfiles or []
def mkpath(self, name, mode=0o777):
return dir_util.mkpath(name, mode, dry_run=self.dry_run)
###########################################################################
# Fix the --root option for the install_lib command.
class InstallLibWithRoot(install_lib):
user_options = install_lib.user_options[:]
user_options.append( ('root=',None,"install everything relative to this alternate root directory") )
def initialize_options(self):
install_lib.initialize_options(self)
self.root = None
def finalize_options(self):
own_install_dir = self.install_dir is not None
install_lib.finalize_options(self)
self.set_undefined_options('install', ('root', 'root'))
if self.root is not None and own_install_dir:
self.install_dir = change_root(self.root, self.install_dir)
###########################################################################
class Uninstall(Command):
description = "Remove all installed files"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def get_command_name(self):
return 'uninstall'
def run(self):
global INSTALL_LIST
if not os.path.isfile(INSTALL_LIST):
self.announce("Unable to uninstall, can't find the file list %s." % INSTALL_LIST)
return
# Suck in the file list.
fhandle = open(INSTALL_LIST,'r')
file_list = fhandle.readlines()
fhandle.close()
# Remove the files first.
for item in file_list:
item = item.strip()
if os.path.isfile(item) or os.path.islink(item):
self.announce("removing '%s'" % item)
if not self.dry_run:
try:
os.remove(item)
except OSError as details:
self.warn("Could not remove file: %s" % details)
elif not os.path.isdir(item):
self.announce("skipping removal of '%s' (does not exist)" % item)
# Remove the directories.
file_list.sort()
file_list.reverse()
# Starting with the longest paths first.
for item in file_list:
item = item.strip()
if os.path.isdir(item):
self.announce("removing '%s'" % item)
if not self.dry_run:
try:
os.rmdir(item)
except OSError as details:
self.warn("Could not remove directory: %s" % details)
###########################################################################
class BuildKControlModule(Command):
description = "Build KControl extensions"
user_options = [('no-kcontrol',None,"Don't build kcontrol extensions"),
('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'),
('kde-inc-dir=',None,'Directory containing C++ header files for KDE'),
('kde-lib-dir=',None,'Directory containing library files for KDE'),
('kde-kcm-lib-dir=',None,'Directory for KDE kcm library files'),
('tqt-inc-dir=',None,'Directory containing C++ header files for TQt'),
('tqt-lib-dir=',None,'Directory containing library files for TQt'),
('sip-dir=',None,'Directory containing the sip library files'),
('clib=',None,'gcc library and path'),
('pytqt-dir=',None,'PyTQt module directory'),
('pytde-dir=',None,'PyTDE module directory'),
('data-dir=',None,'installation directory for data (script) files')]
def initialize_options(self):
self.no_kcontrol = 0
self.build_dir = None
self.python_inc_dir = None
self.python_dir = None
self.kde_inc_dir = None
self.kde_lib_dir = None
self.kde_kcm_lib_dir = None
self.tqt_inc_dir = None
self.tqt_lib_dir = None
self.sip_dir = None
self.clib = None
self.pytqt_dir = None
self.pytde_dir = None
self.data_dir = None
def finalize_options(self):
if self.no_kcontrol==0:
self.set_undefined_options('install', ('build_base', 'build_dir'),('install_application_data','data_dir'))
install = self.get_finalized_command('install')
self.install_prefix = ask_kde_config('--prefix').strip()
# KDE inc dir: find it!
if self.kde_inc_dir is None:
canidatepaths = []
tdedir = os.getenv("TDEDIR")
if tdedir!=None:
canidatepaths.append(os.path.join(tdedir,"include"))
canidatepaths.append(os.path.join(install.prefix,"include"))
canidatepaths.append(os.path.join(self.install_prefix,'include'))
canidatepaths.append(os.path.join(self.install_prefix,'include','tde'))
self.kde_inc_dir = FindFileInPaths('tdeapplication.h',canidatepaths)
if self.kde_inc_dir is None:
raise SystemExit("Failed to find the TDE header file directory.")
if FindFileInPaths('tdeapplication.h',[self.kde_inc_dir]) is None:
raise SystemExit("Failed to find TDE header files in: %s" % self.kde_inc_dir)
self.announce("Using %s for KDE header files" % self.kde_inc_dir)
# KDE lib dir
if self.kde_lib_dir is None:
self.kde_lib_dir = os.path.join(self.install_prefix,"lib")
self.announce("Using %s for KDE library files" % self.kde_lib_dir)
# KDE KCM lib dir
if self.kde_kcm_lib_dir is None:
self.kde_kcm_lib_dir = os.path.join(self.kde_lib_dir,"trinity")
if FindFileInPaths('*kcm*.so',[self.kde_kcm_lib_dir]) is None:
raise SystemExit("Failed to find TDE KCM files in: %s" % self.kde_kcm_lib_dir)
self.announce("Using %s for KDE KCM library files" % self.kde_kcm_lib_dir)
# TQt inc dir
if self.tqt_inc_dir is None:
canidatepaths = []
tqtinc = os.getenv("TQTINC")
if tqtinc != None:
canidatepaths.append(tqtinc)
tqtdir = os.getenv("TQTDIR")
if tqtdir != None:
canidatepaths.append(os.path.join(tqtdir,"include"))
canidatepaths.append(os.path.join(install.prefix,"lib/tqt3/include"))
canidatepaths.append(os.path.join(install.prefix,"include"))
canidatepaths.append("/opt/tqt3/include")
canidatepaths.append("/usr/include/tqt3")
self.tqt_inc_dir = FindFileInPaths('ntqstring.h',canidatepaths)
if self.tqt_inc_dir is None:
self.tqt_inc_dir = FindFileInPaths('tqstring.h',canidatepaths)
if self.tqt_inc_dir is None:
raise SystemExit("Failed to find the TQt header file directory")
if FindFileInPaths('ntqstring.h',[self.tqt_inc_dir]) is None:
if FindFileInPaths('tqstring.h',[self.tqt_inc_dir]) is None:
raise SystemExit("Failed to find TQt header files in: %s" % self.tqt_inc_dir)
self.announce("Using %s for TQt header files" % self.tqt_inc_dir)
# TQt lib dir
if self.tqt_lib_dir is None:
canidatepaths = []
tqtlib = os.getenv("TQTLIB")
if tqtlib != None:
canidatepaths.append(tqtlib)
tqtdir = os.getenv("TQTDIR")
if tqtdir != None:
canidatepaths.append(os.path.join(tqtdir,get_libdir_name()))
canidatepaths.append(os.path.join(install.prefix,"lib/tqt3/"+get_libdir_name()))
canidatepaths.append(os.path.join(install.prefix,"lib/tqt3/"+get_libdir_name()))
canidatepaths.append(os.path.join(install.prefix,get_libdir_name()))
canidatepaths.append("/opt/tqt3/"+get_libdir_name())
canidatepaths.append("/opt/tqt/"+get_libdir_name())
canidatepaths.append("/opt/tqt/lib/"+get_libdir_name())
canidatepaths.append("/opt/tqt3/lib/"+get_libdir_name())
self.tqt_lib_dir = FindFileInPaths('libtqt*',canidatepaths)
if self.tqt_lib_dir is None:
canidatepaths = []
tqtlib = os.getenv("TQTLIB")
if tqtlib != None:
canidatepaths.append(tqtlib)
tqtdir = os.getenv("TQTDIR")
if tqtdir != None:
canidatepaths.append(os.path.join(tqtdir,get_libdir_name()))
canidatepaths.append(os.path.join(install.prefix,"lib/tqt3/"+get_libdir_name()))
canidatepaths.append(os.path.join(install.prefix,get_libdir_name()))
canidatepaths.append("/opt/tqt3/"+get_libdir_name())
canidatepaths.append("/opt/tqt3/lib/"+get_libdir_name())
self.tqt_lib_dir = FindFileInPaths('libtqt*',canidatepaths)
if self.tqt_lib_dir is None:
raise SystemExit("Failed to find TQt library files")
self.announce("Using %s for TQt library files" % self.tqt_lib_dir)
# 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)
# PyTQt dir
if self.pytqt_dir is None:
self.pytqt_dir = FindFileInPaths("PyTQt", sys.path)
if self.pytqt_dir is None:
self.pytqt_dir = os.path.join(sysconfig.get_python_lib(), 'PyTQt')
if (FindFileInPaths("libtqtcmodule*",[self.pytqt_dir]) is None) and (FindFileInPaths("tqt*",[self.pytqt_dir]) is None):
raise SystemExit("Failed to find the PyTQt directory: %s" % self.pytqt_dir)
self.announce("Using %s for PyTQt modules" % self.pytqt_dir)
# PyTDE dir
if self.pytde_dir is None:
self.pytde_dir = sysconfig.get_python_lib()
if (FindFileInPaths("libtdecorecmodule*",[self.pytde_dir]) is None) and (FindFileInPaths("tdecore*",[self.pytde_dir]) is None):
raise SystemExit("Failed to find the PyTDE directory: %s" % self.pytde_dir)
self.announce("Using %s for PyTDE modules" % self.pytde_dir)
# Sip dir
if self.sip_dir is None:
self.sip_dir = os.path.dirname(FindFileInPaths("sip_tqt*", sys.path))
if self.sip_dir is None:
self.sip_dir = sysconfig.get_python_lib()
if (FindFileInPaths("libsip_tqt*", [self.sip_dir]) is None) and (FindFileInPaths("sip_tqt*", [self.sip_dir]) is None):
raise SystemExit("Failed to find libsip files in directory: %s" % self.sip_dir)
self.announce("Using %s for libsip files" % self.sip_dir)
# Find the C library (libgcc, libgcc_s or some other variation).
if self.clib is None:
canidatepaths = ["/usr/"+get_libdir_name(), "/usr/local/"+get_libdir_name(), "/usr/lib" ]
self.clib = FindFileInPaths("libgcc*.so",canidatepaths)
if self.clib!=None:
self.clib = glob.glob(os.path.join(self.clib,'libgcc*.so'))[0]
else:
self.clib = 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("tdedistutils.py (1): 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_kcm'
def run(self):
if self.no_kcontrol:
self.announce("Skipping KControl modules")
return
if not os.path.isdir(self.build_dir):
os.mkdir(self.build_dir)
for moduletuple in self.distribution.kcontrol_modules:
self.announce("Building KControl module from desktop file %s." % moduletuple[0])
# Read the desktop file
factoryfunction = None
libraryname = None
cmodulecategory = None
try:
fhandle = open(moduletuple[0],'r')
for line in fhandle.readlines():
parts = line.strip().split('=')
try:
if parts[0]=="X-TDE-Library":
libraryname = parts[1]
elif parts[0]=="Exec":
shellcmd = parts[1].split()
modulepath = shellcmd[-1]
if '/' in modulepath:
cmodulecategory = os.path.dirname(modulepath)
else:
cmodulecategory = ""
elif parts[0]=="X-TDE-FactoryName":
factoryfunction = 'create_'+parts[1]
except IndexError:
pass
fhandle.close()
except IOError:
raise SystemExit("Failed to find kcontrol desktop file: %s" % moduletuple[0])
# Sanity check.
if factoryfunction is None:
raise SystemExit("Failed to find factory name (Was there a X-TDE-FactoryName entry in the desktop file?)")
if libraryname is None:
raise SystemExit("Failed to find library name (Was there a X-TDE-Library entry in the desktop file?)")
if cmodulecategory is None:
raise SystemExit("Failed to find the kcontrol category name (Was there a Exec entry in the desktop file?)")
modulename = os.path.basename(moduletuple[1])
if modulename.endswith('.py'):
modulename = modulename[:-3]
desktopfilename = moduletuple[0]
stub_cpp_name = 'kcm_'+libraryname+'.cpp'
stub_so_name = 'kcm_'+libraryname+'.so'
stub_la_name = 'kcm_'+libraryname+'.la'
python_version = '%i.%i' % (sys.version_info[0],sys.version_info[1])
# Build the 'stub' code.
cppcode = self.cpptemplate % {"moduledir": self.data_dir,
"extramodule": os.getenv("EXTRA_MODULE_DIR"),
"modulename": modulename,
"factoryfunction": factoryfunction,
"python_version": python_version}
# Put it on disk.
cppfile = os.path.join(os.path.dirname(moduletuple[0]),stub_cpp_name)
try:
fhandle = open(cppfile,'w')
fhandle.write(cppcode)
fhandle.close()
except IOError:
raise SystemExit("Could not write the C++ stub: %s" % cppfile)
# Compile the stub 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'])
#cmdlist.extend(sysconfig.get_config_var("CXX").split())
# 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'])
#sysconfig.get_config_var("CFLAGS").split()
# includes
cmdlist.append("-I" + sysconfig.get_config_var("INCLUDEDIR"))
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("-I" + self.kde_inc_dir)
cmdlist.append("-I" + self.kde_inc_dir + "/tde")
cmdlist.append("-I" + self.tqt_inc_dir)
cmdlist.append("-I/usr/include/tqt")
cmdlist.append("-I.")
# input
cmdlist.append(cppfile)
# output
outputfile = os.path.join(self.build_dir,libraryname+'.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("-avoid-version")
cmdlist.append("-shared")
cmdlist.append("-export-dynamic")
# object
cmdlist.append(outputfile)
cmdlist.append("-rpath"); cmdlist.append(self.kde_kcm_lib_dir)
cmdlist.append("-o"); cmdlist.append(os.path.join(self.build_dir,stub_la_name))
# Link libs
linklist = []
linklist.append("-lpython%s%s" % (python_version, sys.abiflags))
linklist.extend(sysconfig.get_config_var("LIBS").split())
# FIXME I doubt half of these libraries need to be here.
linklist.append(self.sip_dir+"/sip_tqt.so")
# PyTQt libs
linklist.append(self.pytqt_dir+"/tqt.so")
# PyTDE libs
linklist.append(self.pytde_dir+"/tdecore.so")
linklist.append(self.pytde_dir+"/tdeui.so")
# linklist.append("-L"+self.sip_dir); linklist.append("-lsip_tqt")
# # PyTQt libs
# linklist.append("-L"+self.pytqt_dir); linklist.append("-lqtcmodule")
# # PyTDE libs
# linklist.append("-L"+self.pytde_dir); linklist.append("-ltdecorecmodule"); linklist.append("-ltdeuicmodule")
linklist.append("-L"+self.kde_lib_dir); linklist.append("-L/opt/trinity/lib"); linklist.append("-ltdecore"); linklist.append("-lpythonize")
linklist.append("-L"+self.tqt_lib_dir); linklist.append("-ltqt-mt")
linklist.append("-lm")
linklist.append("-lc")
linklist.append(self.clib)
linklist.append("-R"); linklist.append(self.python_dir)
linklist.append("-R"); linklist.append(self.tqt_lib_dir)
linklist.append("-R"); linklist.append(self.sip_dir)
linklist.append("-R"); linklist.append(self.pytqt_dir)
linklist.append("-R"); linklist.append(self.pytde_dir)
linklist.append("-R"); linklist.append(self.kde_lib_dir)
cmdlist.extend(linklist)
spawn(cmdlist) # Execute!!
print()
cpptemplate = r"""
/*
* pykcm_launcher.cpp
*
* Launch Control Centre modules written in Python using an embedded Python
* interpreter.
* Based on David Boddie's PyTDE-components.
*/
// pythonize.h must be included first.
#include <pythonize.h>
#include <tdecmodule.h>
#include <tdeglobal.h>
#include <tdelocale.h>
#include <klibloader.h>
#include <kstandarddirs.h>
#include <ksimpleconfig.h>
#include <tqstring.h>
#include <sip-tqt.h>
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif // _GNU_SOURCE
#include <dlfcn.h>
#define MODULE_DIR "%(moduledir)s"
#define EXTRA_MODULE_DIR "%(extramodule)s"
#define MODULE_NAME "%(modulename)s"
#define FACTORY "%(factoryfunction)s"
#define CPP_FACTORY %(factoryfunction)s
#define debug 1
static TDECModule *report_error(const char *msg) {
if (debug) printf ("error: %%s\n", msg);
return NULL;
}
static TDECModule* return_instance( TQWidget *parent, const char *name ) {
TDECModule* tdecmodule;
PyObject *pyTDECModuleTuple;
PyObject *pyTDECModule;
Pythonize *pyize; // Pythonize object to manage the Python interpreter.
// Try to determine what py script we're loading. Note that "name"
// typically appears to be NULL.
TQString script(MODULE_NAME);
// Reload this module, but this time tell the runtime linker to make the
// symbols global and available for later loaded libraries/module.
Dl_info info;
if (!dladdr((const void *)(&return_instance), &info) || !info.dli_fname || !dlopen(info.dli_fname, RTLD_GLOBAL|RTLD_NOW)) {
return report_error ("***Unable to export symbols\n");
}
// Start the interpreter.
pyize = initialize();
if (!pyize) {
return report_error ("***Failed to start interpreter\n");
}
// Add the path to the python script to the interpreter search path.
TQString path = TQString(MODULE_DIR);
if(path == TQString::null) {
return report_error ("***Failed to locate script path");
}
if(!pyize->appendToSysPath (path.latin1 ())) {
return report_error ("***Failed to set sys.path\n");
}
// Add the extra path to the python script to the interpreter search path.
TQString extrapath = TQString(EXTRA_MODULE_DIR);
if(!pyize->appendToSysPath (extrapath.latin1 ())) {
return report_error ("***Failed to set extra sys.path\n");
}
// Load the Python script.
PyObject *pyModule = pyize->importModule ((char *)script.latin1 ());
if(!pyModule) {
PyErr_Print();
return report_error ("***failed to import module\n");
}
// Inject a helper function
TQString bridge = TQString("import sip_tqt\n"
"from PyTQt import tqt\n"
"def kcontrol_bridge_" FACTORY "(parent,name):\n"
" if parent!=0:\n"
" wparent = sip_tqt.wrapinstance(parent,tqt.TQWidget)\n"
" else:\n"
" wparent = None\n"
" inst = " FACTORY "(wparent, name)\n"
" return (inst,sip_tqt.unwrapinstance(inst))\n");
PyRun_String(bridge.latin1(),Py_file_input,PyModule_GetDict(pyModule),PyModule_GetDict(pyModule));
// Get the Python module's factory function.
PyObject *kcmFactory = pyize->getNewObjectRef(pyModule, "kcontrol_bridge_" FACTORY);
if(!kcmFactory) {
return report_error ("***failed to find module factory\n");
}
// Call the factory function. Set up the args.
PyObject *pyParent = PyLong_FromVoidPtr(parent);
PyObject *pyName = PyBytes_FromString(MODULE_NAME);
// Using NN here is effect gives our references to the arguement away.
PyObject *args = Py_BuildValue ("NN", pyParent, pyName);
if(pyName && pyParent && args) {
// run the factory function
pyTDECModuleTuple = pyize->runFunction(kcmFactory, args);
if(!pyTDECModuleTuple) {
PyErr_Print();
return report_error ("*** runFunction failure\n;");
}
} else {
return report_error ("***failed to create args\n");
}
// cleanup a bit
pyize->decref(args);
pyize->decref(kcmFactory);
// Stop this from getting garbage collected.
Py_INCREF(PyTuple_GET_ITEM(pyTDECModuleTuple,0));
// convert the TDECModule PyObject to a real C++ TDECModule *.
pyTDECModule = PyTuple_GET_ITEM(pyTDECModuleTuple,1);
tdecmodule = (TDECModule *)PyLong_AsVoidPtr(pyTDECModule);
if(!tdecmodule) {
return report_error ("***failed sip-tqt conversion to C++ pointer\n");
}
pyize->decref(pyTDECModuleTuple);
// PyTDE can't run the module without this - Pythonize
// grabs the lock at initialization and we have to give
// it back before exiting. At this point, we no longer need
// it.
//pyize->releaseLock ();
// take care of any translation info
TDEGlobal::locale()->insertCatalogue(script);
// Return the pointer to our new TDECModule
return tdecmodule;
}
extern "C" {
// Factory function that kcontrol will call.
TDECModule* CPP_FACTORY(TQWidget *parent, const char *name) {
return return_instance(parent, name);
}
}
"""
###########################################################################
class InstallKControlModule(Command):
description = "Install Kcontrol module files"
user_options = [
('install-dir=', 'd', "base directory for installing kcontrol module files"),
('install-cmd=', None, "Command to use to install the files"),
('xdg-apps-dir=',None,"directory for XDG app files"),
('build-dir=','b', "build directory (where to install from)"),
('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.build_dir = None
self.install_dir = None
self.install_cmd = None
self.xdg_apps_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_xdg_apps_dir = self.xdg_apps_dir is not None
self.set_undefined_options('install',
('build_base', 'build_dir'),
('install_kcm', 'install_dir'),
('install_xdg_apps','xdg_apps_dir'),
('root', 'root'),
('force', 'force'),
('skip_build', 'skip_build'),
('install_cmd', 'install_cmd')
)
if own_install_dir and self.root is not None:
self.install_dir = change_root(self.root,self.installdir)
if own_xdg_apps_dir and self.root is not None:
self.xdg_apps_dir = change_root(self.root,self.xdg_apps_dir)
def get_command_name(self):
return 'install_kcm'
def run(self):
if not self.skip_build:
self.run_command('build_kcm')
self.announce("Installing Kcontrol module files...")
for moduletuple in self.distribution.kcontrol_modules:
self.announce("Building KControl module from desktop file %s." % moduletuple[0])
# Read the desktop file
libraryname = None
cmodulecategory = None
try:
fhandle = open(moduletuple[0],'r')
for line in fhandle.readlines():
parts = line.strip().split('=')
try:
if parts[0]=="X-TDE-Library":
libraryname = parts[1]
elif parts[0]=="Exec":
shellcmd = parts[1].split()
modulepath = shellcmd[-1]
if '/' in modulepath:
cmodulecategory = os.path.dirname(modulepath)
else:
cmodulecategory = ""
except IndexError:
pass
fhandle.close()
except IOError:
raise SystemExit("Failed to find kcontrol desktop file: %s" % moduletuple[0])
if libraryname is None:
raise SystemExit("Failed to find library name (Was there a X-TDE-Library entry in the desktop file?)")
if cmodulecategory is None:
raise SystemExit("Failed to find the kcontrol category name (Was there a Exec entry in the desktop file?)")
desktopfilename = moduletuple[0]
self.outfiles.extend(self.mkpath(self.xdg_apps_dir))
desktopfile_dest = os.path.join(self.xdg_apps_dir,os.path.basename(desktopfilename))
self.copy_file(desktopfilename, desktopfile_dest)
stub_la_name = 'kcm_'+libraryname+'.la'
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,stub_la_name))
cmdlist.append(os.path.join(self.install_dir,stub_la_name))
spawn(cmdlist) # Execute!!
print()
self.outfiles = [os.path.join(self.install_dir,os.path.basename(file)) for file in glob.glob(os.path.join(self.build_dir,'.libs','kcm_'+libraryname+'*'))]
self.outfiles.append(desktopfile_dest)
self.announce("Done installing Kcontrol module files.")
def get_outputs(self):
return self.outfiles or []
def mkpath(self, name, mode=0o777):
return dir_util.mkpath(name, mode, dry_run=self.dry_run)
###########################################################################
class BuildDocbookHTML(Command):
description = "Build Docbook HTML documentation"
user_options = [('meinproc-exe=',None,"Path to the meinproc executable")]
def initialize_options(self):
self.html_prefix = None
self.meinproc_exe = None
def finalize_options(self):
self.set_undefined_options('build', ('meinproc_exe', 'meinproc_exe') )
def get_command_name(self):
return 'build_docbook'
def run(self):
for docbook_tuple in self.distribution.docbooks:
input_dir = docbook_tuple[0]
language_code = docbook_tuple[1]
self.announce("Building Docbook documentation from directory %s." % input_dir)
indexdoc_file_name = os.path.join(input_dir,'index.docbook')
if not os.path.exists(indexdoc_file_name):
raise SystemExit("File %s is missing." % indexdoc_file_name)
cwd = os.getcwd()
os.chdir(input_dir)
try:
spawn([self.meinproc_exe,"--check","--cache",'index.cache.bz2', 'index.docbook'])
spawn([self.meinproc_exe, 'index.docbook'])
finally:
os.chdir(cwd)
###########################################################################
class InstallDocbookHTML(Command):
description = "Install Docbook HTML files"
user_options = [
('install-dir=', 'd',"base directory for installing docbook HTML 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.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
self.set_undefined_options('install',
('install_html', 'install_dir'),
('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.installdir)
def get_command_name(self):
return 'install_html'
def run(self):
if not self.skip_build:
self.run_command('build_html')
self.announce("Installing HTML files...")
counter = 0
for docbook_tuple in self.distribution.docbooks:
input_dir = docbook_tuple[0]
language_code = docbook_tuple[1]
self.announce("Install Docbook documentation from directory %s." % input_dir)
source_file = os.path.join(input_dir,'index.cache.bz2')
if not os.path.exists(source_file):
raise SystemExit("File %s is missing." % source_file)
dest_path = os.path.join(self.install_dir, language_code, self.distribution.metadata.name)
self.outfiles.extend(self.mkpath(dest_path))
dest_file = os.path.join(dest_path,'index.cache.bz2')
self.copy_file(source_file, dest_file)
self.outfiles.append(dest_file)
counter += 1
# Also install any lose HTML files.
for source_file in glob.glob(os.path.join(input_dir,'*.html')):
htmlfile = os.path.basename(source_file)
dest_file = os.path.join(dest_path,htmlfile)
self.copy_file(source_file, dest_file)
self.outfiles.append(dest_file)
counter += 1
if len(docbook_tuple)==3:
extra_files = docbook_tuple[2]
for file in extra_files:
source_file = os.path.join(input_dir,file)
dest_file = os.path.join(self.install_dir, language_code, self.distribution.metadata.name,file)
self.copy_file(source_file, dest_file)
self.outfiles.append(dest_file)
counter += 1
self.announce("Done installing %i HTML files." % counter)
def get_outputs(self):
return self.outfiles or []
def mkpath(self, name, mode=0o777):
return dir_util.mkpath(name, mode, dry_run=self.dry_run)
###########################################################################
class UpdateI18NMessages(Command):
description = "Extract and update messages for translation"
user_options = [('xgettext-exe=',None,'Full path to the xgetext executable'),\
('kde-pot=',None,'Location of the the KDE pot file'),\
('msgmerge-exe=',None,'Full path to the msgmerge executable')]
def initialize_options(self):
self.xgettext_exe = None
self.msgmerge_exe = None
self.kde_pot = None
def finalize_options(self):
if self.xgettext_exe is None:
install = self.get_finalized_command('install')
canidate_paths = []
if install.user_supplied_kde_prefix:
canidate_paths.append(os.path.join(install.kde_prefix,'bin'))
self.announce("Detecting xgettext...")
canidate_paths.append(ask_kde_config('--install exe --expandvars').strip())
self.xgettext_exe = FindExeOnPath('xgettext',canidate_paths)
if self.xgettext_exe is None:
raise SystemExit("Unable to find 'xgettext'.")
self.announce(" ...xgettext found at %s" % self.xgettext_exe)
if self.msgmerge_exe is None:
install = self.get_finalized_command('install')
canidate_paths = []
if install.user_supplied_kde_prefix:
canidate_paths.append(os.path.join(install.kde_prefix,'bin'))
self.announce("Detecting msgmerge...")
canidate_paths.append(ask_kde_config('--install exe --expandvars').strip())
self.msgmerge_exe = FindExeOnPath('msgmerge',canidate_paths)
if self.msgmerge_exe is None:
raise SystemExit("Unable to find 'xgettext'.")
self.announce(" ...msgmerge found at %s" % self.msgmerge_exe)
if self.kde_pot is None:
self.announce("Detecting kde.pot...")
canidatepaths = []
tdedir = os.getenv("TDEDIR")
if tdedir!=None:
canidatepaths.append(os.path.join(tdedir,"include"))
install = self.get_finalized_command('install')
canidatepaths.append(os.path.join(install.kde_prefix,"include"))
canidatepaths.append('/opt/trinity/include')
canidatepaths.append('/opt/kde/include')
kde_pot_dir = FindFileInPaths('kde.pot',canidatepaths)
if kde_pot_dir is None:
raise SystemExit("Failed to find the kde.pot file.")
self.kde_pot = os.path.join(kde_pot_dir,'kde.pot')
self.announce(" ...kde.pot found at %s" % self.kde_pot)
def get_command_name(self):
return 'update_messages'
def run(self):
if self.distribution.i18n is None: return
self.announce("Extracting and merging i18n messages...")
po_dir = self.distribution.i18n[0]
# FIXME : .rc and .ui files
input_files = []
# Compile any UI files
for dir in self.distribution.i18n[1]:
for file in glob.glob(os.path.join(dir,'*.ui')):
tqtuicompiler.UpdateUI(file,kde=True)
# Fetch all of the python files.
for dir in self.distribution.i18n[1]:
input_files.extend(glob.glob(os.path.join(dir,'*.py')))
target_pot = os.path.join(po_dir,self.distribution.metadata.name+".pot")
cmd = [self.xgettext_exe, '-o', target_pot, '-ki18n', '-ktr2i18n', \
'-kI18N_NOOP', '-ktranslate', '-kaliasLocale','-x',self.kde_pot]
cmd.extend(input_files)
spawn(cmd)
for po_file in glob.glob(os.path.join(po_dir,'*.po')):
temp_po = po_file + '.temp'
cmd = [self.msgmerge_exe,'-q','-o',temp_po,po_file,target_pot]
spawn(cmd)
os.rename(temp_po,po_file)
self.announce("Finished with i18n messages.")
###########################################################################
class BuildI18NMessages(Command):
description = "Build i18n messages"
user_options = [('msgfmt-exe=',None,'Path to the msgfmt executable')]
def initialize_options(self):
self.msgfmt_exe = None
def finalize_options(self):
self.set_undefined_options('build', ('msgfmt_exe', 'msgfmt_exe'))
def get_command_name(self):
return 'build_messages'
def run(self):
if self.distribution.i18n is None: return
self.announce("Building i18n messages...")
po_dir = self.distribution.i18n[0]
i = 0
for po_file in [file for file in os.listdir(po_dir) if file.endswith('.po')]:
source = os.path.join(po_dir,po_file)
target = source[:-3]+'.gmo'
cmd = [self.msgfmt_exe,'-o',target, source]
spawn(cmd)
i += 1
self.announce("Done building %i i18n messages." % i)
###########################################################################
class InstallI18NMessages(Command):
description = "Install messages"
user_options = [
('install-dir=', 'd',"base directory for installing message files (default: installation base dir)"),
('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.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
self.set_undefined_options('install',
('install_messages', 'install_dir'),
('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.installdir)
def get_command_name(self):
return 'install_messages'
def run(self):
if not self.skip_build:
self.run_command('build_messages')
self.announce("Installing i18n messages...")
po_dir = self.distribution.i18n[0]
counter = 0
for po_file in os.listdir(po_dir):
if po_file.endswith('.po'):
source_file = os.path.join(po_dir,po_file[:-3]) + '.gmo'
# Setup installation of the translation file.
dest_path = os.path.join(self.install_dir, po_file[:-3],'LC_MESSAGES')
self.outfiles.extend(self.mkpath(dest_path))
dest_file = os.path.join(dest_path, self.distribution.metadata.name+'.mo')
self.copy_file(source_file, dest_file)
self.outfiles.append(dest_file)
counter += 1
self.announce("Done installing %i i18n messages." % counter)
def get_outputs(self):
return self.outfiles
def mkpath(self, name, mode=0o777):
return dir_util.mkpath(name, mode, dry_run=self.dry_run)
###########################################################################
class BuildTdeioslave(Command):
description = "Build Tdeioslaves"
user_options = [('no-tdeioslave',None,"Don't build tdeioslaves"),
('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'),
('kde-inc-dir=',None,'Directory containing C++ header files for KDE'),
('kde-lib-dir=',None,'Directory containing library files for KDE'),
('kde-tdeioslave-lib-dir=',None,'Directory for KDE tdeioslave library files'),
('kde-protocol-dir=',None,'Directory for KDE tdeioslave protocol files'),
('tqt-inc-dir=',None,'Directory containing C++ header files for TQt'),
('tqt-lib-dir=',None,'Directory containing library files for TQt'),
('sip-dir=','/usr/lib/pyshared/python*','Directory containing the sip library files'),
('clib=',None,'gcc library and path'),
('pytqt-dir=','/usr/lib/pyshared/python*','PyTQt module directory'),
('pytde-dir=',None,'PyTDE module directory'),
('data-dir=',None,'installation directory for data (script) files')]
def initialize_options(self):
self.no_tdeioslave = 0
self.build_dir = None
self.python_inc_dir = None
self.python_dir = None
self.kde_inc_dir = None
self.kde_lib_dir = None
self.kde_tdeioslave_lib_dir = None
self.kde_protocol_dir = None
self.tqt_inc_dir = None
self.tqt_lib_dir = None
self.sip_dir = None
self.clib = None
self.pytqt_dir = None
self.pytde_dir = None
self.data_dir = None
def finalize_options(self):
if self.no_tdeioslave==0:
self.set_undefined_options('install', ('build_base', 'build_dir'),('install_application_data','data_dir'))
install = self.get_finalized_command('install')
self.install_prefix = ask_kde_config('--prefix').strip()
# KDE inc dir: find it!
if self.kde_inc_dir is None:
canidatepaths = []
tdedir = os.getenv("TDEDIR")
if tdedir!=None:
canidatepaths.append(os.path.join(tdedir,"include"))
canidatepaths.append(os.path.join(install.prefix,"include"))
canidatepaths.append(os.path.join(self.install_prefix,'include'))
canidatepaths.append(os.path.join(self.install_prefix,'include','tde'))
self.kde_inc_dir = FindFileInPaths('tdeapplication.h',canidatepaths)
if self.kde_inc_dir is None:
raise SystemExit("Failed to find the TDE header file directory.")
if FindFileInPaths('tdeapplication.h',[self.kde_inc_dir]) is None:
raise SystemExit("Failed to find TDE header files in: %s" % self.kde_inc_dir)
self.announce("Using %s for KDE header files" % self.kde_inc_dir)
# KDE lib dir
if self.kde_lib_dir is None:
self.kde_lib_dir = os.path.join(self.install_prefix,"lib")
self.announce("Using %s for KDE library files" % self.kde_lib_dir)
# KDE tdeioslave lib dir
if self.kde_tdeioslave_lib_dir is None:
self.kde_tdeioslave_lib_dir = os.path.join(self.kde_lib_dir,"trinity")
if FindFileInPaths('tdeio_*.so',[self.kde_tdeioslave_lib_dir]) is None:
raise SystemExit("Failed to find TDE Tdeioslave library files in: %s" % self.kde_tdeioslave_lib_dir)
self.announce("Using %s for KDE Tdeioslave library files" % self.kde_tdeioslave_lib_dir)
# TQt inc dir
if self.tqt_inc_dir is None:
canidatepaths = []
tqtinc = os.getenv("TQTINC")
if tqtinc != None:
canidatepaths.append(tqtinc)
tqtdir = os.getenv("TQTDIR")
if tqtdir != None:
canidatepaths.append(os.path.join(tqtdir,"include"))
canidatepaths.append(os.path.join(install.prefix,"lib/tqt3/include"))
canidatepaths.append(os.path.join(install.prefix,"include"))
canidatepaths.append("/opt/tqt3/include")
canidatepaths.append("/opt/tqt3/lib/include")
self.tqt_inc_dir = FindFileInPaths('ntqstring.h',canidatepaths)
if self.tqt_inc_dir is None:
self.tqt_inc_dir = FindFileInPaths('tqstring.h',canidatepaths)
if self.tqt_inc_dir is None:
raise SystemExit("Failed to find the TQt header file directory")
if FindFileInPaths('ntqstring.h',[self.tqt_inc_dir]) is None:
if FindFileInPaths('tqstring.h',[self.tqt_inc_dir]) is None:
raise SystemExit("Failed to find TQt header files in: %s" % self.tqt_inc_dir)
self.announce("Using %s for TQt header files" % self.tqt_inc_dir)
# TQt lib dir
if self.tqt_lib_dir is None:
canidatepaths = []
tqtlib = os.getenv("TQTLIB")
if tqtlib != None:
canidatepaths.append(tqtlib)
tqtdir = os.getenv("TQTDIR")
if tqtdir != None:
canidatepaths.append(os.path.join(tqtdir,get_libdir_name()))
canidatepaths.append(os.path.join(install.prefix,"lib/tqt3/"+get_libdir_name()))
canidatepaths.append(os.path.join(install.prefix,"lib/tqt3/"+get_libdir_name()))
canidatepaths.append(os.path.join(install.prefix,get_libdir_name()))
canidatepaths.append("/opt/tqt3/"+get_libdir_name())
canidatepaths.append("/opt/tqt/"+get_libdir_name())
canidatepaths.append("/opt/tqt/lib/"+get_libdir_name())
canidatepaths.append("/opt/tqt3/lib/"+get_libdir_name())
self.tqt_lib_dir = FindFileInPaths('libtqt*',canidatepaths)
if self.tqt_lib_dir is None:
canidatepaths = []
tqtlib = os.getenv("TQTLIB")
if tqtlib != None:
canidatepaths.append(tqtlib)
tqtdir = os.getenv("TQTDIR")
if tqtdir != None:
canidatepaths.append(os.path.join(tqtdir,get_libdir_name()))
canidatepaths.append(os.path.join(install.prefix,"lib/tqt3/"+get_libdir_name()))
canidatepaths.append(os.path.join(install.prefix,get_libdir_name()))
canidatepaths.append("/opt/tqt3/"+get_libdir_name())
canidatepaths.append("/opt/tqt3/lib/"+get_libdir_name())
self.tqt_lib_dir = FindFileInPaths('libtqt*',canidatepaths)
if self.tqt_lib_dir is None:
raise SystemExit("Failed to find TQt library files")
self.announce("Using %s for TQt library files" % self.tqt_lib_dir)
# 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)
# PyTQt dir
if self.pytqt_dir is None:
self.pytqt_dir = FindFileInPaths("PyTQt", sys.path)
if self.pytqt_dir is None:
self.pytqt_dir = os.path.join(sysconfig.get_python_lib(), 'PyTQt')
if (FindFileInPaths("libtqtcmodule*",[self.pytqt_dir]) is None) and (FindFileInPaths("tqt*",[self.pytqt_dir]) is None):
raise SystemExit("Failed to find the PyTQt directory: %s" % self.pytqt_dir)
self.announce("Using %s for PyTQt modules" % self.pytqt_dir)
# PyTDE dir
if self.pytde_dir is None:
self.pytde_dir = sysconfig.get_python_lib()
if (FindFileInPaths("libtdecorecmodule*",[self.pytde_dir]) is None) and (FindFileInPaths("tdecore*",[self.pytde_dir]) is None):
raise SystemExit("Failed to find the PyTDE directory: %s" % self.pytde_dir)
self.announce("Using %s for PyTDE modules" % self.pytde_dir)
# Sip dir
if self.sip_dir is None:
self.sip_dir = os.path.dirname(FindFileInPaths("sip_tqt*", sys.path))
if self.sip_dir is None:
self.sip_dir = sysconfig.get_python_lib()
if (FindFileInPaths("libsip_tqt*", [self.sip_dir]) is None) and (FindFileInPaths("sip_tqt*", [self.sip_dir]) is None):
raise SystemExit("Failed to find libsip files in directory: %s" % self.sip_dir)
self.announce("Using %s for libsip files" % self.sip_dir)
# Find the C library (libgcc, libgcc_s or some other variation).
if self.clib is None:
canidatepaths = ["/usr/"+get_libdir_name(), "/usr/local/"+get_libdir_name() ]
self.clib = FindFileInPaths("libgcc*.so",canidatepaths)
if self.clib!=None:
self.clib = glob.glob(os.path.join(self.clib,'libgcc*.so'))[0]
else:
self.clib = 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("tdedistutils.py (2): 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_tdeioslave'
def run(self):
if self.no_tdeioslave:
self.announce("Skipping TDEIO Slaves")
return
if not os.path.isdir(self.build_dir):
os.mkdir(self.build_dir)
for moduletuple in self.distribution.tdeioslaves:
self.announce("Building TDEIO Slave from protocol file %s." % moduletuple[0])
protocolfilename = moduletuple[0]
# Read the protocol file
libraryname = None
try:
fhandle = open(protocolfilename,'r')
for line in fhandle.readlines():
parts = line.strip().split('=')
try:
if parts[0]=="exec":
libraryname = parts[1]
except IndexError:
pass
fhandle.close()
except IOError:
raise SystemExit("Failed to find tdeioslave protocol file: %s" % moduletuple[0])
# Sanity check.
if libraryname is None:
raise SystemExit("Failed to find library name (Was there a exec entry in the protocol file?)")
modulename = os.path.basename(moduletuple[1])
if modulename.endswith('.py'):
modulename = modulename[:-3]
stub_cpp_name = libraryname+'.cpp'
stub_so_name = libraryname+'.so'
stub_la_name = libraryname+'.la'
python_version = '%i.%i' % (sys.version_info[0],sys.version_info[1])
# Build the 'stub' code.
cppcode = self.cpptemplate % {"moduledir": self.data_dir,
"modulename": modulename,
"python_version": python_version}
# Put it on disk.
cppfile = os.path.join(os.path.dirname(moduletuple[0]),stub_cpp_name)
try:
fhandle = open(cppfile,'w')
fhandle.write(cppcode)
fhandle.close()
except IOError:
raise SystemExit("Could not write the C++ stub: %s" % cppfile)
# Compile the stub 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'])
#cmdlist.extend(sysconfig.get_config_var("CXX").split())
# 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'])
#sysconfig.get_config_var("CFLAGS").split()
# includes
cmdlist.append("-I" + sysconfig.get_config_var("INCLUDEDIR"))
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("-I" + self.kde_inc_dir)
cmdlist.append("-I" + self.kde_inc_dir + "/tde")
cmdlist.append("-I" + self.tqt_inc_dir)
cmdlist.append("-I/usr/include/tqt")
cmdlist.append("-I.")
# input
cmdlist.append(cppfile)
# output
outputfile = os.path.join(self.build_dir,libraryname+'.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("-avoid-version")
cmdlist.append("-shared")
cmdlist.append("-export-dynamic")
# object
cmdlist.append(outputfile)
cmdlist.append("-rpath"); cmdlist.append(self.kde_tdeioslave_lib_dir)
cmdlist.append("-o"); cmdlist.append(os.path.join(self.build_dir,stub_la_name))
# Link libs
linklist = []
linklist.append("-lpython%s" % python_version)
linklist.extend(sysconfig.get_config_var("LIBS").split())
# FIXME I doubt half of these libraries need to be here.
linklist.append(self.sip_dir+"/sip_tqt.so")
# PyTQt libs
linklist.append(self.pytqt_dir+"/tqt.so")
# PyTDE libs
linklist.append(self.pytde_dir+"/tdecore.so")
# linklist.append("-L"+self.sip_dir); linklist.append("-lsip_tqt")
# # PyTQt libs
# linklist.append("-L"+self.pytqt_dir); linklist.append("-lqtcmodule")
# # PyTDE libs
# linklist.append("-L"+self.pytde_dir); linklist.append("-ltdecorecmodule"); linklist.append("-ltdeuicmodule")
linklist.append("-L"+self.kde_lib_dir); linklist.append("-L/opt/trinity/lib"); linklist.append("-ltdecore"); linklist.append("-lpythonize")
linklist.append("-L"+self.tqt_lib_dir); linklist.append("-lqt-mt")
linklist.append("-lm")
linklist.append("-lc")
linklist.append(self.clib)
linklist.append("-R"); linklist.append(self.python_dir)
linklist.append("-R"); linklist.append(self.tqt_lib_dir)
linklist.append("-R"); linklist.append(self.sip_dir)
linklist.append("-R"); linklist.append(self.pytqt_dir)
linklist.append("-R"); linklist.append(self.pytde_dir)
linklist.append("-R"); linklist.append(self.kde_lib_dir)
cmdlist.extend(linklist)
spawn(cmdlist) # Execute!!
print()
cpptemplate = r"""
/*
* Launch Control Centre modules written in Python using an embedded Python
* interpreter.
* Based on David Boddie's PyTDE-components.
*/
#include <stdio.h>
#include <Python.h>
#include <kinstance.h>
#define MODULE_DIR "%(moduledir)s"
#define MODULE_NAME "%(modulename)s"
#define FACTORY "SlaveFactory"
const char modname[] = MODULE_NAME;
#define MAIN_METHOD "dispatchLoop"
FILE *d = NULL;
PyObject* call_function(PyObject *callable, PyObject *args) {
PyObject *result, *pArgs;
if (callable == NULL) {
printf(MODULE_NAME " tdeioslave error: callable == NULL in call_function\n");
return NULL;
}
if (PyCallable_Check(callable)) {
if(args == NULL) {
pArgs = PyTuple_New(0);
} else {
pArgs = args;
}
result = PyObject_CallObject(callable, pArgs);
/* If the arguments were created is this function then decrease
their reference count. */
if(args == NULL) {
Py_XDECREF(pArgs);
/* pDict and pFunc are borrowed and must not be Py_DECREF-ed */
}
if(result == NULL) {
PyErr_Print();
PyErr_Clear();
}
}
return result;
}
extern "C" {
int kdemain( int argc, char **argv) {
PyObject *pModule, *pName, *pDict;
TDEInstance slave(MODULE_NAME);
Py_SetProgramName(argv[0]);
Py_Initialize();
//PyEval_InitThreads();
PySys_SetArgv(1, argv);
PyRun_SimpleString("import sys\n");
PyRun_SimpleString("sys.path.append('"MODULE_DIR"')\n");
pName = PyBytes_FromString(modname);
pModule = PyImport_Import(pName);
Py_XDECREF(pName);
if(pModule == NULL) {
printf(MODULE_NAME " tdeioslave error: pModule == NULL\n");
return 1;
} else {
PyObject *pClass, *pMethod, *pArgs, *pArg1, *pArg2, *pInstance;
int i;
pDict = PyModule_GetDict(pModule);
/* pDict is a borrowed reference */
pClass = PyDict_GetItemString(pDict, FACTORY);
if(pClass == NULL) {
printf(MODULE_NAME " tdeioslave error: pClass == NULL\n");
return 1;
} else {
pArgs = PyTuple_New(2);
pArg1 = PyBytes_FromString(argv[2]);
pArg2 = PyBytes_FromString(argv[3]);
PyTuple_SetItem(pArgs, 0, pArg1);
PyTuple_SetItem(pArgs, 1, pArg2);
call_function(pClass, pArgs);
/* Some time later... */
Py_XDECREF(pClass);
Py_XDECREF(pArgs);
}
Py_XDECREF(pModule);
}
Py_Finalize();
return 0;
}
}
"""
###########################################################################
class InstallTdeioslave(Command):
description = "Install Tdeioslave files"
user_options = [
('install-dir=', 'd', "base directory for installing tdeioslave module files"),
('install-cmd=', None, "Command to use to install the files"),
('install-protocol-dir=',None,"directory for tdeioslave protocol files"),
('build-dir=','b', "build directory (where to install from)"),
('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.build_dir = None
self.install_dir = None
self.install_cmd = None
self.install_protocol_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_install_protocol_dir = self.install_protocol_dir is not None
self.set_undefined_options('install',
('build_base', 'build_dir'),
('install_tdeioslave', 'install_dir'),
('root', 'root'),
('force', 'force'),
('skip_build', 'skip_build'),
('install_cmd', 'install_cmd'),
('install_protocol','install_protocol_dir')
)
if own_install_dir and self.root is not None:
self.install_dir = change_root(self.root,self.installdir)
if own_install_protocol_dir and self.root is not None:
self.install_protocol_dir = change_root(self.root,self.install_protocol_dir)
def get_command_name(self):
return 'install_tdeioslave'
def run(self):
if not self.skip_build:
self.run_command('build_tdeioslave')
self.announce("Installing Tdeioslave files...")
for moduletuple in self.distribution.tdeioslaves:
self.announce("Building Tdeioslave module from protocol file %s." % moduletuple[0])
protocolfilename = moduletuple[0]
# Read the protocol file
libraryname = None
try:
fhandle = open(protocolfilename,'r')
for line in fhandle.readlines():
parts = line.strip().split('=')
try:
if parts[0]=="exec":
libraryname = parts[1]
except IndexError:
pass
fhandle.close()
except IOError:
raise SystemExit("Failed to find tdeioslave protocol file: %s" % moduletuple[0])
if libraryname is None:
raise SystemExit("Failed to find library name (Was there a exec entry in the protocol file?)")
self.outfiles.extend(self.mkpath(self.install_protocol_dir))
protocolfile_dest = os.path.join(self.install_protocol_dir,os.path.basename(protocolfilename))
self.copy_file(protocolfilename, protocolfile_dest)
stub_la_name = libraryname+'.la'
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,stub_la_name))
cmdlist.append(os.path.join(self.install_dir,stub_la_name))
spawn(cmdlist) # Execute!!
print()
self.outfiles = [os.path.join(self.install_dir,os.path.basename(file)) for file in glob.glob(os.path.join(self.build_dir,'.libs',libraryname+'*'))]
self.outfiles.append(protocolfile_dest)
self.announce("Done installing Tdeioslave files.")
def get_outputs(self):
return self.outfiles or []
def mkpath(self, name, mode=0o777):
return dir_util.mkpath(name, mode, dry_run=self.dry_run)
###########################################################################
class CheckPyTQt(Command):
description = "Checks for the presence of a working PyTQt installation"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
self.min_tqt_version = self.distribution.min_tqt_version
def run(self):
if self.min_tqt_version!=None:
tqtver,kdever = get_tqt_kde_versions()
if compare_versions(self.min_tqt_version,tqtver)==1:
raise SystemExit("Your TQt version is too old. Version %s or higher is required, found %s." % (self.min_tqt_version,tqtver))
self.announce("Found TQt version %s." % tqtver)
try:
self.announce("Checking for a working PyTQt...")
from PyTQt import tqt
self.announce(" ...PyTQt is working")
except:
raise SystemExit("Couldn't import TQt! Please make sure that PyTQt is installed and working.")
def get_outputs(self): return []
###########################################################################
class CheckPyTDE(Command):
description = "Checks for the presence of a working PyTDE installation"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
self.min_kde_version = self.distribution.min_kde_version
def run(self):
if self.min_kde_version!=None:
tqtver,kdever = get_tqt_kde_versions()
if compare_versions(self.min_kde_version,kdever)==1:
raise SystemExit("Your TDE version is too old. Version %s or higher is required, found %s." % (self.min_kde_version,kdever))
self.announce("Found KDE version %s." % kdever)
self.announce("Checking for a working PyTDE...")
# Try to import modules one by one.
for k_module in ('dcop', 'tdecore', 'tdeui', 'tdeio', 'tdefile', 'tdeparts', 'tdehtml', 'tdespell'):
self.announce(k_module)
try:
exec('import ' + k_module)
except:
raise SystemExit("Error: Couldn't find module '" + k_module + "'. \n" + \
"Couldn't import KDE! Please make sure that PyTDE is installed and working.\n" + \
"PyTDE is available here: http://www.trinitydesktop.org")
self.announce(" ...PyTDE is working")
def get_outputs(self): return []
###########################################################################
def FindFileInPaths2(globpattern,canidatepaths):
if canidatepaths is None or len(canidatepaths)==0:
return (None,None)
# Look for the globpattern on the path.
for path in canidatepaths:
if path!=None:
files = glob.glob(os.path.join(path, globpattern))
if len(files)!=0:
return (path,os.path.basename(files[0]))
# Continue searching with a breadth first search.
dirs = []
for path in canidatepaths:
# Examine any directories on this path.
dirlist = glob.glob(os.path.join(path, "*"))
for item in dirlist:
if os.path.isdir(item):
# Examine each subdirectory.
dirs.append(item)
# Examine all subdirectories.
return FindFileInPaths2(globpattern, dirs)
###########################################################################
def FindFileInPaths(globpattern,canidatepaths):
x,y = FindFileInPaths2(globpattern,canidatepaths)
return x
###########################################################################
# FIXME replace this with spawn.find_executable().
def FindExeOnPath(exe_name,high_prio_dirs=None,low_prio_dirs=None):
candiate_paths = []
if high_prio_dirs is not None:
candiate_paths.extend(high_prio_dirs)
path_var = os.getenv("PATH")
candiate_paths.extend(path_var.split(':'))
if low_prio_dirs is not None:
candiate_paths.extend(low_prio_dirs)
for dir in candiate_paths:
if dir is not None:
candiate = os.path.join(dir,exe_name)
if os.path.isfile(candiate):
if os.access(candiate,os.X_OK):
return candiate
return None
###########################################################################
def ask_kde_config(question):
# Look for the tde-config program
kdeconfig = find_executable("tde-config", os.environ['PATH'] + os.pathsep + \
os.pathsep.join(['/bin','/usr/bin','/opt/trinity/bin','/opt/kde/bin','/usr/local/bin']))
if kdeconfig!=None:
# Ask the tde-config program for the
fhandle = os.popen(kdeconfig+' ' + question,'r')
result = fhandle.read()
fhandle.close()
return result
else:
return None
###########################################################################
# Convert for example, "3.1.1a" => [3,1,1,'a']
#
def split_version_name(name):
result = []
accu = ''
type = 0
for c in name:
if type==0:
if c.isdigit():
type = 1
else:
type = 2
accu += c
elif c=='.':
if type==1:
result.append(int(accu))
else:
result.append(accu)
accu = ''
type = 0
elif type==1:
# Digits
if c.isdigit():
accu += c
else:
result.append(int(accu))
type = 2
accu = c
else:
if c.isdigit():
result.append(accu)
type = 1
accu = c
else:
accu += c
if accu!='':
result.append(accu)
return result
###########################################################################
#
# Returns:
# -1 if a < b
# 0 if a and b are equal
# 1 if a > b
def compare_versions(a,b):
aparts = split_version_name(a)
bparts = split_version_name(b)
if len(aparts)>len(bparts):
compmax = len(aparts)
else:
compmax = len(bparts)
i = 0
for i in range(compmax):
abit = 0
if i<len(aparts):
abit = aparts[i]
bit = 0
if i<len(bparts):
bbit = bparts[i]
if isinstance(abit,str) and not isinstance(bbit,str):
return 1
elif not isinstance(abit,str) and isinstance(bbit,str):
return -1
else:
if abit>bbit:
return 1
elif abit<bbit:
return -1
return 0
###########################################################################
def get_tqt_kde_versions():
versioninfo = ask_kde_config('--version')
tqtver = None
kdever = None
if versioninfo!=None:
for line in versioninfo.splitlines():
if line.startswith("TQt: "):
tqtver = line[4:]
elif line.startswith("Qt: "):
tqtver = line[4:]
elif line.startswith("TDE: "):
kdever = line[5:]
return tqtver,kdever
###########################################################################
def compile_tqtdesigner(ui_files,
force=0,
prefix=None, base_dir=None,
verbose=1, dry_run=0):
"""Compile a collection of TQT Designer UI files to .py
If 'dry_run' is true, doesn't actually do anything that would
affect the filesystem.
"""
generated_files = []
for file in ui_files:
if not file.endswith(".ui"):
continue
# Terminology from the py_compile module:
# cfile - byte-compiled file
# dfile - purported source filename (same as 'file' by default)
if base_dir:
file = os.path.join(base_dir ,file)
pyfile = file[:-3] + '.py'
uifile = file
pyfile_base = os.path.basename(pyfile)
if force or newer(uifile, pyfile):
log.info("compiling TQt-Designer UI %s to %s", file, pyfile_base)
if not dry_run:
tqtuicompiler.CompileUI(uifile, pyfile)
generated_files.append(pyfile)
else:
log.debug("skipping TQt-Designer compilation of %s to %s",
file, pyfile_base)
return generated_files
###########################################################################
def get_libdir_name():
if os.uname()[4] in ['x86_64','mips64','ppc64','sparc64','s390x','aarch64','ppc64le']:
return 'lib64'
else:
return 'lib'