xref: /openbmc/openbmc/poky/meta/classes-recipe/native.bbclass (revision 8460358c3d24c71d9d38fd126c745854a6301564)
1#
2# Copyright OpenEmbedded Contributors
3#
4# SPDX-License-Identifier: MIT
5#
6
7# We want native packages to be relocatable
8inherit relocatable
9
10# Native packages are built indirectly via dependency,
11# no need for them to be a direct target of 'world'
12EXCLUDE_FROM_WORLD = "1"
13
14PACKAGE_ARCH = "${BUILD_ARCH}"
15
16# used by cmake class
17OECMAKE_RPATH = "${libdir}"
18OECMAKE_RPATH:class-native = "${libdir}"
19
20TARGET_ARCH = "${BUILD_ARCH}"
21TARGET_OS = "${BUILD_OS}"
22TARGET_VENDOR = "${BUILD_VENDOR}"
23TARGET_PREFIX = "${BUILD_PREFIX}"
24TARGET_CC_ARCH = "${BUILD_CC_ARCH}"
25TARGET_LD_ARCH = "${BUILD_LD_ARCH}"
26TARGET_AS_ARCH = "${BUILD_AS_ARCH}"
27TARGET_CPPFLAGS = "${BUILD_CPPFLAGS}"
28TARGET_CFLAGS = "${BUILD_CFLAGS}"
29TARGET_CXXFLAGS = "${BUILD_CXXFLAGS}"
30TARGET_LDFLAGS = "${BUILD_LDFLAGS}"
31TARGET_FPU = ""
32TUNE_FEATURES = ""
33ABIEXTENSION = ""
34
35HOST_ARCH = "${BUILD_ARCH}"
36HOST_OS = "${BUILD_OS}"
37HOST_VENDOR = "${BUILD_VENDOR}"
38HOST_PREFIX = "${BUILD_PREFIX}"
39HOST_CC_ARCH = "${BUILD_CC_ARCH}"
40HOST_LD_ARCH = "${BUILD_LD_ARCH}"
41HOST_AS_ARCH = "${BUILD_AS_ARCH}"
42
43STAGING_BINDIR = "${STAGING_BINDIR_NATIVE}"
44STAGING_BINDIR_CROSS = "${STAGING_BINDIR_NATIVE}"
45
46# native pkg doesn't need the TOOLCHAIN_OPTIONS.
47TOOLCHAIN_OPTIONS = ""
48
49# Don't build ptest natively
50PTEST_ENABLED = "0"
51
52# Don't use site files for native builds
53export CONFIG_SITE = "${COREBASE}/meta/site/native"
54
55# set the compiler as well. It could have been set to something else
56export CC = "${BUILD_CC}"
57export CXX = "${BUILD_CXX}"
58export FC = "${BUILD_FC}"
59export CPP = "${BUILD_CPP}"
60export LD = "${BUILD_LD}"
61export CCLD = "${BUILD_CCLD}"
62export AR = "${BUILD_AR}"
63export AS = "${BUILD_AS}"
64export RANLIB = "${BUILD_RANLIB}"
65export STRIP = "${BUILD_STRIP}"
66export NM = "${BUILD_NM}"
67
68# Path prefixes
69base_prefix = "${STAGING_DIR_NATIVE}"
70prefix = "${STAGING_DIR_NATIVE}${prefix_native}"
71exec_prefix = "${STAGING_DIR_NATIVE}${prefix_native}"
72
73bindir = "${STAGING_BINDIR_NATIVE}"
74sbindir = "${STAGING_SBINDIR_NATIVE}"
75base_libdir = "${STAGING_BASE_LIBDIR_NATIVE}"
76libdir = "${STAGING_LIBDIR_NATIVE}"
77includedir = "${STAGING_INCDIR_NATIVE}"
78sysconfdir = "${STAGING_ETCDIR_NATIVE}"
79datadir = "${STAGING_DATADIR_NATIVE}"
80
81baselib = "lib"
82
83export lt_cv_sys_lib_dlsearch_path_spec = "${libdir} ${base_libdir} /lib /lib64 /usr/lib /usr/lib64"
84
85NATIVE_PACKAGE_PATH_SUFFIX ?= ""
86bindir .= "${NATIVE_PACKAGE_PATH_SUFFIX}"
87sbindir .= "${NATIVE_PACKAGE_PATH_SUFFIX}"
88base_libdir .= "${NATIVE_PACKAGE_PATH_SUFFIX}"
89libdir .= "${NATIVE_PACKAGE_PATH_SUFFIX}"
90libexecdir .= "${NATIVE_PACKAGE_PATH_SUFFIX}"
91
92do_populate_sysroot[sstate-inputdirs] = "${SYSROOT_DESTDIR}/${STAGING_DIR_NATIVE}/"
93do_populate_sysroot[sstate-outputdirs] = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/${PN}"
94
95# Since we actually install these into situ there is no staging prefix
96STAGING_DIR_HOST = ""
97STAGING_DIR_TARGET = ""
98PKG_CONFIG_DIR = "${libdir}/pkgconfig"
99
100EXTRA_NATIVE_PKGCONFIG_PATH ?= ""
101PKG_CONFIG_PATH .= "${EXTRA_NATIVE_PKGCONFIG_PATH}"
102PKG_CONFIG_SYSROOT_DIR = ""
103PKG_CONFIG_SYSTEM_LIBRARY_PATH[unexport] = "1"
104PKG_CONFIG_SYSTEM_INCLUDE_PATH[unexport] = "1"
105
106# we dont want libc-*libc to kick in for native recipes
107LIBCOVERRIDE = ""
108CLASSOVERRIDE = "class-native"
109MACHINEOVERRIDES = ""
110MACHINE_FEATURES = ""
111
112PATH:prepend = "${COREBASE}/scripts/native-intercept:"
113
114# This class encodes staging paths into its scripts data so can only be
115# reused if we manipulate the paths.
116SSTATE_SCAN_CMD ?= "${SSTATE_SCAN_CMD_NATIVE}"
117
118# No strip sysroot when DEBUG_BUILD is enabled
119INHIBIT_SYSROOT_STRIP ?= "${@oe.utils.vartrue('DEBUG_BUILD', '1', '', d)}"
120
121python native_virtclass_handler () {
122    pn = e.data.getVar("PN")
123    if not pn.endswith("-native"):
124        return
125    bpn = e.data.getVar("BPN")
126
127    # Set features here to prevent appends and distro features backfill
128    # from modifying native distro features
129    features = set(d.getVar("DISTRO_FEATURES_NATIVE").split())
130    filtered = set(bb.utils.filter("DISTRO_FEATURES", d.getVar("DISTRO_FEATURES_FILTER_NATIVE"), d).split())
131    d.setVar("DISTRO_FEATURES", " ".join(sorted(features | filtered)))
132
133    classextend = e.data.getVar('BBCLASSEXTEND') or ""
134    if "native" not in classextend:
135        return
136
137    def map_dependencies(varname, d, suffix = "", selfref=True, regex=False):
138        if suffix:
139            varname = varname + ":" + suffix
140        deps = d.getVar(varname)
141        if not deps:
142            return
143        deps = bb.utils.explode_deps(deps)
144        newdeps = []
145        for dep in deps:
146            if regex and dep.startswith("^") and dep.endswith("$"):
147                newdeps.append(dep[:-1].replace(pn, bpn) + "-native$")
148            elif dep == pn:
149                if not selfref:
150                    continue
151                newdeps.append(dep)
152            elif "-cross-" in dep:
153                newdeps.append(dep.replace("-cross", "-native"))
154            elif not dep.endswith("-native"):
155                # Replace ${PN} with ${BPN} in the dependency to make sure
156                # dependencies on, e.g., ${PN}-foo become ${BPN}-foo-native
157                # rather than ${BPN}-native-foo-native.
158                newdeps.append(dep.replace(pn, bpn) + "-native")
159            else:
160                newdeps.append(dep)
161        d.setVar(varname, " ".join(newdeps))
162
163    map_dependencies("DEPENDS", e.data, selfref=False)
164    for pkg in e.data.getVar("PACKAGES", False).split():
165        map_dependencies("RDEPENDS", e.data, pkg)
166        map_dependencies("RRECOMMENDS", e.data, pkg)
167        map_dependencies("RSUGGESTS", e.data, pkg)
168        map_dependencies("RPROVIDES", e.data, pkg)
169        map_dependencies("RREPLACES", e.data, pkg)
170    map_dependencies("PACKAGES", e.data)
171    map_dependencies("PACKAGES_DYNAMIC", e.data, regex=True)
172
173    provides = e.data.getVar("PROVIDES")
174    nprovides = []
175    for prov in provides.split():
176        if prov.find(pn) != -1:
177            nprovides.append(prov)
178        elif not prov.endswith("-native"):
179            nprovides.append(prov + "-native")
180        else:
181            nprovides.append(prov)
182    e.data.setVar("PROVIDES", ' '.join(nprovides))
183
184
185}
186
187addhandler native_virtclass_handler
188native_virtclass_handler[eventmask] = "bb.event.RecipePreFinalise"
189
190python do_addto_recipe_sysroot () {
191    bb.build.exec_func("extend_recipe_sysroot", d)
192}
193addtask addto_recipe_sysroot after do_populate_sysroot
194do_addto_recipe_sysroot[deptask] = "do_populate_sysroot"
195
196inherit nopackages
197
198do_packagedata[stamp-extra-info] = ""
199
200USE_NLS = "no"
201
202RECIPERDEPTASK = "do_populate_sysroot"
203do_populate_sysroot[rdeptask] = "${RECIPERDEPTASK}"
204
205#
206# Native task outputs are directly run on the target (host) system after being
207# built. Even if the output of this recipe doesn't change, a change in one of
208# its dependencies may cause a change in the output it generates (e.g. rpm
209# output depends on the output of its dependent zstd library).
210#
211# This can cause poor interactions with hash equivalence, since this recipes
212# output-changing dependency is "hidden" and downstream task only see that this
213# recipe has the same outhash and therefore is equivalent. This can result in
214# different output in different cases.
215#
216# To resolve this, unhide the output-changing dependency by adding its unihash
217# to this tasks outhash calculation. Unfortunately, don't know specifically
218# know which dependencies are output-changing, so we have to add all of them.
219#
220python native_add_do_populate_sysroot_deps () {
221    current_task = "do_" + d.getVar("BB_CURRENTTASK")
222    if current_task != "do_populate_sysroot":
223        return
224
225    taskdepdata = d.getVar("BB_TASKDEPDATA", False)
226    pn = d.getVar("PN")
227    deps = {
228        dep[0]:dep[6] for dep in taskdepdata.values() if
229            dep[1] == current_task and dep[0] != pn
230    }
231
232    d.setVar("HASHEQUIV_EXTRA_SIGDATA", "\n".join("%s: %s" % (k, deps[k]) for k in sorted(deps.keys())))
233}
234SSTATECREATEFUNCS += "native_add_do_populate_sysroot_deps"
235