Advertisement
Guest User

pyc.py with .pyproj reading support (patched by Aphex)

a guest
Nov 1st, 2010
1,080
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.22 KB | None | 0 0
  1. #####################################################################################
  2. #
  3. #  Copyright (c) Microsoft Corporation. All rights reserved.
  4. #
  5. # This source code is subject to terms and conditions of the Apache License, Version 2.0. A
  6. # copy of the license can be found in the License.html file at the root of this distribution. If
  7. # you cannot locate the  Apache License, Version 2.0, please send an email to
  8. # ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. # by the terms of the Apache License, Version 2.0.
  10. #
  11. # You must not remove this notice, or any other, from this software.
  12. #
  13. #
  14. #####################################################################################
  15.  
  16. """
  17. pyc: The Command-Line Python Compiler
  18.  
  19. Usage: ipy.exe pyc.py [options] file [file ...]
  20.  
  21. Options:
  22.    /out:output_file                          Output file name (default is main_file.<extenstion>)
  23.    /target:dll                               Compile only into dll.  Default
  24.    /target:exe                               Generate console executable stub for startup in addition to dll.
  25.    /target:winexe                            Generate windows executable stub for startup in addition to dll.
  26.    /? /h                                     This message
  27.    
  28. EXE/WinEXE specific options:
  29.    /main:main_file.py                        Main file of the project (module to be executed first)
  30.    /platform:x86                             Compile for x86 only
  31.    /platform:x64                             Compile for x64 only
  32.  
  33.  
  34. Example:
  35.    ipy.exe pyc.py /main:Program.py Form.py /target:winexe
  36. """
  37.  
  38. import sys
  39. import clr
  40. clr.AddReferenceByPartialName("IronPython")
  41. clr.AddReference('System.Xml')
  42. import os
  43.  
  44. from System.Collections.Generic import List
  45. import IronPython.Hosting as Hosting
  46. from IronPython.Runtime.Operations import PythonOps
  47. import System
  48. from System.Reflection import Emit, Assembly
  49. from System.Reflection.Emit import OpCodes, AssemblyBuilderAccess
  50. from System.Reflection import AssemblyName, TypeAttributes, MethodAttributes
  51.  
  52. from System.Xml import XmlDocument, XmlTextReader
  53. from System.IO import StreamReader
  54.  
  55.          
  56. def parsePyProj(filename):
  57.     with System.IO.File.Open(filename,  System.IO.FileMode.Open,  System.IO.FileAccess.Read) as xmlfile:
  58.         textReader = StreamReader(xmlfile)
  59.         reader = XmlTextReader(textReader)
  60.         xmlDoc = XmlDocument()
  61.         xmlDoc.Load(reader)
  62.     includepaths = []
  63.     itemgroups = xmlDoc.GetElementsByTagName("ItemGroup")
  64.     for itemgroup in itemgroups:
  65.         for item in itemgroup:
  66.             relative_path = item.GetAttribute('Include')
  67.             if not relative_path.endswith('.py'):
  68.                 continue #skip non .py files
  69.             fullpath = os.path.join(os.getcwd(), relative_path)
  70.             includepaths.append(fullpath)
  71.     #sort the list (ignoring case)
  72.     includepaths.sort(key=str.lower)
  73.     return includepaths
  74.            
  75.  
  76. def GenerateExe(name, targetKind, platform, machine, main_module):
  77.     """generates the stub .EXE file for starting the app"""    
  78.     aName = AssemblyName(System.IO.FileInfo(name).Name)
  79.     ab = PythonOps.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave)
  80.     mb = ab.DefineDynamicModule(name,  aName.Name + '.exe')
  81.     tb = mb.DefineType('PythonMain', TypeAttributes.Public)
  82.     mainMethod = tb.DefineMethod('Main', MethodAttributes.Public | MethodAttributes.Static, int, ())
  83.     #fix for stathread issue:
  84.     mainMethod.SetCustomAttribute(clr.GetClrType(System.STAThreadAttribute).GetConstructor(()), System.Array[System.Byte](()))
  85.     if targetKind == System.Reflection.Emit.PEFileKinds.WindowApplication:
  86.         mainMethod.SetCustomAttribute(clr.GetClrType(System.STAThreadAttribute).GetConstructor(()), System.Array[System.Byte](()))
  87.     gen = mainMethod.GetILGenerator()
  88.    
  89.     # get the ScriptCode assembly...
  90.     gen.EmitCall(OpCodes.Call, clr.GetClrType(Assembly).GetMethod("GetEntryAssembly"), ())
  91.     gen.EmitCall(OpCodes.Callvirt, clr.GetClrType(Assembly).GetMethod("get_Location"), ())
  92.     gen.Emit(OpCodes.Newobj, clr.GetClrType(System.IO.FileInfo).GetConstructor( (str, ) ))
  93.     gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.FileInfo).GetMethod("get_Directory"), ())
  94.     gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.DirectoryInfo).GetMethod("get_FullName"), ())
  95.     gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Environment).GetMethod("set_CurrentDirectory"), ())
  96.     gen.Emit(OpCodes.Ldstr, name + ".dll")
  97.     gen.EmitCall(OpCodes.Call, clr.GetClrType(System.IO.Path).GetMethod("GetFullPath", (clr.GetClrType(str), )), ())
  98.     gen.EmitCall(OpCodes.Call, clr.GetClrType(System.Reflection.Assembly).GetMethod("LoadFile", (clr.GetClrType(str), )), ())
  99.    
  100.     # emit module name
  101.     gen.Emit(OpCodes.Ldstr, "__main__")
  102.    
  103.     gen.Emit(OpCodes.Ldnull)
  104.    
  105.     # call InitializeModule
  106.     gen.EmitCall(OpCodes.Call, clr.GetClrType(PythonOps).GetMethod("InitializeModule"), ())    
  107.     gen.Emit(OpCodes.Ret)
  108.    
  109.     tb.CreateType()
  110.     ab.SetEntryPoint(mainMethod, targetKind)
  111.     ab.Save(aName.Name + '.exe', platform, machine)
  112.    
  113. def Main(args):
  114.     files = []
  115.     main = None          # The main file to start the execution (passed to the PythonCompiler)
  116.     main_name = None     # File which will drive the name of the assembly if "output" not provided
  117.     output = None        # Output assembly name
  118.     target = System.Reflection.Emit.PEFileKinds.Dll
  119.     platform = System.Reflection.PortableExecutableKinds.ILOnly
  120.     machine  = System.Reflection.ImageFileMachine.I386
  121.     pyproj_name = None #.Pyproj file to read in all files of a solution
  122.  
  123.     for arg in args:
  124.         if arg.startswith("/main:"):
  125.             main_name = main = arg[6:]
  126.        
  127.         elif arg.startswith("/pyproj:"):
  128.             pyproj_name = arg[8:]
  129.  
  130.         elif arg.startswith("/out:"):
  131.             output = arg[5:]
  132.            
  133.         elif arg.startswith("/target:"):
  134.             tgt = arg[8:]
  135.             if tgt == "exe": target = System.Reflection.Emit.PEFileKinds.ConsoleApplication
  136.             elif tgt == "winexe": target = System.Reflection.Emit.PEFileKinds.WindowApplication
  137.             else: target = System.Reflection.Emit.PEFileKinds.Dll
  138.  
  139.         elif arg.startswith("/platform:"):
  140.             pform = arg[10:]
  141.             if pform == "x86":
  142.                 platform = System.Reflection.PortableExecutableKinds.ILOnly | System.Reflection.PortableExecutableKinds.Required32Bit
  143.                 machine  = System.Reflection.ImageFileMachine.I386
  144.             elif pform == "x64":
  145.                 platform = System.Reflection.PortableExecutableKinds.ILOnly | System.Reflection.PortableExecutableKinds.PE32Plus
  146.                 machine  = System.Reflection.ImageFileMachine.AMD64
  147.             else:
  148.                 platform = System.Reflection.PortableExecutableKinds.ILOnly
  149.                 machine  = System.Reflection.ImageFileMachine.I386
  150.  
  151.         elif arg in ["/?", "-?", "/h", "-h"]:
  152.             print __doc__
  153.             sys.exit(0)
  154.  
  155.         else:
  156.             files.append(arg)
  157.  
  158.     if pyproj_name is not None:
  159.         solutionfiles = parsePyProj(pyproj_name)
  160.         files += solutionfiles
  161.  
  162.     if not files and not main_name:
  163.         print __doc__
  164.         sys.exit(0)
  165.  
  166.     if target != System.Reflection.Emit.PEFileKinds.Dll and main_name == None:
  167.         print __doc__
  168.         sys.exit(0)
  169.         print "EXEs require /main:<filename> to be specified"
  170.    
  171.     if not output and main_name:
  172.         output = System.IO.Path.GetFileNameWithoutExtension(main_name)
  173.     elif not output and files:
  174.         output = System.IO.Path.GetFileNameWithoutExtension(files[0])
  175.        
  176.     print "Input Files:"
  177.     for file in files:
  178.         print "\t%s" % file
  179.  
  180.     print "Output:\n\t%s" % output
  181.     print "Target:\n\t%s" % target
  182.     print 'Platform:\n\t%s' % platform
  183.     print 'Machine:\n\t%s' % machine
  184.  
  185.     print 'Compiling...'    
  186.     clr.CompileModules(output + '.dll', mainModule = main_name, *files)
  187.    
  188.     if target != System.Reflection.Emit.PEFileKinds.Dll:
  189.         GenerateExe(output, target, platform, machine, main_name)
  190.    
  191.     print 'Saved to %s' % (output, )
  192.  
  193. if __name__ == "__main__":
  194.     Main(sys.argv[1:])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement