changeset 4067:bdcddfdc57d0

Install binary of-* packages * Makefile.in: (OCTAVE_FORGE_PKG_BUILD) call pkg-install.py if building binary packages * src/of-io-1-cross-fixes.patch: new patch * src/of-specfun-1-cross-fixes.patch: new patch * tools/pkg-install.py: new file
author John Donoghue <john.donoghue@ieee.org>
date Sat, 26 Dec 2015 22:00:59 -0500
parents 0962acdde3be
children b74ded5caa31
files Makefile.in src/of-io-1-cross-fixes.patch src/of-specfun-1-cross-fixes.patch tools/pkg-install.py
diffstat 4 files changed, 437 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.in	Wed Dec 23 08:11:04 2015 -0500
+++ b/Makefile.in	Sat Dec 26 22:00:59 2015 -0500
@@ -653,13 +653,18 @@
 endef
 else
 define OCTAVE_FORGE_PKG_BUILD
-    if [ $(ENABLE_BINARY_PACKAGES) = yes ]; then \
-      $(OCTAVE_FORGE_PKG_COMPILE); \
-    fi
-    mkdir -p '$(3)$(HOST_PREFIX)/src'
-    cd '$(1)/..' \
-      && tar cvfz $($(PKG)_FILE) $($(PKG)_SUBDIR) \
-      && $(INSTALL) -m644 '$($(PKG)_FILE)' '$(3)$(HOST_PREFIX)/src'
+    if [ $(ENABLE_BINARY_PACKAGES) = no ]; then \
+      mkdir -p '$(3)$(HOST_PREFIX)/src'; \
+      cd '$(1)/..' \
+        && tar cvfz $($(PKG)_FILE) $($(PKG)_SUBDIR) \
+        && $(INSTALL) -m644 '$($(PKG)_FILE)' '$(3)$(HOST_PREFIX)/src'; \
+    else \
+      cd '$(1)/..' && \
+      tar cfz $($(PKG)_FILE) $($(PKG)_SUBDIR) && \
+         OCTAVE_CONFIG=$(MXE_OCTAVECONFIG) TMP="$(1)/.." \
+         MKOCTFILE=$(MXE_MKOCTFILE) MAKE=$(MAKE) CONFIGURE_OPTIONS="$(HOST_AND_BUILD_CONFIGURE_OPTIONS)" $(4) \
+         $(TOP_DIR)/tools/pkg-install.py -verbose "$($(PKG)_FILE)"; \
+     fi
 endef
 endif
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/of-io-1-cross-fixes.patch	Sat Dec 26 22:00:59 2015 -0500
@@ -0,0 +1,12 @@
+diff -ur io.bak/src/Makefile io/src/Makefile
+--- io.bak/src/Makefile	2015-12-26 17:19:18.198422122 -0500
++++ io/src/Makefile	2015-12-26 17:19:46.303214603 -0500
+@@ -12,7 +12,7 @@
+ ## xmltree_read.l:150: warning: ‘bufferliteral’ defined but not used
+ ## xmltree_read.l:1221: warning: ‘input’ defined but not used
+ #MKOCTFILE = mkoctfile -Wall
+-MKOCTFILE = mkoctfile
++MKOCTFILE ?= mkoctfile
+ 
+ ifdef FLEXML
+ # flexml is a dead project.  It requires flex 2.5.4a-6  (flex-old on Debian).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/of-specfun-1-cross-fixes.patch	Sat Dec 26 22:00:59 2015 -0500
@@ -0,0 +1,13 @@
+diff -ur specfun.orig/src/Makefile specfun/src/Makefile
+--- specfun.orig/src/Makefile	2015-12-26 20:11:36.382164834 -0500
++++ specfun/src/Makefile	2015-12-26 20:12:17.449868085 -0500
+@@ -1,6 +1,8 @@
++MKOCTFILE ?= mkoctfile
++
+ all: ellipj.oct
+ 
+ %.oct: %.cc
+-	mkoctfile -s $<
++	$(MKOCTFILE) -s $<
+ 
+ clean: ; -rm *.o core octave-core *.oct *~
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/pkg-install.py	Sat Dec 26 22:00:59 2015 -0500
@@ -0,0 +1,400 @@
+#!/usr/bin/python
+import sys
+import os
+import re
+import tempfile
+import shutil
+import fnmatch
+import subprocess
+
+class Env:
+  mkoctfile = "mkoctfile";
+  octave_config = "octave-config";
+  make = "make"
+  verbose = True;
+  prefix = ""
+  pkg = ""
+  arch = ""
+  tmp = "/tmp"
+  apiversion = ""
+  bin_dir = ""
+  m_dir = ""
+  arch_dir = ""
+  config_opts = ""
+
+def show_usage():
+  print sys.argv(0), "[options] pkg1 [pkg2]"
+
+def verify_directory(dirname):
+  for f in [ "COPYING", "DESCRIPTION" ]:
+    if os.path.isfile(dirname + "/" + f) == False:
+      raise Exception, "package is missing file " + f
+
+def get_description(descfile):
+  with open(descfile, 'r') as f:
+    lines = f.read().splitlines()
+    d = dict(s.split(': ',1) for s in lines if s.find(': ') != -1)
+    return d
+
+def extract_pkg(filename, nm):
+  pkg = []
+  with open(filename, 'r') as f:
+    lines = f.read().splitlines()
+    for l in lines:
+      so = re.search(nm, l, re.M|re.S)
+      if so:
+        pkg.append(str(so.group(1)))
+  return pkg 
+
+def write_index_file(env, desc, index_nm):
+
+  with open(index_nm, 'w') as f:
+    files = os.listdir(env.m_dir)
+    classes = fnmatch.filter(files, "@*")
+
+    # check classes
+    for c in classes:
+      class_name = c
+      class_path = env.m_dir + "/" + c;
+      if os.path.isdir(class_path) == True:
+        class_files = list(class_name + "/" + a for a in os.listdir(class_path))
+        files += class_files
+   
+    # arch dependant 
+    if os.path.exists(env.arch_dir) == True:
+      archfiles = os.listdir(env.arch_dir)
+      files += archfiles
+
+    functions = []
+    for a in files:
+      if a.endswith(".m"):
+        functions.append( str(a[0:len(a)-2]) )
+      elif a.endswith(".oct"):
+        functions.append( str(a[0:len(a)-4]) )
+       
+    f.write(env.pkg + " >> " + desc['Title'] +  "\n");
+    f.write(desc['Categories'].replace(",", " ") + "\n")
+    for a in functions:
+      f.write("  " + a + "\n")
+
+def finish_installation(env, packdir):
+  # octave would run post_install.m here - instead we will copy the post_install.m 
+  # somewhere and then on initial startup, run the post_install
+  if os.path.isfile(packdir + "/post_install.m") == True:
+    if env.verbose:
+      print "Copying .. post_install.m"
+    destdir = env.prefix + "/share/octave/site/m/once_only"
+    if os.path.exists(destdir) == False:
+      os.makedirs(destdir)
+    shutil.copy2(packdir + "/post_install.m", destdir + "/" + env.pkg + "-post_install.m")
+
+def create_pkgadddel (env, packdir, nm):
+  if env.verbose:
+    print "Creating...", nm
+
+  instfid = open(env.m_dir + "/" + nm, "w")
+  if os.path.exists(env.arch_dir) == True:
+    archfid = open(env.arch_dir + "/" + nm, "w")
+  else:
+    archfid = instfid
+
+  # search inst .m files for PKG_ commands
+  instdir = packdir + "/inst"
+  files = list(instdir + "/" + a for a in os.listdir(instdir))
+  m_files = fnmatch.filter(files, "*.m")
+  for f in m_files:
+    for a in extract_pkg(f, '^[#%][#%]* *' + nm + ': *(.*)$'):
+      instfid.write("%s\n" % str(a))
+
+  # search inst .m files for PKG_ commands
+  if os.path.exists(packdir + "/src") == True:
+    srcdir = packdir + "/src"
+    files = list(srcdir + "/" + a for a in os.listdir(srcdir))
+    c_files = fnmatch.filter(files, "*.cc")
+    for f in c_files:
+      for a in extract_pkg(f, '^//* *' + nm + ': *(.*)$'):
+        archfid.write("%s\n" % str(a))
+      for a in extract_pkg(f, '^/\** *' + nm + ': *(.*) *\*/$'):
+        archfid.write("%s\n" % a)
+
+  # add PKG_XXX from packdir if exists
+  if os.path.isfile(packdir + "/" + nm) == True:
+    with open(packdir + "/" + nm, 'r') as f:
+      lines = f.read().splitlines()
+      for a in lines:
+        archfid.write("%s\n" % a)
+
+  # close files
+  if archfid != instfid:
+    archfid.close()
+    if os.stat(env.arch_dir + "/" + nm).st_size == 0:
+      os.remove(env.arch_dir + "/" + nm)
+  instfid.close()
+  if os.stat(env.m_dir + "/" + nm).st_size == 0:
+    os.remove(env.m_dir + "/" + nm)
+
+def generate_lookfor_cache (env):
+  # TODO create doc-cache
+  pass
+
+def copyfile(files, destdir):
+  if os.path.exists(destdir) == False:
+    os.mkdir(destdir)
+  for a in files:
+    if os.path.isfile(a):
+      shutil.copy2(a, destdir)
+    if os.path.isdir(a):
+      name= os.path.basename(a)
+      morefiles=(a + "/" + b for b in os.listdir(a))
+      copyfile(morefiles, destdir + "/" + name)
+
+def copy_files(env, pkgdir):
+  if os.path.exists(env.m_dir) == False:
+    os.makedirs(env.m_dir)
+  instdir = pkgdir + "/inst"
+
+  if env.verbose:
+    print "Copying m files ..."
+
+  files = list(instdir + "/" + a for a in os.listdir(instdir))
+  # filter for arch folder
+  if os.path.exists(instdir + "/" + env.arch) == True:
+    files.remove(instdir + "/" + env.arch)
+  
+  copyfile(files, env.m_dir)
+
+  if os.path.exists(instdir + "/" + env.arch) == True:
+    if env.verbose:
+      print "Copying arch files ..."
+    files = list(instdir + "/" + env.arch + "/" + a for a in os.listdir(instdir + "/" + env.arch))
+    if len(files) > 0:
+      if os.path.exists(env.arch_dir) == False:
+        os.makedirs(env.arch_dir)
+      copyfile(files, env.arch_dir)
+      shutil.rmtree(instdir + "/" + env.arch)
+
+  # packinfo
+  if env.verbose:
+    print "Copying packinfo files ..."
+  if os.path.exists(env.m_dir + "/packinfo") == False:
+    os.makedirs(env.m_dir + "/packinfo")
+  copyfile([pkgdir + "/DESCRIPTION"], env.m_dir + "/packinfo")
+  copyfile([pkgdir + "/COPYING"], env.m_dir + "/packinfo")
+  copyfile([pkgdir + "/CITATION"], env.m_dir + "/packinfo")
+  copyfile([pkgdir + "/NEWS"], env.m_dir + "/packinfo")
+  copyfile([pkgdir + "/ONEWS"], env.m_dir + "/packinfo")
+  copyfile([pkgdir + "/ChangeLog"], env.m_dir + "/packinfo")
+
+  # index file
+  if env.verbose:
+    print "Copying/creating INDEX ..."
+  if os.path.isfile(pkgdir + "/INDEX") == True:
+    copyfile([pkgdir + "/INDEX"], env.m_dir + "/packinfo")
+  else:
+    desc = get_description(pkgdir + "/DESCRIPTION")
+    write_index_file(env, desc, env.m_dir + "/packinfo/INDEX")
+
+  copyfile([pkgdir + "on_uninstall.m"], env.m_dir + "/packinfo")
+
+  # doc dir ?
+  docdir = pkgdir + "/doc"
+  if os.path.exists(docdir) == True:
+    if env.verbose:
+      print "Copying doc files ..."
+    files = (docdir + "/" + a for a in os.listdir(docdir))
+    copyfile(files, env.m_dir + "/doc")
+
+   # bin dir ?
+  bindir = pkgdir + "/bin"
+  if os.path.exists(bindir) == True:
+    if env.verbose:
+      print "Copying bin files ..."
+    files = (bindir + "/" + a for a in os.listdir(bindir))
+    copyfile(files, env.m_dir + "/bin")
+
+def configure_make(env, packdir):
+  if os.path.isdir(packdir + "/inst") == False:
+    os.mkdir(packdir + "/inst")
+
+  if os.path.isdir(packdir + "/src") == True:
+    src = packdir + "/src"
+    os.chdir(src)
+
+    if os.path.isfile(src + "/configure") == True:
+      if env.verbose:
+        print "running ./configure " + env.config_opts
+
+      os.system("./configure " + env.config_opts + "")
+
+    if os.path.isfile(src + "/Makefile") == True:
+      if env.verbose:
+        print "running make ..."
+      if os.system(env.make + " --directory '" + src + "'" ) != 0:
+        raise Exception, "make failed during build - stopping install"
+
+    # copy files to inst and inst arch
+    files = src + "/FILES"
+    instdir = packdir + "/inst"
+    archdir = instdir + "/" + env.arch
+
+    if os.path.isfile(files) == True:
+      pass # TODO yet
+    else:
+      # get .m, .oct and .mex files
+      files = os.listdir(src)
+      m_files = fnmatch.filter(files, "*.m")
+      mex_files = fnmatch.filter(files, "*.mex")
+      oct_files = fnmatch.filter(files, "*.oct")
+      files = m_files + mex_files + oct_files
+      files = list(src + "/" + s for s in files)
+
+    # split files into arch and non arch files
+    archdependant = fnmatch.filter(files, "*.mex") + fnmatch.filter(files,"*.oct")
+    archindependant = list( x for x in files if x not in archdependant )
+
+    # copy the files
+    copyfile(archindependant, instdir)
+    copyfile(archdependant, archdir)
+
+def add_package_list(env, desc):
+  #pkglist = env.prefix + "/share/octave/octave_packages"
+  #with open(pkglist, 'r') as f:
+  #  lines = f.read().splitlines()
+  # currently doing nothing for adding, will let installer do
+  pass
+  
+def uninstall_pkg(pkg,env):
+  pass
+
+def install_pkg(pkg, env):
+  pkg = os.path.abspath(pkg)
+  currdir = os.getcwd()
+
+  try:
+    ## Check that the directory in prefix exist. If it doesn't: create it!
+    tmpdir = tempfile.mkdtemp("-pkg","tmp", env.tmp)
+    os.chdir(tmpdir)
+
+    # unpack dir
+    if env.verbose:
+      os.system("tar xzvf '" + pkg + "'") 
+    else:
+      os.system("tar xzf '" + pkg + "'") 
+
+    # get list for files creates
+    files=os.listdir(tmpdir)
+    if len(files) != 1:
+      print "Expected to unpack to only one directory"
+
+    packdir = os.path.abspath(files[0])
+
+    # verify have expected min files
+    verify_directory(packdir)
+
+    # read the description file
+    desc = get_description(packdir + "/DESCRIPTION")
+
+    # make the path names
+    env.pkg = desc['Name'].lower()
+    env.m_dir = env.prefix + "/share/octave/packages/" + env.pkg + "-" + desc['Version'];
+    env.arch_dir = env.prefix + "/lib/octave/packages/" + env.pkg + "-" + desc['Version'] + "/" + env.arch + "-" + env.apiversion
+
+    configure_make (env, packdir)
+
+    # install package files
+    copy_files(env, packdir)
+    create_pkgadddel (env, packdir, "PKG_ADD");
+    create_pkgadddel (env, packdir, "PKG_DEL");
+    finish_installation(env, packdir)
+    generate_lookfor_cache (env);
+
+    # update package list
+    add_package_list(env, desc)
+  finally:
+    if env.verbose:
+      print "cleaning up"
+    os.chdir(currdir)
+    shutil.rmtree(tmpdir)
+  
+
+def pkg (args):
+  arch = ''
+
+  env = Env()
+
+  files = []
+ 
+  for a in args:
+    print a
+    c=a.split("=")
+    key=c[0]
+    if len(c) > 1:
+      val=c[1]
+    else:
+      val=""
+
+    if key == "-verbose":
+      env.verbose = True;
+    elif key == "--verbose":
+      env.verbose = True;
+    elif val == "":
+      files.append(key)
+
+
+  if os.environ.get("OCTAVE_CONFIG") != None:
+    env.octave_config = os.environ["OCTAVE_CONFIG"]
+  if os.environ.get("MAKE") != None:
+    env.make = os.environ["MAKE"]
+  if os.environ.get("MKOCTFILE") != None:
+    env.mkoctfile = os.environ["MKOCTFILE"]
+  if os.environ.get("TMP") != None:
+    env.tmp = os.environ["TMP"]
+
+  if env.verbose:
+    env.mkoctfile = env.mkoctfile + " --verbose"
+
+  # make sure we have these set up in env
+  os.environ['OCTAVE_CONFIG'] = env.octave_config;
+  os.environ['MAKE'] = env.make;
+  os.environ['MKOCTFILE'] = env.mkoctfile;
+  os.environ['TMP'] = env.tmp;
+  os.environ['OCTAVE'] = 'echo';
+
+  if os.environ.get("CC") == None:
+    os.environ['CC'] = os.popen(env.mkoctfile + " -p CC").read().rstrip("\r\n")
+  if os.environ.get("CXX") == None:
+    os.environ['CXX'] = os.popen(env.mkoctfile + " -p CXX").read().rstrip("\r\n")
+  if os.environ.get("AR") == None:
+    os.environ['AR'] = os.popen(env.mkoctfile + " -p AR").read().rstrip("\r\n")
+  if os.environ.get("RANLIB") == None:
+    os.environ['RANLIB'] = os.popen(env.mkoctfile + " -p RANLIB").read().rstrip("\r\n")
+  
+  if os.environ.get("CONFIGURE_OPTIONS") != None:
+    env.config_opts = os.environ['CONFIGURE_OPTIONS']
+
+  # work out what arch is etc from mkoctfile/config
+  if env.prefix == "":
+    env.prefix = os.popen(env.octave_config + " -p PREFIX").read().rstrip("\r\n")
+
+  env.arch = os.popen(env.octave_config + " -p CANONICAL_HOST_TYPE").read().rstrip("\r\n")
+  env.apiversion = os.popen(env.octave_config + " -p API_VERSION").read().rstrip("\r\n")
+  env.bindir = os.popen(env.octave_config + " -p BINDIR").read().rstrip("\r\n")
+
+  if env.verbose:
+    print "mkoctfile=", env.mkoctfile
+    print "arch=", env.arch
+    print "apiversion=", env.apiversion
+    print "prefix=", env.prefix
+    print "files=", files
+    print "verbose=", env.verbose
+
+  for a in files:
+    install_pkg(a, env)
+
+  return 0
+
+if __name__ == "__main__":
+  if len(sys.argv) > 1:
+    pkg(sys.argv[1:])
+  else:
+    show_usage()