Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame^] | 1 | # These directories will be staged in the sysroot |
| 2 | SYSROOT_DIRS = " \ |
| 3 | ${includedir} \ |
| 4 | ${libdir} \ |
| 5 | ${base_libdir} \ |
| 6 | ${nonarch_base_libdir} \ |
| 7 | ${datadir} \ |
| 8 | " |
| 9 | |
| 10 | # These directories are also staged in the sysroot when they contain files that |
| 11 | # are usable on the build system |
| 12 | SYSROOT_DIRS_NATIVE = " \ |
| 13 | ${bindir} \ |
| 14 | ${sbindir} \ |
| 15 | ${base_bindir} \ |
| 16 | ${base_sbindir} \ |
| 17 | ${libexecdir} \ |
| 18 | ${sysconfdir} \ |
| 19 | ${localstatedir} \ |
| 20 | " |
| 21 | SYSROOT_DIRS_append_class-native = " ${SYSROOT_DIRS_NATIVE}" |
| 22 | SYSROOT_DIRS_append_class-cross = " ${SYSROOT_DIRS_NATIVE}" |
| 23 | SYSROOT_DIRS_append_class-crosssdk = " ${SYSROOT_DIRS_NATIVE}" |
| 24 | |
| 25 | # These directories will not be staged in the sysroot |
| 26 | SYSROOT_DIRS_BLACKLIST = " \ |
| 27 | ${mandir} \ |
| 28 | ${docdir} \ |
| 29 | ${infodir} \ |
| 30 | ${datadir}/locale \ |
| 31 | ${datadir}/applications \ |
| 32 | ${datadir}/fonts \ |
| 33 | ${datadir}/pixmaps \ |
| 34 | " |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 35 | |
| 36 | sysroot_stage_dir() { |
| 37 | src="$1" |
| 38 | dest="$2" |
| 39 | # if the src doesn't exist don't do anything |
| 40 | if [ ! -d "$src" ]; then |
| 41 | return |
| 42 | fi |
| 43 | |
| 44 | mkdir -p "$dest" |
| 45 | ( |
| 46 | cd $src |
| 47 | find . -print0 | cpio --null -pdlu $dest |
| 48 | ) |
| 49 | } |
| 50 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 51 | sysroot_stage_dirs() { |
| 52 | from="$1" |
| 53 | to="$2" |
| 54 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame^] | 55 | for dir in ${SYSROOT_DIRS}; do |
| 56 | sysroot_stage_dir "$from$dir" "$to$dir" |
| 57 | done |
| 58 | |
| 59 | # Remove directories we do not care about |
| 60 | for dir in ${SYSROOT_DIRS_BLACKLIST}; do |
| 61 | rm -rf "$to$dir" |
| 62 | done |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 63 | } |
| 64 | |
| 65 | sysroot_stage_all() { |
| 66 | sysroot_stage_dirs ${D} ${SYSROOT_DESTDIR} |
| 67 | } |
| 68 | |
| 69 | python sysroot_strip () { |
| 70 | import stat, errno |
| 71 | |
| 72 | dvar = d.getVar('SYSROOT_DESTDIR', True) |
| 73 | pn = d.getVar('PN', True) |
| 74 | |
| 75 | os.chdir(dvar) |
| 76 | |
| 77 | # Return type (bits): |
| 78 | # 0 - not elf |
| 79 | # 1 - ELF |
| 80 | # 2 - stripped |
| 81 | # 4 - executable |
| 82 | # 8 - shared library |
| 83 | # 16 - kernel module |
| 84 | def isELF(path): |
| 85 | type = 0 |
| 86 | ret, result = oe.utils.getstatusoutput("file \"%s\"" % path.replace("\"", "\\\"")) |
| 87 | |
| 88 | if ret: |
| 89 | bb.error("split_and_strip_files: 'file %s' failed" % path) |
| 90 | return type |
| 91 | |
| 92 | # Not stripped |
| 93 | if "ELF" in result: |
| 94 | type |= 1 |
| 95 | if "not stripped" not in result: |
| 96 | type |= 2 |
| 97 | if "executable" in result: |
| 98 | type |= 4 |
| 99 | if "shared" in result: |
| 100 | type |= 8 |
| 101 | return type |
| 102 | |
| 103 | |
| 104 | elffiles = {} |
| 105 | inodes = {} |
| 106 | libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir", True)) |
| 107 | baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir", True)) |
| 108 | if (d.getVar('INHIBIT_SYSROOT_STRIP', True) != '1'): |
| 109 | # |
| 110 | # First lets figure out all of the files we may have to process |
| 111 | # |
| 112 | for root, dirs, files in os.walk(dvar): |
| 113 | for f in files: |
| 114 | file = os.path.join(root, f) |
| 115 | |
| 116 | try: |
| 117 | ltarget = oe.path.realpath(file, dvar, False) |
| 118 | s = os.lstat(ltarget) |
| 119 | except OSError as e: |
| 120 | (err, strerror) = e.args |
| 121 | if err != errno.ENOENT: |
| 122 | raise |
| 123 | # Skip broken symlinks |
| 124 | continue |
| 125 | if not s: |
| 126 | continue |
| 127 | # Check its an excutable |
| 128 | if (s[stat.ST_MODE] & stat.S_IXUSR) or (s[stat.ST_MODE] & stat.S_IXGRP) or (s[stat.ST_MODE] & stat.S_IXOTH) \ |
| 129 | or ((file.startswith(libdir) or file.startswith(baselibdir)) and ".so" in f): |
| 130 | # If it's a symlink, and points to an ELF file, we capture the readlink target |
| 131 | if os.path.islink(file): |
| 132 | continue |
| 133 | |
| 134 | # It's a file (or hardlink), not a link |
| 135 | # ...but is it ELF, and is it already stripped? |
| 136 | elf_file = isELF(file) |
| 137 | if elf_file & 1: |
| 138 | if elf_file & 2: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 139 | if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn, True) or "").split(): |
| 140 | bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn)) |
| 141 | else: |
| 142 | bb.warn("File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 143 | continue |
| 144 | |
| 145 | if s.st_ino in inodes: |
| 146 | os.unlink(file) |
| 147 | os.link(inodes[s.st_ino], file) |
| 148 | else: |
| 149 | inodes[s.st_ino] = file |
| 150 | # break hardlink |
| 151 | bb.utils.copyfile(file, file) |
| 152 | elffiles[file] = elf_file |
| 153 | |
| 154 | # |
| 155 | # Now strip them (in parallel) |
| 156 | # |
| 157 | strip = d.getVar("STRIP", True) |
| 158 | sfiles = [] |
| 159 | for file in elffiles: |
| 160 | elf_file = int(elffiles[file]) |
| 161 | #bb.note("Strip %s" % file) |
| 162 | sfiles.append((file, elf_file, strip)) |
| 163 | |
| 164 | oe.utils.multiprocess_exec(sfiles, oe.package.runstrip) |
| 165 | } |
| 166 | |
| 167 | do_populate_sysroot[dirs] = "${SYSROOT_DESTDIR}" |
| 168 | do_populate_sysroot[umask] = "022" |
| 169 | |
| 170 | addtask populate_sysroot after do_install |
| 171 | |
| 172 | SYSROOT_PREPROCESS_FUNCS ?= "" |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 173 | SYSROOT_DESTDIR = "${WORKDIR}/sysroot-destdir" |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 174 | SYSROOT_LOCK = "${STAGING_DIR}/staging.lock" |
| 175 | |
| 176 | # We clean out any existing sstate from the sysroot if we rerun configure |
| 177 | python sysroot_cleansstate () { |
| 178 | ss = sstate_state_fromvars(d, "populate_sysroot") |
| 179 | sstate_clean(ss, d) |
| 180 | } |
| 181 | do_configure[prefuncs] += "sysroot_cleansstate" |
| 182 | |
| 183 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame^] | 184 | BB_SETSCENE_VERIFY_FUNCTION2 = "sysroot_checkhashes2" |
| 185 | |
| 186 | def sysroot_checkhashes2(covered, tasknames, fns, d, invalidtasks): |
| 187 | problems = set() |
| 188 | configurefns = set() |
| 189 | for tid in invalidtasks: |
| 190 | if tasknames[tid] == "do_configure" and tid not in covered: |
| 191 | configurefns.add(fns[tid]) |
| 192 | for tid in covered: |
| 193 | if tasknames[tid] == "do_populate_sysroot" and fns[tid] in configurefns: |
| 194 | problems.add(tid) |
| 195 | return problems |
| 196 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 197 | BB_SETSCENE_VERIFY_FUNCTION = "sysroot_checkhashes" |
| 198 | |
| 199 | def sysroot_checkhashes(covered, tasknames, fnids, fns, d, invalidtasks = None): |
| 200 | problems = set() |
| 201 | configurefnids = set() |
| 202 | if not invalidtasks: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame^] | 203 | invalidtasks = range(len(tasknames)) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 204 | for task in invalidtasks: |
| 205 | if tasknames[task] == "do_configure" and task not in covered: |
| 206 | configurefnids.add(fnids[task]) |
| 207 | for task in covered: |
| 208 | if tasknames[task] == "do_populate_sysroot" and fnids[task] in configurefnids: |
| 209 | problems.add(task) |
| 210 | return problems |
| 211 | |
| 212 | python do_populate_sysroot () { |
| 213 | bb.build.exec_func("sysroot_stage_all", d) |
| 214 | bb.build.exec_func("sysroot_strip", d) |
| 215 | for f in (d.getVar('SYSROOT_PREPROCESS_FUNCS', True) or '').split(): |
| 216 | bb.build.exec_func(f, d) |
| 217 | pn = d.getVar("PN", True) |
| 218 | multiprov = d.getVar("MULTI_PROVIDER_WHITELIST", True).split() |
| 219 | provdir = d.expand("${SYSROOT_DESTDIR}${base_prefix}/sysroot-providers/") |
| 220 | bb.utils.mkdirhier(provdir) |
| 221 | for p in d.getVar("PROVIDES", True).split(): |
| 222 | if p in multiprov: |
| 223 | continue |
| 224 | p = p.replace("/", "_") |
| 225 | with open(provdir + p, "w") as f: |
| 226 | f.write(pn) |
| 227 | } |
| 228 | |
| 229 | do_populate_sysroot[vardeps] += "${SYSROOT_PREPROCESS_FUNCS}" |
| 230 | do_populate_sysroot[vardepsexclude] += "MULTI_PROVIDER_WHITELIST" |
| 231 | |
| 232 | SSTATETASKS += "do_populate_sysroot" |
| 233 | do_populate_sysroot[cleandirs] = "${SYSROOT_DESTDIR}" |
| 234 | do_populate_sysroot[sstate-inputdirs] = "${SYSROOT_DESTDIR}" |
| 235 | do_populate_sysroot[sstate-outputdirs] = "${STAGING_DIR_HOST}/" |
| 236 | do_populate_sysroot[stamp-extra-info] = "${MACHINE}" |
| 237 | |
| 238 | python do_populate_sysroot_setscene () { |
| 239 | sstate_setscene(d) |
| 240 | } |
| 241 | addtask do_populate_sysroot_setscene |
| 242 | |
| 243 | |