buildglibc.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #!/usr/bin/python
  2. import sys, os, string, subprocess, shutil, fileinput, multiprocessing, re, resource
  3. def replaceAll(fd,searchExp,replaceExp):
  4. for line in fileinput.input(fd, inplace=1):
  5. if searchExp in line:
  6. line = line.replace(searchExp,replaceExp)
  7. sys.stdout.write(line)
  8. def prependText(filename, text) :
  9. data = ""
  10. with open(filename, 'r') as original:
  11. data = original.read()
  12. with open(filename, 'w') as modified:
  13. modified.write(text)
  14. modified.write(data)
  15. def appendText(filename, text) :
  16. with open(filename, "a") as myfile:
  17. myfile.write(text)
  18. home = os.getcwd()
  19. glibc = "glibc-2.19"
  20. glibcParent = "" # glibc parent directory
  21. glibcDir = "" # glibc dir (ex. glibc-2.19)
  22. buildDir = "glibc-build"
  23. installDir = os.path.dirname(home) + '/Runtime/'
  24. do_install = False
  25. commandStr = ""
  26. commandOutput = ""
  27. quiet = False
  28. debug_flags = ""
  29. for arg in sys.argv[1:]:
  30. if arg == '--quiet' or arg == '-q':
  31. quiet = True
  32. if arg == '--debug':
  33. debug_flags = "-g"
  34. if arg == 'install':
  35. do_install = True
  36. #########################################
  37. #### get the locations of directories ###
  38. #########################################
  39. if not do_install:
  40. if not quiet:
  41. iput = raw_input('use {0} as the source of GNU libc? ([y]/n):'.format(glibc)).lower()
  42. if not iput == 'y' and not iput == '' :
  43. glibc = raw_input('enter the glibc source to install with: ')
  44. if not quiet:
  45. iput = raw_input('{0} contains glibc code to compile? ([y]/n): '.format(glibc)).lower()
  46. if not iput == 'y' and not iput == '':
  47. glibc = raw_input('directory containing glibc code to compile: ')
  48. if os.path.isdir(glibc) :
  49. glibc = os.path.abspath(glibc)
  50. glibcParent,glibcDir = os.path.split(glibc)
  51. print 'building in {0}: {1}'.format(glibcParent, glibcDir)
  52. if not quiet:
  53. iput = raw_input('use {0} as the directory to build glibc in? ([y]/n): '.format(buildDir)).lower()
  54. if not iput == 'y' and not iput == '':
  55. buildDir = raw_input('the directory to build glibc in: ')
  56. buildDir = os.path.abspath(buildDir)
  57. print 'using build dir: {0}'.format(buildDir)
  58. if os.path.isdir(buildDir) :
  59. if not quiet:
  60. clean = raw_input('clean build (delete {0}, rerun configure, etc.)? ([y]/n): '.format(buildDir))
  61. else:
  62. clean = 'y'
  63. if clean == 'y' or clean == '':
  64. shutil.rmtree(buildDir)
  65. os.makedirs(buildDir)
  66. else :
  67. print 'Then just go to {0} and type make...'.format(buildDir)
  68. exit(0)
  69. else :
  70. os.makedirs(buildDir)
  71. if do_install and not quiet:
  72. iput = raw_input('use {0} as the directory to install glibc in? ([y]/n): '.format(installDir)).lower()
  73. if not iput == 'y' and not iput == '':
  74. installDir = raw_input('the directory to install glibc in: ')
  75. installDir = os.path.abspath(installDir)
  76. print 'using install dir: {0}'.format(installDir)
  77. ################################
  78. #### doctor glibc's Makefile ###
  79. ################################
  80. if not do_install:
  81. os.chdir(buildDir)
  82. cflags = '{0} -O2 -U_FORTIFY_SOURCE -fno-stack-protector'.format(debug_flags)
  83. extra_defs = ''
  84. disabled_features = { 'nscd' }
  85. extra_flags = '--with-tls --enable-add-ons=nptl --without-selinux --disable-test {0}'.format(' '.join(['--disable-' + f for f in disabled_features]))
  86. ## configure
  87. commandStr = r'CFLAGS="{2}" {3} {0}/configure --prefix={1} {4} | tee configure.out'.format(glibc, installDir, cflags, extra_defs, extra_flags)
  88. print commandStr
  89. commandOutput = subprocess.call(commandStr, shell=True)
  90. ## Enable parallel builds
  91. numCPUs = multiprocessing.cpu_count()
  92. ## Don't use up all the cores!
  93. numCPUs = numCPUs - 1
  94. if numCPUs == 0:
  95. numCPUs = 1
  96. replaceAll('Makefile', r'# PARALLELMFLAGS = -j4', r'PARALLELMFLAGS = -j{0}'.format(numCPUs))
  97. link_binaries = [ ( 'elf', 'ld-linux-x86-64.so.2' ),
  98. ( 'nptl', 'libpthread.so.0' ),
  99. ( '', 'libc.so' ),
  100. ( '', 'libc.so.6' ),
  101. ( 'nptl_db','libthread_db.so.1' ),
  102. ( 'math', 'libm.so.6' ),
  103. ( 'dlfcn', 'libdl.so.2' ),
  104. ( 'login', 'libutil.so.1' ),
  105. ( 'csu', 'crt1.o' ),
  106. ( 'csu', 'crti.o' ),
  107. ( 'csu', 'crtn.o' ),
  108. ( 'libos', 'liblibos.so.1' ) ]
  109. if not do_install:
  110. for (dir, bin) in link_binaries:
  111. if dir != '':
  112. print bin + ' -> ' + dir + '/' + bin
  113. os.symlink(dir + '/' + bin, bin)
  114. print '\n\n\nNow type \'make\' in \'{0}\'\n\n'.format(buildDir)
  115. if do_install:
  116. for (dir, bin) in link_binaries:
  117. print installDir + '/' + bin + ' -> ' + buildDir + '/' + dir + '/' + bin
  118. if not os.path.lexists(installDir + '/' + bin):
  119. os.symlink(os.path.relpath(buildDir + '/' + dir + '/' + bin, installDir), installDir + '/' + bin)