[Distutils] segmentation fault using kinterbasdb extension on
cygwin.dll
eumir camara
eumir_camara at yahoo.com
Fri Aug 15 02:17:40 EDT 2003
I was able to build and install kinterbasdb_3.1_pre4
on cygwin successfully. But I kept getting a
segmentation fault (core dumped) when connecting to
firebird 1.03.
ENVIRONMENT:
======================================================
win2k service pack 3
kinterbasdb 3.1_pre4
cygwin
cygwin python 2.2.3
egenix-mx-base-2.0.4
firebird 1.03 windows
STEPS:
======================================================
1) downloaded kinterbasdb 3.1_pre4 and untar to a
directory
2) modified setup.cfg
database_home_dir=c:/progra~1/firebird
database_include_dir=c:/progra~1/firebird/include
database_lib_dir=c:/progra~1/firebird/lib
3) modified setup.py
file included below
4) built kinterbasdb extension
$ python setup.py build
5) installed kinterbasdb extension
$ python setup.py install
6) tested installation
setup.py
7) resulted in segmentation fault (core dumped)
QUESTIONS:
======================================================
Did i build the extension properly?
Is it possible that it couldn't find a required
gds32.dll?
Is it possible that it could find it gds32.dll, but is
not because it uses MSVCRT.dll while the
_kinterbasdb.dll uses cygwin1.dll?
thank you,
eumir_camara at yahoo.com
setup.py begin =======================================
import ConfigParser, os, os.path, shutil, string, sys,
types
import distutils.core
import distutils.ccompiler
import distutils.sysconfig
class BuildError(Exception): pass
def doCommand(cmd, header='COMMAND EXECUTION ERROR'):
print '\t' + cmd
taskOutStream = os.popen(cmd)
taskOutput = taskOutStream.read()
taskRetCode = taskOutStream.close()
if taskRetCode is not None:
raise BuildError('\n%s\n Command [%s] died
with error:\n[%s]\n'
% (header, cmd, taskOutput)
)
return taskOutput
def doLibConvCmd(cmd):
return doCommand(cmd, LIBCONVERSION_ERROR_HEADER)
def determineWindowsSystemDir():
if sys.platform == 'cygwin':
return doCommand('cygpath --sysdir')[:-1] #
Trailing newline.
else:
# (normal win32)
# If I were willing to introduce a win32all
dependency into this build
# script, this function would be replaced by
win32api.GetSystemDirectory.
winDir = os.environ.get('SYSTEMROOT',
os.environ.get('WINDIR', 'C:\\Windows'))
winSysDir = os.path.join(winDir, 'system32')
if not os.path.isdir(winSysDir):
winSysDir = os.path.join(winDir, 'system')
return winSysDir
# Be careful about changing these messages; the docs
refer to them.
PYTHON_SYSTEM_ERROR_HEADER = 'PYTHON SYSTEM ERROR:'
COMPILER_CONFIGURATION_ERROR_HEADER = 'COMPILER
CONFIGURATION ERROR:'
KIDB_DISTRIBUTION_ERROR_HEADER = 'KINTERBASDB
DISTRIBUTION ERROR:'
LIBCONVERSION_ERROR_HEADER = 'LIBRARY CONVERSION
ERROR:'
AUTODETECTION_ERROR_HEADER = 'LIBRARY AUTODETECTION
ERROR:'
MANUAL_SPECIFICATION_ERROR_HEADER = 'LIBRARY MANUAL
SPECIFICATION ERROR:'
DISTUTILS_URL =
'http://www.python.org/sigs/distutils-sig/distutils.html'
# mx.DateTime is not really required now that date I/O
is handled by
# dynamic type translation. See the
typeconv_preferred.py in this directory
# for a date I/O implementation that uses Python 2.3
stdlib datetime module
# rather than mx.DateTime.
# In any case, mx.DateTime is no longer linked to
kinterbasdb at the C level--
# it's just a standard Python import now.
# DATETIME_URL =
'http://www.lemburg.com/files/python/eGenix-mx-Extensions.html'
VERSION_FILE = 'version.txt'
CONFIG_FILE = 'setup.cfg'
PYTHON_VERSION_THRESHOLD = '2.1'
if sys.version < PYTHON_VERSION_THRESHOLD:
sys.stderr.write(
'%s\n'
' Beginning with kinterbasdb 3.1,
kinterbasdb'
' no longer officially supports\n versions of
Python prior to %s.\n\n'
% (PYTHON_SYSTEM_ERROR_HEADER,
PYTHON_VERSION_THRESHOLD)
)
sys.exit(-1)
DEBUG = int(os.environ.get('KINTERBASDB_DEBUG', 0))
try:
import distutils
except ImportError:
sys.stderr.write(
"%s\n"
" Cannot import the standard package
'distutils'.\n"
" distutils did not join the standard
library until Python 1.6,\n"
" and some some nonstandard Python
distributions do not\n"
" include the package.\n"
" You must either upgrade to a Python
version with distutils\n"
" integrated, or download the package
from:\n"
" %s"
% (PYTHON_SYSTEM_ERROR_HEADER,
DISTUTILS_URL,)
)
sys.exit(1)
import distutils.core
import distutils.ccompiler
import distutils.sysconfig
# Module name and version number:
kinterbasdb_name = 'kinterbasdb'
# Retrive the kinterbasdb version number from a
standard text file for the sake
# of maintainability:
try:
kinterbasdb_version =
string.strip(open(VERSION_FILE).read())
except IOError:
sys.stderr.write(
"%s\n"
" Missing file 'version.txt'; cannot
determine kinterbasdb"
" version."
% KIDB_DISTRIBUTION_ERROR_HEADER
)
sys.exit(1)
# These config parameters are user-specifiable via
setup.cfg:
DATETIME_INCLUDE_DIR = None
DATABASE_IS_FIREBIRD = None
DATABASE_HOME_DIR = None
DATABASE_INCLUDE_DIR = None
DATABASE_LIB_DIR = None
DATABASE_LIB_NAME = None
# These config parameters are not drawn from
setup.cfg:
CUSTOM_PREPROCESSOR_DEFS = []
PLATFORM_SPECIFIC_INCLUDE_DIRS = []
PLATFORM_SPECIFIC_LIB_DIRS = []
PLATFORM_SPECIFIC_LIB_NAMES = []
PLATFORM_SPECIFIC_EXTRA_COMPILER_ARGS = []
PLATFORM_SPECIFIC_EXTRA_LINKER_ARGS = []
# See if the user manually specified various build
options in the setup config
# file. If so, skip autodetection for the options
that the user has specified.
config = ConfigParser.ConfigParser()
config.read(CONFIG_FILE)
if config.has_section('manual_config'):
# It would be better to test against
sys.version_info rather than the
# string sys.version, but it's not available on
older Python versions.
if sys.version < '1.6':
# Compensate for 1.5.2's lack of
ConfigParser.ConfigParser.has_option:
def config_has_option(section, option,
config=config):
try:
return config.get(section, option)
except ConfigParser.NoOptionError:
return None
config.has_option = config_has_option
if config.has_option('manual_config',
'datetime_include_dir'):
DATETIME_INCLUDE_DIR =
config.get('manual_config', 'datetime_include_dir')
if config.has_option('manual_config',
'database_is_firebird'):
DATABASE_IS_FIREBIRD =
config.get('manual_config', 'database_is_firebird')
if config.has_option('manual_config',
'database_home_dir'):
DATABASE_HOME_DIR =
config.get('manual_config', 'database_home_dir')
if config.has_option('manual_config',
'database_include_dir'):
DATABASE_INCLUDE_DIR =
config.get('manual_config', 'database_include_dir')
if config.has_option('manual_config',
'database_lib_dir'):
DATABASE_LIB_DIR = config.get('manual_config',
'database_lib_dir')
if config.has_option('manual_config',
'database_lib_name'):
DATABASE_LIB_NAME =
config.get('manual_config', 'database_lib_name')
if DEBUG:
print "*** CONFIG OPTIONS SPECIFIED IN %s SECTION
'manual_config' ***" % CONFIG_FILE
for key in config.options('manual_config'):
print '%s:' % (key)
print ' %s' % (config.get('manual_config',
key))
ALL_AUTODETECT_OPTIONS_MANUALLY_SPECIFIED = (
DATETIME_INCLUDE_DIR
and DATABASE_IS_FIREBIRD is not None
and DATABASE_HOME_DIR
and DATABASE_INCLUDE_DIR
and DATABASE_LIB_DIR
and DATABASE_LIB_NAME
)
# Utility functions:
def verifyAutodetectedDatabaseIncludeDir():
if not os.path.exists(DATABASE_INCLUDE_DIR):
sys.stderr.write(
"%s\n"
" Cannot autodetect the database
header file directory.\n"
" (Tried %s)\n"
" Try specifying the
'database_include_dir' option in\n"
" the 'manual_config' section of the
setup config file (%s).\n"
% (AUTODETECTION_ERROR_HEADER,
DATABASE_INCLUDE_DIR, CONFIG_FILE)
)
sys.exit(1)
def verifyUserSpecifiedDatabaseIncludeDir():
if not os.path.exists(DATABASE_INCLUDE_DIR):
sys.stderr.write(
"%s\n"
" The user-specified database header
file directory\n"
" %s\n"
" does not exist.\n"
" Try modifying the
'database_include_dir' option in\n"
" the 'manual_config' section of the
setup config file (%s),\n"
" or comment out that option to force
this script to\n"
" to autodetect it.\n"
% (MANUAL_SPECIFICATION_ERROR_HEADER,
DATABASE_INCLUDE_DIR, CONFIG_FILE)
)
sys.exit(1)
def verifyAutodetectedDatabaseLibraryDir():
if not os.path.exists(DATABASE_LIB_DIR):
sys.stderr.write(
"%s\n"
" Cannot autodetect the database lib
directory.\n"
" (Tried %s)\n"
" Try specifying the
'database_include_dir' option in\n"
" the 'manual_config' section of the
setup config file (%s).\n"
% (AUTODETECTION_ERROR_HEADER,
DATABASE_LIB_DIR, CONFIG_FILE)
)
sys.exit(1)
def verifyUserSpecifiedDatabaseLibraryDir():
if not os.path.exists(DATABASE_LIB_DIR):
sys.stderr.write(
"%s\n"
" The user-specified database lib
directory\n"
" %s\n"
" does not exist.\n"
" Try modifying the
'database_lib_dir' option in\n"
" the 'manual_config' section of the
setup config file (%s),\n"
" or comment out that option to force
this script to\n"
" to autodetect it.\n"
% (MANUAL_SPECIFICATION_ERROR_HEADER,
DATABASE_LIB_DIR, CONFIG_FILE)
)
sys.exit(1)
def findSpacelessDirName(d):
# On Windows, try to find the spaceless version of
the provided directory
# name.
# This function was added on 2002.03.14 as part of
an ugly hack to
# surmount a bug in the distutils package.
# Sometime distutils causes None to be fed to this
function.
if not d:
return d
d = os.path.normpath(os.path.abspath(d))
if ' ' not in d:
return d
# If d doesn't exist, its short equivalent can't
be determined.
# However, for the purposes of this program (which
is solely for
# convenience anyway) it's better just to risk
feeding the
# compiler/linker a path with a space in it than
it is to raise
# an exception when there's still a *chance* of
success.
if not os.path.isdir(d):
return d
try:
import win32api
return
os.path.normcase(win32api.GetShortPathName(d))
except ImportError:
# Since win32api is not available, we'll
revert to a lame,
# manual approximation of GetShortPathName.
pass
ds = d.split(os.sep) # Split into components.
if DEBUG:
print 'ds is', ds
ds[0] = ds[0] + '\\' # Add slash back onto drive
designation so that
# it's like c:\ rather than
just c:
dsNoSpaces = [] # Will contain a version of the
directory components
# with all spaces removed.
for x in range(len(ds)):
dir = ds[x]
if DEBUG:
print 'dir is', dir
if dir.find(' ') == -1:
shortDir = dir
else:
fullDir = apply(os.path.join, ds[:x + 1])
if DEBUG:
print 'fullDir is', fullDir
# Must deal with names like 'abc de' that
have their space
# before the sixth character.
dirNoSpaces = dir.replace(' ', '')
if len(dirNoSpaces) < 6:
shortDirBase = dirNoSpaces
else:
shortDirBase = dirNoSpaces[:6]
# Search for shortDirBase~i until we find
it.
shortDir = None
i = 1
while i < 9: # This code doesn't handle
situations where there are
# more than nine directories
with the same prefix.
maybeShortDir = '%s~%d' %
(shortDirBase, i)
fullMaybeShortDir = os.path.join(
os.path.dirname(fullDir),
maybeShortDir)
if not
os.path.isdir(fullMaybeShortDir):
continue
# There follows a *really* lame
approximation of
# os.path.samefile, which is not
available on Windows.
if os.listdir(fullMaybeShortDir) ==
os.listdir(fullDir):
shortDir = maybeShortDir
break
i = i + 1
if shortDir is None:
raise Exception('Unable to find
shortened version of'
' directory named %s' % d)
dsNoSpaces.append(shortDir)
if DEBUG:
print 'dsNoSpaces is', dsNoSpaces
return os.path.normcase(apply(os.path.join,
dsNoSpaces))
# Perform generic compilation parameter setup, then
switch to platform-
# specific.
curdirAbs = os.path.abspath(os.curdir)
# Autodetect Python directory info.
if DEBUG:
print '*** PYTHON SETTINGS ***'
pythonHomeDir = sys.exec_prefix
pythonPkgDir = distutils.sysconfig.get_python_lib()
if DEBUG:
print '\tPython home dir:', pythonHomeDir
print '\tPython package dir:', pythonPkgDir
print '\tPlatform', sys.platform
# Begin platform-specific compilation parameter setup:
if sys.platform == 'win32':
ALL_AUTODETECT_WINDOWS_REGISTRY_OPTIONS_MANUALLY_SPECIFIED
= (
DATABASE_HOME_DIR
and DATABASE_INCLUDE_DIR
and DATABASE_LIB_DIR
and DATABASE_LIB_NAME
)
CUSTOM_PREPROCESSOR_DEFS.append( ('WIN32', None) )
# If this is a source distribution, add a couple
of necessary include and
# lib directories.
pcbuildDir = os.path.join(
os.path.split(distutils.sysconfig.get_python_inc())[0],
'PCBuild')
if os.path.exists(pcbuildDir):
PLATFORM_SPECIFIC_LIB_DIRS.append(pcbuildDir)
pySrcDistExtraIncludeDir = os.path.join(
os.path.split(distutils.sysconfig.get_python_inc())[0],
'PC')
PLATFORM_SPECIFIC_INCLUDE_DIRS.append(pySrcDistExtraIncludeDir)
# Verify the various directories (such as include
and library dirs) that
# will be used during compilation.
# Open the registry in preparation for reading
various installation
# directories from it.
try:
import _winreg
except ImportError:
# If the user has manually specified all of
the options that would
# require registry access to autodetect, we
can proceed despite the
# lack of _winreg.
if not
ALL_AUTODETECT_WINDOWS_REGISTRY_OPTIONS_MANUALLY_SPECIFIED:
sys.stderr.write(
"%s\n"
" Cannot import the standard
package '_winreg'.\n"
" _winreg did not join the
standard library until\n"
" Python 2.0. If you are using a
source distribution\n"
" of Python 2.0 or later, you may
have simply forgotten\n"
" to compile the _winreg C
extension.\n"
" You can get around the lack of
_winreg by manually\n"
" specifying all of the
configuration options in the\n"
" 'manual_config' section of the
setup config file (%s)."
% (AUTODETECTION_ERROR_HEADER,
CONFIG_FILE)
)
sys.exit(1)
if not
ALL_AUTODETECT_WINDOWS_REGISTRY_OPTIONS_MANUALLY_SPECIFIED:
try:
r = _winreg.ConnectRegistry(None,
_winreg.HKEY_LOCAL_MACHINE)
except WindowsError, e:
sys.stderr.write(
"%s\n"
" Unable to connect to the
HKEY_LOCAL_MACHINE section of\n"
" the Windows registry.\n"
" The specific error encountered
is:\n"
" %s"
% (AUTODETECTION_ERROR_HEADER,
str(e))
)
sys.exit(1)
if DEBUG:
print '*** DATABASE SETTINGS ***'
# Autodetect database directory info if the user
did not specify it.
if not DATABASE_HOME_DIR:
def findDatabaseHomeDir(databaseInfoKey,
databaseHomeValueName):
databaseCurrentVersionKey =
_winreg.OpenKey(r, databaseInfoKey)
try:
return _winreg.QueryValueEx(
databaseCurrentVersionKey,
databaseHomeValueName
)[0]
finally:
_winreg.CloseKey(databaseCurrentVersionKey)
# Try to find Firebird first; revert to
Interbase only if necessary.
try:
try:
DATABASE_HOME_DIR =
findDatabaseHomeDir(
r'SOFTWARE\FirebirdSQL\Firebird\CurrentVersion',
'RootDirectory'
)
DATABASE_IS_FIREBIRD = 1
if DEBUG:
print ' Autodetected database
is Firebird.'
except WindowsError:
# Revert to Interbase.
DATABASE_IS_FIREBIRD = 0
DATABASE_HOME_DIR =
findDatabaseHomeDir(
r'SOFTWARE\Borland\InterBase\CurrentVersion',
'RootDirectory'
)
if DEBUG:
print ' Autodetected database
is Interbase.'
except WindowsError, e:
sys.stderr.write(
"%s\n"
" Unable to retrieve database
directory from the\n"
" Windows registry.\n"
" Try specifying the
'database_home_dir' option in the\n"
" 'manual_config' section of the
setup config file (%s).\n"
" The specific error encountered
is:\n"
" %s"
% (AUTODETECTION_ERROR_HEADER,
CONFIG_FILE, str(e))
)
sys.exit(1)
if DATABASE_INCLUDE_DIR:
verifyUserSpecifiedDatabaseIncludeDir()
databaseSDKDir =
os.path.dirname(DATABASE_INCLUDE_DIR)
else: # user-specified DATABASE_INCLUDE_DIR
databaseSDKDir =
os.path.join(DATABASE_HOME_DIR, 'SDK')
if DATABASE_IS_FIREBIRD or not
os.path.exists(databaseSDKDir):
databaseSDKDir = DATABASE_HOME_DIR
DATABASE_INCLUDE_DIR =
os.path.join(databaseSDKDir, 'include')
if DEBUG:
print '\tDATABASE_INCLUDE_DIR exists
at\n\t %s: %d' \
% (DATABASE_INCLUDE_DIR,
os.path.exists(DATABASE_INCLUDE_DIR))
verifyAutodetectedDatabaseIncludeDir()
if DATABASE_LIB_DIR:
verifyUserSpecifiedDatabaseLibraryDir()
else: # user-specified DATABASE_LIB_DIR
DATABASE_LIB_DIR =
os.path.join(databaseSDKDir, 'lib')
verifyAutodetectedDatabaseLibraryDir()
# Perform compiler-specific setup.
if not DATABASE_LIB_NAME:
DATABASE_LIB_NAME = 'gds32'
# I should discover a way to ask distutils what
compiler it's
# configured to use--the current code would only
detect a compiler
# change via the command line. I've looked at the
compiler subpackage
# of distutils, and can't find any such facility
(though it can be
# queried for the system's default compiler).
customCompilerName = 'msvc'
import re
argJam = string.lower(string.join(sys.argv[1:]))
match = re.search(r'--compiler=(?P<cname>\S+)',
argJam)
if match:
customCompilerName = match.group('cname')
else:
match = re.search(r'-c\s+(?P<cname>\S+)',
argJam)
if match:
customCompilerName = match.group('cname')
if customCompilerName == 'msvc':
if not DATABASE_IS_FIREBIRD:
DATABASE_LIB_DIR =
os.path.join(databaseSDKDir, r'lib_ms')
if not os.path.exists(DATABASE_LIB_DIR):
DATABASE_LIB_DIR =
os.path.join(databaseSDKDir, r'lib')
if not DATABASE_LIB_NAME or DATABASE_LIB_NAME
== 'gds32':
DATABASE_LIB_NAME = 'gds32_ms'
elif customCompilerName == 'bcpp':
COMPILER_EXE_NAME = 'bcc32.exe'
# Try to find the home directory of the
Borland compiler by searching
# each directory listed in the PATH.
osPath = string.split(os.environ['PATH'],
os.pathsep)
bccHome = None
for dir in osPath:
if os.path.exists(os.path.join(dir,
COMPILER_EXE_NAME)):
bccHome = os.path.split(dir)[0]
break
else:
# Couldn't find it.
sys.stderr.write(
"%s\n"
" Unable to find the home
directory of the Borland"
" compiler.\n"
" You must add the 'bin'
subdirectory of the"
" compiler's\n"
" home directory to your PATH.\n"
" One way to do this is to type a
command of the"
" format\n"
" SET
PATH=%%PATH%%;c:\\EXAMPLE_DIR\\bin\n"
" in the same command prompt you
use to run the"
" kinterbasdb setup script."
%
(COMPILER_CONFIGURATION_ERROR_HEADER,)
)
sys.exit(1)
# Override the default behavior of
distutils.bcppcompiler.BCPPCompiler
# in order to force it to issue the correct
command.
from distutils.bcppcompiler import
BCPPCompiler
def _makeDirNameSpacless(kwargs, argName):
x = kwargs.get(argName, None)
if x is None:
return
elif isinstance(x, types.StringType):
kwargs[argName] =
findSpacelessDirName(x)
else: # sequence of strings
kwargs[argName] = [
findSpacelessDirName(d) for d in x ]
class BCPP_UGLY_Hack(BCPPCompiler):
def compile (self, *args, **kwargs):
bccIncludePreargDir =
findSpacelessDirName('%s\include' % bccHome)
bccLibPreargDir =
findSpacelessDirName('%s\lib' % bccHome)
bccLibPSDKPreargDir =
findSpacelessDirName('%s\lib\psdk' % bccHome)
kwargs['extra_preargs'] = (
[
r'-I"%s"' %
bccIncludePreargDir,
r'-L"%s"' % bccLibPreargDir,
r'-L"%s"' %
bccLibPSDKPreargDir
]
+ kwargs.get('extra_preargs', [])
)
for argName in ('output_dir',
'include_dirs'):
_makeDirNameSpacless(kwargs,
argName)
return BCPPCompiler.compile(self,
*args, **kwargs)
def link (self, *args, **kwargs):
ilinkLibPreargDir =
findSpacelessDirName('%s\lib' % bccHome)
ilinkLibPSDKPreargDir =
findSpacelessDirName('%s\lib\psdk' % bccHome)
myPreArgs = [
r'/L"%s"' % ilinkLibPreargDir,
r'/L"%s"' % ilinkLibPSDKPreargDir
]
if not
kwargs.has_key('extra_preargs'):
argsAsList = list(args)
argsAsList[9] = myPreArgs # see
distuils.ccompiler.py
args = tuple(argsAsList)
else:
kwargs['extra_preargs'] =
myPreArgs + kwargs.get['extra_preargs']
for argName in (
'output_dir', 'library_dirs',
'runtime_library_dirs',
'build_temp'
):
_makeDirNameSpacless(kwargs,
argName)
return BCPPCompiler.link(self, *args,
**kwargs)
compilerSetupTuple =
distutils.ccompiler.compiler_class['bcpp']
import distutils.bcppcompiler
distutils.bcppcompiler.BCPP_UGLY_Hack =
BCPP_UGLY_Hack
distutils.ccompiler.compiler_class['bcpp'] = (
compilerSetupTuple[0], 'BCPP_UGLY_Hack',
compilerSetupTuple[2])
# Use coff2omf to create a
Borland-compiler-compatible library file,
# "pythonVV_bcpp.lib", from the standard
"pythonVV.lib".
# It would be better to use sys.version_info
rather than the
# string sys.version, but it's not available
on older Python
# versions.
pyLibVersionSuffix = sys.version[0] +
sys.version[2]
# 2003.03.28: Accomodate source dists of
Python on Windows (give the
# PCBuild\pythonVV.lib file (if any)
precedence over the
# libs\pythonVV.lib file (if any)):
pythonLibsDir = os.path.join(pythonHomeDir,
'PCbuild')
if not
os.path.exists(os.path.join(pythonLibsDir,
'python%s.lib' % pyLibVersionSuffix)):
pythonLibsDir =
os.path.join(pythonHomeDir, 'libs')
newLibFilename = os.path.join(pythonLibsDir,
'python%s_bcpp.lib' % pyLibVersionSuffix)
print 'setup.py is trying to create %s' %
newLibFilename
if not
os.path.exists(os.path.join(newLibFilename)):
# oldLibFilename = '%s\libs\python%s.lib'
% (
oldLibFilename =
os.path.join(pythonLibsDir, 'python%s.lib' %
pyLibVersionSuffix)
coff2omfCommand = ('coff2omf %s %s' %
(oldLibFilename, newLibFilename))
os.system(coff2omfCommand)
# Do this test instead of checking the
return value of
# os.system, which will not reliably
indicate an error
# condition on Win9x.
if not os.path.exists(newLibFilename):
sys.stderr.write(
"%s\n"
" Unable to create a
Borland-compatible Python"
" library file using the\n"
" coff2omf utility.\n"
" Tried command:\n"
" %s"
% (
COMPILER_CONFIGURATION_ERROR_HEADER,
coff2omfCommand)
)
sys.exit(1)
assert os.path.exists(newLibFilename)
if DEBUG:
print '\tDATABASE_LIB_DIR exists at\n\t %s:
%d' \
% (DATABASE_LIB_DIR,
os.path.exists(DATABASE_LIB_DIR))
print '\tDATABASE_LIB_NAME is\n\t %s' %
DATABASE_LIB_NAME
elif sys.platform == 'cygwin':
print ' *** CYGWIN LIBRARY GENERATION : begin
***'
DATABASE_LIB_NAME = 'gds32'
PLATFORM_SPECIFIC_LIB_DIRS.append('/usr/lib')
PLATFORM_SPECIFIC_EXTRA_COMPILER_ARGS.append('-DUSE_DL_IMPORT')
# PLATFORM_SPECIFIC_EXTRA_LINKER_ARGS = []
winSysDir = determineWindowsSystemDir()
libUltimateDest = '/usr/lib/libgds32.a'
libUltimateDir, libName =
os.path.split(libUltimateDest)
fbDir = 'c:/progra~1/firebird'
if os.path.isfile(libUltimateDest):
print ('\tCygwin-compatible Firebird library
already exists at:\n\t %s'
% libUltimateDest
)
else:
print (
'\n\tsetup.py is trying to create
cygwin-compatible Firebird'
' library at:\n'
'\t "%s"'
% libUltimateDest
)
fbClientLibFilename = os.path.join(fbDir,
'lib', 'gds32.lib')
origCurDir = os.path.abspath(os.curdir)
os.chdir(winSysDir)
try:
# Create def file containing symbols from
gds32.lib.
doLibConvCmd(
'''(echo EXPORTS; nm %s | grep " T
_"'''
''' | sed 's/.* T _//g' | sed
's/@.*$//g')'''
''' > gds32.def'''
% fbClientLibFilename
)
# End lame pexports substitute.
# Create lib file from DLL and the
just-generated def file.
doLibConvCmd(
'dlltool --dllname gds32.dll --def
gds32.def --output-lib %s'
% libName
)
os.remove('gds32.def')
# Move the lib file to a location where
cygwin-GCC's linker will
# find it.
shutil.copyfile(libName, libUltimateDest)
os.remove(libName)
finally:
os.chdir(origCurDir)
assert os.path.isfile(libUltimateDest)
print ' *** CYGWIN LIBRARY GENERATION : end
***\n'
else: # not Windows
# If the platform isn't Linux, issue a warning.
if len(sys.platform) < 5 or not
string.lower(sys.platform)[:5] == 'linux':
sys.stderr.write("Warning: The kinterbasdb
setup code was not"
" specifically written to support your
platform (%s), and"
" may not work properly.\n"
% sys.platform
)
else:
# The platform is Linux.
pass
# Is libcrypt necessary on all POSIX OSes, or just
Linux?
# Until someone informs me otherwise, I'll assume
all.
if os.name == 'posix':
PLATFORM_SPECIFIC_LIB_NAMES.append('crypt')
# Verify the various directories (such as include
and library dirs) that
# will be used during compilation.
# Assumption:
# This is a Unix-like OS, where a proper
installation routine would have
# placed the database [header, library] files in a
system-wide dirs.
# We have no way of knowing beyond the shadow of a
doubt whether that
# has happened (as opposed to the situation on
Windows, where we can
# consult the registry to determine where a binary
installer placed its
# files), so we'll just let the compiler complain
if it can't find the
# [header, library] files.
# If, on the other hand, the user manually
specified the directories, we
# may verify that they exist.
if DATABASE_INCLUDE_DIR: # the user manually
specified it
verifyUserSpecifiedDatabaseIncludeDir()
if DATABASE_LIB_DIR: # the user manually specified
it
verifyUserSpecifiedDatabaseLibraryDir()
# 2003.04.12: begin block
# On FreeBSD 4, the header and library files
apparently are not made
# visible by default (perhaps because the
installation that prompted this
# change was from a source distribution rather
than an RPM, as all of my
# testing on Linux has been?).
# This script attempts to "autodetect" an
installation at the default
# location, but only if:
# - no DATABASE_HOME_DIR has been manually
specified
# - the default installation directory actually
exists
#
# This "autodetection" will probably work for some
other Unixes as well.
if not DATABASE_HOME_DIR:
DEFAULT_FREEBSD_HOME_DIR =
'/usr/local/firebird'
if os.path.isdir(DEFAULT_FREEBSD_HOME_DIR):
DATABASE_HOME_DIR =
DEFAULT_FREEBSD_HOME_DIR
if not DATABASE_INCLUDE_DIR:
DATABASE_INCLUDE_DIR =
os.path.join(DATABASE_HOME_DIR, 'include')
if not DATABASE_LIB_DIR:
DATABASE_LIB_DIR =
os.path.join(DATABASE_HOME_DIR, 'lib')
# 2003.04.12: end block
if not DATABASE_LIB_NAME:
DATABASE_LIB_NAME = 'gds'
# Now finished with platform-specific compilation
parameter setup.
# Create a list of all INCLUDE dirs to be passed to
setup():
allIncludeDirs = []
# Add Python include directory:
allIncludeDirs.append(distutils.sysconfig.get_python_inc())
if len(PLATFORM_SPECIFIC_INCLUDE_DIRS) > 0:
allIncludeDirs.extend(PLATFORM_SPECIFIC_INCLUDE_DIRS)
if DATETIME_INCLUDE_DIR:
allIncludeDirs.append(DATETIME_INCLUDE_DIR)
if DATABASE_INCLUDE_DIR:
allIncludeDirs.append(DATABASE_INCLUDE_DIR)
# Create a list of all LIB names to be passed to
setup():
allLibNames = []
if DATABASE_LIB_NAME:
allLibNames.append(DATABASE_LIB_NAME)
allLibNames.extend(PLATFORM_SPECIFIC_LIB_NAMES)
if DEBUG:
print '\tLIBRARY NAMES ', allLibNames
# Create a list of all LIB directories to be passed to
setup():
allLibDirs = []
if len(PLATFORM_SPECIFIC_LIB_DIRS) > 0:
allLibDirs.extend(PLATFORM_SPECIFIC_LIB_DIRS)
if DATABASE_LIB_DIR:
allLibDirs.append(DATABASE_LIB_DIR)
if DEBUG:
print '\tLIBRARY DIRS ', allLibDirs
# Create a list of all macro definitions that must be
passed to distutils.
allMacroDefs = []
if len(CUSTOM_PREPROCESSOR_DEFS) > 0:
allMacroDefs.extend(CUSTOM_PREPROCESSOR_DEFS)
# Create a list of all extra options to pass to the
compiler, linker.
allExtraCompilerArgs = []
if len(PLATFORM_SPECIFIC_EXTRA_COMPILER_ARGS) > 0:
allExtraCompilerArgs.extend(PLATFORM_SPECIFIC_EXTRA_COMPILER_ARGS)
allExtraLinkerArgs = []
if len(PLATFORM_SPECIFIC_EXTRA_LINKER_ARGS) > 0:
allExtraLinkerArgs.extend(PLATFORM_SPECIFIC_EXTRA_LINKER_ARGS)
extensionModules = [
distutils.core.Extension(
"kinterbasdb._kinterbasdb",
sources=["_kinterbasdb.c", "_kievents.c"],
libraries=allLibNames,
include_dirs=allIncludeDirs,
library_dirs=allLibDirs,
define_macros=allMacroDefs,
extra_compile_args=allExtraCompilerArgs,
extra_link_args=allExtraLinkerArgs
),
]
# 2003.02.18: IB 5.5 build hack:
allPythonModules = [
'kinterbasdb.__init__',
'kinterbasdb.k_exceptions',
# 2003.03.30: dynamic type conv:
'kinterbasdb.typeconv_active',
'kinterbasdb.typeconv_backcompat',
'kinterbasdb.typeconv_preferred',
# 2003.05.19: additional components of refactored
dynamic type conv:
'kinterbasdb.typeconv_fixed_stdlib',
'kinterbasdb.typeconv_fixed_fixedpoint',
'kinterbasdb.typeconv_datetime_mx',
'kinterbasdb.typeconv_datetime_stdlib',
'kinterbasdb.typeconv_util_isinstance',
]
# Build somewhat differently if we're dealing with an
IB version before 6.0.
# (Innocent until proven guilty.)
isIBLessThan_6_0 = 0
for incDir in allIncludeDirs:
headerFilename = os.path.join(incDir, 'ibase.h')
if os.path.exists(headerFilename):
# Using the isc_decode_sql_time symbol as the
detector is kinda arbitrary.
if
open(headerFilename).read().find('isc_decode_sql_time')
== -1:
isIBLessThan_6_0 = 1
break
if isIBLessThan_6_0:
print >> sys.stderr, \
'WARNING: Not building the
kinterbasdb._services module because' \
' IB 5.5 does not support it.'
else:
# Only include the services module if dealing with
>= IB 6.0.
allPythonModules.append('kinterbasdb.services')
extensionModules.append(
distutils.core.Extension(
"kinterbasdb._kiservices",
sources=["_kiservices.c"],
libraries=allLibNames,
include_dirs=allIncludeDirs,
library_dirs=allLibDirs,
define_macros=allMacroDefs,
extra_compile_args=allExtraCompilerArgs,
extra_link_args=allExtraLinkerArgs
)
)
# end IB 5.5 build hack of 2003.02.18
# Now we've detected and verified all compilation
parameters, and are ready to
# compile.
if DEBUG:
print '*** SETTINGS DETECTION PHASE COMPLETE;
READY FOR BUILD ***'
print ("\tThe DEBUG flag is enabled, so the setup
script stops\n"
"\t before actually invoking the distutils
setup procedure."
)
sys.exit(0)
# The MEAT:
distutils.core.setup(
name=kinterbasdb_name,
version=kinterbasdb_version,
author='''Originally by Alexander Kuznetsov ;
rewritten and expanded by David
Rushby
with contributions from several
others
(see docs/license.txt for
details).''',
author_email='woodsplitter at rocketmail.com',
url='http://kinterbasdb.sourceforge.net',
description='Python DB API 2.0 extension for
Firebird and Interbase',
long_description=
'kinterbasdb allows Python to access the
Firebird and Interbase\n'
'SQL servers according to the interface
defined by the Python\n'
'Database API Specification version 2.0.',
license='see docs/license.txt',
# 2003.02.18: IB 5.5 build hack:
# For IB 5.5, need to include only specific
components of the kinterbasdb
# package, not the whole package.
#packages=['kinterbasdb'],
package_dir={'kinterbasdb': os.curdir},
py_modules=allPythonModules,
ext_modules=extensionModules,
data_files = [
# documentation:
('Lib/site-packages/kinterbasdb/docs',
[
'docs/index.html',
'docs/installation-source.html',
'docs/installation-binary.html',
'docs/usage.html',
'docs/changelog.txt',
'docs/license.txt',
'docs/Python-DB-API-2.0.html',
'docs/links.html',
'docs/global.css',
'docs/w3c.png',
]
)
]
)
setup.py end =========================================
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com
More information about the Distutils-SIG
mailing list