Changeset View
Changeset View
Standalone View
Standalone View
Mk/Uses/cargo.mk
# $FreeBSD$ | |||||
# | |||||
# This file contains logic to ease porting of Rust packages or | # This file contains logic to ease porting of Rust packages or | ||||
# binaries using the `cargo` command. | # binaries using the `cargo` command. | ||||
# | # | ||||
# Feature: cargo | # Feature: cargo | ||||
# Usage: USES=cargo | # Usage: USES=cargo | ||||
# Valid ARGS: none | # Valid ARGS: configure, build, install, test | ||||
# | # | ||||
# (no args) defaults to: configure, build, install, test | |||||
# configure vendor crates | |||||
# build run cargo build | |||||
# install run cargo install | |||||
# test run cargo test | |||||
# | |||||
# MAINTAINER: rust@FreeBSD.org | # MAINTAINER: rust@FreeBSD.org | ||||
.if !defined(_INCLUDE_USES_CARGO_MK) | .if !defined(_INCLUDE_USES_CARGO_MK) | ||||
_INCLUDE_USES_CARGO_MK= yes | _INCLUDE_USES_CARGO_MK= yes | ||||
.if !empty(cargo_ARGS) | _valid_ARGS= configure build install test | ||||
IGNORE+= USES=cargo takes no arguments | |||||
.for _arg in ${cargo_ARGS} | |||||
. if empty(_valid_ARGS:M${_arg}) | |||||
IGNORE= 'USES+= cargo:${cargo_ARGS}' usage: argument [${_arg}] is not recognized | |||||
.endif | . endif | ||||
.endfor | |||||
.if empty(cargo_ARGS) | |||||
cargo_ARGS+= configure build install test | |||||
.endif | |||||
# List of static dependencies. The format is cratename-version. | # List of static dependencies. The format is cratename-version. | ||||
# CARGO_CRATES will be downloaded from MASTER_SITES_CRATESIO. | # CARGO_CRATES will be downloaded from MASTER_SITES_CRATESIO. | ||||
CARGO_CRATES?= | CARGO_CRATES?= | ||||
# List of features to build (space separated list). | # List of features to build (space separated list). | ||||
# Use special token --no-default-features to disable default | # Use special token --no-default-features to disable default | ||||
# features by passing it to cargo build/install/test. | # features by passing it to cargo build/install/test. | ||||
CARGO_FEATURES?= | CARGO_FEATURES?= | ||||
# Cargo profile | |||||
# See https://doc.rust-lang.org/cargo/reference/profiles.html#profile-selection | |||||
# XXX: Enable as soon as --profile is stable | |||||
# .if defined(WITH_DEBUG) | |||||
# CARGO_PROFILE?= dev | |||||
# .else | |||||
# CARGO_PROFILE?= release | |||||
# .endif | |||||
# CARGO_PROFILE_BUILD?= ${CARGO_PROFILE} | |||||
# CARGO_PROFILE_INSTALL?= ${CARGO_PROFILE} | |||||
# CARGO_PROFILE_TEST?= ${CARGO_PROFILE} | |||||
# Name of the local directory for vendoring crates. | # Name of the local directory for vendoring crates. | ||||
CARGO_VENDOR_DIR?= ${WRKSRC}/cargo-crates | CARGO_VENDOR_DIR?= ${WRKSRC}/cargo-crates | ||||
# Default path for cargo manifest. | # Default path for cargo manifest. | ||||
CARGO_CARGOTOML?= ${WRKSRC}/Cargo.toml | CARGO_CARGOTOML?= ${WRKSRC}/Cargo.toml | ||||
CARGO_CARGOLOCK?= ${WRKSRC}/Cargo.lock | CARGO_CARGOLOCK?= ${WRKSRC}/Cargo.lock | ||||
# Save crates inside ${DISTDIR}/rust/crates by default. | # Save crates inside ${DISTDIR}/rust/crates by default. | ||||
CARGO_DIST_SUBDIR?= rust/crates | CARGO_DIST_SUBDIR?= rust/crates | ||||
# Generate list of DISTFILES. | # Generate list of DISTFILES. | ||||
.for _crate in ${CARGO_CRATES} | .for _crate in ${CARGO_CRATES} | ||||
MASTER_SITES+= CRATESIO/${_crate:C/^([-_a-zA-Z0-9]+)-[0-9].*/\1/}/${_crate:C/^[-_a-zA-Z0-9]+-([0-9].*)/\1/}:cargo_${_crate:C/[^a-zA-Z0-9_]//g} | MASTER_SITES+= CRATESIO/${_crate:C/^([-_a-zA-Z0-9]+)-[0-9].*/\1/}/${_crate:C/^[-_a-zA-Z0-9]+-([0-9].*)/\1/}:cargo_${_crate:C/[^a-zA-Z0-9_]//g} | ||||
DISTFILES+= ${CARGO_DIST_SUBDIR}/${_crate}.tar.gz:cargo_${_crate:C/[^a-zA-Z0-9_]//g} | DISTFILES+= ${CARGO_DIST_SUBDIR}/${_crate}.tar.gz:cargo_${_crate:C/[^a-zA-Z0-9_]//g} | ||||
.endfor | .endfor | ||||
# Build dependencies. | # Build dependencies. | ||||
CARGO_BUILDDEP?= yes | CARGO_BUILDDEP?= yes | ||||
.if ${CARGO_BUILDDEP:tl} == "yes" | .if ${CARGO_BUILDDEP:tl} == "yes" | ||||
BUILD_DEPENDS+= ${RUST_DEFAULT}>=1.51.0:lang/${RUST_DEFAULT} | rust_ARGS+= build | ||||
. include "${USESDIR}/rust.mk" | |||||
.endif | .endif | ||||
# Location of cargo binary (default to lang/rust's Cargo binary) | |||||
CARGO_CARGO_BIN?= ${LOCALBASE}/bin/cargo | |||||
# Location of the cargo output directory. | # Location of the cargo output directory. | ||||
CARGO_TARGET_DIR?= ${WRKDIR}/target | CARGO_TARGET_DIR?= ${WRKDIR}/target | ||||
# Environment for cargo | # Environment for cargo | ||||
# - CARGO_HOME: local cache of the registry index | # CARGO_HOME: local cache of the registry index | ||||
# - CARGO_BUILD_JOBS: configure number of jobs to run | # CARGO_BUILD_JOBS: configure number of jobs to run | ||||
# - CARGO_TARGET_DIR: location of where to place all generated artifacts | # CARGO_TARGET_DIR: location of where to place all generated artifacts | ||||
# - RUST_BACKTRACE: produce backtraces when something in the build panics | CARGO_ENV+= CARGO_BUILD_JOBS=${MAKE_JOBS_NUMBER} \ | ||||
# - RUSTC: path of rustc binary (default to lang/rust) | |||||
# - RUSTDOC: path of rustdoc binary (default to lang/rust) | |||||
# - RUSTFLAGS: custom flags to pass to all compiler invocations that Cargo performs | |||||
CARGO_ENV+= \ | |||||
CARGO_HOME=${WRKDIR}/cargo-home \ | CARGO_HOME=${WRKDIR}/cargo-home \ | ||||
CARGO_BUILD_JOBS=${MAKE_JOBS_NUMBER} \ | CARGO_TARGET_DIR=${CARGO_TARGET_DIR} | ||||
CARGO_TARGET_DIR=${CARGO_TARGET_DIR} \ | # Strip symbols from binaries | ||||
RUST_BACKTRACE=1 \ | # XXX: Enable when feature is stable | ||||
RUSTC=${LOCALBASE}/bin/rustc \ | # .if !defined(WITH_DEBUG) | ||||
RUSTDOC=${LOCALBASE}/bin/rustdoc \ | # CARGO_ENV+= CARGO_PROFILE_${CARGO_PROFILE:tu}_STRIP="symbols" | ||||
RUSTFLAGS="${RUSTFLAGS} -C linker=${CC:Q} ${LDFLAGS:C/.+/-C link-arg=&/}" | # .endif | ||||
# Adjust -C target-cpu if -march/-mcpu is set by bsd.cpu.mk | |||||
.if ${ARCH} == amd64 || ${ARCH} == i386 | |||||
RUSTFLAGS+= ${CFLAGS:M-march=*:S/-march=/-C target-cpu=/} | |||||
.elif ${ARCH:Mpowerpc64*} | |||||
RUSTFLAGS+= ${CFLAGS:M-mcpu=*:S/-mcpu=/-C target-cpu=/:S/power/pwr/} | |||||
.else | |||||
RUSTFLAGS+= ${CFLAGS:M-mcpu=*:S/-mcpu=/-C target-cpu=/} | |||||
.endif | |||||
.if defined(PPC_ABI) && ${PPC_ABI} == ELFv1 | .if defined(PPC_ABI) && ${PPC_ABI} == ELFv1 | ||||
USE_GCC?= yes | USE_GCC?= yes | ||||
.endif | .endif | ||||
# Helper to shorten cargo calls. | # Helper to shorten cargo calls. | ||||
CARGO_CARGO_RUN= \ | CARGO_CARGO_RUN= \ | ||||
cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} ${CARGO_ENV} \ | cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} ${CARGO_ENV} \ | ||||
${CARGO_CARGO_BIN} | ${CARGO} | ||||
# User arguments for cargo targets. | # User arguments for cargo targets. | ||||
CARGO_BUILD_ARGS?= | CARGO_BUILD_ARGS?= | ||||
CARGO_INSTALL_ARGS?= | CARGO_INSTALL_ARGS?= | ||||
CARGO_INSTALL_PATH?= . | CARGO_INSTALL_PATH?= . | ||||
CARGO_TEST_ARGS?= | CARGO_TEST_ARGS?= | ||||
CARGO_UPDATE_ARGS?= | CARGO_UPDATE_ARGS?= | ||||
# Use module targets ? | |||||
CARGO_BUILD?= yes | |||||
CARGO_CONFIGURE?= yes | |||||
CARGO_INSTALL?= yes | |||||
CARGO_TEST?= yes | |||||
# Set CARGO_USE_GIT{HUB,LAB} to yes if your application requires | # Set CARGO_USE_GIT{HUB,LAB} to yes if your application requires | ||||
# some dependencies from git repositories hosted on GitHub or | # some dependencies from git repositories hosted on GitHub or | ||||
# GitLab instances. All Cargo.toml files will be patched to point | # GitLab instances. All Cargo.toml files will be patched to point | ||||
# to the right offline sources based on what is defined in | # to the right offline sources based on what is defined in | ||||
# {GH,GL}_TUPLE. This makes sure that cargo does not attempt to | # {GH,GL}_TUPLE. This makes sure that cargo does not attempt to | ||||
# access the network during the build. | # access the network during the build. | ||||
CARGO_USE_GITHUB?= no | CARGO_USE_GITHUB?= yes | ||||
CARGO_USE_GITLAB?= no | CARGO_USE_GITLAB?= yes | ||||
# Manage crate features. | # Manage crate features. | ||||
.if !empty(CARGO_FEATURES:M--no-default-features) | .if !empty(CARGO_FEATURES:M--no-default-features) | ||||
CARGO_BUILD_ARGS+= --no-default-features | CARGO_BUILD_ARGS+= --no-default-features | ||||
CARGO_INSTALL_ARGS+= --no-default-features | CARGO_INSTALL_ARGS+= --no-default-features | ||||
CARGO_TEST_ARGS+= --no-default-features | CARGO_TEST_ARGS+= --no-default-features | ||||
.endif | .endif | ||||
.if !empty(CARGO_FEATURES:N--no-default-features) | .if !empty(CARGO_FEATURES:N--no-default-features) | ||||
CARGO_BUILD_ARGS+= --features='${CARGO_FEATURES:N--no-default-features}' | CARGO_BUILD_ARGS+= --features='${CARGO_FEATURES:N--no-default-features}' | ||||
CARGO_INSTALL_ARGS+= --features='${CARGO_FEATURES:N--no-default-features}' | CARGO_INSTALL_ARGS+= --features='${CARGO_FEATURES:N--no-default-features}' | ||||
CARGO_TEST_ARGS+= --features='${CARGO_FEATURES:N--no-default-features}' | CARGO_TEST_ARGS+= --features='${CARGO_FEATURES:N--no-default-features}' | ||||
.endif | .endif | ||||
.if !defined(WITH_DEBUG) | .if !defined(WITH_DEBUG) | ||||
CARGO_BUILD_ARGS+= --release | CARGO_BUILD_ARGS+= --release | ||||
CARGO_TEST_ARGS+= --release | CARGO_TEST_ARGS+= --release | ||||
.else | .else | ||||
CARGO_INSTALL_ARGS+= --debug | CARGO_INSTALL_ARGS+= --debug | ||||
.endif | .endif | ||||
# XXX: Enable when --profile is stable, maybe replace --release and --debug | |||||
# .if !empty(CARGO_PROFILE_BUILD) | |||||
# CARGO_BUILD_ARGS+= --profile=${CARGO_PROFILE_BUILD} | |||||
# .endif | |||||
# .if !empty(CARGO_PROFILE_INSTALL) | |||||
# CARGO_INSTALL_ARGS+= --profile=${CARGO_PROFILE_INSTALL} | |||||
# .endif | |||||
# .if !empty(CARGO_PROFILE_TEST) | |||||
# CARGO_TEST_ARGS+= --profile=${CARGO_PROFILE_TEST} | |||||
# .endif | |||||
.if ${CARGO_CRATES:Mcmake-[0-9]*} | .if ${CARGO_CRATES:Mcmake-[0-9]*} | ||||
BUILD_DEPENDS+= cmake:devel/cmake | BUILD_DEPENDS+= cmake:devel/cmake | ||||
.endif | .endif | ||||
.if ${CARGO_CRATES:Mgettext-sys-[0-9]*} | .if ${CARGO_CRATES:Mgettext-sys-[0-9]*} | ||||
CARGO_ENV+= GETTEXT_BIN_DIR=${LOCALBASE}/bin \ | CARGO_ENV+= GETTEXT_BIN_DIR=${LOCALBASE}/bin \ | ||||
GETTEXT_INCLUDE_DIR=${LOCALBASE}/include \ | GETTEXT_INCLUDE_DIR=${LOCALBASE}/include \ | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | |||||
.if !empty(_CARGO_GIT_PATCH_CARGOTOML) | .if !empty(_CARGO_GIT_PATCH_CARGOTOML) | ||||
_USES_patch+= 600:cargo-patch-git | _USES_patch+= 600:cargo-patch-git | ||||
cargo-patch-git: | cargo-patch-git: | ||||
@${FIND} ${WRKDIR} -name Cargo.toml -type f -exec \ | @${FIND} ${WRKDIR} -name Cargo.toml -type f -exec \ | ||||
${SED} -i.dist -E ${_CARGO_GIT_PATCH_CARGOTOML} {} + | ${SED} -i.dist -E ${_CARGO_GIT_PATCH_CARGOTOML} {} + | ||||
.endif | .endif | ||||
.if ${CARGO_CONFIGURE:tl} == "yes" | .if ${cargo_ARGS:Mconfigure} | ||||
_USES_configure+= 250:cargo-configure | _USES_configure+= 250:cargo-configure | ||||
# configure hook. Place a config file for overriding crates-io index | # configure hook. Place a config file for overriding crates-io index | ||||
# by local source directory. | # by local source directory. | ||||
cargo-configure: | cargo-configure: | ||||
# Check that the running kernel has COMPAT_FREEBSD11 required by lang/rust post-ino64 | # Check that the running kernel has COMPAT_FREEBSD11 required by lang/rust post-ino64 | ||||
@${SETENV} CC="${CC}" OPSYS="${OPSYS}" OSVERSION="${OSVERSION}" WRKDIR="${WRKDIR}" \ | @${SETENV} CC="${CC}" OPSYS="${OPSYS}" OSVERSION="${OSVERSION}" WRKDIR="${WRKDIR}" \ | ||||
${SH} ${SCRIPTSDIR}/rust-compat11-canary.sh | ${SH} ${SCRIPTSDIR}/rust-compat11-canary.sh | ||||
@${MKDIR} ${WRKDIR}/.cargo | @${MKDIR} ${WRKDIR}/.cargo | ||||
@${ECHO_CMD} "[source.cargo]" > ${WRKDIR}/.cargo/config | @${ECHO_CMD} "[source.cargo]" > ${WRKDIR}/.cargo/config | ||||
@${ECHO_CMD} "directory = '${CARGO_VENDOR_DIR}'" >> ${WRKDIR}/.cargo/config | @${ECHO_CMD} "directory = '${CARGO_VENDOR_DIR}'" >> ${WRKDIR}/.cargo/config | ||||
@${ECHO_CMD} "[source.crates-io]" >> ${WRKDIR}/.cargo/config | @${ECHO_CMD} "[source.crates-io]" >> ${WRKDIR}/.cargo/config | ||||
@${ECHO_CMD} "replace-with = 'cargo'" >> ${WRKDIR}/.cargo/config | @${ECHO_CMD} "replace-with = 'cargo'" >> ${WRKDIR}/.cargo/config | ||||
@if ! ${GREP} -qF '[profile.release]' ${CARGO_CARGOTOML}; then \ | @cd ${WRKSRC}; for _toml in ${CARGO_CARGOTOML}; do \ | ||||
${ECHO_CMD} "" >> ${CARGO_CARGOTOML}; \ | [ -d "$${_toml}" ] && _toml="$${_toml}/Cargo.toml"; \ | ||||
${ECHO_CMD} "[profile.release]" >> ${CARGO_CARGOTOML}; \ | ${CARGO_CARGO_RUN} update \ | ||||
${ECHO_CMD} "opt-level = 2" >> ${CARGO_CARGOTOML}; \ | --manifest-path "$${_toml}" \ | ||||
${ECHO_CMD} "debug = false" >> ${CARGO_CARGOTOML}; \ | |||||
fi | |||||
@${CARGO_CARGO_RUN} update \ | |||||
--manifest-path ${CARGO_CARGOTOML} \ | |||||
--verbose \ | --verbose \ | ||||
${CARGO_UPDATE_ARGS} | ${CARGO_UPDATE_ARGS}; \ | ||||
done | |||||
.endif | .endif | ||||
.if !target(do-build) && ${CARGO_BUILD:tl} == "yes" | .if ${cargo_ARGS:Mbuild} | ||||
do-build: | # Hook it to before pre-build. This might need to run before, e.g., | ||||
@${CARGO_CARGO_RUN} build \ | # USES=python's default do-build | ||||
--manifest-path ${CARGO_CARGOTOML} \ | _USES_build+= 250:cargo-build | ||||
cargo-build: | |||||
@cd ${WRKSRC}; for _toml in ${CARGO_CARGOTOML}; do \ | |||||
[ -d "$${_toml}" ] && _toml="$${_toml}/Cargo.toml"; \ | |||||
${ECHO_MSG} "===> Building $${_toml}"; \ | |||||
${CARGO_CARGO_RUN} build \ | |||||
--manifest-path "$${_toml}" \ | |||||
--verbose \ | --verbose \ | ||||
${CARGO_BUILD_ARGS} | ${CARGO_BUILD_ARGS}; \ | ||||
done | |||||
# Provide empty target if no other USES provided one | |||||
. if !target(do-build) | |||||
do-build: | |||||
@${DO_NADA} | |||||
.endif | . endif | ||||
.endif | |||||
.if !target(do-install) && ${CARGO_INSTALL:tl} == "yes" | |||||
do-install: | .if ${cargo_ARGS:Minstall} | ||||
_USES_install+= 250:cargo-install | |||||
cargo-install: | |||||
. for path in ${CARGO_INSTALL_PATH} | . for path in ${CARGO_INSTALL_PATH} | ||||
@${CARGO_CARGO_RUN} install \ | @${CARGO_CARGO_RUN} install \ | ||||
--no-track \ | --no-track \ | ||||
--path "${path}" \ | --path "${path}" \ | ||||
--root "${STAGEDIR}${PREFIX}" \ | --root "${STAGEDIR}${PREFIX}" \ | ||||
--verbose \ | --verbose \ | ||||
${CARGO_INSTALL_ARGS} | ${CARGO_INSTALL_ARGS} | ||||
. endfor | . endfor | ||||
# Provide empty target if no other USES provided one | |||||
. if !target(do-install) | |||||
do-install: | |||||
@${DO_NADA} | |||||
.endif | . endif | ||||
.endif | |||||
.if !target(do-test) && ${CARGO_TEST:tl} == "yes" | .if ${cargo_ARGS:Mtest} | ||||
do-test: | _USES_test+= 250:cargo-test | ||||
@${CARGO_CARGO_RUN} test \ | cargo-test: | ||||
--manifest-path ${CARGO_CARGOTOML} \ | @cd ${WRKSRC}; for _toml in ${CARGO_CARGOTOML}; do \ | ||||
[ -d "$${_toml}" ] && _toml="$${_toml}/Cargo.toml"; \ | |||||
${ECHO_MSG} "===> Testing $${_toml}"; \ | |||||
${CARGO_CARGO_RUN} test \ | |||||
--manifest-path "$${_toml}" \ | |||||
--verbose \ | --verbose \ | ||||
${CARGO_TEST_ARGS} | ${CARGO_TEST_ARGS}; \ | ||||
done | |||||
.endif | .endif | ||||
# | # | ||||
# Helper targets for port maintainers | # Helper targets for port maintainers | ||||
# | # | ||||
# cargo-crates will output the crates list from Cargo.lock. If there | # cargo-crates will output the crates list from Cargo.lock. If there | ||||
# is no Cargo.lock for some reason, try and generate it first. | # is no Cargo.lock for some reason, try and generate it first. | ||||
cargo-crates: extract | cargo-crates: extract | ||||
@if [ ! -r "${CARGO_CARGOLOCK}" ]; then \ | @cd ${WRKSRC}; _lock="${CARGO_CARGOLOCK}"; \ | ||||
${ECHO_MSG} "===> ${CARGO_CARGOLOCK} not found. Trying to generate it..."; \ | [ -d "$${_lock}" ] && _lock="$${_toml}/Cargo.lock"; \ | ||||
for _toml in ${CARGO_CARGOTOML}; do \ | |||||
[ -d "$${_toml}" ] && _toml="$${_toml}/Cargo.toml"; \ | |||||
if [ ! -r "$${_lock}" ]; then \ | |||||
${ECHO_MSG} "===> $${_lock} not found. Trying to generate it..."; \ | |||||
${CARGO_CARGO_RUN} generate-lockfile \ | ${CARGO_CARGO_RUN} generate-lockfile \ | ||||
--manifest-path ${CARGO_CARGOTOML} \ | --manifest-path "$${_toml}" \ | ||||
--verbose; \ | --verbose; \ | ||||
fi | fi; \ | ||||
@${SETENV} USE_GITHUB=${USE_GITHUB} USE_GITLAB=${USE_GITLAB} GL_SITE=${GL_SITE} \ | done; \ | ||||
${SETENV} USE_GITHUB=${USE_GITHUB} USE_GITLAB=${USE_GITLAB} GL_SITE=${GL_SITE} \ | |||||
${AWK} -f ${SCRIPTSDIR}/cargo-crates.awk ${CARGO_CARGOLOCK} | ${AWK} -f ${SCRIPTSDIR}/cargo-crates.awk ${CARGO_CARGOLOCK} | ||||
# cargo-crates-licenses will try to grab license information from | # cargo-crates-licenses will try to grab license information from | ||||
# all downloaded crates. | # all downloaded crates. | ||||
cargo-crates-licenses: configure | cargo-crates-licenses: configure | ||||
@${FIND} ${CARGO_VENDOR_DIR} -name 'Cargo.toml' -maxdepth 2 \ | @${FIND} ${CARGO_VENDOR_DIR} -name 'Cargo.toml' -maxdepth 2 \ | ||||
-exec ${GREP} -H '^license' {} \; \ | -exec ${GREP} -H '^license' {} \; \ | ||||
| ${SED} \ | | ${SED} \ | ||||
-e 's@^${CARGO_VENDOR_DIR}/@@' \ | -e 's@^${CARGO_VENDOR_DIR}/@@' \ | ||||
-e 's@/Cargo.toml:license.*= *"@|@' \ | -e 's@/Cargo.toml:license.*= *"@|@' \ | ||||
-e 's@"$$@@g' | sort | /usr/bin/column -t -s '|' | -e 's@"$$@@g' | sort | /usr/bin/column -t -s '|' | ||||
.endif | .endif |