1*4882a593SmuzhiyunSUMMARY = "Rust compiler and runtime libaries" 2*4882a593SmuzhiyunHOMEPAGE = "http://www.rust-lang.org" 3*4882a593SmuzhiyunSECTION = "devel" 4*4882a593SmuzhiyunLICENSE = "MIT | Apache-2.0" 5*4882a593SmuzhiyunLIC_FILES_CHKSUM = "file://COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0" 6*4882a593Smuzhiyun 7*4882a593Smuzhiyuninherit rust 8*4882a593Smuzhiyuninherit cargo_common 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunDEPENDS += "file-native python3-native" 11*4882a593SmuzhiyunDEPENDS:append:class-native = " rust-llvm-native" 12*4882a593Smuzhiyun 13*4882a593SmuzhiyunS = "${RUSTSRC}" 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun# We generate local targets, and need to be able to locate them 16*4882a593Smuzhiyunexport RUST_TARGET_PATH="${WORKDIR}/targets/" 17*4882a593Smuzhiyun 18*4882a593Smuzhiyunexport FORCE_CRATE_HASH="${BB_TASKHASH}" 19*4882a593Smuzhiyun 20*4882a593SmuzhiyunRUST_ALTERNATE_EXE_PATH ?= "${STAGING_LIBDIR}/llvm-rust/bin/llvm-config" 21*4882a593Smuzhiyunexport YOCTO_ALTERNATE_EXE_PATH = "${RUST_ALTERNATE_EXE_PATH}" 22*4882a593Smuzhiyunexport YOCTO_ALTERNATE_MULTILIB_NAME = "/${BASELIB}" 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun# We don't want to use bitbakes vendoring because the rust sources do their 25*4882a593Smuzhiyun# own vendoring. 26*4882a593SmuzhiyunCARGO_DISABLE_BITBAKE_VENDORING = "1" 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun# We can't use RUST_BUILD_SYS here because that may be "musl" if 29*4882a593Smuzhiyun# TCLIBC="musl". Snapshots are always -unknown-linux-gnu 30*4882a593SmuzhiyunSNAPSHOT_BUILD_SYS = "${RUST_BUILD_ARCH}-unknown-linux-gnu" 31*4882a593Smuzhiyunsetup_cargo_environment () { 32*4882a593Smuzhiyun # The first step is to build bootstrap and some early stage tools, 33*4882a593Smuzhiyun # these are build for the same target as the snapshot, e.g. 34*4882a593Smuzhiyun # x86_64-unknown-linux-gnu. 35*4882a593Smuzhiyun # Later stages are build for the native target (i.e. target.x86_64-linux) 36*4882a593Smuzhiyun cargo_common_do_configure 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun printf '[target.%s]\n' "${SNAPSHOT_BUILD_SYS}" >> ${CARGO_HOME}/config 39*4882a593Smuzhiyun printf "linker = '%s'\n" "${RUST_BUILD_CCLD}" >> ${CARGO_HOME}/config 40*4882a593Smuzhiyun} 41*4882a593Smuzhiyun 42*4882a593Smuzhiyuninclude rust-common.inc 43*4882a593Smuzhiyun 44*4882a593Smuzhiyundo_rust_setup_snapshot () { 45*4882a593Smuzhiyun for installer in "${WORKDIR}/rust-snapshot-components/"*"/install.sh"; do 46*4882a593Smuzhiyun "${installer}" --prefix="${WORKDIR}/rust-snapshot" --disable-ldconfig 47*4882a593Smuzhiyun done 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun # Some versions of rust (e.g. 1.18.0) tries to find cargo in stage0/bin/cargo 50*4882a593Smuzhiyun # and fail without it there. 51*4882a593Smuzhiyun mkdir -p ${RUSTSRC}/build/${BUILD_SYS} 52*4882a593Smuzhiyun ln -sf ${WORKDIR}/rust-snapshot/ ${RUSTSRC}/build/${BUILD_SYS}/stage0 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun # Need to use uninative's loader if enabled/present since the library paths 55*4882a593Smuzhiyun # are used internally by rust and result in symbol mismatches if we don't 56*4882a593Smuzhiyun if [ ! -z "${UNINATIVE_LOADER}" -a -e "${UNINATIVE_LOADER}" ]; then 57*4882a593Smuzhiyun for bin in cargo rustc rustdoc; do 58*4882a593Smuzhiyun patchelf-uninative ${WORKDIR}/rust-snapshot/bin/$bin --set-interpreter ${UNINATIVE_LOADER} 59*4882a593Smuzhiyun done 60*4882a593Smuzhiyun fi 61*4882a593Smuzhiyun} 62*4882a593Smuzhiyunaddtask rust_setup_snapshot after do_unpack before do_configure 63*4882a593Smuzhiyundo_rust_setup_snapshot[dirs] += "${WORKDIR}/rust-snapshot" 64*4882a593Smuzhiyundo_rust_setup_snapshot[vardepsexclude] += "UNINATIVE_LOADER" 65*4882a593Smuzhiyun 66*4882a593Smuzhiyunpython do_configure() { 67*4882a593Smuzhiyun import json 68*4882a593Smuzhiyun try: 69*4882a593Smuzhiyun import configparser 70*4882a593Smuzhiyun except ImportError: 71*4882a593Smuzhiyun import ConfigParser as configparser 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun # toml is rather similar to standard ini like format except it likes values 74*4882a593Smuzhiyun # that look more JSON like. So for our purposes simply escaping all values 75*4882a593Smuzhiyun # as JSON seem to work fine. 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun e = lambda s: json.dumps(s) 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun config = configparser.RawConfigParser() 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun # [target.ARCH-poky-linux] 82*4882a593Smuzhiyun target_section = "target.{}".format(d.getVar('TARGET_SYS')) 83*4882a593Smuzhiyun config.add_section(target_section) 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun llvm_config = d.expand("${YOCTO_ALTERNATE_EXE_PATH}") 86*4882a593Smuzhiyun config.set(target_section, "llvm-config", e(llvm_config)) 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun config.set(target_section, "cxx", e(d.expand("${RUST_TARGET_CXX}"))) 89*4882a593Smuzhiyun config.set(target_section, "cc", e(d.expand("${RUST_TARGET_CC}"))) 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun # If we don't do this rust-native will compile it's own llvm for BUILD. 92*4882a593Smuzhiyun # [target.${BUILD_ARCH}-unknown-linux-gnu] 93*4882a593Smuzhiyun target_section = "target.{}".format(d.getVar('SNAPSHOT_BUILD_SYS')) 94*4882a593Smuzhiyun config.add_section(target_section) 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun config.set(target_section, "llvm-config", e(llvm_config)) 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun config.set(target_section, "cxx", e(d.expand("${RUST_BUILD_CXX}"))) 99*4882a593Smuzhiyun config.set(target_section, "cc", e(d.expand("${RUST_BUILD_CC}"))) 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun # [rust] 102*4882a593Smuzhiyun config.add_section("rust") 103*4882a593Smuzhiyun config.set("rust", "rpath", e(True)) 104*4882a593Smuzhiyun config.set("rust", "channel", e("stable")) 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun # Whether or not to optimize the compiler and standard library 107*4882a593Smuzhiyun config.set("rust", "optimize", e(True)) 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun # [build] 110*4882a593Smuzhiyun config.add_section("build") 111*4882a593Smuzhiyun config.set("build", "submodules", e(False)) 112*4882a593Smuzhiyun config.set("build", "docs", e(False)) 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun rustc = d.expand("${WORKDIR}/rust-snapshot/bin/rustc") 115*4882a593Smuzhiyun config.set("build", "rustc", e(rustc)) 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun # Support for the profiler runtime to generate e.g. coverage report, 118*4882a593Smuzhiyun # PGO etc. 119*4882a593Smuzhiyun config.set("build", "profiler", e(True)) 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun cargo = d.expand("${WORKDIR}/rust-snapshot/bin/cargo") 122*4882a593Smuzhiyun config.set("build", "cargo", e(cargo)) 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun config.set("build", "vendor", e(True)) 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun if not "targets" in locals(): 127*4882a593Smuzhiyun targets = [d.getVar("TARGET_SYS")] 128*4882a593Smuzhiyun config.set("build", "target", e(targets)) 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun if not "hosts" in locals(): 131*4882a593Smuzhiyun hosts = [d.getVar("HOST_SYS")] 132*4882a593Smuzhiyun config.set("build", "host", e(hosts)) 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun # We can't use BUILD_SYS since that is something the rust snapshot knows 135*4882a593Smuzhiyun # nothing about when trying to build some stage0 tools (like fabricate) 136*4882a593Smuzhiyun config.set("build", "build", e(d.getVar("SNAPSHOT_BUILD_SYS"))) 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun # [install] 139*4882a593Smuzhiyun config.add_section("install") 140*4882a593Smuzhiyun # ./x.py install doesn't have any notion of "destdir" 141*4882a593Smuzhiyun # but we can prepend ${D} to all the directories instead 142*4882a593Smuzhiyun config.set("install", "prefix", e(d.getVar("D") + d.getVar("prefix"))) 143*4882a593Smuzhiyun config.set("install", "bindir", e(d.getVar("D") + d.getVar("bindir"))) 144*4882a593Smuzhiyun config.set("install", "libdir", e(d.getVar("D") + d.getVar("libdir"))) 145*4882a593Smuzhiyun config.set("install", "datadir", e(d.getVar("D") + d.getVar("datadir"))) 146*4882a593Smuzhiyun config.set("install", "mandir", e(d.getVar("D") + d.getVar("mandir"))) 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun with open("config.toml", "w") as f: 149*4882a593Smuzhiyun f.write('changelog-seen = 2\n\n') 150*4882a593Smuzhiyun config.write(f) 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun # set up ${WORKDIR}/cargo_home 153*4882a593Smuzhiyun bb.build.exec_func("setup_cargo_environment", d) 154*4882a593Smuzhiyun} 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun 157*4882a593Smuzhiyunrust_runx () { 158*4882a593Smuzhiyun echo "COMPILE ${PN}" "$@" 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun # CFLAGS, LDFLAGS, CXXFLAGS, CPPFLAGS are used by rust's build for a 161*4882a593Smuzhiyun # wide range of targets (not just TARGET). Yocto's settings for them will 162*4882a593Smuzhiyun # be inappropriate, avoid using. 163*4882a593Smuzhiyun unset CFLAGS 164*4882a593Smuzhiyun unset LDFLAGS 165*4882a593Smuzhiyun unset CXXFLAGS 166*4882a593Smuzhiyun unset CPPFLAGS 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun oe_cargo_fix_env 169*4882a593Smuzhiyun 170*4882a593Smuzhiyun python3 src/bootstrap/bootstrap.py ${@oe.utils.parallel_make_argument(d, '-j %d')} "$@" --verbose 171*4882a593Smuzhiyun} 172*4882a593Smuzhiyunrust_runx[vardepsexclude] += "PARALLEL_MAKE" 173*4882a593Smuzhiyun 174*4882a593Smuzhiyundo_compile () { 175*4882a593Smuzhiyun rust_runx build 176*4882a593Smuzhiyun} 177*4882a593Smuzhiyun 178*4882a593Smuzhiyunrust_do_install () { 179*4882a593Smuzhiyun mkdir -p ${D}${bindir} 180*4882a593Smuzhiyun cp build/${HOST_SYS}/stage2/bin/* ${D}${bindir} 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun mkdir -p ${D}${libdir}/rustlib 183*4882a593Smuzhiyun cp -pRd build/${HOST_SYS}/stage2/lib/* ${D}${libdir} 184*4882a593Smuzhiyun # Remove absolute symlink so bitbake doesn't complain 185*4882a593Smuzhiyun rm -f ${D}${libdir}/rustlib/src/rust 186*4882a593Smuzhiyun} 187*4882a593Smuzhiyun 188*4882a593Smuzhiyunrust_install_targets() { 189*4882a593Smuzhiyun # Install our custom target.json files 190*4882a593Smuzhiyun local td="${D}${libdir}/rustlib/" 191*4882a593Smuzhiyun install -d "$td" 192*4882a593Smuzhiyun for tgt in "${WORKDIR}/targets/"* ; do 193*4882a593Smuzhiyun install -m 0644 "$tgt" "$td" 194*4882a593Smuzhiyun done 195*4882a593Smuzhiyun} 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun 198*4882a593Smuzhiyundo_install () { 199*4882a593Smuzhiyun rust_do_install 200*4882a593Smuzhiyun rust_install_targets 201*4882a593Smuzhiyun} 202*4882a593Smuzhiyun# ex: sts=4 et sw=4 ts=8 203