blob: bfabd06f3f1aeaf152b532c82cf8bd8ad9fad3f5 [file] [log] [blame]
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001# These directories will be staged in the sysroot
2SYSROOT_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
12SYSROOT_DIRS_NATIVE = " \
13 ${bindir} \
14 ${sbindir} \
15 ${base_bindir} \
16 ${base_sbindir} \
17 ${libexecdir} \
18 ${sysconfdir} \
19 ${localstatedir} \
20"
21SYSROOT_DIRS_append_class-native = " ${SYSROOT_DIRS_NATIVE}"
22SYSROOT_DIRS_append_class-cross = " ${SYSROOT_DIRS_NATIVE}"
23SYSROOT_DIRS_append_class-crosssdk = " ${SYSROOT_DIRS_NATIVE}"
24
25# These directories will not be staged in the sysroot
26SYSROOT_DIRS_BLACKLIST = " \
27 ${mandir} \
28 ${docdir} \
29 ${infodir} \
30 ${datadir}/locale \
31 ${datadir}/applications \
32 ${datadir}/fonts \
33 ${datadir}/pixmaps \
34"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050035
36sysroot_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 Williamsc124f4f2015-09-15 14:41:29 -050051sysroot_stage_dirs() {
52 from="$1"
53 to="$2"
54
Patrick Williamsc0f7c042017-02-23 20:41:17 -060055 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 Williamsc124f4f2015-09-15 14:41:29 -050063}
64
65sysroot_stage_all() {
66 sysroot_stage_dirs ${D} ${SYSROOT_DESTDIR}
67}
68
69python 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 Williamsd8c66bc2016-06-20 12:57:21 -0500139 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 Williamsc124f4f2015-09-15 14:41:29 -0500143 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
167do_populate_sysroot[dirs] = "${SYSROOT_DESTDIR}"
168do_populate_sysroot[umask] = "022"
169
170addtask populate_sysroot after do_install
171
172SYSROOT_PREPROCESS_FUNCS ?= ""
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500173SYSROOT_DESTDIR = "${WORKDIR}/sysroot-destdir"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500174
175# We clean out any existing sstate from the sysroot if we rerun configure
176python sysroot_cleansstate () {
177 ss = sstate_state_fromvars(d, "populate_sysroot")
178 sstate_clean(ss, d)
179}
180do_configure[prefuncs] += "sysroot_cleansstate"
181
182
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600183BB_SETSCENE_VERIFY_FUNCTION2 = "sysroot_checkhashes2"
184
185def sysroot_checkhashes2(covered, tasknames, fns, d, invalidtasks):
186 problems = set()
187 configurefns = set()
188 for tid in invalidtasks:
189 if tasknames[tid] == "do_configure" and tid not in covered:
190 configurefns.add(fns[tid])
191 for tid in covered:
192 if tasknames[tid] == "do_populate_sysroot" and fns[tid] in configurefns:
193 problems.add(tid)
194 return problems
195
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500196BB_SETSCENE_VERIFY_FUNCTION = "sysroot_checkhashes"
197
198def sysroot_checkhashes(covered, tasknames, fnids, fns, d, invalidtasks = None):
199 problems = set()
200 configurefnids = set()
201 if not invalidtasks:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600202 invalidtasks = range(len(tasknames))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500203 for task in invalidtasks:
204 if tasknames[task] == "do_configure" and task not in covered:
205 configurefnids.add(fnids[task])
206 for task in covered:
207 if tasknames[task] == "do_populate_sysroot" and fnids[task] in configurefnids:
208 problems.add(task)
209 return problems
210
211python do_populate_sysroot () {
212 bb.build.exec_func("sysroot_stage_all", d)
213 bb.build.exec_func("sysroot_strip", d)
214 for f in (d.getVar('SYSROOT_PREPROCESS_FUNCS', True) or '').split():
215 bb.build.exec_func(f, d)
216 pn = d.getVar("PN", True)
217 multiprov = d.getVar("MULTI_PROVIDER_WHITELIST", True).split()
218 provdir = d.expand("${SYSROOT_DESTDIR}${base_prefix}/sysroot-providers/")
219 bb.utils.mkdirhier(provdir)
220 for p in d.getVar("PROVIDES", True).split():
221 if p in multiprov:
222 continue
223 p = p.replace("/", "_")
224 with open(provdir + p, "w") as f:
225 f.write(pn)
226}
227
228do_populate_sysroot[vardeps] += "${SYSROOT_PREPROCESS_FUNCS}"
229do_populate_sysroot[vardepsexclude] += "MULTI_PROVIDER_WHITELIST"
230
231SSTATETASKS += "do_populate_sysroot"
232do_populate_sysroot[cleandirs] = "${SYSROOT_DESTDIR}"
233do_populate_sysroot[sstate-inputdirs] = "${SYSROOT_DESTDIR}"
234do_populate_sysroot[sstate-outputdirs] = "${STAGING_DIR_HOST}/"
235do_populate_sysroot[stamp-extra-info] = "${MACHINE}"
236
237python do_populate_sysroot_setscene () {
238 sstate_setscene(d)
239}
240addtask do_populate_sysroot_setscene
241
242