rust_1.85.1.bb 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. SUMMARY = "Rust compiler and runtime libaries"
  2. HOMEPAGE = "http://www.rust-lang.org"
  3. SECTION = "devel"
  4. LICENSE = "(MIT | Apache-2.0) & Unicode-3.0"
  5. LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=9c0fae516fe8aaea2fb601db4800daf7"
  6. inherit rust
  7. inherit cargo_common
  8. DEPENDS += "file-native python3-native"
  9. DEPENDS:append:class-native = " rust-llvm-native"
  10. DEPENDS:append:class-nativesdk = " nativesdk-rust-llvm"
  11. # native rust uses cargo/rustc from binary snapshots to bootstrap
  12. # but everything else should use our native builds
  13. DEPENDS:append:class-target = " cargo-native rust-native"
  14. DEPENDS:append:class-nativesdk = " cargo-native rust-native"
  15. DEPENDS += "rust-llvm (=${PV})"
  16. RDEPENDS:${PN}:append:class-target = " gcc g++ binutils"
  17. # Otherwise we'll depend on what we provide
  18. INHIBIT_DEFAULT_RUST_DEPS:class-native = "1"
  19. # We don't need to depend on gcc-native because yocto assumes it exists
  20. PROVIDES:class-native = "virtual/${TARGET_PREFIX}rust"
  21. S = "${RUSTSRC}"
  22. # Use at your own risk, accepted values are stable, beta and nightly
  23. RUST_CHANNEL ?= "stable"
  24. PV .= "${@bb.utils.contains('RUST_CHANNEL', 'stable', '', '-${RUST_CHANNEL}', d)}"
  25. export FORCE_CRATE_HASH = "${BB_TASKHASH}"
  26. RUST_ALTERNATE_EXE_PATH ?= "${STAGING_LIBDIR}/llvm-rust/bin/llvm-config"
  27. RUST_ALTERNATE_EXE_PATH_NATIVE = "${STAGING_LIBDIR_NATIVE}/llvm-rust/bin/llvm-config"
  28. # We don't want to use bitbakes vendoring because the rust sources do their
  29. # own vendoring.
  30. CARGO_DISABLE_BITBAKE_VENDORING = "1"
  31. setup_cargo_environment () {
  32. # The first step is to build bootstrap and some early stage tools,
  33. # these are build for the same target as the snapshot, e.g.
  34. # x86_64-unknown-linux-gnu.
  35. # Later stages are build for the native target (i.e. target.x86_64-linux)
  36. cargo_common_do_configure
  37. }
  38. inherit rust-target-config
  39. do_rust_setup_snapshot () {
  40. for installer in "${UNPACKDIR}/rust-snapshot-components/"*"/install.sh"; do
  41. "${installer}" --prefix="${WORKDIR}/rust-snapshot" --disable-ldconfig
  42. done
  43. # Some versions of rust (e.g. 1.18.0) tries to find cargo in stage0/bin/cargo
  44. # and fail without it there.
  45. mkdir -p ${RUSTSRC}/build/${RUST_BUILD_SYS}
  46. ln -sf ${WORKDIR}/rust-snapshot/ ${RUSTSRC}/build/${RUST_BUILD_SYS}/stage0
  47. # Need to use uninative's loader if enabled/present since the library paths
  48. # are used internally by rust and result in symbol mismatches if we don't
  49. if [ ! -z "${UNINATIVE_LOADER}" -a -e "${UNINATIVE_LOADER}" ]; then
  50. for bin in cargo rustc rustdoc; do
  51. patchelf-uninative ${WORKDIR}/rust-snapshot/bin/$bin --set-interpreter ${UNINATIVE_LOADER}
  52. done
  53. fi
  54. }
  55. addtask rust_setup_snapshot after do_unpack before do_configure
  56. addtask do_test_compile after do_configure do_rust_gen_targets
  57. do_rust_setup_snapshot[dirs] += "${WORKDIR}/rust-snapshot"
  58. do_rust_setup_snapshot[vardepsexclude] += "UNINATIVE_LOADER"
  59. RUSTC_BOOTSTRAP = "${STAGING_BINDIR_NATIVE}/rustc"
  60. CARGO_BOOTSTRAP = "${STAGING_BINDIR_NATIVE}/cargo"
  61. RUSTC_BOOTSTRAP:class-native = "${WORKDIR}/rust-snapshot/bin/rustc"
  62. CARGO_BOOTSTRAP:class-native = "${WORKDIR}/rust-snapshot/bin/cargo"
  63. python do_configure() {
  64. import json
  65. import configparser
  66. # toml is rather similar to standard ini like format except it likes values
  67. # that look more JSON like. So for our purposes simply escaping all values
  68. # as JSON seem to work fine.
  69. e = lambda s: json.dumps(s)
  70. config = configparser.RawConfigParser()
  71. # [target.ARCH-poky-linux]
  72. host_section = "target.{}".format(d.getVar('RUST_HOST_SYS'))
  73. config.add_section(host_section)
  74. llvm_config_target = d.expand("${RUST_ALTERNATE_EXE_PATH}")
  75. llvm_config_build = d.expand("${RUST_ALTERNATE_EXE_PATH_NATIVE}")
  76. config.set(host_section, "llvm-config", e(llvm_config_target))
  77. config.set(host_section, "cxx", e(d.expand("${RUST_TARGET_CXX}")))
  78. config.set(host_section, "cc", e(d.expand("${RUST_TARGET_CC}")))
  79. config.set(host_section, "linker", e(d.expand("${RUST_TARGET_CCLD}")))
  80. if "musl" in host_section:
  81. config.set(host_section, "musl-root", e(d.expand("${STAGING_DIR_HOST}${exec_prefix}")))
  82. # If we don't do this rust-native will compile it's own llvm for BUILD.
  83. # [target.${BUILD_ARCH}-unknown-linux-gnu]
  84. build_section = "target.{}".format(d.getVar('RUST_BUILD_SYS'))
  85. if build_section != host_section:
  86. config.add_section(build_section)
  87. config.set(build_section, "llvm-config", e(llvm_config_build))
  88. config.set(build_section, "cxx", e(d.expand("${RUST_BUILD_CXX}")))
  89. config.set(build_section, "cc", e(d.expand("${RUST_BUILD_CC}")))
  90. config.set(build_section, "linker", e(d.expand("${RUST_BUILD_CCLD}")))
  91. target_section = "target.{}".format(d.getVar('RUST_TARGET_SYS'))
  92. if target_section != host_section and target_section != build_section:
  93. config.add_section(target_section)
  94. config.set(target_section, "llvm-config", e(llvm_config_target))
  95. config.set(target_section, "cxx", e(d.expand("${RUST_TARGET_CXX}")))
  96. config.set(target_section, "cc", e(d.expand("${RUST_TARGET_CC}")))
  97. config.set(target_section, "linker", e(d.expand("${RUST_TARGET_CCLD}")))
  98. # [llvm]
  99. config.add_section("llvm")
  100. config.set("llvm", "static-libstdcpp", e(False))
  101. config.set("llvm", "download-ci-llvm", e(False))
  102. if "llvm" in (d.getVar('TC_CXX_RUNTIME') or ""):
  103. config.set("llvm", "use-libcxx", e(True))
  104. # [rust]
  105. config.add_section("rust")
  106. config.set("rust", "rpath", e(True))
  107. config.set("rust", "remap-debuginfo", e(True))
  108. config.set("rust", "download-rustc", e(False))
  109. config.set("rust", "llvm-tools", e(False))
  110. config.set("rust", "channel", e(d.expand("${RUST_CHANNEL}")))
  111. # Whether or not to optimize the compiler and standard library
  112. config.set("rust", "optimize", e(True))
  113. # Emits extraneous output from tests to ensure that failures of the test
  114. # harness are debuggable just from logfiles
  115. config.set("rust", "verbose-tests", e(True))
  116. # [build]
  117. config.add_section("build")
  118. config.set("build", "submodules", e(False))
  119. config.set("build", "docs", e(False))
  120. rustc = d.getVar('RUSTC_BOOTSTRAP')
  121. config.set("build", "rustc", e(rustc))
  122. cargo = d.getVar('CARGO_BOOTSTRAP')
  123. config.set("build", "cargo", e(cargo))
  124. config.set("build", "vendor", e(True))
  125. config.set("build", "target", e([d.getVar("RUST_TARGET_SYS")]))
  126. config.set("build", "host", e([d.getVar("RUST_HOST_SYS")]))
  127. # We can't use BUILD_SYS since that is something the rust snapshot knows
  128. # nothing about when trying to build some stage0 tools (like fabricate)
  129. config.set("build", "build", e(d.getVar("RUST_BUILD_SYS")))
  130. # [install]
  131. config.add_section("install")
  132. # ./x.py install doesn't have any notion of "destdir"
  133. # but we can prepend ${D} to all the directories instead
  134. config.set("install", "prefix", e(d.getVar("D") + d.getVar("prefix")))
  135. config.set("install", "bindir", e(d.getVar("D") + d.getVar("bindir")))
  136. config.set("install", "libdir", e(d.getVar("D") + d.getVar("libdir")))
  137. config.set("install", "datadir", e(d.getVar("D") + d.getVar("datadir")))
  138. config.set("install", "mandir", e(d.getVar("D") + d.getVar("mandir")))
  139. config.set("install", "sysconfdir", e(d.getVar("D") + d.getVar("sysconfdir")))
  140. with open("config.toml", "w") as f:
  141. f.write('change-id = 116881\n\n')
  142. config.write(f)
  143. # set up ${WORKDIR}/cargo_home
  144. bb.build.exec_func("setup_cargo_environment", d)
  145. }
  146. rust_runx () {
  147. echo "COMPILE ${PN}" "$@"
  148. # CFLAGS, LDFLAGS, CXXFLAGS, CPPFLAGS are used by rust's build for a
  149. # wide range of targets (not just TARGET). Yocto's settings for them will
  150. # be inappropriate, avoid using.
  151. unset CFLAGS
  152. unset LDFLAGS
  153. unset CXXFLAGS
  154. unset CPPFLAGS
  155. export RUSTFLAGS="${RUST_DEBUG_REMAP}"
  156. # Copy the natively built llvm-config into the target so we can run it. Horrible,
  157. # but works!
  158. if [ ${RUST_ALTERNATE_EXE_PATH_NATIVE} != ${RUST_ALTERNATE_EXE_PATH} -a ! -f ${RUST_ALTERNATE_EXE_PATH} ]; then
  159. mkdir -p `dirname ${RUST_ALTERNATE_EXE_PATH}`
  160. cp ${RUST_ALTERNATE_EXE_PATH_NATIVE} ${RUST_ALTERNATE_EXE_PATH}
  161. if [ -e ${STAGING_LIBDIR_NATIVE}/libc++.so.1 ]; then
  162. chrpath -r \$ORIGIN/../../../../../`basename ${STAGING_DIR_NATIVE}`${libdir_native} ${RUST_ALTERNATE_EXE_PATH}
  163. else
  164. chrpath -d ${RUST_ALTERNATE_EXE_PATH}
  165. fi
  166. fi
  167. oe_cargo_fix_env
  168. python3 src/bootstrap/bootstrap.py ${@oe.utils.parallel_make_argument(d, '-j %d')} "$@" --verbose
  169. }
  170. rust_runx[vardepsexclude] += "PARALLEL_MAKE"
  171. require rust-source.inc
  172. require rust-snapshot.inc
  173. INSANE_SKIP:${PN}:class-native = "already-stripped"
  174. FILES:${PN} += "${libdir}/rustlib"
  175. FILES:${PN} += "${libdir}/*.so"
  176. FILES:${PN}-dev = ""
  177. do_compile () {
  178. }
  179. do_test_compile[dirs] = "${B}"
  180. do_test_compile () {
  181. rust_runx build src/tools/remote-test-server --target "${RUST_TARGET_SYS}"
  182. }
  183. ALLOW_EMPTY:${PN} = "1"
  184. PACKAGES =+ "${PN}-rustdoc ${PN}-tools-clippy ${PN}-tools-rustfmt"
  185. FILES:${PN}-rustdoc = "${bindir}/rustdoc"
  186. FILES:${PN}-tools-clippy = "${bindir}/cargo-clippy ${bindir}/clippy-driver"
  187. FILES:${PN}-tools-rustfmt = "${bindir}/rustfmt"
  188. RDEPENDS:${PN}-rustdoc = "${PN}"
  189. RDEPENDS:${PN}-tools-clippy = "${PN}"
  190. RDEPENDS:${PN}-tools-rustfmt = "${PN}"
  191. SUMMARY:${PN}-tools-clippy = "A collection of lints to catch common mistakes and improve your Rust code"
  192. SUMMARY:${PN}-tools-rustfmt = "A tool for formatting Rust code according to style guidelines"
  193. do_install () {
  194. rust_do_install
  195. }
  196. rust_do_install() {
  197. rust_runx install
  198. }
  199. rust_do_install:class-nativesdk() {
  200. export PSEUDO_UNLOAD=1
  201. rust_runx install
  202. rust_runx install clippy
  203. rust_runx install rustfmt
  204. unset PSEUDO_UNLOAD
  205. install -d ${D}${bindir}
  206. for i in cargo-clippy clippy-driver rustfmt; do
  207. cp build/${RUST_BUILD_SYS}/stage2-tools/${RUST_HOST_SYS}/release/$i ${D}${bindir}
  208. chrpath -r "\$ORIGIN/../lib" ${D}${bindir}/$i
  209. done
  210. chown root:root ${D}/ -R
  211. rm ${D}${libdir}/rustlib/uninstall.sh
  212. rm ${D}${libdir}/rustlib/install.log
  213. rm ${D}${libdir}/rustlib/manifest*
  214. rm ${D}${libdir}/rustlib/${RUST_HOST_SYS}/lib/libstd*.so
  215. ENV_SETUP_DIR=${D}${base_prefix}/environment-setup.d
  216. mkdir "${ENV_SETUP_DIR}"
  217. RUST_ENV_SETUP_SH="${ENV_SETUP_DIR}/rust.sh"
  218. RUST_HOST_TRIPLE=`echo ${RUST_HOST_SYS} | tr '[:lower:]' '[:upper:]' | sed 's/-/_/g'`
  219. RUST_HOST_CC=`echo ${RUST_HOST_SYS} | sed 's/-/_/g'`
  220. SDKLOADER=${@bb.utils.contains('SDK_ARCH', 'x86_64', 'ld-linux-x86-64.so.2', '', d)}${@bb.utils.contains('SDK_ARCH', 'i686', 'ld-linux.so.2', '', d)}${@bb.utils.contains('SDK_ARCH', 'aarch64', 'ld-linux-aarch64.so.1', '', d)}${@bb.utils.contains('SDK_ARCH', 'ppc64le', 'ld64.so.2', '', d)}${@bb.utils.contains('SDK_ARCH', 'riscv64', 'ld-linux-riscv64-lp64d.so.1', '', d)}
  221. cat <<- EOF > "${RUST_ENV_SETUP_SH}"
  222. export CARGO_TARGET_${RUST_HOST_TRIPLE}_RUNNER="\$OECORE_NATIVE_SYSROOT/lib/${SDKLOADER}"
  223. export CC_$RUST_HOST_CC="${CCACHE}${HOST_PREFIX}gcc"
  224. EOF
  225. }
  226. FILES:${PN} += "${base_prefix}/environment-setup.d"
  227. EXTRA_TOOLS ?= "cargo-clippy clippy-driver rustfmt"
  228. rust_do_install:class-target() {
  229. export PSEUDO_UNLOAD=1
  230. rust_runx install
  231. rust_runx install clippy
  232. rust_runx install rustfmt
  233. unset PSEUDO_UNLOAD
  234. install -d ${D}${bindir}
  235. for i in ${EXTRA_TOOLS}; do
  236. cp build/${RUST_BUILD_SYS}/stage2-tools/${RUST_HOST_SYS}/release/$i ${D}${bindir}
  237. chrpath -r "\$ORIGIN/../lib" ${D}${bindir}/$i
  238. done
  239. install -d ${D}${libdir}/rustlib/${RUST_HOST_SYS}
  240. install -m 0644 ${WORKDIR}/rust-targets/${RUST_HOST_SYS}.json ${D}${libdir}/rustlib/${RUST_HOST_SYS}/target.json
  241. chown root:root ${D}/ -R
  242. rm ${D}${libdir}/rustlib/uninstall.sh
  243. rm ${D}${libdir}/rustlib/install.log
  244. rm ${D}${libdir}/rustlib/manifest*
  245. rm ${D}${libdir}/rustlib/${RUST_HOST_SYS}/lib/libstd*.so
  246. }
  247. addtask do_update_snapshot after do_patch
  248. do_update_snapshot[nostamp] = "1"
  249. # Run with `bitbake -c update_snapshot rust` to update `rust-snapshot.inc`
  250. # with the checksums for the rust snapshot associated with this rustc-src
  251. # tarball.
  252. python do_update_snapshot() {
  253. import json
  254. import re
  255. import sys
  256. from collections import defaultdict
  257. key_value_pairs = {}
  258. with open(os.path.join(d.getVar("S"), "src", "stage0")) as f:
  259. for line in f:
  260. # Skip empty lines or comments
  261. if not line.strip() or line.startswith("#"):
  262. continue
  263. # Split the line into key and value using '=' as separator
  264. match = re.match(r'(\S+)\s*=\s*(\S+)', line.strip())
  265. if match:
  266. key = match.group(1)
  267. value = match.group(2)
  268. key_value_pairs[key] = value
  269. # Extract the required values from key_value_pairs
  270. config_dist_server = key_value_pairs.get('dist_server', '')
  271. compiler_date = key_value_pairs.get('compiler_date', '')
  272. compiler_version = key_value_pairs.get('compiler_version', '')
  273. src_uri = defaultdict(list)
  274. # Assuming checksums_sha256 is now a key-value pair like: checksum_key = checksum_value
  275. for k, v in key_value_pairs.items():
  276. # Match the pattern for checksums
  277. if "dist" in k and "tar.xz" in k:
  278. m = re.search(f"dist/{compiler_date}/(?P<component>.*)-{compiler_version}-(?P<arch>.*)-unknown-linux-gnu\\.tar\\.xz", k)
  279. if m:
  280. component = m.group('component')
  281. arch = m.group('arch')
  282. src_uri[arch].append(f"SRC_URI[{component}-snapshot-{arch}.sha256sum] = \"{v}\"")
  283. # Create the snapshot string with the extracted values
  284. snapshot = """\
  285. ## This is information on the rust-snapshot (binary) used to build our current release.
  286. ## snapshot info is taken from rust/src/stage0
  287. ## Rust is self-hosting and bootstraps itself with a pre-built previous version of itself.
  288. ## The exact (previous) version that has been used is specified in the source tarball.
  289. ## The version is replicated here.
  290. SNAPSHOT_VERSION = "%s"
  291. """ % compiler_version
  292. # Add the checksum components to the snapshot
  293. for arch, components in src_uri.items():
  294. snapshot += "\n".join(components) + "\n\n"
  295. # Add the additional snapshot URIs
  296. snapshot += """\
  297. SRC_URI += " \\
  298. ${RUST_DIST_SERVER}/dist/${RUST_STD_SNAPSHOT}.tar.xz;name=rust-std-snapshot-${RUST_BUILD_ARCH};subdir=rust-snapshot-components \\
  299. ${RUST_DIST_SERVER}/dist/${RUSTC_SNAPSHOT}.tar.xz;name=rustc-snapshot-${RUST_BUILD_ARCH};subdir=rust-snapshot-components \\
  300. ${RUST_DIST_SERVER}/dist/${CARGO_SNAPSHOT}.tar.xz;name=cargo-snapshot-${RUST_BUILD_ARCH};subdir=rust-snapshot-components \\
  301. "
  302. RUST_DIST_SERVER = "%s"
  303. RUST_STD_SNAPSHOT = "rust-std-${SNAPSHOT_VERSION}-${RUST_BUILD_ARCH}-unknown-linux-gnu"
  304. RUSTC_SNAPSHOT = "rustc-${SNAPSHOT_VERSION}-${RUST_BUILD_ARCH}-unknown-linux-gnu"
  305. CARGO_SNAPSHOT = "cargo-${SNAPSHOT_VERSION}-${RUST_BUILD_ARCH}-unknown-linux-gnu"
  306. """ % config_dist_server
  307. # Write the updated snapshot information to the rust-snapshot.inc file
  308. with open(os.path.join(d.getVar("THISDIR"), "rust-snapshot.inc"), "w") as f:
  309. f.write(snapshot)
  310. }
  311. RUSTLIB_DEP:class-nativesdk = ""
  312. # musl builds include libunwind.a
  313. INSANE_SKIP:${PN} = "staticdev"
  314. BBCLASSEXTEND = "native nativesdk"