.travis.install.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #!/usr/bin/env python
  2. # Part of `travis-lazarus` (https://github.com/nielsAD/travis-lazarus)
  3. # License: MIT
  4. import sys
  5. import os
  6. import subprocess
  7. OS_NAME=os.environ.get('TRAVIS_OS_NAME') or 'linux'
  8. OS_PMAN={'linux': 'sudo apt-get', 'osx': 'brew'}[OS_NAME]
  9. LAZ_TMP_DIR=os.environ.get('LAZ_TMP_DIR') or 'lazarus_tmp'
  10. LAZ_REL_DEF=os.environ.get('LAZ_REL_DEF') or {'linux':'amd64', 'qemu-arm':'amd64', 'qemu-arm-static':'amd64', 'osx':'i386', 'wine':'32'}
  11. LAZ_BIN_SRC=os.environ.get('LAZ_BIN_SRC') or 'https://sourceforge.net/projects/lazarus/files/%(target)s/Lazarus%%20%(version)s/'
  12. LAZ_BIN_TGT=os.environ.get('LAZ_BIN_TGT') or {
  13. 'linux': 'Lazarus%%20Linux%%20%(release)s%%20DEB',
  14. 'qemu-arm': 'Lazarus%%20Linux%%20%(release)s%%20DEB',
  15. 'qemu-arm-static': 'Lazarus%%20Linux%%20%(release)s%%20DEB',
  16. 'osx': 'Lazarus%%20Mac%%20OS%%20X%%20%(release)s',
  17. 'wine': 'Lazarus%%20Windows%%20%(release)s%%20bits'
  18. }
  19. def install_osx_dmg(dmg):
  20. try:
  21. # Mount .dmg file and parse (automatically determined) target volumes
  22. res = subprocess.check_output('sudo hdiutil attach %s | grep /Volumes/' % (dmg), shell=True)
  23. vol = ('/Volumes/' + l.strip().split('/Volumes/')[-1] for l in res.splitlines() if '/Volumes/' in l)
  24. except:
  25. return False
  26. # Install .pkg files with installer
  27. install_pkg = lambda v, f: os.system('sudo installer -pkg %s/%s -target /' % (v, f)) == 0
  28. for v in vol:
  29. try:
  30. if not all(map(lambda f: (not f.endswith('.pkg')) or install_pkg(v, f), os.listdir(v))):
  31. return False
  32. finally:
  33. # Unmount after installation
  34. os.system('hdiutil detach %s' % (v))
  35. return True
  36. def install_lazarus_default():
  37. if OS_NAME == 'linux':
  38. # Make sure nogui is installed for headless runs
  39. pkg = 'lazarus lcl-nogui'
  40. elif OS_NAME == 'osx':
  41. # Install brew cask first
  42. pkg = 'fpc caskroom/cask/brew-cask && %s cask install fpcsrc lazarus' % (OS_PMAN)
  43. else:
  44. # Default to lazarus
  45. pkg = 'lazarus'
  46. return os.system('%s install %s' % (OS_PMAN, pkg)) == 0
  47. def install_lazarus_version(ver,rel,env):
  48. # Download all files in directory for specified Lazarus version
  49. osn = env or OS_NAME
  50. tgt = LAZ_BIN_TGT[osn] % {'release': rel or LAZ_REL_DEF[osn]}
  51. src = LAZ_BIN_SRC % {'target': tgt, 'version': ver}
  52. if os.system('echo wget -w 1 -np -m -A download %s' % (src)) != 0:
  53. return False
  54. if os.system('wget -w 1 -np -m -A download %s' % (src)) != 0:
  55. return False
  56. if os.system('grep -Rh refresh sourceforge.net/ | grep -o "https://[^\\?]*" > urllist') != 0:
  57. return False
  58. if os.system('while read url; do wget --content-disposition "${url}" -A .deb,.dmg,.exe -P %s; done < urllist' % (LAZ_TMP_DIR)) != 0:
  59. return False
  60. if osn == 'wine':
  61. # Install wine and Xvfb
  62. if os.system('sudo dpkg --add-architecture i386 && %s update && %s install xvfb wine' % (OS_PMAN, OS_PMAN)) != 0:
  63. return False
  64. # Initialize virtual display and wine directory
  65. if os.system('Xvfb %s & sleep 3 && wineboot -i' % (os.environ.get('DISPLAY') or '')) != 0:
  66. return False
  67. # Install basic Wine prerequisites, ignore failure
  68. os.system('winetricks -q corefonts')
  69. # Install all .exe files with wine
  70. process_file = lambda f: (not f.endswith('.exe')) or os.system('wine %s /VERYSILENT /DIR="c:\\lazarus"' % (f)) == 0
  71. elif osn == 'qemu-arm' or osn == 'qemu-arm-static':
  72. # Install qemu and arm cross compiling utilities
  73. if os.system('%s install libgtk2.0-dev qemu-user qemu-user-static binutils-arm-linux-gnueabi gcc-arm-linux-gnueabi' % (OS_PMAN)) != 0:
  74. return False
  75. # Install all .deb files (for linux) and cross compile later
  76. process_file = lambda f: (not f.endswith('.deb')) or os.system('sudo dpkg --force-overwrite -i %s' % (f)) == 0
  77. elif osn == 'linux':
  78. # Install dependencies
  79. if os.system('%s install libgtk2.0-dev' % (OS_PMAN)) != 0:
  80. return False
  81. # Install all .deb files
  82. process_file = lambda f: (not f.endswith('.deb')) or os.system('sudo dpkg --force-overwrite -i %s' % (f)) == 0
  83. elif osn == 'osx':
  84. # Install all .dmg files
  85. process_file = lambda f: (not f.endswith('.dmg')) or install_osx_dmg(f)
  86. else:
  87. return False
  88. # Process all downloaded files
  89. if not all(map(lambda f: process_file(os.path.join(LAZ_TMP_DIR, f)), sorted(os.listdir(LAZ_TMP_DIR)))):
  90. return False
  91. if osn == 'wine':
  92. # Set wine Path (persistently) to include Lazarus binary directory
  93. if os.system('wine cmd /C reg add HKEY_CURRENT_USER\\\\Environment /v PATH /t REG_SZ /d "%PATH%\\;c:\\\\lazarus"') != 0:
  94. return False
  95. # Redirect listed executables so they execute in wine
  96. for alias in ('fpc', 'lazbuild', 'lazarus'):
  97. os.system('echo "#!/usr/bin/env bash \nwine %(target)s \$@" | sudo tee %(name)s > /dev/null && sudo chmod +x %(name)s' % {
  98. 'target': subprocess.check_output("find $WINEPREFIX -iname '%s.exe' | head -1 " % (alias), shell=True).strip(),
  99. 'name': '/usr/bin/%s' % (alias)
  100. })
  101. elif osn == 'qemu-arm' or osn == 'qemu-arm-static':
  102. fpcv = subprocess.check_output('fpc -iV', shell=True).strip()
  103. gccv = subprocess.check_output('arm-linux-gnueabi-gcc -dumpversion', shell=True).strip()
  104. opts = ' '.join([
  105. 'CPU_TARGET=arm',
  106. 'OS_TARGET=linux',
  107. 'BINUTILSPREFIX=arm-linux-gnueabi-',
  108. # 'CROSSOPT="-CpARMV7A -CfVFPV3_D16"',
  109. 'OPT=-dFPC_ARMEL',
  110. 'INSTALL_PREFIX=/usr'
  111. ])
  112. # Compile ARM cross compiler
  113. if os.system('cd /usr/share/fpcsrc/%s && sudo make clean crossall crossinstall %s' % (fpcv, opts)) != 0:
  114. return False
  115. # Symbolic link to update default FPC cross compiler for ARM
  116. if os.system('sudo ln -sf /usr/lib/fpc/%s/ppcrossarm /usr/bin/ppcarm' % (fpcv)) != 0:
  117. return False
  118. # Update config file with paths to ARM libraries
  119. config = '\n'.join([
  120. '#INCLUDE /etc/fpc.cfg',
  121. '#IFDEF CPUARM',
  122. '-Xd','-Xt',
  123. '-XParm-linux-gnueabi-',
  124. '-Fl/usr/arm-linux-gnueabi/lib',
  125. '-Fl/usr/lib/gcc/arm-linux-gnueabi/%s' % (gccv),
  126. '-Fl/usr/lib/gcc-cross/arm-linux-gnueabi/%s' % (gccv),
  127. # '-CpARMV7A', '-CfVFPV3_D16',
  128. '#ENDIF',
  129. ''
  130. ])
  131. with open(os.path.expanduser('~/.fpc.cfg'),'w') as f:
  132. f.write(config)
  133. return True
  134. def install_lazarus(ver=None,rel=None,env=None):
  135. return install_lazarus_version(ver,rel,env) if ver else install_lazarus_default()
  136. def main():
  137. os.system('%s update' % (OS_PMAN))
  138. return install_lazarus(os.environ.get('LAZ_VER'),os.environ.get('LAZ_REL'),os.environ.get('LAZ_ENV'))
  139. if __name__ == '__main__':
  140. sys.exit(int(not main()))