From bcaec55e4e64f6bca21cf0e50eaec787bd29b735 Mon Sep 17 00:00:00 2001 From: Henryk Ploetz Date: Tue, 2 Oct 2007 18:51:53 +0000 Subject: mono 1.2.5.1: added mono.bbclass, many changes required for packaging New file: packages/mono/mono-mcs-intermediate_1.2.5.1.bb Compiles mono in native mode with standard prefix, then tars up the resulting tree and puts the tarfile into staging New file: packages/mono/mono_files.py Automatically generated using collect-path.py (attached to this mail) and contains a list that maps file patterns to package names (and contained assemblies, see below). New file: classes/mono.bbclass Has a helper function for the list that maps file patterns to package names and assemblies (see below). Also has a function mono_do_clilibs and inserts that function into PACKAGEFUNCS. This function calls mono_find_provides_and_requires which finds out (through calls to monodis --assembly and monodis --assemblyref) which assemblies are provided and required by a particular package. mono_do_clilibs then puts the information about provided assemblies into ${STAGING_DIR}/clilibs/${packagename}.list and information about the required packages into ${PKGDEST}/{packagename}.clilibdeps where it will later be picked up by the modified read_shlibdeps. Originally I had dependency resolution through the partial list in mono_files.py but obviously this doens't scale, so I implemented the new method with mono_do_clilibs. The benefit is now that I don't really need the extra information in mono_files.py anymore and can in principle get rid of mono_get_file_table and related code. Instead it should be possible to modify collect-paths.py to output bitbake .inc code (e.g. PACKAGES = "..." and a whole lot of FILES_... = "...") instead of python code. There's still the minor problem of how to handle the .mdb files, that's why I didn't implement it yet but instead opted for an approach that I knew would work. (Debian just puts the .mdb files into the individual packages, while I would argue that they do belong into corresponding -dbg packages.) Modified file: classes/package.bbclass In read_shlibdeps I folded the two identical code blocks dealing with *.shlibdeps and *.pcdeps into one and added *.clilibdeps (generated by mono_do_clilibs above). Modified file: packages/mono/mono_1.2.5.1.bb Add the mono-mcs-intermediate workaround. Add a whole lot of python code in populate_packages_prepend in order to split up the packages based on information from mono_files.py (via mono.bbclass' mono_get_file_table). As I said above a lot of this code can hopefully be replaced in the future. --- classes/mono.bbclass | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 classes/mono.bbclass (limited to 'classes/mono.bbclass') diff --git a/classes/mono.bbclass b/classes/mono.bbclass new file mode 100644 index 0000000000..dcf5f7272c --- /dev/null +++ b/classes/mono.bbclass @@ -0,0 +1,214 @@ +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() +} + +python() { + # 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) +} -- cgit v1.2.3 From c682389deb5384a1a18c9755376b0d255a9c3482 Mon Sep 17 00:00:00 2001 From: Henryk Ploetz Date: Wed, 3 Oct 2007 01:04:46 +0000 Subject: mono.bbclass: fix whitespace problem - fix for the problem experienced by scruggs on IRC today. There was an inconsistency in the amount and type of whitespace used in the python anonymous blocks between mono.bbclass and multimachine.bbclass. - fixed a small problem in the error output of mono_do_clilibs --- classes/mono.bbclass | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'classes/mono.bbclass') diff --git a/classes/mono.bbclass b/classes/mono.bbclass index dcf5f7272c..c50274ed0c 100644 --- a/classes/mono.bbclass +++ b/classes/mono.bbclass @@ -186,7 +186,7 @@ python mono_do_clilibs() { if not dep_pkg in deps: deps.append(dep_pkg) else: - bb.note("Couldn't find CLI library provider for %s" % n) + 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): @@ -198,7 +198,8 @@ python mono_do_clilibs() { fd.close() } -python() { +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) @@ -211,4 +212,7 @@ python() { i = PACKAGEFUNCS.index("populate_packages") PACKAGEFUNCS.insert(i+1, "mono_do_clilibs") bb.data.setVar("PACKAGEFUNCS", " ".join(PACKAGEFUNCS), d) + +python () { + mono_after_parse(d) } -- cgit v1.2.3 From 8afc20e8be1f622e700f9f6a5dc3717577bc90d2 Mon Sep 17 00:00:00 2001 From: Henryk Ploetz Date: Sun, 7 Oct 2007 19:32:36 +0000 Subject: mono: clean up packaging --- classes/mono.bbclass | 58 ---------------------------------------------------- 1 file changed, 58 deletions(-) (limited to 'classes/mono.bbclass') diff --git a/classes/mono.bbclass b/classes/mono.bbclass index c50274ed0c..b7c5439b86 100644 --- a/classes/mono.bbclass +++ b/classes/mono.bbclass @@ -1,61 +1,3 @@ -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 = [] -- cgit v1.2.3 From 44d93f432e5c3aff0fb7e31c508e8100b640365e Mon Sep 17 00:00:00 2001 From: Henryk Ploetz Date: Wed, 17 Oct 2007 08:16:52 +0000 Subject: mono.bbclass: Stage all .dll files that have been packaged so that other packages can compile against them --- classes/mono.bbclass | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'classes/mono.bbclass') diff --git a/classes/mono.bbclass b/classes/mono.bbclass index b7c5439b86..ccb16d9acc 100644 --- a/classes/mono.bbclass +++ b/classes/mono.bbclass @@ -140,6 +140,23 @@ python mono_do_clilibs() { fd.close() } +do_mono_stage() { + if [ "${INHIBIT_MONO_STAGE}" = "1" ] + then + return + fi + + for package in ${PACKAGES}; do + if [ -d "${PKGDEST}/${package}/${libdir}" ]; then + cd "${PKGDEST}/${package}/${libdir}" + for file in `find . -iname "*.dll"`; do + cp --parent -fpPR "${file}" "${STAGING_LIBDIR}/" + done + fi + done +} +addtask mono_stage after do_package before do_populate_staging + def mono_after_parse(d): import bb # Insert mono_do_clilibs into PACKAGEFUNCS -- cgit v1.2.3