[Python-Dev] Compiling python with the free .NET SDK

Garth garth at garthy.com
Sat Jan 17 15:54:29 EST 2004


Hi

I written a script that allows you to compile python with the free .NET 
Framework SDK. It reads in the XML file and uses a rule set to build the 
commands. At the moment it just executes them but I'm going to write a 
Makefile writter (GNU make is all I know though)  It's probably possible 
to write rules to compile with mingw32 as well.

What would be a real help is if someone could send me the console output 
from the Debug and Release buiilds when you use command line devstudio 
to build it as some of the xml properties  make no sense but I could 
probably work out what they mean. Things like 'RuntimeLibrary="2"' have 
no meaning unless I can see the output.

You need the free .NET framework SDK and the Platform SDK both available 
for free from microsoft

Just put the two python files in the PCBuild directory and run

vcproj_read.py pythoncore.vcproj "Release|Win32"

or

vcproj_read.py pythoncore.vcproj "Debug|Win32"

I've only tested it with pythoncode.vcproj and python.vcproj so if you 
get a keyerror around line 187 you need to add more rules to interpret 
the settings.

Cheers

Garth


-------------- next part --------------
import sys
from xml.dom.ext.reader import Sax2
import xml.dom.ext
import file_rules

if len(sys.argv) < 3:
    print "<XML_PROJECT FILE> <CONFIG>"
    sys.exit(1)

xml_file = file( sys.argv[1], 'rU' )

reader = Sax2.Reader()

doc = reader.fromStream( xml_file )

xml_file.close()

vsproj = doc.getElementsByTagName('VisualStudioProject')[0]

def attributes2dict(dom):
    """
    """
    d = {}
    for attr in dom.attributes:
        #print attr
        d[attr.name] = attr.nodeValue
    return d

def xmlnode2dict( dom ):
    #print dom
    #print dir(dom)
    #self = { }
    self = attributes2dict( dom )
    if dom.hasChildNodes():
        for child in dom.childNodes:
            try:
                childdict = xmlnode2dict( child )
                try:
                    self[child.nodeName].append( childdict )
                except KeyError:
                   self[child.nodeName] = [ childdict ]
            except TypeError:
                pass #print "skipping",child
    return self



project = xmlnode2dict( vsproj )

# Select the configuration

for config in project['Configurations'][0]['Configuration']:
    if config['Name'] == sys.argv[2]:
        currentconfig = config

try:
    print "Config selected",  currentconfig['Name']
except NameError:
    print "Couldn't find config",sys.argv[2]
    sys.exit(1)

file_rules.currentconfig = currentconfig

# write the makefile  by sening ocommand off to MakfileWrite class
# For now just exe
objectlist = []
import os
for f in project['Files'][0]['File']:
    print "Processing ",f['RelativePath']
    
    cmdline,obj  = file_rules.generate_command_line( f )
    print cmdline
        
    if cmdline:
        os.system( cmdline )

    objectlist.append( obj )

# Now link.....
print "link ",objectlist
print "When I get around to writing it"

   
-------------- next part --------------
import os.path

# Tool rule setting
# Sometimes file setting s override trhe config rule and sometimes they
# just add to it maybe this is wrong?
TOOL_RULE_OVERRIDE = 0
TOOL_RULE_BOTH = 1

currentconfig = None

def find_file_config( fileconfig ):
    for config in fileconfig['FileConfiguration']:
        if config['Name'] == currentconfig['Name']:
            return config

def find_tool_settings( fileconfig, name, setting, rule):
    settings = []
    try:
        currentfileconfig = find_file_config( fileconfig )
        for tool in currentfileconfig['Tool']:
            if tool['Name'] == name:
                if tool[setting] != '':
                    settings.append( tool[setting] )
                if rule == TOOL_RULE_OVERRIDE:
                    return tool[setting]
    except KeyError:
        # OK no file specific config for this file
        pass
    
    for tool in currentconfig['Tool']:
        if tool['Name'] == name:
            settings.append( tool[setting] )
            if rule == TOOL_RULE_BOTH:
                return settings
            else:
                return tool[setting]
            
    raise KeyError,"DAMN" + str(fileconfig) + str(name) + str(setting)

# Guessing at this.. need to fill in the real values
DebugInformationFormatmap = {'3' : '-Zi'}

Optimizationmap = {'0' : "",
                   '1' : "/O1",
                   '2' : "/O2",
                   '3' : "/Ox"}


def option_list( fconfig, tool, var, delimiter, prefix ):
    """
    """
    options = find_tool_settings( fconfig, tool,var,TOOL_RULE_BOTH)
    optionlist = []
    for option in options:
        optionlist += option.split( delimiter )
    return  prefix + prefix.join( optionlist )

def option_param( fconfig, tool, var, prefix ):
    """
    """
    option = find_tool_settings( fconfig, tool,var,TOOL_RULE_OVERRIDE)
    return prefix + option

def option_bool( fconfig, tool, boolname, prefix ):
    """
    """
    line = ""
    b = find_tool_settings( fconfig, 'VCCLCompilerTool',boolname,TOOL_RULE_OVERRIDE)
    if bool(b):
        line = prefix
    return line
        
def option_bool_param(fconfig, tool, boolname, paramname, prefix ):
    """
    """
    line = ""
    b = find_tool_settings( fconfig, 'VCCLCompilerTool',boolname,TOOL_RULE_OVERRIDE)
    if bool(b):
        paramvalue = find_tool_settings( fconfig, 'VCCLCompilerTool',paramname,TOOL_RULE_OVERRIDE)
        line = prefix + paramvalue
    return line


def option_map( fconfig, tool, var, optionmap ):
    """
    """
    option = find_tool_settings( fconfig, tool,var,TOOL_RULE_OVERRIDE)
    return optionmap[ option ]

toolextmap = {'c' : 'VCCLCompilerTool',
              'rc': 'VCResourceCompilerTool', 
              'ico' : None,}

# HMM are the ones I'm not sure about...
OPTION_TYPE_HMM = 0

OPTION_TYPE_BOOL = 1 
OPTION_TYPE_BOOL_PARAM = 2
OPTION_TYPE_MAP = 3
OPTION_TYPE_PARAM = 4 
OPTION_TYPE_LIST = 5

# IGNORE is there as they are probably used in some other
# parameter thing
OPTION_TYPE_IGNORE = 6

toolmap = {'VCCLCompilerTool' : { 'pre' : 'cl ' ,
                                  'post' : ' -c ',
                                  'objpath': 'ObjectFile',
                                  'objext' : 'obj',
                                  #'Name': {'type' : OPTION_TYPE_IGNORE },
                                  'AdditionalOptions' : {'type' : OPTION_TYPE_PARAM,
                                                         'flag' : '',
                                                         },
                                  'PrecompiledHeaderFile': {'type' : OPTION_TYPE_IGNORE },
                                  'EnableFunctionLevelLinking' : { 'type' : OPTION_TYPE_BOOL,
                                                                   'flag' : '-Gy'
                                                                   },
                                  'StringPooling': { 'type' : OPTION_TYPE_BOOL,
                                                                   'flag' : '-Gf'
                                                                   },
                                  # Not sure about this one
                                  'InlineFunctionExpansion': { 'type' : OPTION_TYPE_BOOL,
                                                               'flag' : '-Ob1'
                                                               },
                                  'ProgramDataBaseFileName' : {'type' : OPTION_TYPE_IGNORE },
                                  
                                  'RuntimeLibrary' : {'type' : OPTION_TYPE_HMM },
                                  'AssemblerListingLocation' : {'type' : OPTION_TYPE_HMM },
                                  'CompileAs' : {'type' : OPTION_TYPE_HMM },
                                  
                                  'AdditionalIncludeDirectories' : {'type' : OPTION_TYPE_LIST,
                                                                  'delim' : ',',
                                                                  'flag' : ' -I',
                                                                  },
                                  'PreprocessorDefinitions' :  {'type' : OPTION_TYPE_LIST,
                                                                'delim' : ';',
                                                                'flag' : ' -D',
                                                                },
                                  'BrowseInformation' : { 'type' : OPTION_TYPE_BOOL_PARAM,
                                                          'paramname' :'ProgramDataBaseFileName',
                                                          'flag' : '-FR'
                                                          },
                                  'DebugInformationFormat' : { 'type' : OPTION_TYPE_MAP,
                                                               'map' : DebugInformationFormatmap,
                                                               },
                                  'ObjectFile' : {'type' : OPTION_TYPE_PARAM,
                                                  'flag' : '-Fo',
                                                  },
                                  'Optimization': { 'type' : OPTION_TYPE_MAP,
                                                    'map' : Optimizationmap,
                                                    },
                                  'WarningLevel' : {'type' : OPTION_TYPE_PARAM,
                                                    'flag' : '-W',
                                                    },
                                  'UsePrecompiledHeader': { 'type' : OPTION_TYPE_BOOL_PARAM,
                                                            'paramname' :'PrecompiledHeaderFile',
                                                            'flag' : '-YX',
                                                            },
                                  'SuppressStartupBanner' : { 'type' : OPTION_TYPE_BOOL,
                                                              'flag' : '-nologo'
                                                              },
                                  },
           'VCResourceCompilerTool' : {'pre' : 'rc ' ,
                                       'post' : '',
                                       'objpath': None,
                                       'objext' : 'res',
                                       'Name': {'type' : OPTION_TYPE_IGNORE },
                                       'PreprocessorDefinitions' :  {'type' : OPTION_TYPE_LIST,
                                                                     'delim' : ';',
                                                                     'flag' : ' -d',
                                                                     },
                                       'AdditionalIncludeDirectories' : {'type' : OPTION_TYPE_LIST,
                                                                         'delim' : ',',
                                                                         'flag' : ' -i',
                                                                         },
                                       'Culture': {'type' : OPTION_TYPE_PARAM,
                                                   'flag' : '-l',
                                                   },
                                       }
           }

def run_option( f, tool, option ):
    """
    """
    line = ""
    oinfo = toolmap[tool][option]
#    print oinfo
    if oinfo['type'] == OPTION_TYPE_HMM:
        print "Option ", option, "Not implemented yet!"
        pass
    elif oinfo['type'] == OPTION_TYPE_BOOL:

        line = option_bool(f, tool, option, oinfo['flag'] )
        
    elif oinfo['type'] == OPTION_TYPE_BOOL_PARAM :

        line = option_bool_param( f, tool, option, oinfo['paramname'], oinfo['flag'] )

    elif oinfo['type'] == OPTION_TYPE_MAP:
        
        line = option_map( f, tool, option, Optimizationmap)

    elif oinfo['type'] == OPTION_TYPE_PARAM:

        line = option_param( f, tool, option, oinfo['flag'] )

    elif oinfo['type'] == OPTION_TYPE_LIST:
        
        line = option_list( f, tool, option, oinfo['delim'], oinfo['flag'] )
    return line

def generate_command_line( f ):
    """
    """
    cmd = ""
    obj = ""
    ext = f['RelativePath'].split(".")[-1]
    toolname = toolextmap[ ext ]
    if toolname:
        lines = []
        for tool in currentconfig['Tool']:
            if tool['Name'] == toolname:
                for setting in tool:
                    lines.append( run_option( f, toolname, setting) )

        cmd = toolmap[ toolname ]['pre']
        cmd += (" ".join( lines ))
        cmd +=  toolmap[ toolname ]['post']
        cmd += " " + f['RelativePath']
        if toolmap[ toolname ]['objpath']:
            objectpath = find_tool_settings( f, toolname, toolmap[ toolname ]['objpath'] ,TOOL_RULE_OVERRIDE)
        else:
            objectpath = os.path.split( f['RelativePath'] )[0]
            
        objectfile = "".join( os.path.splitext( os.path.split( f['RelativePath'] )[1] )[0] ) + toolmap[ toolname ]['objext'] 
        obj = os.path.join(objectpath,objectfile) 
    return ( cmd, obj)  
    

def generate_command_line_old( f ):
    """
    """
    ext = f['RelativePath'].split(".")[-1]
    cmdlinefunc = filetype[ ext ]
    return cmdlinefunc( f )


def generate_link_line( files ):
    """
    """
    line = ['link']
    raise SystemError,"WriteME!"
                 



More information about the Python-Dev mailing list