雖然 Intel Compiler for Linux 的 install.sh 本來就可以把 binary 安裝到 Debian 裡,不過會使用到 rpm 資料庫;我不喜歡。

因此,我擴充之前作的字串取代 python script,強化成 installer,已測試過 Intel C++ Compiler 與 Intel Fortran Compiler 8.1 與 9.0 版。

以下是這個 script 的內容,檔名請取為 icinst.py

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

"""
Intel Compiler 安裝指令稿

利用 alien 來把 Intel Compiler 安裝在 Debian 上。

在安裝完畢後,會將:
1. <INSTALLDIR>/bin 目錄內各文字檔內的安裝目錄位置取代為
   絕對路徑。
2. <INSTALLDIR>/bin 目錄內各指令稿檔案內, RedHat 系所使
   用的 'man -w' 取代為 Debian 使用的 'manpath'。

請利用參數 '-h' 取得詳細的參數說明。

$Id: icinst.py,v 1.1 2005/06/24 04:45:49 yungyuc Exp $
"""

import sys, os
from popen2 import popen2

__revision__ = "$Revision: 1.1 $".split()[1]

class parameters:
  """
  處理指令行引數。
  """
  def __init__(self):
    from optparse import OptionParser, OptionGroup
    op = OptionParser(
        usage = "usage: %prog <rpmpackage> <dir>",
        version = "%prog, " + "%s" % __revision__
        )
    op.add_option("-f", action="store_true", \
        dest="forcedel", default=False, \
        help="if destination directory exists, delete it without warning."
        )
    self.op = op
    (self.options, self.args) = self.op.parse_args()
params = parameters()

def test_prerequisite( targets ):
  """
  測試安裝所需的工具是否存在。
  """
  result = []
  for target in targets:
    so, si = popen2( "whereis %s" % target )
    if len(so.read().split()) == 1:
      result.append( False )
    else:
      result.append( True )
  return result

def subs(old, new, fn):
  """
  執行取代工作的函式
  old: 被取代字串
  new: 新取代字串
  fn:  工作的目標檔名
  """
  import re
  # 讀取來源資料
  f = open( fn, 'r' );
  orig = f.read();
  f.close()
  # 執行取代
  replaced = re.sub( old, new, orig )
  # 把取代後的整筆資料寫回檔案
  f = open( fn, 'w' )
  f.write( replaced )
  f.close()

def extract_rpm( rpmfn ):
  """
  用 alien 把 .rpm 拆開,
  傳回暫存目錄 itmp。
  """
  so, si = popen2( "fakeroot alien -s -d %s" % rpmfn )
  tbuf = so.read().split()
  itmp = tbuf[1]
  return itmp

def install_setpath( itmp, inst_destination ):
  """
  從 itmp 裡找出包含 'bin', 'lib' 等目錄的父目錄,
  據以決定 (isrc, idst) 並且傳回。
  """
  for root, dirs, filenames in os.walk( itmp ):
    if "bin" in dirs:
      skel = ""
      while root != itmp:
        root, tail = os.path.split(root)
        skel = os.path.join( tail, skel )
  isrc = os.path.join(itmp, skel)[:-1]
  idst = os.path.join(inst_destination, skel)[:-1]
  while True:
    try:
      os.renames( isrc, idst )
      break
    except OSError, (errno, strerror):
      if errno == 39:
        if not params.options.forcedel:
          sys.stderr.write(
              "[ERROR] destination dir '%s' not empty, "
              "clean up tmp dir '%s' \n" %
              ( idst, itmp )
              )
          os.system( "rm -rf %s" % itmp )
          sys.exit(39)
        else:
          sys.stderr.write(
              "[WARN] destination dir '%s' not empty, "
              "but I am forced to delete it anyway\n" %
              idst
              )
          os.system( "rm -rf %s" % idst )
  return isrc, idst

def install( rpmsrc, inst_destination ):
  """
  安裝 .rpm 到指定的目錄。
  """
  sys.stdout.write( "Extracting %s\n" % rpmsrc )
  itmp = extract_rpm( rpmsrc )
  isrc, idst = install_setpath( itmp, inst_destination )

  # 掃瞄 bin 裡的檔案型態
  so, si = popen2( 'file %s' % os.path.join(idst, "bin", '*') )
  fns = []
  for line in so.readlines():
    tokens = line.split(':')
    fns.append( tokens[:2] )

  sys.stdout.write(
      "Substituting '<INSTALLDIR>' with proper idst (%s) for: \n" %
      os.path.abspath(idst)
      )
  for fn, des in fns:
    if des.find('text') != -1:
      subs("<INSTALLDIR>", os.path.abspath(idst), fn)
      sys.stdout.write( " \""+os.path.basename(fn)+"\"" )
  sys.stdout.write( "\nin %s .\n" % os.path.join(idst, "bin"))

  sys.stdout.write(
      "Substituting 'man -w' with 'manpath' for: \n"
      )
  for fn, des in fns:
    if des.find('shell script') != -1:
      subs("man -w", "manpath", fn)
      sys.stdout.write( " \""+os.path.basename(fn)+"\"" )
  sys.stdout.write( "\nin %s .\n" % os.path.join(idst, "bin"))

  os.system( "rm -rf %s" % itmp )
  sys.stdout.write( "Installed at %s\n" % idst )

def main():
  """
  主函式。
  """

  # 檢查必要的工具程式
  prs = 'fakeroot', 'alien'
  sys.stdout.write( "Tools" )
  for pr in prs: sys.stdout.write( " '%s'" % pr )
  sys.stdout.write( " would be used to do the installation.\n" )
  rprs = test_prerequisite( prs )
  missing = False
  for pr, rpr in zip(prs,rprs):
    if rpr == False:
      sys.stdout.write( "[ERROR] tool '%s' missing.\n" % pr )
      missing = True
  if missing:
    sys.exit(5)
  sys.stdout.write( "\n" )

  if len(params.args) < 2:
    sys.stdout.write( "please specify correct parameters.\n\n" )
    params.op.print_help()
    sys.exit(-1)
  else:
    install( params.args[0], params.args[1] )

if __name__ == '__main__':
  main()
Posted by yungyuc at 22:04, 0 comment, 0 trackback.
Navigate
Add a trackback
Add a comment

Your name. (required)

Your personal website. (optional)

Your email address. Will not show in page. (suggested, but optional)

Text format is "Plain Text".

Enter "FYDlP"
© hover year to navigate month: powered by django