diff --git a/Mk/Scripts/cargo-crates-git-common.awk b/Mk/Scripts/cargo-crates-git-common.awk new file mode 100644 index 000000000000..c1c5dcc7ce6e --- /dev/null +++ b/Mk/Scripts/cargo-crates-git-common.awk @@ -0,0 +1,105 @@ +# MAINTAINER: rust@FreeBSD.org + +BEGIN { + # No approval required to add a new gitlab instance here + gitlab_hosts["code.videolan.org"] = 1 + gitlab_hosts["foss.heptapod.net"] = 1 + gitlab_hosts["framagit.org"] = 1 + gitlab_hosts["gitlab.com"] = 1 + gitlab_hosts["gitlab.common-lisp.net"] = 1 + gitlab_hosts["gitlab.cs.fau.de"] = 1 + gitlab_hosts["gitlab.dune-project.org"] = 1 + gitlab_hosts["gitlab.freedesktop.org"] = 1 + gitlab_hosts["gitlab.gnome.org"] = 1 + gitlab_hosts["gitlab.howett.net"] = 1 + gitlab_hosts["gitlab.inria.fr"] = 1 + gitlab_hosts["gitlab.isc.org"] = 1 + gitlab_hosts["gitlab.linphone.org"] = 1 + gitlab_hosts["gitlab.mathematik.uni-stuttgart.de"] = 1 + gitlab_hosts["gitlab.mn.tu-dresden.de"] = 1 + gitlab_hosts["gitlab.mpcdf.mpg.de"] = 1 + gitlab_hosts["gitlab.redox-os.org"] = 1 + gitlab_hosts["gitlab.torproject.org"] = 1 + gitlab_hosts["gitlab.xfce.org"] = 1 + gitlab_hosts["invent.kde.org"] = 1 + gitlab_hosts["salsa.debian.org"] = 1 + gitlab_hosts["source.puri.sm"] = 1 +} + +function warn(fmt, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) { + printf("WARNING: " fmt "\n", a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) >"/dev/stderr" +} + +function commit_from_git_url(url) { + if (url["query", "tag"]) { + return url["query", "tag"] + } else { + return url["fragment"] + } +} + +function split_git_url(info, git_url, url, path, account, project, commit, i, dir_ver, host) { + delete info + split_url(url, git_url) + url["scheme"] = tolower(url["scheme"]) + url["host"] = tolower(url["host"]) + if (url["scheme"] ~ /^git(\+https?)?$/) { + if (url["host"] == "github.com") { + split(url["path"], path, "/") + account = path[2] + project = path[3] + sub(/\.[gG][iI][tT]$/, "", project) + commit = commit_from_git_url(url) + + delete url + url["scheme"] = "https" + url["host"] = "codeload.github.com" + url["path"] = sprintf("/%s/%s/tar.gz/%s", account, project, commit) + url["query"] = "dummy" + url["query", "dummy"] = "/" + info["site"] = join_url(url) + + info["filename"] = sprintf("%s-%s-%s_GH0.tar.gz", account, project, commit) + + # Per bsd.sites.mk: + # "GitHub silently converts tags starting with v to not have v in the filename + # and extraction directory. It also replaces + with -." + dir_ver = commit + sub(/^[vV]/, "", dir_ver) + gsub(/\+/, "-", dir_ver) + gsub(/--/, "-", dir_ver) + info["dir"] = sprintf("%s-%s", project, dir_ver) + + return 1 + } else if (gitlab_hosts[url["host"]]) { + split(url["path"], path, "/") + account = path[2] + for (i = 3; i < length(path); i++) { + account = account "/" path[i] + } + project = path[i] + sub(/\.[gG][iI][tT]$/, "", project) + commit = commit_from_git_url(url) + + host = url["host"] + delete url + url["scheme"] = "https" + url["host"] = host + url["path"] = sprintf("/%s/%s/-/archive/%s.tar.gz", account, project, commit) + url["query"] = "dummy" + url["query", "dummy"] = "/" + info["site"] = join_url(url) + + gsub(/\//, "-", account) + info["filename"] = sprintf("%s-%s-%s_GL0.tar.gz", account, project, commit) + + info["dir"] = sprintf("%s-%s", project, commit) + + return 1 + } + } + + warn("Do not know how to handle %s", git_url) + warn("If it points to a GitLab instance try adding the hostname to gitlab_hosts[] at the top of cargo-crates-git-common.awk") + return 0 +} diff --git a/Mk/Scripts/cargo-crates-git-configure.awk b/Mk/Scripts/cargo-crates-git-configure.awk new file mode 100644 index 000000000000..ade8718e44f6 --- /dev/null +++ b/Mk/Scripts/cargo-crates-git-configure.awk @@ -0,0 +1,137 @@ +# MAINTAINER: rust@FreeBSD.org + +function parse_sources( sources_len, raw_sources, i, j, k, original_crate_source, url, crate_source, crate_names, crate_name) { + sources_len = 0 + split(GIT_SOURCES, raw_sources) + for (i = 1; i <= length(raw_sources); i++) { + j = index(raw_sources[i], "@") + if (j == 0) { + warn("invalid source: %s\n", raw_sources[i]) + continue + } + original_crate_source = substr(raw_sources[i], j + 1) + split_url(url, original_crate_source) + sub(/^git\+/, "", url["scheme"]) + delete url["fragment"] + delete url["query"] + #sub(/\.git$/, "", url["path"]) + crate_source = join_url(url) + + split(substr(raw_sources[i], 1, j - 1), crate_names, ",") + for (k = 1; k <= length(crate_names); k++) { + crate_name = crate_names[k] + if (!source_crates[crate_source]) { + sources[++sources_len] = crate_source + } + source_crates[crate_source] = source_crates[crate_source] " " crate_name + original_crate_sources[crate_source, crate_name] = original_crate_source + } + } +} + +function get_source_dir(crate_source, crate_name, git_info, path, in_package, pattern, cmd, cargotoml, line) { + if (!split_git_url(git_info, original_crate_sources[crate_source, crate_name])) { + exit 1 + } + path = WRKDIR "/" git_info["dir"] + # Try to find the first Cargo.toml that defines our crate + # We are looking for + # [package] + # name = "$crate_name" + in_package = 0 + pattern = sprintf("^[ \t]*name[ \t]*=[ \t]*['\"]%s['\"]", crate_name) + cmd = FIND " " path " -name Cargo.toml -type f" + while ((cmd | getline cargotoml) > 0) { + while (getline line output + continue + } + } else if (line ~ /^[ \t]*\[[ \t]*patch\.crates-io[ \t]*\][ \t]*$/) { + in_patch_crates_io = 1 + } else if (line ~ /^[ \t]*\[/) { + in_patch_crates_io = 0 + } + print line >output + } + close(input) + close(output) +} + +function add_crates_io_patches( header_printed, cmd, cargotoml, source, crates) { + header_printed = 0 +# --exclude-dir not supported on FreeBSD < 13 +# cmd = GREP " --include='*/Cargo.toml' --exclude-dir='" CARGO_VENDOR_DIR "' -Flr 'patch.crates-io' " WRKSRC + cmd = FIND " " WRKSRC " -name Cargo.toml -not -path '" CARGO_VENDOR_DIR "/*' -exec " GREP " -Flr 'patch.crates-io' {} \\\+" + while (cmd | getline cargotoml) { + if (0 != system(CP " " cargotoml " " cargotoml ".orig-cargo")) { + exit 1 + } + find_replaced_crates(cargotoml ".orig-cargo", cargotoml) + if (length(replaced_crates) > 0) { + for (i in sources) { + source = sources[i] + split(source_crates[source], crates) + for (j in crates) { + if (replaced_crates[crates[j]]) { + if (!header_printed) { + printf("[patch.crates-io]\n") + header_printed = 1 + } + printf("%s = { path = '%s' }\n", crates[j], get_source_dir(source, crates[j])) + } + } + } + } + } + close(cmd) +} + +function add_git_patches( i, j, source, crates) { + for (i = 1; i <= length(sources); i++) { + source = sources[i] + split(source_crates[source], crates) + printf("[patch.'%s']\n", source) + for (j = 1; j <= length(crates); j++) { + printf("%s = { path = '%s' }\n", crates[j], get_source_dir(source, crates[j])) + } + } +} + +END { + parse_sources() + add_crates_io_patches() + add_git_patches() +} diff --git a/Mk/Scripts/cargo-crates-git-fetch.awk b/Mk/Scripts/cargo-crates-git-fetch.awk new file mode 100644 index 000000000000..241b6d3b72f2 --- /dev/null +++ b/Mk/Scripts/cargo-crates-git-fetch.awk @@ -0,0 +1,20 @@ +# MAINTAINER: rust@FreeBSD.org +# +# Return (index, site, filename, wrksrc, crates) 5-tuples from git URL specs in CARGO_CRATES + +END { + split(GIT_SOURCES, git_sources) + for (i = 1; i <= length(git_sources); i++) { + git_source = git_sources[i] + j = index(git_source, "@") + if (j == 0) { + warn("invalid source: %s", git_source) + } else { + crate_source = substr(git_source, j + 1) + crates = substr(git_source, 0, j - 1) + if (split_git_url(git_info, crate_source)) { + printf("%d %s %s %s %s\n", group++, git_info["site"], git_info["filename"], git_info["dir"], crates) + } + } + } +} diff --git a/Mk/Scripts/cargo-crates.awk b/Mk/Scripts/cargo-crates.awk index 56b3beafac11..0cc8fe7a27f9 100644 --- a/Mk/Scripts/cargo-crates.awk +++ b/Mk/Scripts/cargo-crates.awk @@ -1,122 +1,62 @@ # MAINTAINER: rust@FreeBSD.org BEGIN { - gh_tuple_len = 0 - gl_tuple_len = 0 crates_len = 0 - package_name = "" crate_name = "" crate_version = "" crate_source = "" - - gitlab_sites["https://gitlab.com"] = 1 - gitlab_sites["https://gitlab.freedesktop.org"] = 1 - gitlab_sites["https://gitlab.gnome.org"] = 1 - gitlab_sites["https://gitlab.redox-os.org"] = 1 } /^name = ".*"/ { crate_name = $3 gsub(/"/, "", crate_name) - - package_name = $3 - gsub("[^a-zA-Z_]", "", package_name) } /^version = ".*"/ { crate_version = $3 gsub(/"/, "", crate_version) } /^source = ".*"/ { crate_source = $3 gsub(/"/, "", crate_source) } /^\[\[package\]\]$/ { add_crate() } function add_crate() { - if (crate_source == "registry+https://github.com/rust-lang/crates.io-index") { + if (crate_source ~ /^git\+/) { + gsub(/#/, "\\#", crate_source) + if (git_crates[crate_source]) { + git_crates[crate_source] = git_crates[crate_source] "," crate_name + } else { + git_crates[crate_source] = crate_name + } + } else if (crate_source == "registry+https://github.com/rust-lang/crates.io-index") { crates[crates_len++] = sprintf("%s-%s", crate_name, crate_version) } crate_name = "" crate_version = "" crate_source = "" } -!gh_tuple_seen[$0] && /^source = "git\+(https|http|git):\/\/.*\/.*#.*"/ { - gh_tuple_seen[$0] = 1 - split_url(url, substr($3, 1 + length("\"git+"), length($3) - 1 - length("\"git+"))) - - split(url["path"], path, "/") - account = path[2] - project = path[3] - gsub("\.git$", "", project) - - if (match(url["query"], "^tag=")) { - split(url["query"], tag_, "=") - tag = tag_[2] - } else { - tag = url["fragment"] - } - - added = 0 - if (url["host"] == "github.com") { - added = 1 - gh_tuple[gh_tuple_len++] = sprintf(\ - "%s:%s:%s:%s", account, project, tag, package_name) - } else { - repo_site = sprintf("%s://%s", url["scheme"], url["host"]) - for (site in gitlab_sites) { - if (repo_site != site) { - continue - } - if (ENVIRON["GL_SITE"] == site) { - gl_tuple[gl_tuple_len++] = sprintf(\ - "%s:%s:%s:%s", account, project, tag, package_name) - } else { - gl_tuple[gl_tuple_len++] = sprintf(\ - "%s:%s:%s:%s:%s", site, account, project, tag, package_name) - } - added = 1 - break - } - } - - if (!added) { - printf "Warning: Ignoring git source on line %d: %s\n", NR, $3 > "/dev/stderr" - } -} - function print_array(start, arr, arrlen) { end = " \\\n" for (i = 0; i < arrlen; i++) { if (i == arrlen - 1) { end = "\n" } printf "%s\t%s%s", start, arr[i], end start = "\t" } } END { add_crate() - - if (gh_tuple_len > 0 && ENVIRON["USE_GITHUB"] == "") { - printf "USE_GITHUB=\tnodefault\n" - } - print_array("GH_TUPLE=", gh_tuple, gh_tuple_len) - if (gl_tuple_len > 0 && ENVIRON["USE_GITLAB"] == "") { - printf "USE_GITLAB=\tnodefault\n" + for (crate_source in git_crates) { + crates[crates_len++] = git_crates[crate_source] "@" crate_source } - print_array("GL_TUPLE=", gl_tuple, gl_tuple_len) print_array("CARGO_CRATES=", crates, crates_len) - if (gh_tuple_len > 0) { - printf "CARGO_USE_GITHUB=\tyes\n" - } - if (gl_tuple_len > 0) { - printf "CARGO_USE_GITLAB=\tyes\n" - } } diff --git a/Mk/Uses/cargo.mk b/Mk/Uses/cargo.mk index 131b02f52ba1..e1f5544b9c0b 100644 --- a/Mk/Uses/cargo.mk +++ b/Mk/Uses/cargo.mk @@ -1,368 +1,368 @@ # This file contains logic to ease porting of Rust packages or # binaries using the `cargo` command. # # Feature: cargo # Usage: USES=cargo # Valid ARGS: none # # MAINTAINER: rust@FreeBSD.org .if !defined(_INCLUDE_USES_CARGO_MK) _INCLUDE_USES_CARGO_MK= yes .if !empty(cargo_ARGS) IGNORE+= USES=cargo takes no arguments .endif .sinclude "${MASTERDIR}/Makefile.crates" # List of static dependencies. The format is cratename-version. # CARGO_CRATES will be downloaded from MASTER_SITE_CRATESIO. CARGO_CRATES?= # List of features to build (space separated list). # Use special token --no-default-features to disable default # features by passing it to cargo build/install/test. CARGO_FEATURES?= # Name of the local directory for vendoring crates. CARGO_VENDOR_DIR?= ${WRKSRC}/cargo-crates # Default path for cargo manifest. CARGO_CARGOTOML?= ${WRKSRC}/Cargo.toml CARGO_CARGOLOCK?= ${WRKSRC}/Cargo.lock # Save crates inside ${DISTDIR}/rust/crates by default. CARGO_DIST_SUBDIR?= rust/crates # Generate list of DISTFILES. # Prefer canonical file extension .crate going forward .if make(makesum) CARGO_CRATE_EXT= .crate .else # If there is a rust/crates/*.tar.gz in distinfo keep using the old # extension. We need to delay eval until the last moment for # DISTINFO_FILE. We cache the command output to avoid multiple # slow grep runs for every CARGO_CRATE_EXT access. CARGO_CRATE_EXT= ${defined(_CARGO_CRATE_EXT_CACHE):?${_CARGO_CRATE_EXT_CACHE}:${:!if ${GREP} -q '\(${CARGO_DIST_SUBDIR}/.*\.tar\.gz\)' "${DISTINFO_FILE}" 2>/dev/null; then ${ECHO_CMD} .tar.gz; else ${ECHO_CMD} .crate; fi!:_=_CARGO_CRATE_EXT_CACHE}} .endif + +_CARGO_CRATES:= ${CARGO_CRATES:N*@git+*} +_CARGO_GIT_SOURCES:= ${CARGO_CRATES:M*@git+*} # enumerate crates for unqiue and sane distfile group names -_CARGO_CRATES:= ${empty(CARGO_CRATES):?:${CARGO_CRATES:range:@i@$i ${CARGO_CRATES:[$i]}@}} +_CARGO_CRATES:= ${empty(_CARGO_CRATES):?:${_CARGO_CRATES:range:@i@$i ${_CARGO_CRATES:[$i]}@}} # split up crates into (index, crate, name, version) 4-tuples -_CARGO_CRATES:= ${_CARGO_CRATES:C/^([-_a-zA-Z0-9]+)-([0-9].*)/\0 \1 \2/} +_CARGO_CRATES:= ${_CARGO_CRATES:C/^([-_a-zA-Z0-9]+)-([0-9].*)/\0 \1 \2/} + .for _index _crate _name _version in ${_CARGO_CRATES} # Resolving CRATESIO alias is very inefficient with many MASTER_SITES, consume MASTER_SITE_CRATESIO directly MASTER_SITES+= ${MASTER_SITE_CRATESIO:S,%SUBDIR%,${_name}/${_version},:S,$,:_cargo_${_index},} DISTFILES+= ${CARGO_DIST_SUBDIR}/${_crate}${CARGO_CRATE_EXT}:_cargo_${_index} + +# Provide pointer to the crate's extraction dir +WRKSRC_crate_${_name}= ${CARGO_VENDOR_DIR}/${_crate} +# ... also with version suffix in case of multiple versions of the +# same crate +WRKSRC_crate_${_crate}= ${CARGO_VENDOR_DIR}/${_crate} .endfor +_CARGO_AWK= ${AWK} -vCP="${CP}" -vFIND="${FIND}" -vGREP="${GREP}" \ + -vCARGO_VENDOR_DIR="${CARGO_VENDOR_DIR}" \ + -vGIT_SOURCES="${_CARGO_GIT_SOURCES}" \ + -vWRKDIR="${WRKDIR}" -vWRKSRC="${WRKSRC}" \ + -f${SCRIPTSDIR}/split-url.awk \ + -f${SCRIPTSDIR}/cargo-crates-git-common.awk -f + +.if !empty(_CARGO_GIT_SOURCES) +. for _index _site _filename _wrksrc _crates in ${:!${_CARGO_AWK} ${SCRIPTSDIR}/cargo-crates-git-fetch.awk /dev/null!} +MASTER_SITES+= ${_site}:_cargo_git${_index} +DISTFILES+= ${_filename}:_cargo_git${_index} +. for _crate in ${_crates:S/,/ /g} +# Make sure the build dependencies checks below can work for git sourced crates too +_CARGO_CRATES+= @git ${_crate} ${_crate} @git + +# Provide pointer to the crate's extraction dir +# +# This might not point to the actual crate's sources since a +# single git source can contain multiple crates. We cannot collect +# subdir information until after the full extraction is done and we +# cannot set make variables at that point. This is better than +# nothing. +WRKSRC_crate_${_crate}= ${WRKDIR}/${_wrksrc} +. endfor +. endfor +.endif + # Build dependencies. CARGO_BUILDDEP?= yes .if ${CARGO_BUILDDEP:tl} == "yes" BUILD_DEPENDS+= ${RUST_DEFAULT}>=1.56.0:lang/${RUST_DEFAULT} .endif # Location of cargo binary (default to lang/rust's Cargo binary) CARGO_CARGO_BIN?= ${LOCALBASE}/bin/cargo # Location of the cargo output directory. CARGO_TARGET_DIR?= ${WRKDIR}/target # Default target platform (affects some RUSTFLAGS if passed) CARGO_BUILD_TARGET?= ${ARCH:S/amd64/x86_64/:S/i386/i686/}-unknown-${OPSYS:tl} # Environment for cargo # - CARGO_HOME: local cache of the registry index # - CARGO_BUILD_JOBS: configure number of jobs to run # - CARGO_TARGET_DIR: location of where to place all generated artifacts # - RUST_BACKTRACE: produce backtraces when something in the build panics # - 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_BUILD_JOBS=${MAKE_JOBS_NUMBER} \ CARGO_BUILD_TARGET=${CARGO_BUILD_TARGET} \ CARGO_TARGET_DIR=${CARGO_TARGET_DIR} \ CARGO_TARGET_${CARGO_BUILD_TARGET:S/-/_/g:tu}_LINKER="${CC}" \ RUST_BACKTRACE=1 \ RUSTC=${LOCALBASE}/bin/rustc \ RUSTDOC=${LOCALBASE}/bin/rustdoc \ RUSTFLAGS="${RUSTFLAGS} ${LDFLAGS:C/.+/-C link-arg=&/}" # 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 USE_GCC?= yes STRIP_CMD= ${LOCALBASE}/bin/strip # unsupported e_type with base strip .endif # Helper to shorten cargo calls. -CARGO_CARGO_RUN= \ - cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} ${CARGO_ENV} \ - ${CARGO_CARGO_BIN} +_CARGO_RUN= ${SETENV} ${MAKE_ENV} ${CARGO_ENV} ${CARGO_CARGO_BIN} +CARGO_CARGO_RUN= cd ${WRKSRC}; ${SETENV} CARGO_FREEBSD_PORTS_SKIP_GIT_UPDATE=1 ${_CARGO_RUN} # User arguments for cargo targets. CARGO_BUILD_ARGS?= CARGO_INSTALL_ARGS?= CARGO_INSTALL_PATH?= . CARGO_TEST_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 -# some dependencies from git repositories hosted on GitHub or -# GitLab instances. All Cargo.toml files will be patched to point -# to the right offline sources based on what is defined in -# {GH,GL}_TUPLE. This makes sure that cargo does not attempt to -# access the network during the build. -CARGO_USE_GITHUB?= no -CARGO_USE_GITLAB?= no - # rustc stashes intermediary files in TMPDIR (default /tmp) which # might cause issues for users that for some reason space limit # their /tmp. WRKDIR should have plenty of space. # Allow users and ports to still overwrite it. .if ${TMPDIR:U/tmp} == /tmp TMPDIR= ${WRKDIR} .endif # Manage crate features. .if !empty(CARGO_FEATURES:M--no-default-features) CARGO_BUILD_ARGS+= --no-default-features CARGO_INSTALL_ARGS+= --no-default-features CARGO_TEST_ARGS+= --no-default-features .endif .if !empty(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_TEST_ARGS+= --features='${CARGO_FEATURES:N--no-default-features}' .endif .if !defined(WITH_DEBUG) CARGO_BUILD_ARGS+= --release CARGO_TEST_ARGS+= --release .else CARGO_INSTALL_ARGS+= --debug .endif .if ${_CARGO_CRATES:Mcmake} BUILD_DEPENDS+= cmake:devel/cmake .endif .if ${_CARGO_CRATES:Mgettext-sys} CARGO_ENV+= GETTEXT_BIN_DIR=${LOCALBASE}/bin \ GETTEXT_INCLUDE_DIR=${LOCALBASE}/include \ GETTEXT_LIB_DIR=${LOCALBASE}/lib .endif .if ${_CARGO_CRATES:Mjemalloc-sys} BUILD_DEPENDS+= gmake:devel/gmake .endif .if ${_CARGO_CRATES:Mlibgit2-sys} # Use the system's libgit2 instead of building the bundled version CARGO_ENV+= LIBGIT2_SYS_USE_PKG_CONFIG=1 .endif .if ${_CARGO_CRATES:Mlibssh2-sys} # Use the system's libssh2 instead of building the bundled version CARGO_ENV+= LIBSSH2_SYS_USE_PKG_CONFIG=1 .endif .if ${_CARGO_CRATES:Monig_sys} # onig_sys always prefers the system library but will try to link # statically with it. Since devel/oniguruma doesn't provide a static # library it'll link to libonig.so instead. Strictly speaking setting # RUSTONIG_SYSTEM_LIBONIG is not necessary, but will force onig_sys to # always use the system's libonig as returned by `pkg-config oniguruma`. CARGO_ENV+= RUSTONIG_SYSTEM_LIBONIG=1 .endif .if ${_CARGO_CRATES:Mopenssl-src} DEV_WARNING+= "Please make sure this port uses the system OpenSSL and consider removing CARGO_CRATES=${CARGO_CRATES:Mopenssl-src-[0-9]*} (a vendored copy of OpenSSL) from the build, e.g., by patching Cargo.toml appropriately." .endif .if ${_CARGO_CRATES:Mopenssl-sys} # Make sure that openssl-sys can find the correct version of OpenSSL CARGO_ENV+= OPENSSL_LIB_DIR=${OPENSSLLIB} \ OPENSSL_INCLUDE_DIR=${OPENSSLINC} .endif .if ${_CARGO_CRATES:Mpkg-config} .include "${USESDIR}/pkgconfig.mk" .endif .for _index _crate _name _version in ${_CARGO_CRATES} # Split up semantic version and try to sanitize it by removing # pre-release identifier (-) or build metadata (+) . if ${_version:S/./ /:S/./ /:C/[-+].*//:_:[#]} == 3 . for _major _minor _patch in $_ # FreeBSD 12.0 changed ABI: r318736 and r320043 # https://github.com/rust-lang/libc/commit/78f93220d70e # https://github.com/rust-lang/libc/commit/969ad2b73cdc . if ${_name} == libc && ${_major} == 0 && (${_minor} < 2 || (${_minor} == 2 && ${_patch} < 38)) DEV_ERROR+= "CARGO_CRATES=${_crate} may be unstable on FreeBSD 12.0. Consider updating to the latest version \(higher than 0.2.37\)." . endif . if ${_name} == libc && ${_major} == 0 && (${_minor} < 2 || (${_minor} == 2 && ${_patch} < 49)) DEV_ERROR+= "CARGO_CRATES=${_crate} may be unstable on aarch64 or not build on armv6, armv7, powerpc64. Consider updating to the latest version \(higher than 0.2.49\)." . endif # FreeBSD 12.0 updated base OpenSSL in r339270: # https://github.com/sfackler/rust-openssl/commit/276577553501 . if ${_name} == openssl && !exists(${PATCHDIR}/patch-openssl-1.1.1) && ${_major} == 0 && (${_minor} < 10 || (${_minor} == 10 && ${_patch} < 4)) DEV_WARNING+= "CARGO_CRATES=${_crate} does not support OpenSSL 1.1.1. Consider updating to the latest version \(higher than 0.10.3\)." . endif . endfor . endif .endfor _USES_extract+= 600:cargo-extract cargo-extract: # target for preparing crates directory. It will put all crates in # the local crates directory. @${ECHO_MSG} "===> Moving crates to ${CARGO_VENDOR_DIR}" @${MKDIR} ${CARGO_VENDOR_DIR} -.for _crate in ${CARGO_CRATES} +.for _index _crate _name _version in ${_CARGO_CRATES} +. if ${_index} != @git @${MV} ${WRKDIR}/${_crate} ${CARGO_VENDOR_DIR}/${_crate} @${PRINTF} '{"package":"%s","files":{}}' \ $$(${SHA256} -q ${DISTDIR}/${CARGO_DIST_SUBDIR}/${_crate}${CARGO_CRATE_EXT}) \ > ${CARGO_VENDOR_DIR}/${_crate}/.cargo-checksum.json @if [ -r ${CARGO_VENDOR_DIR}/${_crate}/Cargo.toml.orig ]; then \ ${MV} ${CARGO_VENDOR_DIR}/${_crate}/Cargo.toml.orig \ ${CARGO_VENDOR_DIR}/${_crate}/Cargo.toml.orig-cargo; \ fi +. endif .endfor -_CARGO_GIT_PATCH_CARGOTOML= -.if ${CARGO_USE_GITHUB:tl} == "yes" -. for _group in ${GH_TUPLE:C@^[^:]*:[^:]*:[^:]*:(([^:/]*)?)((/.*)?)@\2@} -. if empty(CARGO_GIT_SUBDIR:M${_group}\:*) -_CARGO_GIT_PATCH_CARGOTOML:= ${_CARGO_GIT_PATCH_CARGOTOML} \ - -e "s@git *= *['\"](https|http|git)://github.com/${GH_ACCOUNT_${_group}}/${GH_PROJECT_${_group}}(\.git)?/?[\"']@path = \"${WRKSRC_${_group}}\"@" -. else -. for _group2 _crate _subdir in ${CARGO_GIT_SUBDIR:M${_group}\:*:S,:, ,g} -_CARGO_GIT_PATCH_CARGOTOML:= ${_CARGO_GIT_PATCH_CARGOTOML} \ - -e "/^${_crate} =/ s@git *= *['\"](https|http|git)://github.com/${GH_ACCOUNT_${_group}}/${GH_PROJECT_${_group}}(\.git)?/?[\"']@path = \"${WRKSRC_${_group}}/${_subdir}\"@" -. endfor -. endif -. endfor -.endif -.if ${CARGO_USE_GITLAB:tl} == "yes" -. for _group in ${GL_TUPLE:C@^(([^:]*://[^:/]*(:[0-9]{1,5})?(/[^:]*[^/])?:)?)([^:]*):([^:]*):([^:]*)(:[^:/]*)((/.*)?)@\8@:S/^://} -. if empty(CARGO_GIT_SUBDIR:M${_group}\:*) -_CARGO_GIT_PATCH_CARGOTOML:= ${_CARGO_GIT_PATCH_CARGOTOML} \ - -e "s@git *= *['\"]${GL_SITE_${_group}}/${GL_ACCOUNT_${_group}}/${GL_PROJECT_${_group}}(\.git)?/?['\"]@path = \"${WRKSRC_${_group}}\"@" -. else -. for _group2 _crate _subdir in ${CARGO_GIT_SUBDIR:M${_group}\:*:S,:, ,g} -_CARGO_GIT_PATCH_CARGOTOML:= ${_CARGO_GIT_PATCH_CARGOTOML} \ - -e "/^${_crate} = / s@git *= *['\"]${GL_SITE_${_group}}/${GL_ACCOUNT_${_group}}/${GL_PROJECT_${_group}}(\.git)?/?['\"]@path = \"${WRKSRC_${_group}}/${_subdir}\"@" -. endfor -. endif -. endfor -.endif - -.if !empty(_CARGO_GIT_PATCH_CARGOTOML) -_USES_patch+= 600:cargo-patch-git - -cargo-patch-git: - @${FIND} ${WRKDIR} -name Cargo.toml -type f -exec \ - ${SED} -i.dist -E ${_CARGO_GIT_PATCH_CARGOTOML} {} + -.endif - .if ${CARGO_CONFIGURE:tl} == "yes" _USES_configure+= 250:cargo-configure # configure hook. Place a config file for overriding crates-io index # by local source directory. cargo-configure: # Check that the running kernel has COMPAT_FREEBSD11 required by lang/rust post-ino64 @${SETENV} CC="${CC}" OPSYS="${OPSYS}" OSVERSION="${OSVERSION}" WRKDIR="${WRKDIR}" \ ${SH} ${SCRIPTSDIR}/rust-compat11-canary.sh + @${ECHO_MSG} "===> Cargo config:" @${MKDIR} ${WRKDIR}/.cargo - @${ECHO_CMD} "[source.cargo]" > ${WRKDIR}/.cargo/config - @${ECHO_CMD} "directory = '${CARGO_VENDOR_DIR}'" >> ${WRKDIR}/.cargo/config - @${ECHO_CMD} "[source.crates-io]" >> ${WRKDIR}/.cargo/config - @${ECHO_CMD} "replace-with = 'cargo'" >> ${WRKDIR}/.cargo/config + @: > ${WRKDIR}/.cargo/config.toml + @${ECHO_CMD} "[source.cargo]" >> ${WRKDIR}/.cargo/config.toml + @${ECHO_CMD} "directory = '${CARGO_VENDOR_DIR}'" >> ${WRKDIR}/.cargo/config.toml + @${ECHO_CMD} "[source.crates-io]" >> ${WRKDIR}/.cargo/config.toml + @${ECHO_CMD} "replace-with = 'cargo'" >> ${WRKDIR}/.cargo/config.toml +.if !empty(_CARGO_GIT_SOURCES) + @${_CARGO_AWK} ${SCRIPTSDIR}/cargo-crates-git-configure.awk \ + /dev/null >> ${WRKDIR}/.cargo/config.toml +.endif + @${CAT} ${WRKDIR}/.cargo/config.toml @if ! ${GREP} -qF '[profile.release]' ${CARGO_CARGOTOML}; then \ ${ECHO_CMD} "" >> ${CARGO_CARGOTOML}; \ ${ECHO_CMD} "[profile.release]" >> ${CARGO_CARGOTOML}; \ ${ECHO_CMD} "opt-level = 2" >> ${CARGO_CARGOTOML}; \ ${ECHO_CMD} "debug = false" >> ${CARGO_CARGOTOML}; \ fi + @${ECHO_MSG} "===> Updating Cargo.lock" @${CARGO_CARGO_RUN} update \ --manifest-path ${CARGO_CARGOTOML} \ --verbose \ --verbose \ ${CARGO_UPDATE_ARGS} .endif .if !target(do-build) && ${CARGO_BUILD:tl} == "yes" do-build: @${CARGO_CARGO_RUN} build \ --manifest-path ${CARGO_CARGOTOML} \ --verbose \ --verbose \ ${CARGO_BUILD_ARGS} .endif .if !target(do-install) && ${CARGO_INSTALL:tl} == "yes" do-install: . for path in ${CARGO_INSTALL_PATH} @${CARGO_CARGO_RUN} install \ --no-track \ --path "${path}" \ --root "${STAGEDIR}${PREFIX}" \ --verbose \ --verbose \ ${CARGO_INSTALL_ARGS} . endfor .endif .if !target(do-test) && ${CARGO_TEST:tl} == "yes" do-test: @${CARGO_CARGO_RUN} test \ --manifest-path ${CARGO_CARGOTOML} \ --verbose \ --verbose \ ${CARGO_TEST_ARGS} .endif # # Helper targets for port maintainers # # cargo-crates will output the crates list from Cargo.lock. If there # is no Cargo.lock for some reason, try and generate it first. cargo-crates: extract @if [ ! -r "${CARGO_CARGOLOCK}" ]; then \ ${ECHO_MSG} "===> ${CARGO_CARGOLOCK} not found. Trying to generate it..."; \ - ${CARGO_CARGO_RUN} generate-lockfile \ + cd ${WRKSRC}; ${_CARGO_RUN} generate-lockfile \ --manifest-path ${CARGO_CARGOTOML} \ --verbose; \ fi - @${SETENV} USE_GITHUB=${USE_GITHUB} USE_GITLAB=${USE_GITLAB} GL_SITE=${GL_SITE} \ - ${AWK} -f ${SCRIPTSDIR}/split-url.awk -f ${SCRIPTSDIR}/cargo-crates.awk ${CARGO_CARGOLOCK} + @${_CARGO_AWK} ${SCRIPTSDIR}/cargo-crates.awk ${CARGO_CARGOLOCK} # cargo-crates-licenses will try to grab license information from # all downloaded crates. cargo-crates-licenses: configure @${FIND} ${CARGO_VENDOR_DIR} -name 'Cargo.toml' -maxdepth 2 \ -exec ${GREP} -H '^license' {} \; \ | ${SED} \ -e 's@^${CARGO_VENDOR_DIR}/@@' \ -e 's@/Cargo.toml:license.*= *"@|@' \ -e 's@"$$@@g' | sort | /usr/bin/column -t -s '|' .endif