Compiling python with the free .NET SDK

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 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" 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!"

Garth wrote:
I've put the build logs into http://www.dcl.hpi.uni-potsdam.de/home/loewis/buildlog.tgz I believe the console logs would be useless, as devenv generates response files which contain the actual command line arguments. HTH, Martin

Martin v. Löwis wrote:
Hi, Thanks for the build logs. Very useful and I can now build the whole of python with the free microsoft tools and GNU make. It appears that you still have a dependency on 'largeint.lib' in pythoncore. This is no longer required and the largeint.h was removed a in the move to VS.NET. (I think) When I remove it by hand editing the file python still builds. Can you update the project files in cvs. Cheers Garth

Garth wrote:
Thanks for the build logs. Very useful and I can now build the whole of python with the free microsoft tools and GNU make.
Very good! If you are ready to release it, feel free to submit a patch to SF.
Thanks for pointing that out. I just fixed it. Regards, Martin

Garth wrote:
I've put the build logs into http://www.dcl.hpi.uni-potsdam.de/home/loewis/buildlog.tgz I believe the console logs would be useless, as devenv generates response files which contain the actual command line arguments. HTH, Martin

Martin v. Löwis wrote:
Hi, Thanks for the build logs. Very useful and I can now build the whole of python with the free microsoft tools and GNU make. It appears that you still have a dependency on 'largeint.lib' in pythoncore. This is no longer required and the largeint.h was removed a in the move to VS.NET. (I think) When I remove it by hand editing the file python still builds. Can you update the project files in cvs. Cheers Garth

Garth wrote:
Thanks for the build logs. Very useful and I can now build the whole of python with the free microsoft tools and GNU make.
Very good! If you are ready to release it, feel free to submit a patch to SF.
Thanks for pointing that out. I just fixed it. Regards, Martin
participants (2)
-
"Martin v. Löwis"
-
Garth