summaryrefslogtreecommitdiff
path: root/classes/mono.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'classes/mono.bbclass')
-rw-r--r--classes/mono.bbclass218
1 files changed, 218 insertions, 0 deletions
diff --git a/classes/mono.bbclass b/classes/mono.bbclass
new file mode 100644
index 0000000000..c50274ed0c
--- /dev/null
+++ b/classes/mono.bbclass
@@ -0,0 +1,218 @@
+def mono_get_file_table(packageversion, d):
+ # The packageversion is currently ignored, but might be used in the future
+ # if more than one mono version is available and different versions
+ # need to use different tables
+
+ import bb, sys, os, glob, commands
+ curdir = os.path.dirname( bb.data.getVar('FILE', d, 1) )
+ if curdir not in sys.path: sys.path.append( curdir )
+ from mono_files import debian_mono_file_table
+
+ # mono-jay is not being built (for all platforms at least)
+ IGNORE = ("mono-jay", )
+ file_table = [
+ # Standard package
+ {"name": "mono-doc"},
+
+ # Virtual packages
+ {"name": "mono"},
+ {"name": "mono-runtime"},
+
+ # Not provided by Debian:
+ {"name": "libnunit2.2-cil",
+ "patterns": [
+ "/usr/lib/mono/gac/nunit.*/2.2.*",
+ "/usr/lib/mono/1.0/nunit.*.dll",
+ "/usr/lib/pkgconfig/mono-nunit.pc",
+ ],
+ "assemblies": [
+ ("nunit.core", "2.2.0.0"),
+ ("nunit.framework", "2.2.0.0"),
+ ("nunit.util", "2.2.0.0"),
+ ("nunit.mocks", "2.2.8.0"),
+ ],
+ },
+ {"name": "libmono-cecil0.5-cil",
+ "patterns": [
+ "/usr/lib/mono/gac/Mono.Cecil/0.5.*",
+ ],
+ "assemblies": [
+ ("Mono.Cecil", "0.5.*"),
+ ],
+ },
+ {"name": "libmono-db2-1.0-cil",
+ "patterns": [
+ "/usr/lib/mono/gac/IBM.Data.DB2/1.0*",
+ "/usr/lib/mono/1.0/IBM.Data.DB2.dll",
+ ],
+ "assemblies": [
+ ("IBM.Data.DB2", "1.0*"),
+ ],
+ },
+ ] + debian_mono_file_table
+
+ file_table = [e for e in file_table
+ if not (e.has_key("name") and e["name"] in IGNORE)]
+
+ return file_table
+
+def mono_find_provides_and_requires(files, d):
+ provides = []
+ requires = []
+
+ import bb, os, commands
+
+ pathprefix = "export PATH=%s; export LANG=; export LC_ALL=; " % bb.data.getVar('PATH', d, 1)
+ for filename in files:
+ if not filename.endswith(".dll") and not filename.endswith(".exe"):
+ continue
+ if not os.path.isfile(filename) or os.path.islink(filename):
+ continue
+
+ ## Provides
+ name, version = None, None
+
+ ret, result = commands.getstatusoutput("%smonodis --assembly '%s'" % (pathprefix, filename))
+ if ret:
+ bb.error("raw_provides_and_requires: monodis --assembly '%s' failed, dependency information will be inaccurate" % filename)
+ continue
+ for line in result.splitlines():
+ if not ":" in line: continue
+ key, value = line.split(":", 1)
+ if key.strip() == "Name":
+ name = value.strip()
+ elif key.strip() == "Version":
+ version = value.strip()
+ if name is not None and version is not None:
+ if (name, version) not in provides:
+ provides.append( (name, version) )
+
+ ## Requires
+ name, version = None, None
+ ret, result = commands.getstatusoutput("%smonodis --assemblyref '%s'" % (pathprefix, filename))
+ if ret:
+ bb.error("raw_provides_and_requires: monodis --assemblyref '%s' failed, dependency information will be inaccurate" % filename)
+ continue
+ for line in result.splitlines():
+ if not "=" in line: continue
+ key, value = line.split("=", 1)
+ if ":" in key and key.split(":",1)[1].strip() == "Version":
+ version = value.strip()
+ elif key.strip() == "Name":
+ name = value.strip()
+ if name is not None and version is not None:
+ if (name, version) not in requires:
+ requires.append( (name, version) )
+ name, version = None, None
+
+ # Remove everything from requires that's already in provides as it's not actually required
+ # to be provided externally
+ requires = [e for e in requires if not e in provides]
+ return provides, requires
+
+python mono_do_clilibs() {
+ import bb, os, re, os.path
+
+ exclude_clilibs = bb.data.getVar('EXCLUDE_FROM_CLILIBS', d, 0)
+ if exclude_clilibs:
+ bb.note("not generating clilibs")
+ return
+
+ lib_re = re.compile("^lib.*\.so")
+ libdir_re = re.compile(".*/lib$")
+
+ packages = bb.data.getVar('PACKAGES', d, 1)
+
+ workdir = bb.data.getVar('WORKDIR', d, 1)
+ if not workdir:
+ bb.error("WORKDIR not defined")
+ return
+
+ staging = bb.data.getVar('STAGING_DIR', d, 1)
+ if not staging:
+ bb.error("STAGING_DIR not defined")
+ return
+
+ pkgdest = bb.data.getVar('PKGDEST', d, 1)
+
+ clilibs_dir = os.path.join(staging, "clilibs")
+ bb.mkdirhier(clilibs_dir)
+
+ provides, requires = {}, {}
+ private_libs = bb.data.getVar('PRIVATE_CLILIBS', d, 1)
+ for pkg in packages.split():
+ bb.debug(2, "calculating clilib provides for %s" % pkg)
+
+ files_to_check = []
+ top = os.path.join(pkgdest, pkg)
+ for root, dirs, files in os.walk(top):
+ for file in files:
+ path = os.path.join(root, file)
+ if file.endswith(".exe") or file.endswith(".dll"):
+ files_to_check.append( path )
+ provides[pkg], requires[pkg] = mono_find_provides_and_requires(files_to_check, d)
+ clilibs_file = os.path.join(clilibs_dir, pkg + ".list")
+ if os.path.exists(clilibs_file):
+ os.remove(clilibs_file)
+ if len(provides[pkg]) > 0:
+ fd = open(clilibs_file, 'w')
+ for s in provides[pkg]:
+ fd.write(" ".join(s) + '\n')
+ fd.close()
+
+ clilib_provider = {}
+ list_re = re.compile('^(.*)\.list$')
+ for file in os.listdir(clilibs_dir):
+ m = list_re.match(file)
+ if m:
+ dep_pkg = m.group(1)
+ fd = open(os.path.join(clilibs_dir, file))
+ lines = fd.readlines()
+ fd.close()
+ for l in lines:
+ clilib_provider[tuple(l.rstrip().split())] = dep_pkg
+
+ for pkg in packages.split():
+ bb.debug(2, "calculating clilib requirements for %s" % pkg)
+
+ deps = []
+ for n in requires[pkg]:
+ if n in clilib_provider.keys():
+ dep_pkg = clilib_provider[n]
+
+ if dep_pkg == pkg:
+ continue
+
+ if not dep_pkg in deps:
+ deps.append(dep_pkg)
+ else:
+ bb.note("Couldn't find CLI library provider for %s" % (n,))
+
+ deps_file = os.path.join(pkgdest, pkg + ".clilibdeps")
+ if os.path.exists(deps_file):
+ os.remove(deps_file)
+ if len(deps) > 0:
+ fd = open(deps_file, 'w')
+ for dep in deps:
+ fd.write(dep + '\n')
+ fd.close()
+}
+
+def mono_after_parse(d):
+ import bb
+ # Insert mono_do_clilibs into PACKAGEFUNCS
+ # Needs to be called after populate_packages, but before read_shlibdeps
+ PACKAGEFUNCS = bb.data.getVar("PACKAGEFUNCS", d, 1)
+ if PACKAGEFUNCS:
+ PACKAGEFUNCS = PACKAGEFUNCS.split()
+ if "read_shlibdeps" in PACKAGEFUNCS:
+ i = PACKAGEFUNCS.index("read_shlibdeps")
+ PACKAGEFUNCS.insert(i, "mono_do_clilibs")
+ elif "populate_packages" in PACKAGEFUNCS:
+ i = PACKAGEFUNCS.index("populate_packages")
+ PACKAGEFUNCS.insert(i+1, "mono_do_clilibs")
+ bb.data.setVar("PACKAGEFUNCS", " ".join(PACKAGEFUNCS), d)
+
+python () {
+ mono_after_parse(d)
+}