genbench.py (9624B)
1 #!/usr/bin/env python 2 # encoding: utf-8 3 4 import sys 5 import os.path 6 from random import Random 7 random = Random(0) # initialise with seed to have reproductible benches 8 9 HELP_USAGE = """Usage: generate_libs.py root libs classes internal external. 10 root - Root directory where to create libs. 11 libs - Number of libraries (libraries only depend on those with smaller numbers) 12 classes - Number of classes per library 13 internal - Number of includes per file referring to that same library 14 external - Number of includes per file pointing to other libraries 15 16 For example: 17 ./genbench.py /tmp/build 200 100 15 5 18 19 To try the waf part, do: 20 waf configure build -p -j5 21 22 To test the autotools part, do: 23 touch README AUTHORS NEWS ChangeLog && 24 autoreconf --install --symlink --verbose && 25 mkdir autotools-build-dir && 26 cd autotools-build-dir && 27 ../configure --disable-shared CXXFLAGS=-Wall && 28 time make -j4 --silent && 29 time make -j4 --silent 30 """ 31 32 def lib_name(i): 33 return "lib_" + str(i) 34 35 def createHeader(name): 36 filename = name + ".h" 37 handle = open(filename, "w" ) 38 39 guard = name + '_h_' 40 handle.write ('#ifndef ' + guard + '\n'); 41 handle.write ('#define ' + guard + '\n\n'); 42 43 handle.write ('class ' + name + ' {\n'); 44 handle.write ('public:\n'); 45 handle.write (' ' + name + '();\n'); 46 handle.write (' ~' + name + '();\n'); 47 handle.write ('};\n\n'); 48 49 handle.write ('#endif\n'); 50 51 52 def createCPP(name, lib_number, classes_per_lib, internal_includes, external_includes): 53 filename = name + ".cpp" 54 handle = open(filename, "w" ) 55 56 header= name + ".h" 57 handle.write ('#include "' + header + '"\n'); 58 59 includes = random.sample(range(classes_per_lib), internal_includes) 60 for i in includes: 61 handle.write ('#include "class_' + str(i) + '.h"\n') 62 63 if (lib_number > 0): 64 includes = random.sample(range(classes_per_lib), external_includes) 65 lib_list = range(lib_number) 66 for i in includes: 67 libname = 'lib_' + str(random.choice(lib_list)) 68 handle.write ('#include <' + libname + '/' + 'class_' + str(i) + '.h>\n') 69 70 handle.write ('\n'); 71 handle.write (name + '::' + name + '() {}\n'); 72 handle.write (name + '::~' + name + '() {}\n'); 73 74 75 def createSConscript(lib_number, classes): 76 handle = open("SConscript", "w"); 77 handle.write("Import('env')\n") 78 handle.write('list = Split("""\n'); 79 for i in range(classes): 80 handle.write(' class_' + str(i) + '.cpp\n') 81 handle.write(' """)\n\n') 82 handle.write('env.StaticLibrary("lib_' + str(lib_number) + '", list)\n\n') 83 84 def createLibCMakeLists(lib_number, classes): 85 handle = open("CMakeLists.txt", "w") 86 handle.write("""add_library(lib_%s STATIC %s)\n""" % (str(lib_number), ' '.join(('class_%s' % str(i) for i in range(classes))))) 87 88 def createLibMakefile(lib_number, classes): 89 handle = open("Makefile", "w"); 90 handle.write ("""COMPILER = g++ 91 INC = -I.. 92 CCFLAGS = -g -Wall $(INC) 93 ARCHIVE = ar 94 DEPEND = makedepend 95 .SUFFIXES: .o .cpp 96 97 """) 98 handle.write ("lib = lib_" + str(lib_number) + ".a\n") 99 handle.write ("src = \\\n") 100 for i in range(classes): 101 handle.write('class_' + str(i) + '.cpp \\\n') 102 handle.write (""" 103 104 objects = $(patsubst %.cpp, %.o, $(src)) 105 106 all: depend $(lib) 107 108 $(lib): $(objects) 109 $(ARCHIVE) cr $@ $^ 110 touch $@ 111 112 .cpp.o: 113 $(COMPILER) $(CCFLAGS) -c $< 114 115 clean: 116 @rm $(objects) $(lib) 2> /dev/null 117 118 depend: 119 @$(DEPEND) $(INC) $(src) 120 121 """) 122 123 def createLibJamFile(lib_number, classes): 124 handle = open("Jamfile", "w") 125 handle.write ("SubDir TOP lib_" + str(lib_number) + " ;\n\n") 126 handle.write ("SubDirHdrs $(INCLUDES) ;\n\n") 127 handle.write ("Library lib_" + str(lib_number) + " :\n") 128 for i in range(classes): 129 handle.write(' class_' + str(i) + '.cpp\n') 130 handle.write (' ;\n') 131 132 def createVCProjFile(lib_number, classes): 133 handle = open("lib_" + str(lib_number) + ".vcproj", "w") 134 handle.write("""<?xml version="1.0" encoding="Windows-1252"?> 135 <VisualStudioProject 136 ProjectType="Visual C++" 137 Version="7.10" 138 Name=""" + '"' + lib_name(lib_number) + '"' + """ 139 ProjectGUID="{CF495178-8865-4D20-939D-AAA""" + str(lib_number) + """}" 140 Keyword="Win32Proj"> 141 <Platforms> 142 <Platform 143 Name="Win32"/> 144 </Platforms> 145 <Configurations> 146 <Configuration 147 Name="Debug|Win32" 148 OutputDirectory="Debug" 149 IntermediateDirectory="Debug" 150 ConfigurationType="4" 151 CharacterSet="2"> 152 <Tool 153 Name="VCCLCompilerTool" 154 Optimization="0" 155 PreprocessorDefinitions="WIN32;_DEBUG;_LIB" 156 AdditionalIncludeDirectories=".." 157 MinimalRebuild="TRUE" 158 BasicRuntimeChecks="3" 159 RuntimeLibrary="5" 160 UsePrecompiledHeader="0" 161 WarningLevel="3" 162 Detect64BitPortabilityProblems="TRUE" 163 DebugInformationFormat="4"/> 164 <Tool 165 Name="VCCustomBuildTool"/> 166 <Tool 167 Name="VCLibrarianTool" 168 OutputFile="$(OutDir)/""" + lib_name(lib_number) + """.lib"/> 169 </Configuration> 170 </Configurations> 171 <References> 172 </References> 173 <Files> 174 """) 175 176 for i in range(classes): 177 handle.write(r' <File RelativePath=".\class_' + str(i) + '.cpp"/>\n') 178 179 handle.write(""" 180 </Files> 181 <Globals> 182 </Globals> 183 </VisualStudioProject> 184 """) 185 186 def createLibrary(lib_number, classes, internal_includes, external_includes): 187 name = "lib_" + str(lib_number) 188 setDir(name) 189 for i in range(classes): 190 classname = "class_" + str(i) 191 createHeader(classname) 192 createCPP(classname, lib_number, classes, internal_includes, external_includes) 193 createSConscript(lib_number, classes) 194 createLibCMakeLists(lib_number, classes) 195 createLibMakefile(lib_number, classes) 196 createAutotools(lib_number, classes) 197 198 os.chdir("..") 199 200 def createCMakeLists(libs): 201 handle = open("CMakeLists.txt", "w") 202 handle.write("""project('profiling-test') 203 cmake_minimum_required(VERSION 2.8) 204 205 include_directories(${CMAKE_SOURCE_DIR}) 206 """) 207 208 for i in range(libs): 209 handle.write("""add_subdirectory(lib_%s)\n""" % str(i)) 210 211 def createSConstruct(libs): 212 handle = open("SConstruct", "w"); 213 handle.write("""env = Environment(CPPFLAGS=['-Wall'], CPPDEFINES=['LINUX'], CPPPATH=[Dir('#')])\n""") 214 handle.write("""env.Decider('timestamp-newer')\n""") 215 handle.write("""env.SetOption('implicit_cache', True)\n""") 216 handle.write("""env.SourceCode('.', None)\n""") 217 218 for i in range(libs): 219 handle.write("""env.SConscript("lib_%s/SConscript", exports=['env'])\n""" % str(i)) 220 221 def createFullMakefile(libs): 222 handle = open("Makefile", "w") 223 224 handle.write('subdirs = \\\n') 225 for i in range(libs): 226 handle.write('lib_' + str(i) + '\\\n') 227 handle.write(""" 228 229 all: $(subdirs) 230 @for i in $(subdirs); do \ 231 $(MAKE) -C $$i all; done 232 233 clean: 234 @for i in $(subdirs); do \ 235 (cd $$i; $(MAKE) clean); done 236 237 depend: 238 @for i in $(subdirs); do \ 239 (cd $$i; $(MAKE) depend); done 240 """) 241 242 def createFullJamfile(libs): 243 handle = open("Jamfile", "w") 244 handle.write ("SubDir TOP ;\n\n") 245 246 for i in range(libs): 247 handle.write('SubInclude TOP ' + lib_name(i) + ' ;\n') 248 249 handle = open("Jamrules", "w") 250 handle.write('INCLUDES = $(TOP) ;\n') 251 252 WT = """#! /usr/bin/env python 253 # encoding: utf-8 254 255 VERSION = '0.0.2' 256 APPNAME = 'build_bench' 257 top = '.' 258 out = 'out' 259 260 def options(opt): 261 opt.load('compiler_cxx') 262 263 def configure(conf): 264 conf.load('compiler_cxx') 265 266 def build(bld): 267 for i in range(%d): 268 filez = ' '.join(['lib_%%d/class_%%d.cpp' %% (i, j) for j in range(%d)]) 269 bld.stlib( 270 source = filez, 271 target = 'lib_%%d' %% i, 272 includes = '.', # include the top-level 273 ) 274 """ 275 276 def createWtop(libs, classes): 277 f = open('wscript', 'w') 278 f.write(WT % (libs, classes)) 279 f.close() 280 281 def createFullSolution(libs): 282 handle = open("solution.sln", "w") 283 handle.write("Microsoft Visual Studio Solution File, Format Version 8.00\n") 284 285 for i in range(libs): 286 project_name = lib_name(i) + '\\' + lib_name(i) + '.vcproj' 287 handle.write('Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "' + lib_name(i) + 288 '", "' + project_name + '", "{CF495178-8865-4D20-939D-AAA' + str(i) + '}"\n') 289 handle.write('EndProject\n') 290 291 def createAutotoolsTop(libs): 292 handle = open("configure.ac", "w") 293 handle.write('''\ 294 AC_INIT([bench], [1.0.0]) 295 AC_CONFIG_AUX_DIR([autotools-aux]) 296 AM_INIT_AUTOMAKE([subdir-objects nostdinc no-define tar-pax dist-bzip2]) 297 AM_PROG_LIBTOOL 298 AC_CONFIG_HEADERS([config.h]) 299 AC_CONFIG_FILES([Makefile]) 300 AC_OUTPUT 301 ''') 302 303 handle = open("Makefile.am", "w") 304 handle.write('''\ 305 AM_CPPFLAGS = -I$(srcdir) 306 lib_LTLIBRARIES = 307 ''') 308 for i in range(libs): handle.write('include lib_%s/Makefile.am\n' % str(i)) 309 310 def createAutotools(lib_number, classes): 311 312 handle = open("Makefile.am", "w") 313 handle.write('''\ 314 lib_LTLIBRARIES += lib%s.la 315 lib%s_la_SOURCES =''' % (str(lib_number), str(lib_number))) 316 for i in range(classes): handle.write(' lib_%s/class_%s.cpp' % (str(lib_number), str(i))) 317 handle.write('\n') 318 319 def setDir(dir): 320 if (not os.path.exists(dir)): 321 os.mkdir(dir) 322 os.chdir(dir) 323 324 def main(argv): 325 if len(argv) != 6: 326 print(HELP_USAGE) 327 return 328 329 root_dir = argv[1] 330 libs = int(argv[2]) 331 classes = int(argv[3]) 332 internal_includes = int(argv[4]) 333 external_includes = int(argv[5]) 334 335 setDir(root_dir) 336 for i in range(libs): 337 createLibrary(i, classes, internal_includes, external_includes) 338 339 createSConstruct(libs) 340 createCMakeLists(libs) 341 createFullMakefile(libs) 342 createWtop(libs, classes) 343 createAutotoolsTop(libs) 344 345 if __name__ == "__main__": 346 main( sys.argv ) 347 348