Squashed 'import-layers/meta-openembedded/' content from commit 247b126

Change-Id: I40827e9ce5fba63f1cca2a0be44976ae8383b4c0
git-subtree-dir: import-layers/meta-openembedded
git-subtree-split: 247b1267bbe95719cd4877d2d3cfbaf2a2f4865a
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/import-layers/meta-openembedded/meta-oe/classes/breakpad.bbclass b/import-layers/meta-openembedded/meta-oe/classes/breakpad.bbclass
new file mode 100644
index 0000000..b3abf27
--- /dev/null
+++ b/import-layers/meta-openembedded/meta-oe/classes/breakpad.bbclass
@@ -0,0 +1,33 @@
+# Class to inherit when you want to build against Breakpad.
+# Apart from inheriting this class, you need to set BREAKPAD_BIN in
+# your recipe, and make sure that you link against libbreakpad_client.a.
+
+DEPENDS += "breakpad breakpad-native"
+
+CFLAGS += "-I${STAGING_DIR_TARGET}${includedir}/breakpad "
+CXXFLAGS += "-I${STAGING_DIR_TARGET}${includedir}/breakpad "
+
+BREAKPAD_BIN ?= ""
+
+python () {
+    breakpad_bin = d.getVar("BREAKPAD_BIN", True)
+
+    if not breakpad_bin:
+       PN = d.getVar("PN", True)
+       FILE = os.path.basename(d.getVar("FILE", True))
+       bb.error("To build %s, see breakpad.bbclass for instructions on \
+                 setting up your Breakpad configuration" % PN)
+       raise ValueError('BREAKPAD_BIN not defined in %s' % PN)
+}
+
+# Add creation of symbols here
+PACKAGE_PREPROCESS_FUNCS += "breakpad_package_preprocess"
+breakpad_package_preprocess () {
+    mkdir -p ${PKGD}/usr/share/breakpad-syms
+    find ${D} -name ${BREAKPAD_BIN} -exec sh -c "dump_syms {} > ${PKGD}/usr/share/breakpad-syms/${BREAKPAD_BIN}.sym" \;
+}
+
+PACKAGES =+ "${PN}-breakpad"
+
+FILES_${PN}-breakpad = "/usr/share/breakpad-syms"
+
diff --git a/import-layers/meta-openembedded/meta-oe/classes/gitpkgv.bbclass b/import-layers/meta-openembedded/meta-oe/classes/gitpkgv.bbclass
new file mode 100644
index 0000000..1cba00c
--- /dev/null
+++ b/import-layers/meta-openembedded/meta-oe/classes/gitpkgv.bbclass
@@ -0,0 +1,113 @@
+# gitpkgv.bbclass provides a GITPKGV and GITPKGVTAG variables to be
+# used in PKGV, as described bellow:
+#
+# - GITPKGV which is a sortable version with the format NN+GITHASH, to
+#   be used in PKGV, where
+#
+#   NN equals the total number of revs up to SRCREV
+#   GITHASH is SRCREV's (full) hash
+#
+# - GITPKGVTAG which is the output of 'git describe' allowing for
+#   automatic versioning
+#
+# gitpkgv.bbclass assumes the git repository has been cloned, and
+# contains SRCREV. So ${GITPKGV} and ${GITPKGVTAG} should never be
+# used in PV, only in PKGV.  It can handle SRCREV = ${AUTOREV}, as
+# well as SRCREV = "<some fixed git hash>".
+#
+# WARNING: if upstream repository is always using consistent and
+# sortable tag name scheme you can get sortable version including tag
+# name with ${GITPKGVTAG}, but be aware that ie tag sequence "v1.0,
+# v1.2, xtest, v2.0" will force you to increment PE to get upgradeable
+# path to v2.0 revisions
+#
+# use example:
+#
+# inherit gitpkgv
+#
+# PV = "1.0+gitr${SRCPV}"      # expands to something like 1.0+gitr3+4c1c21d7dbbf93b0df336994524313dfe0d4963b
+# PKGV = "1.0+gitr${GITPKGV}"  # expands also to something like 1.0+gitr31337+4c1c21d7d
+#
+# or
+#
+# inherit gitpkgv
+#
+# PV = "1.0+gitr${SRCPV}" # expands to something like 1.0+gitr3+4c1c21d7dbbf93b0df336994524313dfe0d4963b
+# PKGV = "${GITPKGVTAG}"  # expands to something like 1.0-31337+g4c1c21d
+#                           if there is tag v1.0 before this revision or
+#                           ver1.0-31337+g4c1c21d if there is tag ver1.0
+
+GITPKGV = "${@get_git_pkgv(d, False)}"
+GITPKGVTAG = "${@get_git_pkgv(d, True)}"
+
+def gitpkgv_drop_tag_prefix(version):
+    import re
+    if re.match("v\d", version):
+        return version[1:]
+    else:
+        return version
+
+def get_git_pkgv(d, use_tags):
+    import os
+    import bb
+    from pipes import quote
+
+    src_uri = d.getVar('SRC_URI', 1).split()
+    fetcher = bb.fetch2.Fetch(src_uri, d)
+    ud = fetcher.ud
+
+    #
+    # If SRCREV_FORMAT is set respect it for tags
+    #
+    format = d.getVar('SRCREV_FORMAT', True)
+    if not format:
+        format = 'default'
+
+    found = False
+    for url in ud.values():
+        if url.type == 'git' or url.type == 'gitsm':
+            for name, rev in url.revisions.items():
+                if not os.path.exists(url.localpath):
+                    return None
+
+                found = True
+
+                vars = { 'repodir' : quote(url.localpath),
+                         'rev' : quote(rev) }
+
+                rev = bb.fetch2.get_srcrev(d).split('+')[1]
+                rev_file = os.path.join(url.localpath, "oe-gitpkgv_" + rev)
+
+                if not os.path.exists(rev_file) or os.path.getsize(rev_file)==0:
+                    commits = bb.fetch2.runfetchcmd(
+                        "cd %(repodir)s && "
+                        "git rev-list %(rev)s -- 2> /dev/null "
+                        "| wc -l" % vars,
+                        d, quiet=True).strip().lstrip('0')
+
+                    if commits != "":
+                        oe.path.remove(rev_file, recurse=False)
+                        open(rev_file, "w").write("%d\n" % int(commits))
+                    else:
+                        commits = "0"
+                else:
+                    commits = open(rev_file, "r").readline(128).strip()
+
+                if use_tags:
+                    try:
+                        output = bb.fetch2.runfetchcmd(
+                            "cd %(repodir)s && "
+                            "git describe %(rev)s 2>/dev/null" % vars,
+                            d, quiet=True).strip()
+                        ver = gitpkgv_drop_tag_prefix(output)
+                    except Exception:
+                        ver = "0.0-%s-g%s" % (commits, rev[:7])
+                else:
+                    ver = "%s+%s" % (commits, rev[:7])
+
+                format = format.replace(name, ver)
+
+    if found:
+        return format
+
+    return '0+0'
diff --git a/import-layers/meta-openembedded/meta-oe/classes/gitver.bbclass b/import-layers/meta-openembedded/meta-oe/classes/gitver.bbclass
new file mode 100644
index 0000000..e7b5155
--- /dev/null
+++ b/import-layers/meta-openembedded/meta-oe/classes/gitver.bbclass
@@ -0,0 +1,75 @@
+# Copyright (C) 2009 Chris Larson <clarson@kergoth.com>
+# Released under the MIT license (see COPYING.MIT for the terms)
+#
+# gitver.bbclass provides a GITVER variable which is a (fairly) sane version,
+# for use in ${PV}, extracted from the ${S} git checkout, assuming it is one.
+# This is most useful in concert with srctree.bbclass.
+
+def git_drop_tag_prefix(version):
+    import re
+    if re.match("v\d", version):
+        return version[1:]
+    else:
+        return version
+
+GIT_TAGADJUST = "git_drop_tag_prefix(version)"
+GITVER = "${@get_git_pv('${S}', d, tagadjust=lambda version:${GIT_TAGADJUST})}"
+GITSHA = "${@get_git_hash('${S}', d)}"
+
+def gitrev_run(cmd, path):
+    (output, error) = bb.process.run(cmd, cwd=path)
+    return output.rstrip()
+
+def get_git_pv(path, d, tagadjust=None):
+    import os
+    import bb.process
+
+    gitdir = os.path.abspath(os.path.join(d.getVar("S", True), ".git"))
+    try:
+        ver = gitrev_run("git describe --tags", gitdir)
+    except Exception, exc:
+        bb.fatal(str(exc))
+
+    if not ver:
+        try:
+            ver = gitrev_run("git rev-parse --short HEAD", gitdir)
+        except Exception, exc:
+            bb.fatal(str(exc))
+
+        if ver:
+            return "0.0+%s" % ver
+        else:
+            return "0.0"
+    else:
+        if tagadjust:
+            ver = tagadjust(ver)
+        return ver
+
+def mark_recipe_dependencies(path, d):
+    from bb.parse import mark_dependency
+
+    gitdir = os.path.join(path, ".git")
+
+    # Force the recipe to be reparsed so the version gets bumped
+    # if the active branch is switched, or if the branch changes.
+    mark_dependency(d, os.path.join(gitdir, "HEAD"))
+
+    # Force a reparse if anything in the index changes.
+    mark_dependency(d, os.path.join(gitdir, "index"))
+
+    try:
+        ref = gitrev_run("git symbolic-ref -q HEAD", gitdir)
+    except bb.process.CmdError:
+        pass
+    else:
+        if ref:
+            mark_dependency(d, os.path.join(gitdir, ref))
+
+    # Catch new tags.
+    tagdir = os.path.join(gitdir, "refs", "tags")
+    if os.path.exists(tagdir):
+        mark_dependency(d, tagdir)
+
+python () {
+    mark_recipe_dependencies(d.getVar("S", True), d)
+}
diff --git a/import-layers/meta-openembedded/meta-oe/classes/gpe.bbclass b/import-layers/meta-openembedded/meta-oe/classes/gpe.bbclass
new file mode 100644
index 0000000..9fc1365
--- /dev/null
+++ b/import-layers/meta-openembedded/meta-oe/classes/gpe.bbclass
@@ -0,0 +1,17 @@
+DEPENDS_prepend = "virtual/libintl intltool-native "
+GPE_TARBALL_SUFFIX ?= "gz"
+SRC_URI = "${GPE_MIRROR}/${BP}.tar.${GPE_TARBALL_SUFFIX}"
+FILES_${PN} += "${datadir}/gpe ${datadir}/application-registry"
+SECTION ?= "gpe"
+
+inherit gettext
+
+gpe_do_compile() {
+    oe_runmake PREFIX=${prefix}
+}
+
+gpe_do_install() {
+    oe_runmake PREFIX=${prefix} DESTDIR=${D} install
+}
+
+EXPORT_FUNCTIONS do_compile do_install
diff --git a/import-layers/meta-openembedded/meta-oe/classes/machine_kernel_pr.bbclass b/import-layers/meta-openembedded/meta-oe/classes/machine_kernel_pr.bbclass
new file mode 100644
index 0000000..463b64d
--- /dev/null
+++ b/import-layers/meta-openembedded/meta-oe/classes/machine_kernel_pr.bbclass
@@ -0,0 +1,8 @@
+python __anonymous () {
+
+    machine_kernel_pr = d.getVar('MACHINE_KERNEL_PR', True)
+
+    if machine_kernel_pr:
+        d.setVar('PR', machine_kernel_pr)
+}
+
diff --git a/import-layers/meta-openembedded/meta-oe/classes/socorro-syms.bbclass b/import-layers/meta-openembedded/meta-oe/classes/socorro-syms.bbclass
new file mode 100644
index 0000000..3f6ae63
--- /dev/null
+++ b/import-layers/meta-openembedded/meta-oe/classes/socorro-syms.bbclass
@@ -0,0 +1,231 @@
+# Inherit this class when you want to allow Mozilla Socorro to link Breakpad's
+# stack trace information to the correct source code revision.
+# This class creates a new version of the symbol file (.sym) created by
+# Breakpad. The absolute file paths in the symbol file will be replaced by VCS,
+# branch, file and revision of the source file. That information facilitates the
+# lookup of a particular source code line in the stack trace.
+#
+# Use example:
+#
+# BREAKPAD_BIN = "YourBinary"
+# inherit socorro-syms
+#
+
+# We depend on Breakpad creating the original symbol file.
+inherit breakpad
+
+PACKAGE_PREPROCESS_FUNCS += "symbol_file_preprocess"
+PACKAGES =+ "${PN}-socorro-syms"
+FILES_${PN}-socorro-syms = "/usr/share/socorro-syms"
+
+
+python symbol_file_preprocess() {
+
+    package_dir = d.getVar("PKGD", True)
+    breakpad_bin = d.getVar("BREAKPAD_BIN", True)
+    if not breakpad_bin:
+        package_name = d.getVar("PN", True)
+        bb.error("Package %s depends on Breakpad via socorro-syms. See "
+            "breakpad.bbclass for instructions on setting up the Breakpad "
+            "configuration." % package_name)
+        raise ValueError("BREAKPAD_BIN not defined in %s." % package_name)
+
+    sym_file_name = breakpad_bin + ".sym"
+
+    breakpad_syms_dir = os.path.join(
+        package_dir, "usr", "share", "breakpad-syms")
+    socorro_syms_dir = os.path.join(
+        package_dir, "usr", "share", "socorro-syms")
+    if not os.path.exists(socorro_syms_dir):
+        os.makedirs(socorro_syms_dir)
+
+    breakpad_sym_file_path = os.path.join(breakpad_syms_dir, sym_file_name)
+    socorro_sym_file_path = os.path.join(socorro_syms_dir, sym_file_name)
+
+    create_socorro_sym_file(d, breakpad_sym_file_path, socorro_sym_file_path)
+
+    arrange_socorro_sym_file(socorro_sym_file_path, socorro_syms_dir)
+
+    return
+}
+
+
+def run_command(command, directory):
+
+    (output, error) = bb.process.run(command, cwd=directory)
+    if error:
+        raise bb.process.ExecutionError(command, error)
+
+    return output.rstrip()
+
+
+def create_socorro_sym_file(d, breakpad_sym_file_path, socorro_sym_file_path):
+
+    # In the symbol file, all source files are referenced like the following.
+    # FILE 123 /path/to/some/File.cpp
+    # Go through all references and replace the file paths with repository
+    # paths.
+    with open(breakpad_sym_file_path, 'r') as breakpad_sym_file, \
+            open(socorro_sym_file_path, 'w') as socorro_sym_file:
+
+        for line in breakpad_sym_file:
+            if line.startswith("FILE "):
+                socorro_sym_file.write(socorro_file_reference(d, line))
+            else:
+                socorro_sym_file.write(line)
+
+    return
+
+
+def socorro_file_reference(d, line):
+
+    # The 3rd position is the file path. See example above.
+    source_file_path = line.split()[2]
+    source_file_repo_path = repository_path(
+        d, os.path.normpath(source_file_path))
+
+    # If the file could be found in any repository then replace it with the
+    # repository's path.
+    if source_file_repo_path:
+        return line.replace(source_file_path, source_file_repo_path)
+
+    return line
+
+
+def repository_path(d, source_file_path):
+
+    if not os.path.isfile(source_file_path):
+        return None
+
+    # Check which VCS is used and use that to extract repository information.
+    (output, error) = bb.process.run("git status",
+        cwd=os.path.dirname(source_file_path))
+    if not error:
+        # Make sure the git repository we just found wasn't the yocto repository
+        # itself, i.e. the root of the repository we're looking for must be a
+        # child of the build directory TOPDIR.
+        git_root_dir = run_command(
+            "git rev-parse --show-toplevel", os.path.dirname(source_file_path))
+        if not git_root_dir.startswith(d.getVar("TOPDIR", True)):
+            return None
+
+        return git_repository_path(source_file_path)
+
+    # Here we can add support for other VCSs like hg, svn, cvs, etc.
+
+    # The source file isn't under any VCS so we leave it be.
+    return None
+
+
+def is_local_url(url):
+
+    return \
+        url.startswith("file:") or url.startswith("/") or url.startswith("./")
+
+
+def git_repository_path(source_file_path):
+
+    import re
+
+    # We need to extract the following.
+    # (1): VCS URL, (2): branch, (3): repo root directory name, (4): repo file,
+    # (5): revision.
+
+    source_file_dir = os.path.dirname(source_file_path)
+
+    # (1) Get the VCS URL and extract the server part, i.e. change the URL from
+    # gitolite@git.someserver.com:SomeRepo.git to just git.someserver.com.
+    source_long_url = run_command(
+        "git config --get remote.origin.url", source_file_dir)
+
+    # The URL could be a local download directory. If so, get the URL again
+    # using the local directory's config file.
+    if is_local_url(source_long_url):
+        git_config_file = os.path.join(source_long_url, "config")
+        source_long_url = run_command(
+            "git config --file %s --get remote.origin.url" % git_config_file,
+            source_file_dir)
+
+        # If also the download directory redirects to a local git directory,
+        # then we're probably using source code from a local debug branch which
+        # won't be accessible by Socorro.
+        if is_local_url(source_long_url):
+            return None
+
+    # The URL can have several formats. A full list can be found using
+    # git help clone. Extract the server part with a regex.
+    url_match = re.search(".*(://|@)([^:/]*).*", source_long_url)
+    source_server = url_match.group(2)
+
+    # (2) Get the branch for this file.
+    source_branch_list = run_command("git show-branch --list", source_file_dir)
+    source_branch_match = re.search(".*?\[(.*?)\].*", source_branch_list)
+    source_branch = source_branch_match.group(1)
+
+    # (3) Since the repo root directory name can be changed without affecting
+    # git, we need to extract the name from something more reliable.
+    # The git URL has a repo name that we could use. We just need to strip off
+    # everything around it - from gitolite@git.someserver.com:SomeRepo.git/ to
+    # SomeRepo.
+    source_repo_dir = re.sub("/$", "", source_long_url)
+    source_repo_dir = re.sub("\.git$", "", source_repo_dir)
+    source_repo_dir = re.sub(".*[:/]", "", source_repo_dir)
+
+    # (4) We know the file but want to remove all of the build system dependent
+    # path up to and including the repository's root directory, e.g. remove
+    # /home/someuser/dev/repo/projectx/
+    source_toplevel = run_command(
+        "git rev-parse --show-toplevel", source_file_dir)
+    source_toplevel = source_toplevel + os.path.sep
+    source_file = source_file_path.replace(source_toplevel, "")
+
+    # (5) Get the source revision this file is part of.
+    source_revision = run_command("git rev-parse HEAD", source_file_dir)
+
+    # Assemble the repository path according to the Socorro format.
+    socorro_reference = "git:%s/%s:%s/%s:%s" % \
+        (source_server, source_branch,
+        source_repo_dir, source_file,
+        source_revision)
+
+    return socorro_reference
+
+
+def arrange_socorro_sym_file(socorro_sym_file_path, socorro_syms_dir):
+
+    import re
+
+    # Breakpad's minidump_stackwalk needs a certain directory structure in order
+    # to find correct symbols when extracting a stack trace out of a minidump.
+    # The directory structure must look like the following.
+    # YourBinary/<hash>/YourBinary.sym
+    # YourLibrary.so/<hash>/YourLibrary.so.sym
+    # To be able to create such structure we need to extract the hash value that
+    # is found in each symbol file. The header of the symbol file looks
+    # something like this:
+    # MODULE Linux x86 A079E473106CE51C74C1C25AF536CCD30 YourBinary
+    # See
+    # http://code.google.com/p/google-breakpad/wiki/LinuxStarterGuide
+
+    # Create the directory with the same name as the binary.
+    binary_dir = re.sub("\.sym$", "", socorro_sym_file_path)
+    if not os.path.exists(binary_dir):
+        os.makedirs(binary_dir)
+
+    # Get the hash from the header of the symbol file.
+    with open(socorro_sym_file_path, 'r') as socorro_sym_file:
+
+        # The hash is the 4th argument of the first line.
+        sym_file_hash = socorro_sym_file.readline().split()[3]
+
+    # Create the hash directory.
+    hash_dir = os.path.join(binary_dir, sym_file_hash)
+    if not os.path.exists(hash_dir):
+        os.makedirs(hash_dir)
+
+    # Move the symbol file to the hash directory.
+    sym_file_name = os.path.basename(socorro_sym_file_path)
+    os.rename(socorro_sym_file_path, os.path.join(hash_dir, sym_file_name))
+
+    return
+