blob: a0b09a00bd7a406f609d0d620a93932ff79add16 [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 -0500174SYSROOT_LOCK = "${STAGING_DIR}/staging.lock"
175
176# We clean out any existing sstate from the sysroot if we rerun configure
177python sysroot_cleansstate () {
178 ss = sstate_state_fromvars(d, "populate_sysroot")
179 sstate_clean(ss, d)
180}
181do_configure[prefuncs] += "sysroot_cleansstate"
182
183
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600184BB_SETSCENE_VERIFY_FUNCTION2 = "sysroot_checkhashes2"
185
186def 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 Williamsc124f4f2015-09-15 14:41:29 -0500197BB_SETSCENE_VERIFY_FUNCTION = "sysroot_checkhashes"
198
199def sysroot_checkhashes(covered, tasknames, fnids, fns, d, invalidtasks = None):
200 problems = set()
201 configurefnids = set()
202 if not invalidtasks:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600203 invalidtasks = range(len(tasknames))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500204 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
212python 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
229do_populate_sysroot[vardeps] += "${SYSROOT_PREPROCESS_FUNCS}"
230do_populate_sysroot[vardepsexclude] += "MULTI_PROVIDER_WHITELIST"
231
232SSTATETASKS += "do_populate_sysroot"
233do_populate_sysroot[cleandirs] = "${SYSROOT_DESTDIR}"
234do_populate_sysroot[sstate-inputdirs] = "${SYSROOT_DESTDIR}"
235do_populate_sysroot[sstate-outputdirs] = "${STAGING_DIR_HOST}/"
236do_populate_sysroot[stamp-extra-info] = "${MACHINE}"
237
238python do_populate_sysroot_setscene () {
239 sstate_setscene(d)
240}
241addtask do_populate_sysroot_setscene
242
243