forked from cross-rs/cross
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add scripts to validate target info.
Attempts to recreate the table present in README.md, which can extract the target information for a single target or for all targets. Should currently support the following targets: - Android - glibc - musl - MinGW - FreeBSD - NetBSD - newlib Closes cross-rs#686.
- Loading branch information
1 parent
c72b1d7
commit 4ae5ecc
Showing
2 changed files
with
397 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# this script can be customized with the following env vars: | ||
# CROSS_IMAGE: defaults to `ghcr.io/cross-rs` | ||
# CROSS_CONTAINER_ENGINE: defaults to `docker` or `podman` | ||
# CROSS_IMAGE_VERSION: defaults to `main`. | ||
# | ||
# the output will be similar to the following: | ||
# | `aarch64-unknown-linux-musl` | 1.2.0 | 9.2.0 | ✓ | 5.1.0 | | ||
# | `i686-linux-android` | 9.0.8 | 9.0.8 | ✓ | 5.1.0 | | ||
# | `i686-unknown-linux-musl` | 1.2.0 | 9.2.0 | ✓ | N/A | | ||
# ... | ||
# | ||
# in short, it recreates the table except for the test section in README.md. | ||
|
||
set -eo pipefail | ||
|
||
if [[ -z "$CROSS_IMAGE" ]]; then | ||
CROSS_IMAGE="ghcr.io/cross-rs" | ||
fi | ||
if [[ -z "$CROSS_CONTAINER_ENGINE" ]]; then | ||
if command -v "docker" &>/dev/null; then | ||
CROSS_CONTAINER_ENGINE="docker" | ||
elif command -v "podman" &>/dev/null; then | ||
CROSS_CONTAINER_ENGINE="podman" | ||
else | ||
echo "Unable to find suitable container engine." 1>&2 | ||
exit 1 | ||
fi | ||
fi | ||
if [[ -z "$CROSS_IMAGE_VERSION" ]]; then | ||
CROSS_IMAGE_VERSION="main" | ||
fi | ||
|
||
TARGETS=( | ||
"aarch64-linux-android" | ||
"aarch64-unknown-linux-gnu" | ||
"aarch64-unknown-linux-musl" | ||
"arm-linux-androideabi" | ||
"arm-unknown-linux-gnueabi" | ||
"arm-unknown-linux-gnueabihf" | ||
"arm-unknown-linux-musleabi" | ||
"arm-unknown-linux-musleabihf" | ||
"armv5te-unknown-linux-gnueabi" | ||
"armv5te-unknown-linux-musleabi" | ||
"armv7-linux-androideabi" | ||
"armv7-unknown-linux-gnueabihf" | ||
"armv7-unknown-linux-musleabihf" | ||
# Temporarily disabled: "asmjs-unknown-emscripten" | ||
# Temporarily disabled: "wasm32-unknown-emscripten" | ||
"i586-unknown-linux-gnu" | ||
"i586-unknown-linux-musl" | ||
"i686-linux-android" | ||
"i686-pc-windows-gnu" | ||
"i686-unknown-freebsd" | ||
"i686-unknown-linux-gnu" | ||
"i686-unknown-linux-musl" | ||
"mips-unknown-linux-gnu" | ||
"mips-unknown-linux-musl" | ||
"mips64-unknown-linux-gnuabi64" | ||
"mips64el-unknown-linux-gnuabi64" | ||
"mipsel-unknown-linux-gnu" | ||
"mipsel-unknown-linux-musl" | ||
"powerpc-unknown-linux-gnu" | ||
"powerpc64-unknown-linux-gnu" | ||
"powerpc64le-unknown-linux-gnu" | ||
"riscv64gc-unknown-linux-gnu" | ||
"s390x-unknown-linux-gnu" | ||
"sparc64-unknown-linux-gnu" | ||
# Disabled: "sparcv9-sun-solaris" | ||
# Disabled: "x86_64-sun-solaris" | ||
"thumbv6m-none-eabi" | ||
"thumbv7em-none-eabi" | ||
"thumbv7em-none-eabihf" | ||
"thumbv7m-none-eabi" | ||
"x86_64-linux-android" | ||
"x86_64-pc-windows-gnu" | ||
"x86_64-unknown-freebsd" | ||
# Disabled: "x86_64-unknown-dragonfly" | ||
"x86_64-unknown-linux-gnu" | ||
"x86_64-unknown-linux-musl" | ||
"x86_64-unknown-netbsd" | ||
) | ||
|
||
for target in "${TARGETS[@]}"; do | ||
"${CROSS_CONTAINER_ENGINE}" fetch "${CROSS_IMAGE}"/"${target}":"${CROSS_IMAGE_VERSION}" | ||
TARGET="${target}" "${CROSS_CONTAINER_ENGINE}" run --rm -e TARGET \ | ||
"${CROSS_IMAGE}"/"${target}":"${CROSS_IMAGE_VERSION}" \ | ||
bash -c "`cat extract_target_info.sh`" 2>/dev/null | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,307 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# this script can be invoked as follows: | ||
# export TARGET=aarch64-unknown-linux-musl | ||
# docker run -e TARGET ghcr.io/cross-rs/"$TARGET":main bash -c "`cat extract_target_info.sh`" | ||
# | ||
# the output will be similar to the following: | ||
# | `aarch64-unknown-linux-musl` | 1.2.0 | 9.2.0 | ✓ | 5.1.0 | | ||
# | ||
# in short, it recreates the table except for the test section in README.md. | ||
|
||
set -eo pipefail | ||
|
||
target="${TARGET}" | ||
arch="${target//-*/}" | ||
|
||
extract_regex_version() { | ||
# executing shared libraries outputs to stderr, rest to stdout | ||
version="$($1 --version 2>&1)" | ||
if [[ "${version}" =~ $2 ]]; then | ||
echo "${BASH_REMATCH[1]}" | ||
else | ||
echo "Unable to match $3 version info for ${target}." 1>&2 | ||
exit 1 | ||
fi | ||
} | ||
|
||
max_glibc_version() { | ||
# glibc versions have the following format: | ||
# `libc-$major-$minor.so.$abi`, where the `.$abi` may be optional. | ||
local -a paths=(`ls "${1}"/libc-[0-9]*.[0-9]*.so*`) | ||
local major=0 | ||
local minor=0 | ||
local version | ||
local x | ||
local y | ||
local z | ||
local r | ||
local is_larger | ||
|
||
for i in "${!paths[@]}"; do | ||
file=`basename "${paths[$i]}"` | ||
version="${file//libc-/}" | ||
x=$(echo "${version}" | cut -d '.' -f 1) | ||
y=$(echo "${version}" | cut -d '.' -f 2) | ||
is_larger= | ||
|
||
if [ "${x}" -gt "${major}" ]; then | ||
is_larger=1 | ||
elif [ "${x}" -eq "${major}" ] && [ "${y}" -gt "${minor}" ]; then | ||
is_larger=1 | ||
fi | ||
|
||
if [ -n "${is_larger}" ]; then | ||
major="${x}" | ||
minor="${y}" | ||
fi | ||
done | ||
|
||
echo "${major}.${minor}" | ||
} | ||
|
||
# output variables | ||
libc= | ||
cc= | ||
cxx= | ||
qemu= | ||
|
||
# select toolchain information | ||
compiler_suffix="${target//-/_}" | ||
cc_var="CC_${compiler_suffix}" | ||
cxx_var="CXX_${compiler_suffix}" | ||
cc_regex= | ||
case "${target}" in | ||
*-*-android*) | ||
cc_regex=".* clang version ([0-9]+.[0-9]+.[0-9]+) .*" | ||
;; | ||
*-*-*-musl*) | ||
cc_regex=".*gcc \(GCC\) ([0-9]+.[0-9]+.[0-9]+).*" | ||
;; | ||
*-*-linux-gnu*) | ||
cc_regex=".*gcc \(.*\) ([0-9]+.[0-9]+.[0-9]+).*" | ||
;; | ||
*-*-windows-gnu*) | ||
# MinGW only reports major/minor versions, and can | ||
# have a -posix or -win32 suffix, eg: 7.5-posix | ||
cc_regex=".*gcc.* \(GCC\) ([0-9]+.[0-9]+).*" | ||
;; | ||
*-*-freebsd) | ||
cc_regex=".*gcc \(GCC\) ([0-9]+.[0-9]+.[0-9]+).*" | ||
;; | ||
*-*-netbsd) | ||
cc_regex=".*gcc \(.*\) ([0-9]+.[0-9]+.[0-9]+).*" | ||
;; | ||
*-none-*) | ||
cc_regex=".*gcc \(.*\) ([0-9]+.[0-9]+.[0-9]+).*" | ||
;; | ||
*) | ||
echo "TODO: Currently unsupported" 1>&2 | ||
exit 1 | ||
;; | ||
esac | ||
|
||
# select qemu arch | ||
qarch="${arch}" | ||
case "${arch}" in | ||
arm*) | ||
qarch="arm" | ||
;; | ||
i*86) | ||
qarch="i386" | ||
;; | ||
powerpc) | ||
qarch="ppc" | ||
;; | ||
powerpc64) | ||
qarch="ppc64" | ||
;; | ||
powerpc64le) | ||
if [ "${CROSS_RUNNER}" = "qemu-user" ]; then | ||
qarch="ppc64le" | ||
else | ||
qarch="ppc64" | ||
fi | ||
;; | ||
riscv64*) | ||
qarch="riscv64" | ||
;; | ||
esac | ||
qemu_regex="qemu-${qarch} version ([0-9]+.[0-9]+.[0-9]+).*" | ||
|
||
# evaluate our toolchain info | ||
cc_bin= | ||
cxx_bin= | ||
case "${target}" in | ||
i*86-unknown-linux-gnu | x86_64-unknown-linux-gnu) | ||
cc_bin="gcc" | ||
cxx_bin="g++" | ||
;; | ||
thumb*-none-eabi* | arm*-none-eabi*) | ||
# the ARM/THUMB targets don't have a CC_${compiler_suffix} | ||
cc_bin=arm-none-eabi-gcc | ||
cxx_bin=arm-none-eabi-g++ | ||
;; | ||
*) | ||
cc_bin="${!cc_var}" | ||
cxx_bin="${!cxx_var}" | ||
;; | ||
|
||
esac | ||
cc=$(extract_regex_version "${cc_bin}" "${cc_regex}" compiler) | ||
if command -v "${cxx_bin}" &>/dev/null; then | ||
# test we can compile a c++ program that requires the c++ stdlib | ||
cat <<EOT >> main.cc | ||
#include <iostream> | ||
int main() { | ||
std::cout << "Testing this" << std::endl; | ||
} | ||
EOT | ||
if "${cxx_bin}" main.cc >/dev/null 2>&1; [ "${?}" -eq 0 ]; then | ||
cxx=1 | ||
fi | ||
fi | ||
|
||
case "${target}" in | ||
*-*-android*) | ||
libc="${cc}" | ||
;; | ||
*-*-*-musl*) | ||
toolchain_prefix="${!cc_var//-gcc/}" | ||
libdir="/usr/local/${toolchain_prefix}/lib" | ||
libc_regex=".*Version ([0-9]+.[0-9]+.[0-9]+).*" | ||
if [[ "${arch}" = i[3-7]86 ]] || [ "${arch}" == x86_64 ]; then | ||
libc_cmd="${libdir}/libc.so" | ||
else | ||
libc_cmd="qemu-${qarch} ${libdir}/libc.so" | ||
if ! command -v "qemu-${qarch}" &>/dev/null; then | ||
echo "Unable to get qemu version for ${target}: qemu not found." 1>&2 | ||
exit 1 | ||
fi | ||
fi | ||
libc=$(extract_regex_version "${libc_cmd}" "${libc_regex}" libc) | ||
;; | ||
arm-unknown-linux-gnueabihf) | ||
libdir="/usr/arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib" | ||
libc=$(max_glibc_version "${libdir}") | ||
;; | ||
i*86-unknown-linux-gnu) | ||
libdir="/lib/x86_64-linux-gnu/" | ||
libc=$(max_glibc_version "${libdir}") | ||
;; | ||
x86_64-unknown-linux-gnu) | ||
libdir="/lib64/" | ||
libc=$(max_glibc_version "${libdir}") | ||
;; | ||
*-*-linux-gnu*) | ||
toolchain_prefix="${!cc_var//-gcc/}" | ||
libdir="/usr/${toolchain_prefix}/lib" | ||
libc=$(max_glibc_version "${libdir}") | ||
;; | ||
*-*-windows-gnu) | ||
# no libc, intentionally omitted. | ||
;; | ||
*-*-freebsd) | ||
# we write the FreeBSD version to /opt/freebsd-version | ||
# the symbol versioning can be found here: | ||
# https://wiki.freebsd.org/SymbolVersioning | ||
version=$(cat /opt/freebsd-version) | ||
if [[ "${version}" =~ ([0-9]+)\.([0-9]+)" ("[A-Za-z]+")" ]]; then | ||
major_version="${BASH_REMATCH[1]}" | ||
minor_version="${BASH_REMATCH[2]}" | ||
case "${major_version}" in | ||
7) | ||
libc="1.0" | ||
;; | ||
8) | ||
libc="1.1" | ||
;; | ||
9) | ||
libc="1.2" | ||
;; | ||
10) | ||
libc="1.3" | ||
;; | ||
11) | ||
libc="1.4" | ||
;; | ||
12) | ||
libc="1.5" | ||
;; | ||
13) | ||
libc="1.6" | ||
;; | ||
*) | ||
echo "Invalid FreeBSD version, got ${major_version}.${minor_version}." 1>&2 | ||
exit 1 | ||
;; | ||
esac | ||
else | ||
echo "Unable to get libc version for ${target}: invalid FreeBSD release found." 1>&2 | ||
exit 1 | ||
fi | ||
;; | ||
*-*-netbsd) | ||
# We can read the NetBSD version from the libc symbols. | ||
# The output follows: | ||
# NetBSD 0x00000004 IDENT 902000000 (9.2.0) | ||
libdir="/usr/local/${target}/lib" | ||
version=$(readelf -a "${libdir}"/libc.so | grep NetBSD | head -n 1) | ||
if [[ "${version}" =~ .+" ("([0-9]+)"."([0-9]+)"."([0-9]+)")" ]]; then | ||
major_version="${BASH_REMATCH[1]}" | ||
minor_version="${BASH_REMATCH[2]}" | ||
patch_version="${BASH_REMATCH[3]}" | ||
libc="${major_version}.${minor_version}.${patch_version}" | ||
else | ||
echo "Unable to get libc version for ${target}: invalid NetBSD release found." 1>&2 | ||
exit 1 | ||
fi | ||
;; | ||
thumb*-none-eabi* | arm*-none-eabi*) | ||
# newlib kinda sucks. just query for the install package | ||
pkg=$(dpkg --get-selections | grep -v deinstall | grep newlib | head -n 1) | ||
pkg=$(echo "${pkg}" | cut -f 1) | ||
version=$(dpkg-query --showformat='${Version}' --show "${pkg}") | ||
if [[ "${version}" =~ ([0-9]+)"."([0-9]+)"."([0-9]+)"+".* ]]; then | ||
major_version="${BASH_REMATCH[1]}" | ||
minor_version="${BASH_REMATCH[2]}" | ||
patch_version="${BASH_REMATCH[3]}" | ||
libc="${major_version}.${minor_version}.${patch_version}" | ||
else | ||
echo "Unable to get libc version for ${target}: invalid NetBSD release found." 1>&2 | ||
exit 1 | ||
fi | ||
;; | ||
*) | ||
echo "TODO: Currently unsupported" 1>&2 | ||
exit 1 | ||
;; | ||
esac | ||
|
||
if command -v "qemu-${qarch}" &>/dev/null; then | ||
qemu=$(extract_regex_version "qemu-${qarch}" "${qemu_regex}" qemu) | ||
fi | ||
|
||
# format our output | ||
printf "| %-36s |" "\`${target}\`" | ||
if [ "$libc" != "" ]; then | ||
printf " %-6s |" ${libc} | ||
else | ||
printf " N/A |" | ||
fi | ||
if [ "$cc" != "" ]; then | ||
printf " %-7s |" "${cc}" | ||
else | ||
printf " N/A |" | ||
fi | ||
if [ "$cxx" != "" ]; then | ||
printf " ✓ |" | ||
else | ||
printf " |" | ||
fi | ||
if [ "$qemu" != "" ]; then | ||
printf " %-5s |" "${qemu}" | ||
else | ||
printf " N/A |" | ||
fi | ||
printf "\n" |