mirror of
https://github.com/rust-lang/cargo
synced 2024-09-15 22:09:55 +00:00
230dbf6a59
In general relying on external programs is dicey and tricky as they're very different across systems in both how they're used as well as what versions you'll find. Instead of binding to the least common denominator of CLI, we can code against an exact version of libgit2. This introduces a build-time dependency on cmake which libgit2 requires to build itself, which is unfortunate, but thankfully it's only a build time dep. The build process for libgit2 also automatically detects as many system libraries as possible to use (if available), falling back to bundled versions if not available. I have currently not figured how to control this, so the link-config package is used to build libgit2 which requires that pkg-config be installed to build cargo as well. Closes #138
384 lines
8.1 KiB
Bash
Executable file
384 lines
8.1 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
msg() {
|
|
echo "configure: $1"
|
|
}
|
|
|
|
step_msg() {
|
|
msg
|
|
msg "$1"
|
|
msg
|
|
}
|
|
|
|
warn() {
|
|
echo "configure: WARNING: $1"
|
|
}
|
|
|
|
err() {
|
|
echo "configure: error: $1"
|
|
exit 1
|
|
}
|
|
|
|
need_ok() {
|
|
if [ $? -ne 0 ]
|
|
then
|
|
err "$1"
|
|
fi
|
|
}
|
|
|
|
need_cmd() {
|
|
if command -v $1 >/dev/null 2>&1
|
|
then msg "found $1"
|
|
else err "need $1"
|
|
fi
|
|
}
|
|
|
|
make_dir() {
|
|
if [ ! -d $1 ]
|
|
then
|
|
msg "mkdir -p $1"
|
|
mkdir -p $1
|
|
fi
|
|
}
|
|
|
|
copy_if_changed() {
|
|
if cmp -s $1 $2
|
|
then
|
|
msg "leaving $2 unchanged"
|
|
else
|
|
msg "cp $1 $2"
|
|
cp -f $1 $2
|
|
chmod u-w $2 # make copied artifact read-only
|
|
fi
|
|
}
|
|
|
|
move_if_changed() {
|
|
if cmp -s $1 $2
|
|
then
|
|
msg "leaving $2 unchanged"
|
|
else
|
|
msg "mv $1 $2"
|
|
mv -f $1 $2
|
|
chmod u-w $2 # make moved artifact read-only
|
|
fi
|
|
}
|
|
|
|
putvar() {
|
|
local T
|
|
eval T=\$$1
|
|
eval TLEN=\${#$1}
|
|
if [ $TLEN -gt 35 ]
|
|
then
|
|
printf "configure: %-20s := %.35s ...\n" $1 "$T"
|
|
else
|
|
printf "configure: %-20s := %s %s\n" $1 "$T" "$2"
|
|
fi
|
|
printf "%-20s := %s\n" $1 "$T" >>config.tmp
|
|
}
|
|
|
|
probe() {
|
|
local V=$1
|
|
shift
|
|
local P
|
|
local T
|
|
for P
|
|
do
|
|
T=$(command -v $P 2>&1)
|
|
if [ $? -eq 0 ]
|
|
then
|
|
VER0=$($P --version 2>/dev/null | head -1 \
|
|
| sed -e 's/[^0-9]*\([vV]\?[0-9.]\+[^ ]*\).*/\1/' )
|
|
if [ $? -eq 0 -a "x${VER0}" != "x" ]
|
|
then
|
|
VER="($VER0)"
|
|
else
|
|
VER=""
|
|
fi
|
|
break
|
|
else
|
|
VER=""
|
|
T=""
|
|
fi
|
|
done
|
|
eval $V=\$T
|
|
putvar $V "$VER"
|
|
}
|
|
|
|
probe_need() {
|
|
local V=$1
|
|
probe $*
|
|
eval VV=\$$V
|
|
if [ -z "$VV" ]
|
|
then
|
|
err "needed, but unable to find any of: $*"
|
|
fi
|
|
}
|
|
|
|
validate_opt () {
|
|
for arg in $CFG_CONFIGURE_ARGS
|
|
do
|
|
isArgValid=0
|
|
for option in $BOOL_OPTIONS
|
|
do
|
|
if test --disable-$option = $arg
|
|
then
|
|
isArgValid=1
|
|
fi
|
|
if test --enable-$option = $arg
|
|
then
|
|
isArgValid=1
|
|
fi
|
|
done
|
|
for option in $VAL_OPTIONS
|
|
do
|
|
if echo "$arg" | grep -q -- "--$option="
|
|
then
|
|
isArgValid=1
|
|
fi
|
|
done
|
|
if [ "$arg" = "--help" ]
|
|
then
|
|
echo
|
|
echo "No more help available for Configure options,"
|
|
echo "check the Wiki or join our IRC channel"
|
|
break
|
|
else
|
|
if test $isArgValid -eq 0
|
|
then
|
|
err "Option '$arg' is not recognized"
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
valopt() {
|
|
VAL_OPTIONS="$VAL_OPTIONS $1"
|
|
|
|
local OP=$1
|
|
local DEFAULT=$2
|
|
shift
|
|
shift
|
|
local DOC="$*"
|
|
if [ $HELP -eq 0 ]
|
|
then
|
|
local UOP=$(echo $OP | tr '[:lower:]' '[:upper:]' | tr '\-' '\_')
|
|
local V="CFG_${UOP}"
|
|
eval $V="$DEFAULT"
|
|
for arg in $CFG_CONFIGURE_ARGS
|
|
do
|
|
if echo "$arg" | grep -q -- "--$OP="
|
|
then
|
|
val=$(echo "$arg" | cut -f2 -d=)
|
|
eval $V=$val
|
|
fi
|
|
done
|
|
putvar $V
|
|
else
|
|
if [ -z "$DEFAULT" ]
|
|
then
|
|
DEFAULT="<none>"
|
|
fi
|
|
OP="${OP}=[${DEFAULT}]"
|
|
printf " --%-30s %s\n" "$OP" "$DOC"
|
|
fi
|
|
}
|
|
|
|
opt() {
|
|
BOOL_OPTIONS="$BOOL_OPTIONS $1"
|
|
|
|
local OP=$1
|
|
local DEFAULT=$2
|
|
shift
|
|
shift
|
|
local DOC="$*"
|
|
local FLAG=""
|
|
|
|
if [ $DEFAULT -eq 0 ]
|
|
then
|
|
FLAG="enable"
|
|
else
|
|
FLAG="disable"
|
|
DOC="don't $DOC"
|
|
fi
|
|
|
|
if [ $HELP -eq 0 ]
|
|
then
|
|
for arg in $CFG_CONFIGURE_ARGS
|
|
do
|
|
if [ "$arg" = "--${FLAG}-${OP}" ]
|
|
then
|
|
OP=$(echo $OP | tr 'a-z-' 'A-Z_')
|
|
FLAG=$(echo $FLAG | tr 'a-z' 'A-Z')
|
|
local V="CFG_${FLAG}_${OP}"
|
|
eval $V=1
|
|
putvar $V
|
|
fi
|
|
done
|
|
else
|
|
if [ ! -z "$META" ]
|
|
then
|
|
OP="$OP=<$META>"
|
|
fi
|
|
printf " --%-30s %s\n" "$FLAG-$OP" "$DOC"
|
|
fi
|
|
}
|
|
|
|
envopt() {
|
|
local NAME=$1
|
|
local V="CFG_${NAME}"
|
|
eval VV=\$$V
|
|
|
|
# If configure didn't set a value already, then check environment.
|
|
#
|
|
# (It is recommended that the configure script always check the
|
|
# environment before setting any values to envopt variables; see
|
|
# e.g. how CFG_CC is handled, where it first checks `-z "$CC"`,
|
|
# and issues msg if it ends up employing that provided value.)
|
|
if [ -z "$VV" ]
|
|
then
|
|
eval $V=\$$NAME
|
|
eval VV=\$$V
|
|
fi
|
|
|
|
# If script or environment provided a value, save it.
|
|
if [ ! -z "$VV" ]
|
|
then
|
|
putvar $V
|
|
fi
|
|
}
|
|
|
|
msg "looking for configure programs"
|
|
need_cmd cmp
|
|
need_cmd mkdir
|
|
need_cmd printf
|
|
need_cmd cut
|
|
need_cmd head
|
|
need_cmd grep
|
|
need_cmd xargs
|
|
need_cmd cp
|
|
need_cmd find
|
|
need_cmd uname
|
|
need_cmd date
|
|
need_cmd tr
|
|
need_cmd sed
|
|
need_cmd file
|
|
need_cmd cmake
|
|
need_cmd pkg-config
|
|
|
|
CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/"
|
|
CFG_BUILD_DIR="$(pwd)/"
|
|
CFG_SELF="$0"
|
|
CFG_CONFIGURE_ARGS="$@"
|
|
|
|
OPTIONS=""
|
|
HELP=0
|
|
if [ "$1" = "--help" ]
|
|
then
|
|
HELP=1
|
|
shift
|
|
echo
|
|
echo "Usage: $CFG_SELF [options]"
|
|
echo
|
|
echo "Options:"
|
|
echo
|
|
else
|
|
msg "recreating config.tmp"
|
|
echo '' >config.tmp
|
|
|
|
step_msg "processing $CFG_SELF args"
|
|
fi
|
|
|
|
BOOL_OPTIONS=""
|
|
VAL_OPTIONS=""
|
|
|
|
opt debug 1 "build with extra debug fun"
|
|
opt optimize 0 "build with optimizations"
|
|
opt nightly 0 "build nightly packages"
|
|
opt verify-install 1 "verify installed binaries work"
|
|
opt cross-tests 1 "run cross-compilation tests"
|
|
valopt prefix "/usr/local" "set installation prefix"
|
|
valopt local-rust-root "" "set prefix for local rust binary"
|
|
|
|
if [ $HELP -eq 0 ]; then
|
|
if [ ! -z "${CFG_LOCAL_RUST_ROOT}" ]; then
|
|
export LD_LIBRARY_PATH="${CFG_LOCAL_RUST_ROOT}/lib:$LD_LIBRARY_PATH"
|
|
export DYLD_LIBRARY_PATH="${CFG_LOCAL_RUST_ROOT}/lib:$DYLD_LIBRARY_PATH"
|
|
LRV=`${CFG_LOCAL_RUST_ROOT}/bin/rustc --version`
|
|
if [ $? -eq 0 ]; then
|
|
step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: $LRV"
|
|
else
|
|
err "failed to run rustc at: ${CFG_LOCAL_RUST_ROOT}"
|
|
fi
|
|
CFG_RUSTC="${CFG_LOCAL_RUST_ROOT}/bin/rustc"
|
|
else
|
|
probe_need CFG_RUSTC rustc
|
|
fi
|
|
DEFAULT_BUILD=$("${CFG_RUSTC}" --version verbose | grep 'host: ' | sed 's/host: //')
|
|
fi
|
|
|
|
valopt build "${DEFAULT_BUILD}" "GNUs ./configure syntax LLVM build triple"
|
|
valopt host "${CFG_BUILD}" "GNUs ./configure syntax LLVM host triples"
|
|
valopt target "${CFG_HOST}" "GNUs ./configure syntax LLVM target triples"
|
|
|
|
valopt localstatedir "/var/lib" "local state directory"
|
|
valopt sysconfdir "/etc" "install system configuration files"
|
|
valopt datadir "${CFG_PREFIX}/share" "install data"
|
|
valopt infodir "${CFG_PREFIX}/share/info" "install additional info"
|
|
valopt mandir "${CFG_PREFIX}/share/man" "install man pages in PATH"
|
|
valopt libdir "${CFG_PREFIX}/lib" "install libraries"
|
|
|
|
if [ $HELP -eq 1 ]
|
|
then
|
|
echo
|
|
exit 0
|
|
fi
|
|
|
|
# Validate Options
|
|
step_msg "validating $CFG_SELF args"
|
|
validate_opt
|
|
|
|
step_msg "looking for build programs"
|
|
|
|
probe_need CFG_CURLORWGET curl wget
|
|
probe_need CFG_PYTHON python
|
|
|
|
# a little post-processing of various config values
|
|
CFG_PREFIX=${CFG_PREFIX%/}
|
|
CFG_MANDIR=${CFG_MANDIR%/}
|
|
CFG_HOST="$(echo $CFG_HOST | tr ',' ' ')"
|
|
CFG_TARGET="$(echo $CFG_TARGET | tr ',' ' ')"
|
|
|
|
# copy host-triples to target-triples so that hosts are a subset of targets
|
|
V_TEMP=""
|
|
for i in $CFG_HOST $CFG_TARGET;
|
|
do
|
|
echo "$V_TEMP" | grep -qF $i || V_TEMP="$V_TEMP${V_TEMP:+ }$i"
|
|
done
|
|
CFG_TARGET=$V_TEMP
|
|
|
|
if [ "$CFG_SRC_DIR" != "$CFG_BUILD_DIR" ]; then
|
|
err "cargo does not currently support an out-of-tree build dir"
|
|
fi
|
|
|
|
step_msg "writing configuration"
|
|
|
|
putvar CFG_SRC_DIR
|
|
putvar CFG_BUILD_DIR
|
|
putvar CFG_CONFIGURE_ARGS
|
|
putvar CFG_PREFIX
|
|
putvar CFG_BUILD
|
|
putvar CFG_HOST
|
|
putvar CFG_TARGET
|
|
putvar CFG_LIBDIR
|
|
putvar CFG_MANDIR
|
|
putvar CFG_RUSTC
|
|
|
|
msg
|
|
copy_if_changed ${CFG_SRC_DIR}Makefile.in ./Makefile
|
|
move_if_changed config.tmp config.mk
|
|
rm -f config.tmp
|
|
touch config.stamp
|
|
|
|
step_msg "complete"
|
|
msg
|