separate out CompilationEnvironment structures

This commit is contained in:
David Rose 2009-10-20 19:27:10 +00:00
parent e9f98e18ef
commit d660b6934b

View File

@ -40,92 +40,158 @@ reportedMissing = {}
# Our own Python source trees to watch out for. # Our own Python source trees to watch out for.
sourceTrees = ['direct'] sourceTrees = ['direct']
class CompilationEnvironment:
""" Create an instance of this class to record the commands to
invoke the compiler on a given platform. If needed, the caller
can create a custom instance of this class (or simply set the
compile strings directly) to customize the build environment. """
def __init__(self):
# The command to compile a c to an object file. Replace %(basename)s # The command to compile a c to an object file. Replace %(basename)s
# with the basename of the source file, and an implicit .c extension. # with the basename of the source file, and an implicit .c extension.
compileObj = 'error' self.compileObj = 'error'
# The command to link a single object file into an executable. As # The command to link a single object file into an executable. As
# above, replace $(basename)s with the basename of the original source # above, replace $(basename)s with the basename of the original source
# file, and of the target executable. # file, and of the target executable.
linkExe = 'error' self.linkExe = 'error'
# The command to link a single object file into a shared library. # The command to link a single object file into a shared library.
linkDll = 'error' self.linkDll = 'error'
# Paths to Python stuff. # Paths to Python stuff.
Python = None self.Python = None
PythonIPath = get_python_inc() self.PythonIPath = get_python_inc()
PythonVersion = get_python_version() self.PythonVersion = get_python_version()
# The VC directory of Microsoft Visual Studio (if relevant) # The VC directory of Microsoft Visual Studio (if relevant)
MSVC = None self.MSVC = None
# Directory to Windows Platform SDK (if relevant) # Directory to Windows Platform SDK (if relevant)
PSDK = None self.PSDK = None
# The setting to control release vs. debug builds. Only relevant on # The setting to control release vs. debug builds. Only relevant on
# Windows. # Windows.
MD = None self.MD = None
# The _d extension to add to dll filenames on Windows in debug builds. # The _d extension to add to dll filenames on Windows in debug builds.
dllext = '' self.dllext = ''
self.determineStandardSetup()
def determineStandardSetup(self):
if sys.platform == 'win32': if sys.platform == 'win32':
Python = PREFIX self.Python = PREFIX
if ('VCINSTALLDIR' in os.environ): if ('VCINSTALLDIR' in os.environ):
MSVC = os.environ['VCINSTALLDIR'] self.MSVC = os.environ['VCINSTALLDIR']
elif (Filename('/c/Program Files/Microsoft Visual Studio 9.0/VC').exists()): elif (Filename('/c/Program Files/Microsoft Visual Studio 9.0/VC').exists()):
MSVC = Filename('/c/Program Files/Microsoft Visual Studio 9.0/VC').toOsSpecific() self.MSVC = Filename('/c/Program Files/Microsoft Visual Studio 9.0/VC').toOsSpecific()
elif (Filename('/c/Program Files/Microsoft Visual Studio .NET 2003/Vc7').exists()): elif (Filename('/c/Program Files/Microsoft Visual Studio .NET 2003/Vc7').exists()):
MSVC = Filename('/c/Program Files/Microsoft Visual Studio .NET 2003/Vc7').toOsSpecific() self.MSVC = Filename('/c/Program Files/Microsoft Visual Studio .NET 2003/Vc7').toOsSpecific()
else: else:
print 'Could not locate Microsoft Visual C++ Compiler! Try running from the Visual Studio Command Prompt.' print 'Could not locate Microsoft Visual C++ Compiler! Try running from the Visual Studio Command Prompt.'
sys.exit(1) sys.exit(1)
if ('WindowsSdkDir' in os.environ): if ('WindowsSdkDir' in os.environ):
PSDK = os.environ['WindowsSdkDir'] self.PSDK = os.environ['WindowsSdkDir']
elif (platform.architecture()[0] == '32bit' and Filename('/c/Program Files/Microsoft Platform SDK for Windows Server 2003 R2').exists()): elif (platform.architecture()[0] == '32bit' and Filename('/c/Program Files/Microsoft Platform SDK for Windows Server 2003 R2').exists()):
PSDK = Filename('/c/Program Files/Microsoft Platform SDK for Windows Server 2003 R2').toOsSpecific() self.PSDK = Filename('/c/Program Files/Microsoft Platform SDK for Windows Server 2003 R2').toOsSpecific()
elif (os.path.exists(os.path.join(MSVC, 'PlatformSDK'))): elif (os.path.exists(os.path.join(self.MSVC, 'PlatformSDK'))):
PSDK = os.path.join(MSVC, 'PlatformSDK') self.PSDK = os.path.join(self.MSVC, 'PlatformSDK')
else: else:
print 'Could not locate the Microsoft Windows Platform SDK! Try running from the Visual Studio Command Prompt.' print 'Could not locate the Microsoft Windows Platform SDK! Try running from the Visual Studio Command Prompt.'
sys.exit(1) sys.exit(1)
# We need to use the correct compiler setting for debug vs. release builds. # We need to use the correct compiler setting for debug vs. release builds.
MD = '/MD' self.MD = '/MD'
if isDebugBuild: if isDebugBuild:
MD = '/MDd' self.MD = '/MDd'
dllext = '_d' self.dllext = '_d'
# If it is run by makepanda, it handles the MSVC and PlatformSDK paths itself. # If it is run by makepanda, it handles the MSVC and PlatformSDK paths itself.
if ('MAKEPANDA' in os.environ): if ('MAKEPANDA' in os.environ):
compileObj = 'cl /wd4996 /Fo%(basename)s.obj /nologo /c %(MD)s /Zi /O2 /Ob2 /EHsc /Zm300 /W3 /I"%(pythonIPath)s" %(filename)s' self.compileObj = 'cl /wd4996 /Fo%(basename)s.obj /nologo /c %(MD)s /Zi /O2 /Ob2 /EHsc /Zm300 /W3 /I"%(pythonIPath)s" %(filename)s'
linkExe = 'link /nologo /MAP:NUL /FIXED:NO /OPT:REF /STACK:4194304 /INCREMENTAL:NO /LIBPATH:"%(python)s\libs" /out:%(basename)s.exe %(basename)s.obj' self.linkExe = 'link /nologo /MAP:NUL /FIXED:NO /OPT:REF /STACK:4194304 /INCREMENTAL:NO /LIBPATH:"%(python)s\libs" /out:%(basename)s.exe %(basename)s.obj'
linkDll = 'link /nologo /DLL /MAP:NUL /FIXED:NO /OPT:REF /INCREMENTAL:NO /LIBPATH:"%(python)s\libs" /out:%(basename)s%(dllext)s.pyd %(basename)s.obj' self.linkDll = 'link /nologo /DLL /MAP:NUL /FIXED:NO /OPT:REF /INCREMENTAL:NO /LIBPATH:"%(python)s\libs" /out:%(basename)s%(dllext)s.pyd %(basename)s.obj'
else: else:
os.environ['PATH'] += ';' + MSVC + '\\bin;' + MSVC + '\\Common7\\IDE;' + PSDK + '\\bin' os.environ['PATH'] += ';' + self.MSVC + '\\bin;' + self.MSVC + '\\Common7\\IDE;' + self.PSDK + '\\bin'
compileObj = 'cl /wd4996 /Fo%(basename)s.obj /nologo /c %(MD)s /Zi /O2 /Ob2 /EHsc /Zm300 /W3 /I"%(pythonIPath)s" /I"%(PSDK)s\include" /I"%(MSVC)s\include" %(filename)s' self.compileObj = 'cl /wd4996 /Fo%(basename)s.obj /nologo /c %(MD)s /Zi /O2 /Ob2 /EHsc /Zm300 /W3 /I"%(pythonIPath)s" /I"%(PSDK)s\include" /I"%(MSVC)s\include" %(filename)s'
linkExe = 'link /nologo /MAP:NUL /FIXED:NO /OPT:REF /STACK:4194304 /INCREMENTAL:NO /LIBPATH:"%(PSDK)s\lib" /LIBPATH:"%(MSVC)s\lib" /LIBPATH:"%(python)s\libs" /out:%(basename)s.exe %(basename)s.obj' self.linkExe = 'link /nologo /MAP:NUL /FIXED:NO /OPT:REF /STACK:4194304 /INCREMENTAL:NO /LIBPATH:"%(PSDK)s\lib" /LIBPATH:"%(MSVC)s\lib" /LIBPATH:"%(python)s\libs" /out:%(basename)s.exe %(basename)s.obj'
linkDll = 'link /nologo /DLL /MAP:NUL /FIXED:NO /OPT:REF /INCREMENTAL:NO /LIBPATH:"%(PSDK)s\lib" /LIBPATH:"%(MSVC)s\lib" /LIBPATH:"%(python)s\libs" /out:%(basename)s%(dllext)s.pyd %(basename)s.obj' self.linkDll = 'link /nologo /DLL /MAP:NUL /FIXED:NO /OPT:REF /INCREMENTAL:NO /LIBPATH:"%(PSDK)s\lib" /LIBPATH:"%(MSVC)s\lib" /LIBPATH:"%(python)s\libs" /out:%(basename)s%(dllext)s.pyd %(basename)s.obj'
elif sys.platform == 'darwin': elif sys.platform == 'darwin':
# OSX # OSX
compileObj = "gcc -fPIC -c -o %(basename)s.o -O2 -I%(pythonIPath)s %(filename)s" self.compileObj = "gcc -fPIC -c -o %(basename)s.o -O2 -I%(pythonIPath)s %(filename)s"
linkExe = "gcc -o %(basename)s %(basename)s.o -framework Python" self.linkExe = "gcc -o %(basename)s %(basename)s.o -framework Python"
linkDll = "gcc -undefined dynamic_lookup -bundle -o %(basename)s.so %(basename)s.o" self.linkDll = "gcc -undefined dynamic_lookup -bundle -o %(basename)s.so %(basename)s.o"
else: else:
# Unix # Unix
compileObj = "gcc -fPIC -c -o %(basename)s.o -O2 %(filename)s -I %(pythonIPath)s" self.compileObj = "gcc -fPIC -c -o %(basename)s.o -O2 %(filename)s -I %(pythonIPath)s"
linkExe = "gcc -o %(basename)s %(basename)s.o -lpython%(pythonVersion)s" self.linkExe = "gcc -o %(basename)s %(basename)s.o -lpython%(pythonVersion)s"
linkDll = "gcc -shared -o %(basename)s.so %(basename)s.o -lpython%(pythonVersion)s" self.linkDll = "gcc -shared -o %(basename)s.so %(basename)s.o -lpython%(pythonVersion)s"
if (platform.uname()[1]=="pcbsd"): if (platform.uname()[1]=="pcbsd"):
linkExe += " -L/usr/PCBSD/local/lib" self.linkExe += " -L/usr/PCBSD/local/lib"
linkDll += " -L/usr/PCBSD/local/lib" self.linkDll += " -L/usr/PCBSD/local/lib"
def compileExe(self, filename, basename):
compile = self.compileObj % {
'python' : self.Python,
'MSVC' : self.MSVC,
'PSDK' : self.PSDK,
'MD' : self.MD,
'pythonIPath' : self.PythonIPath,
'pythonVersion' : self.PythonVersion,
'filename' : filename,
'basename' : basename,
}
print >> sys.stderr, compile
if os.system(compile) != 0:
raise StandardError
link = self.linkExe % {
'python' : self.Python,
'MSVC' : self.MSVC,
'PSDK' : self.PSDK,
'pythonIPath' : self.PythonIPath,
'pythonVersion' : self.PythonVersion,
'filename' : filename,
'basename' : basename,
}
print >> sys.stderr, link
if os.system(link) != 0:
raise StandardError
def compileDll(self, filename, basename):
compile = self.compileObj % {
'python' : self.Python,
'MSVC' : self.MSVC,
'PSDK' : self.PSDK,
'MD' : self.MD,
'pythonIPath' : self.PythonIPath,
'pythonVersion' : self.PythonVersion,
'filename' : filename,
'basename' : basename,
}
print >> sys.stderr, compile
if os.system(compile) != 0:
raise StandardError
link = self.linkDll % {
'python' : self.Python,
'MSVC' : self.MSVC,
'PSDK' : self.PSDK,
'pythonIPath' : self.PythonIPath,
'pythonVersion' : self.PythonVersion,
'filename' : filename,
'basename' : basename,
'dllext' : self.dllext,
}
print >> sys.stderr, link
if os.system(link) != 0:
raise StandardError
# The code from frozenmain.c in the Python source repository. # The code from frozenmain.c in the Python source repository.
frozenMainCode = """ frozenMainCode = """
@ -459,11 +525,11 @@ class Freezer:
# if untrue. # if untrue.
self.platform = sys.platform self.platform = sys.platform
# You will also need to change these for a cross-compiler # This is the compilation environment. Fill in your own
# situation. # object here if you have custom needs (for instance, for a
self.compileObj = compileObj # cross-compiler or something). If this is None, then a
self.linkExe = linkExe # default object will be created when it is needed.
self.linkDll = linkDll self.cenv = None
# The filename extension to append to the source file before # The filename extension to append to the source file before
# compiling. # compiling.
@ -1134,6 +1200,9 @@ class Freezer:
dllexport = '__declspec(dllexport) ' dllexport = '__declspec(dllexport) '
dllimport = '__declspec(dllimport) ' dllimport = '__declspec(dllimport) '
if not self.cenv:
self.cenv = CompilationEnvironment()
if compileToExe: if compileToExe:
code = self.frozenMainCode code = self.frozenMainCode
if self.platform == 'win32': if self.platform == 'win32':
@ -1150,11 +1219,11 @@ class Freezer:
else: else:
target = basename target = basename
compileFunc = self.compileExe compileFunc = self.cenv.compileExe
else: else:
if self.platform == 'win32': if self.platform == 'win32':
target = basename + dllext + '.pyd' target = basename + self.cenv.dllext + '.pyd'
else: else:
target = basename + '.so' target = basename + '.so'
@ -1164,7 +1233,7 @@ class Freezer:
'dllexport' : dllexport, 'dllexport' : dllexport,
'dllimport' : dllimport, 'dllimport' : dllimport,
} }
compileFunc = self.compileDll compileFunc = self.cenv.compileDll
text = programFile % { text = programFile % {
'moduleDefs' : '\n'.join(moduleDefs), 'moduleDefs' : '\n'.join(moduleDefs),
@ -1186,63 +1255,6 @@ class Freezer:
return target return target
def compileExe(self, filename, basename):
compile = self.compileObj % {
'python' : Python,
'MSVC' : MSVC,
'PSDK' : PSDK,
'MD' : MD,
'pythonIPath' : PythonIPath,
'pythonVersion' : PythonVersion,
'filename' : filename,
'basename' : basename,
}
print >> sys.stderr, compile
if os.system(compile) != 0:
raise StandardError
link = self.linkExe % {
'python' : Python,
'MSVC' : MSVC,
'PSDK' : PSDK,
'pythonIPath' : PythonIPath,
'pythonVersion' : PythonVersion,
'filename' : filename,
'basename' : basename,
}
print >> sys.stderr, link
if os.system(link) != 0:
raise StandardError
def compileDll(self, filename, basename):
compile = self.compileObj % {
'python' : Python,
'MSVC' : MSVC,
'PSDK' : PSDK,
'MD' : MD,
'pythonIPath' : PythonIPath,
'pythonVersion' : PythonVersion,
'filename' : filename,
'basename' : basename,
}
print >> sys.stderr, compile
if os.system(compile) != 0:
raise StandardError
link = self.linkDll % {
'python' : Python,
'MSVC' : MSVC,
'PSDK' : PSDK,
'pythonIPath' : PythonIPath,
'pythonVersion' : PythonVersion,
'filename' : filename,
'basename' : basename,
'dllext' : dllext,
}
print >> sys.stderr, link
if os.system(link) != 0:
raise StandardError
def makeModuleDef(self, mangledName, code): def makeModuleDef(self, mangledName, code):
result = '' result = ''
result += 'static unsigned char %s[] = {' % (mangledName) result += 'static unsigned char %s[] = {' % (mangledName)