############################################ # Copyright (c) 2012 Microsoft Corporation # # Auxiliary scripts for generating Makefiles # and Visual Studio project files. # # Author: Leonardo de Moura (leonardo) ############################################ import os import glob BUILD_DIR='build' SRC_DIR='src' MODES=[] PLATFORMS=[] class MKException(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) def set_build_dir(d): global BUILD_DIR BUILD_DIR = d mk_dir(BUILD_DIR) def set_src_dir(d): global SRC_DIR SRC_DIR = d def set_modes(l): global MODES MODES=l def set_platforms(l): global PLATFORMS PLATFORMS=l VS_COMMON_OPTIONS='WIN32' VS_DBG_OPTIONS='_DEBUG' VS_RELEASE_OPTIONS='NDEBUG' GUI = 0 Name2GUI = {} def mk_gui_str(id): return '4D2F40D8-E5F9-473B-B548-%012d' % id MODULES = [] HEADERS = [] LIBS = [] EXES = [] DEPS = {} def set_vs_options(common, dbg, release): global VS_COMMON_OPTIONS, VS_DBG_OPTIONS, VS_RELEASE_OPTIONS VS_COMMON_OPTIONS = common VS_DBG_OPTIONS = dbg VS_RELEASE_OPTIONS = release def is_debug(mode): return mode == 'Debug' def is_x64(platform): return platform == 'x64' def mk_dir(d): if not os.path.exists(d): os.makedirs(d) def module_src_dir(name): return '%s%s%s' % (SRC_DIR, os.sep, name) def module_build_dir(name): return '%s%s%s' % (BUILD_DIR, os.sep, name) LIB_KIND = 0 EXE_KIND = 1 def get_extension(kind): if kind == LIB_KIND: return 'lib' elif kind == EXE_KIND: return 'exe' else: raise MKException('unknown kind %s' % kind) def vs_header(f): f.write( '\n' '\n') def vs_project_configurations(f, name): global GUI, Name2GUI f.write(' \n') for mode in MODES: for platform in PLATFORMS: f.write(' \n' % (mode, platform)) f.write(' %s\n' % mode) f.write(' %s\n' % platform) f.write(' \n') f.write(' \n') f.write(' \n') f.write(' {%s}\n' % mk_gui_str(GUI)) f.write(' %s\n' % name) f.write(' Win32Proj\n') f.write(' \n') f.write(' \n') Name2GUI[name] = GUI GUI = GUI + 1 def vs_configurations(f, name, kind): for mode in MODES: for platform in PLATFORMS: f.write(' \n' % (mode, platform)) if kind == LIB_KIND: f.write(' StaticLibrary\n') elif kind == EXE_KIND: f.write(' Application\n') else: raise MKException("unknown kind %s" % kind) f.write(' Unicode\n') f.write(' false\n') f.write(' \n') f.write(' \n') f.write(' \n') f.write(' \n') f.write(' \n') f.write(' \n') f.write(' \n') f.write(' \n') for mode in MODES: for platform in PLATFORMS: if is_x64(platform): f.write(' $(SolutionDir)$(Platform)\$(Configuration)\\n' % (mode, platform)) else: f.write(' $(SolutionDir)$(Configuration)\\n' % (mode, platform)) for mode in MODES: for platform in PLATFORMS: f.write(' %s\n' % (mode, platform, name)) f.write(' .%s\n' % (mode, platform, get_extension(kind))) f.write(' \n') def vs_compilation_options(f, name, deps, kind): for mode in MODES: for platform in PLATFORMS: f.write(' \n' % (mode, platform)) if is_x64(platform): f.write(' \n') f.write(' X64\n') f.write(' \n') f.write(' \n') if is_debug(mode): f.write(' Disabled\n') else: f.write(' Full\n') options = VS_COMMON_OPTIONS if is_debug(mode): options = "%s;%s" % (options, VS_DBG_OPTIONS) else: options = "%s;%s" % (options, VS_RELEASE_OPTIONS) if is_x64(platform): options = "%s;_AMD64_" % options f.write(' %s;%%(PreprocessorDefinitions)\n' % options) if is_debug(mode): f.write(' true\n') f.write(' EnableFastChecks\n') f.write(' Level3\n') f.write(' MultiThreadedDebugDLL\n') f.write(' true\n') f.write(' ProgramDatabase\n') f.write(' ') f.write('..\..\src\%s' % name) for dep in deps: f.write(';..\..\src\%s' % dep) f.write('\n') f.write(' \n') f.write(' \n') f.write(' $(OutDir)%s.%s\n' % (name, get_extension(kind))) f.write(' %(AdditionalLibraryDirectories)\n') if is_x64(platform): f.write(' MachineX64\n') else: f.write(' MachineX86\n') if kind == EXE_KIND: f.write('kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib') for dep in deps: f.write(';$(OutDir)%s.lib' % dep) # if is_x64(platform): # f.write(';..\%s\%s\%s\%s.lib' % (dep, platform, mode, dep)) # else: # f.write(';..\%s\%s\%s.lib' % (dep, mode, dep)) f.write(';%(AdditionalDependencies)\n') f.write(' \n') f.write(' \n') def add_vs_cpps(f, name): f.write(' \n') srcs = module_src_dir(name) for cppfile in glob.glob(os.path.join(srcs, '*.cpp')): f.write(' \n' % (os.sep, os.sep, cppfile)) f.write(' \n') def vs_footer(f): f.write( ' \n' ' \n' ' \n' '\n') def check_new_component(name): if (name in HEADERS) or (name in LIBS) or (name in EXES): raise MKException("Component '%s' was already defined" % name) # Add a directory containing only .h files def add_header(name): check_new_component(name) HEADERS.append(name) def find_all_deps(name, deps): new_deps = [] for dep in deps: if dep in LIBS: if not (dep in new_deps): new_deps.append(dep) for dep_dep in DEPS[dep]: if not (dep_dep in new_deps): new_deps.append(dep_dep) elif dep in HEADERS: if not (dep in new_deps): new_deps.append(dep) else: raise MKException("Unknown component '%s' at '%s'." % (dep, name)) return new_deps def add_component(name, deps, kind): check_new_component(name) if kind == LIB_KIND: LIBS.append(name) elif kind == EXE_KIND: EXES.append(name) else: raise MKException("unknown kind %s" % kind) MODULES.append(name) deps = find_all_deps(name, deps) DEPS[name] = deps print "Dependencies for '%s': %s" % (name, deps) module_dir = module_build_dir(name) mk_dir(module_dir) vs_proj = open('%s%s%s.vcxproj' % (module_dir, os.sep, name), 'w') vs_header(vs_proj) vs_project_configurations(vs_proj, name) vs_configurations(vs_proj, name, kind) vs_compilation_options(vs_proj, name, deps, kind) add_vs_cpps(vs_proj, name) vs_footer(vs_proj) def add_lib(name, deps): add_component(name, deps, LIB_KIND) def add_exe(name, deps): add_component(name, deps, EXE_KIND) def is_lib(name): # Add DLL dependency return name in LIBS def mk_vs_solution(): sln = open('%s%sz3.sln' % (BUILD_DIR, os.sep), 'w') sln.write('\n') sln.write("Microsoft Visual Studio Solution File, Format Version 11.00\n") sln.write("# Visual Studio 2010\n") for module in MODULES: gui = Name2GUI[module] deps = DEPS[module] sln.write('Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%s", "%s%s%s.vcxproj", "{%s}"\n' % (module, module, os.sep, module, mk_gui_str(gui))) if len(deps) > 0: sln.write(' ProjectSection(ProjectDependencies) = postProject\n') for dep in deps: if is_lib(dep): i = Name2GUI[dep] sln.write(' {%s} = {%s}\n' % (mk_gui_str(i), mk_gui_str(i))) sln.write(' EndProjectSection\n') sln.write('EndProject\n') sln.write('Global\n') sln.write('GlobalSection(SolutionConfigurationPlatforms) = preSolution\n') for mode in MODES: for platform in PLATFORMS: sln.write(' %s|%s = %s|%s\n' % (mode, platform, mode, platform)) sln.write('EndGlobalSection\n') sln.write('GlobalSection(ProjectConfigurationPlatforms) = postSolution\n') for module in MODULES: gui = Name2GUI[module] for mode in MODES: for platform in PLATFORMS: sln.write(' {%s}.%s|%s.ActiveCfg = %s|%s\n' % (mk_gui_str(gui), mode, platform, mode, platform)) sln.write(' {%s}.%s|%s.Build.0 = %s|%s\n' % (mk_gui_str(gui), mode, platform, mode, platform)) sln.write('EndGlobalSection\n') print "Visual Solution was generated."