genbench.py 9.4 KB

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