mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
rustbuild: Rewrite the configure script in Python
This commit rewrites our ancient `./configure` script from shell into Python. The impetus for this change is to remove `config.mk` which is just a vestige of the old makefile build system at this point. Instead all configuration is now solely done through `config.toml`. The python script allows us to more flexibly program (aka we can use loops easily) and create a `config.toml` which is based off `config.toml.example`. This way we can preserve comments and munge various values as we see fit. It is intended that the configure script here is a drop-in replacement for the previous configure script, no functional change is intended. Also note that the rationale for this is also because our build system requires Python, so having a python script a bit earlier shouldn't cause too many problems. Closes #40730
This commit is contained in:
parent
398aaffc94
commit
a9b0a7ba93
@ -73,6 +73,10 @@
|
|||||||
# controlled by rustbuild's -j parameter.
|
# controlled by rustbuild's -j parameter.
|
||||||
#link-jobs = 0
|
#link-jobs = 0
|
||||||
|
|
||||||
|
# When invoking `llvm-config` this configures whether the `--shared` argument is
|
||||||
|
# passed to prefer linking to shared libraries.
|
||||||
|
#link-shared = false
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# General build configuration options
|
# General build configuration options
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@ -166,6 +170,15 @@
|
|||||||
# to +10 on Unix platforms, and by using a "low priority" job object on Windows.
|
# to +10 on Unix platforms, and by using a "low priority" job object on Windows.
|
||||||
#low-priority = false
|
#low-priority = false
|
||||||
|
|
||||||
|
# Arguments passed to the `./configure` script, used during distcheck. You
|
||||||
|
# probably won't fill this in but rather it's filled in by the `./configure`
|
||||||
|
# script.
|
||||||
|
#configure-args = []
|
||||||
|
|
||||||
|
# Indicates that a local rebuild is ocurring instead of a full bootstrap,
|
||||||
|
# essentially skipping stage0 as the local compiler is recompiling itself again.
|
||||||
|
#local-rebuild = false
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# General install configuration options
|
# General install configuration options
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@ -195,6 +208,13 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
[rust]
|
[rust]
|
||||||
|
|
||||||
|
# Indicates that the build should be optimized for debugging Rust. Note that
|
||||||
|
# this is typically not what you want as it takes an incredibly large amount of
|
||||||
|
# time to have a debug-mode rustc compile any code (notably libstd). If this
|
||||||
|
# value is set to `true` it will affect a number of configuration options below
|
||||||
|
# as well, if unconfigured.
|
||||||
|
#debug = false
|
||||||
|
|
||||||
# Whether or not to optimize the compiler and standard library
|
# Whether or not to optimize the compiler and standard library
|
||||||
# Note: the slowness of the non optimized compiler compiling itself usually
|
# Note: the slowness of the non optimized compiler compiling itself usually
|
||||||
# outweighs the time gains in not doing optimizations, therefore a
|
# outweighs the time gains in not doing optimizations, therefore a
|
||||||
@ -249,6 +269,10 @@
|
|||||||
# desired in distributions, for example.
|
# desired in distributions, for example.
|
||||||
#rpath = true
|
#rpath = true
|
||||||
|
|
||||||
|
# Suppresses extraneous output from tests to ensure the output of the test
|
||||||
|
# harness is relatively clean.
|
||||||
|
#quiet-tests = false
|
||||||
|
|
||||||
# Flag indicating whether tests are compiled with optimizations (the -O flag) or
|
# Flag indicating whether tests are compiled with optimizations (the -O flag) or
|
||||||
# with debuginfo (the -g flag)
|
# with debuginfo (the -g flag)
|
||||||
#optimize-tests = true
|
#optimize-tests = true
|
||||||
@ -261,6 +285,9 @@
|
|||||||
# Flag indicating whether git info will be retrieved from .git automatically.
|
# Flag indicating whether git info will be retrieved from .git automatically.
|
||||||
#ignore-git = false
|
#ignore-git = false
|
||||||
|
|
||||||
|
# When creating source tarballs whether or not to create a source tarball.
|
||||||
|
#dist-src = false
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Options for specific targets
|
# Options for specific targets
|
||||||
#
|
#
|
||||||
@ -304,6 +331,10 @@
|
|||||||
# linked binaries
|
# linked binaries
|
||||||
#musl-root = "..."
|
#musl-root = "..."
|
||||||
|
|
||||||
|
# Used in testing for configuring where the QEMU images are located, you
|
||||||
|
# probably don't want to use this.
|
||||||
|
#qemu-rootfs = "..."
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Distribution options
|
# Distribution options
|
||||||
#
|
#
|
||||||
|
782
configure
vendored
782
configure
vendored
@ -1,779 +1,17 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/bash is.
|
script="$(dirname $0)"/src/bootstrap/configure.py
|
||||||
if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then
|
|
||||||
POSIX_SHELL="true"
|
|
||||||
export POSIX_SHELL
|
|
||||||
exec /usr/bin/env bash $0 "$@"
|
|
||||||
fi
|
|
||||||
unset POSIX_SHELL # clear it so if we invoke other scripts, they run as bash as well
|
|
||||||
|
|
||||||
msg() {
|
try() {
|
||||||
echo "configure: $*"
|
cmd=$1
|
||||||
}
|
|
||||||
|
|
||||||
step_msg() {
|
|
||||||
msg
|
|
||||||
msg "$1"
|
|
||||||
msg
|
|
||||||
}
|
|
||||||
|
|
||||||
warn() {
|
|
||||||
echo "configure: WARNING: $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
err() {
|
|
||||||
echo "configure: error: $1"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
run() {
|
|
||||||
msg "$@"
|
|
||||||
"$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
need_ok() {
|
|
||||||
if [ $? -ne 0 ]
|
|
||||||
then
|
|
||||||
err "$1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
need_cmd() {
|
|
||||||
if command -v $1 >/dev/null 2>&1
|
|
||||||
then msg "found program '$1'"
|
|
||||||
else err "program '$1' is missing, please install it"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
make_dir() {
|
|
||||||
if [ ! -d $1 ]
|
|
||||||
then
|
|
||||||
run mkdir -p $1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_if_changed() {
|
|
||||||
if cmp -s $1 $2
|
|
||||||
then
|
|
||||||
msg "leaving $2 unchanged"
|
|
||||||
else
|
|
||||||
run 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
|
|
||||||
run 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
|
|
||||||
}
|
|
||||||
|
|
||||||
putpathvar() {
|
|
||||||
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
|
|
||||||
if [ -z "$T" ]
|
|
||||||
then
|
|
||||||
printf "%-20s := \n" $1 >>config.tmp
|
|
||||||
else
|
|
||||||
printf "%-20s := \"%s\"\n" $1 "$T" >>config.tmp
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
probe() {
|
|
||||||
local V=$1
|
|
||||||
shift
|
shift
|
||||||
local P
|
T=$($cmd --version 2>/dev/null)
|
||||||
local T
|
if [ $? -eq 0 ]; then
|
||||||
for P
|
exec $cmd "$script" "$@"
|
||||||
do
|
|
||||||
T=$(command -v $P 2>&1)
|
|
||||||
if [ $? -eq 0 ]
|
|
||||||
then
|
|
||||||
VER0=$($P --version 2>/dev/null \
|
|
||||||
| grep -o '[vV]\?[0-9][0-9.][a-z0-9.-]*' | head -1 )
|
|
||||||
if [ $? -eq 0 -a "x${VER0}" != "x" ]
|
|
||||||
then
|
|
||||||
VER="($VER0)"
|
|
||||||
else
|
|
||||||
VER=""
|
|
||||||
fi
|
|
||||||
break
|
|
||||||
else
|
|
||||||
VER=""
|
|
||||||
T=""
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
eval $V=\$T
|
|
||||||
putpathvar $V "$VER"
|
|
||||||
}
|
|
||||||
|
|
||||||
probe_need() {
|
|
||||||
probe $*
|
|
||||||
local V=$1
|
|
||||||
shift
|
|
||||||
eval VV=\$$V
|
|
||||||
if [ -z "$VV" ]
|
|
||||||
then
|
|
||||||
err "$V needed, but unable to find any of: $*"
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
validate_opt () {
|
try python2.7 "$@"
|
||||||
for arg in $CFG_CONFIGURE_ARGS
|
try python27 "$@"
|
||||||
do
|
try python2 "$@"
|
||||||
isArgValid=0
|
exec python $script "$@"
|
||||||
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 OPTION_NAME DEFAULT DOC` extracts a string-valued option
|
|
||||||
# from command line, using provided default value for the option if
|
|
||||||
# not present, and saves it to the generated config.mk.
|
|
||||||
#
|
|
||||||
# `valopt_nosave` is much the same, except that it does not save the
|
|
||||||
# result to config.mk (instead the script should use `putvar` itself
|
|
||||||
# later on to save it). `valopt_core` is the core upon which the
|
|
||||||
# other two are built.
|
|
||||||
|
|
||||||
valopt_core() {
|
|
||||||
VAL_OPTIONS="$VAL_OPTIONS $2"
|
|
||||||
|
|
||||||
local SAVE=$1
|
|
||||||
local OP=$2
|
|
||||||
local DEFAULT=$3
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
local DOC="$*"
|
|
||||||
if [ $HELP -eq 0 ]
|
|
||||||
then
|
|
||||||
local UOP=$(echo $OP | tr '[:lower:]' '[:upper:]' | tr '\-' '\_')
|
|
||||||
local V="CFG_${UOP}"
|
|
||||||
local V_PROVIDED="${V}_PROVIDED"
|
|
||||||
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
|
|
||||||
eval $V_PROVIDED=1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [ "$SAVE" = "save" ]
|
|
||||||
then
|
|
||||||
putvar $V
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [ -z "$DEFAULT" ]
|
|
||||||
then
|
|
||||||
DEFAULT="<none>"
|
|
||||||
fi
|
|
||||||
OP="${OP}=[${DEFAULT}]"
|
|
||||||
printf " --%-30s %s\n" "$OP" "$DOC"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
valopt_nosave() {
|
|
||||||
valopt_core nosave "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
valopt() {
|
|
||||||
valopt_core save "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# `opt OPTION_NAME DEFAULT DOC` extracts a boolean-valued option from
|
|
||||||
# command line, using the provided default value (0/1) for the option
|
|
||||||
# if not present, and saves it to the generated config.mk.
|
|
||||||
#
|
|
||||||
# `opt_nosave` is much the same, except that it does not save the
|
|
||||||
# result to config.mk (instead the script should use `putvar` itself
|
|
||||||
# later on to save it). `opt_core` is the core upon which the other
|
|
||||||
# two are built.
|
|
||||||
|
|
||||||
opt_core() {
|
|
||||||
BOOL_OPTIONS="$BOOL_OPTIONS $2"
|
|
||||||
|
|
||||||
local SAVE=$1
|
|
||||||
local OP=$2
|
|
||||||
local DEFAULT=$3
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
local DOC="$*"
|
|
||||||
local FLAG=""
|
|
||||||
|
|
||||||
if [ $DEFAULT -eq 0 ]
|
|
||||||
then
|
|
||||||
FLAG="enable"
|
|
||||||
DEFAULT_FLAG="disable"
|
|
||||||
else
|
|
||||||
FLAG="disable"
|
|
||||||
DEFAULT_FLAG="enable"
|
|
||||||
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}"
|
|
||||||
local V_PROVIDED="CFG_${FLAG}_${OP}_PROVIDED"
|
|
||||||
eval $V=1
|
|
||||||
eval $V_PROVIDED=1
|
|
||||||
if [ "$SAVE" = "save" ]
|
|
||||||
then
|
|
||||||
putvar $V
|
|
||||||
fi
|
|
||||||
elif [ "$arg" = "--${DEFAULT_FLAG}-${OP}" ]
|
|
||||||
then
|
|
||||||
OP=$(echo $OP | tr 'a-z-' 'A-Z_')
|
|
||||||
DEFAULT_FLAG=$(echo $DEFAULT_FLAG | tr 'a-z' 'A-Z')
|
|
||||||
local V_PROVIDED="CFG_${DEFAULT_FLAG}_${OP}_PROVIDED"
|
|
||||||
eval $V_PROVIDED=1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
else
|
|
||||||
if [ -n "$META" ]
|
|
||||||
then
|
|
||||||
OP="$OP=<$META>"
|
|
||||||
fi
|
|
||||||
printf " --%-30s %s\n" "$FLAG-$OP" "$DOC"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
opt_nosave() {
|
|
||||||
opt_core nosave "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
opt() {
|
|
||||||
opt_core save "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
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 [ -n "$VV" ]
|
|
||||||
then
|
|
||||||
putvar $V
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
enable_if_not_disabled() {
|
|
||||||
local OP=$1
|
|
||||||
local UOP=$(echo $OP | tr '[:lower:]' '[:upper:]' | tr '\-' '\_')
|
|
||||||
local ENAB_V="CFG_ENABLE_$UOP"
|
|
||||||
local EXPLICITLY_DISABLED="CFG_DISABLE_${UOP}_PROVIDED"
|
|
||||||
eval VV=\$$EXPLICITLY_DISABLED
|
|
||||||
if [ -z "$VV" ]; then
|
|
||||||
eval $ENAB_V=1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
to_gnu_triple() {
|
|
||||||
case $1 in
|
|
||||||
i686-pc-windows-gnu) echo i686-w64-mingw32 ;;
|
|
||||||
x86_64-pc-windows-gnu) echo x86_64-w64-mingw32 ;;
|
|
||||||
*) echo $1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Prints the absolute path of a directory to stdout
|
|
||||||
abs_path() {
|
|
||||||
local _path="$1"
|
|
||||||
# Unset CDPATH because it causes havok: it makes the destination unpredictable
|
|
||||||
# and triggers 'cd' to print the path to stdout. Route `cd`'s output to /dev/null
|
|
||||||
# for good measure.
|
|
||||||
(unset CDPATH && cd "$_path" > /dev/null && pwd)
|
|
||||||
}
|
|
||||||
|
|
||||||
HELP=0
|
|
||||||
for arg; do
|
|
||||||
case "$arg" in
|
|
||||||
--help) HELP=1;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
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 make
|
|
||||||
|
|
||||||
CFG_SRC_DIR="$(abs_path $(dirname $0))/"
|
|
||||||
CFG_SRC_DIR_RELATIVE="$(dirname $0)/"
|
|
||||||
CFG_BUILD_DIR="$(pwd)/"
|
|
||||||
CFG_SELF="$0"
|
|
||||||
CFG_CONFIGURE_ARGS="$@"
|
|
||||||
|
|
||||||
|
|
||||||
case "${CFG_SRC_DIR}" in
|
|
||||||
*\ * )
|
|
||||||
err "The path to the rust source directory contains spaces, which is not supported"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
|
|
||||||
OPTIONS=""
|
|
||||||
if [ "$HELP" -eq 1 ]
|
|
||||||
then
|
|
||||||
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 0 "debug mode; disables optimization unless \`--enable-optimize\` given"
|
|
||||||
opt valgrind 0 "run tests with valgrind (memcheck by default)"
|
|
||||||
opt helgrind 0 "run tests with helgrind instead of memcheck"
|
|
||||||
opt valgrind-rpass 1 "run rpass-valgrind tests with valgrind"
|
|
||||||
opt docs 1 "build standard library documentation"
|
|
||||||
opt compiler-docs 0 "build compiler documentation"
|
|
||||||
opt optimize-tests 1 "build tests with optimizations"
|
|
||||||
opt debuginfo-tests 0 "build tests with debugger metadata"
|
|
||||||
opt quiet-tests 0 "enable quieter output when running tests"
|
|
||||||
opt libcpp 1 "build llvm with libc++ instead of libstdc++ when using clang"
|
|
||||||
opt llvm-assertions 0 "build LLVM with assertions"
|
|
||||||
opt debug-assertions 0 "build with debugging assertions"
|
|
||||||
opt fast-make 0 "use .gitmodules as timestamp for submodule deps"
|
|
||||||
opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds"
|
|
||||||
opt sccache 0 "invoke gcc/clang via sccache to reuse object files between builds"
|
|
||||||
opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
|
|
||||||
opt local-rebuild 0 "assume local-rust matches the current version, for rebuilds; implies local-rust, and is implied if local-rust already matches the current version"
|
|
||||||
opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
|
|
||||||
opt llvm-link-shared 0 "prefer shared linking to LLVM (llvm-config --link-shared)"
|
|
||||||
opt rpath 1 "build rpaths into rustc itself"
|
|
||||||
opt stage0-landing-pads 1 "enable landing pads during bootstrap with stage0"
|
|
||||||
# This is used by the automation to produce single-target nightlies
|
|
||||||
opt dist-host-only 0 "only install bins for the host architecture"
|
|
||||||
opt inject-std-version 1 "inject the current compiler version of libstd into programs"
|
|
||||||
opt llvm-version-check 1 "check if the LLVM version is supported, build anyway"
|
|
||||||
opt codegen-tests 1 "run the src/test/codegen tests"
|
|
||||||
opt option-checking 1 "complain about unrecognized options in this configure script"
|
|
||||||
opt ninja 0 "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)"
|
|
||||||
opt locked-deps 0 "force Cargo.lock to be up to date"
|
|
||||||
opt vendor 0 "enable usage of vendored Rust crates"
|
|
||||||
opt sanitizers 0 "build the sanitizer runtimes (asan, lsan, msan, tsan)"
|
|
||||||
opt dist-src 1 "when building tarballs enables building a source tarball"
|
|
||||||
opt cargo-openssl-static 0 "static openssl in cargo"
|
|
||||||
opt profiler 0 "build the profiler runtime"
|
|
||||||
|
|
||||||
# Optimization and debugging options. These may be overridden by the release channel, etc.
|
|
||||||
opt_nosave optimize 1 "build optimized rust code"
|
|
||||||
opt_nosave optimize-cxx 1 "build optimized C++ code"
|
|
||||||
opt_nosave optimize-llvm 1 "build optimized LLVM"
|
|
||||||
opt_nosave llvm-assertions 0 "build LLVM with assertions"
|
|
||||||
opt_nosave debug-assertions 0 "build with debugging assertions"
|
|
||||||
opt_nosave llvm-release-debuginfo 0 "build LLVM with debugger metadata"
|
|
||||||
opt_nosave debuginfo 0 "build with debugger metadata"
|
|
||||||
opt_nosave debuginfo-lines 0 "build with line number debugger metadata"
|
|
||||||
opt_nosave debuginfo-only-std 0 "build only libstd with debugging information"
|
|
||||||
opt_nosave debug-jemalloc 0 "build jemalloc with --enable-debug --enable-fill"
|
|
||||||
|
|
||||||
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 llvm-root "" "set LLVM root"
|
|
||||||
valopt python "" "set path to python"
|
|
||||||
valopt jemalloc-root "" "set directory where libjemalloc_pic.a is located"
|
|
||||||
valopt build "" "GNUs ./configure syntax LLVM build triple"
|
|
||||||
valopt android-cross-path "" "Android NDK standalone path (deprecated)"
|
|
||||||
valopt i686-linux-android-ndk "" "i686-linux-android NDK standalone path"
|
|
||||||
valopt arm-linux-androideabi-ndk "" "arm-linux-androideabi NDK standalone path"
|
|
||||||
valopt armv7-linux-androideabi-ndk "" "armv7-linux-androideabi NDK standalone path"
|
|
||||||
valopt aarch64-linux-android-ndk "" "aarch64-linux-android NDK standalone path"
|
|
||||||
valopt x86_64-linux-android-ndk "" "x86_64-linux-android NDK standalone path"
|
|
||||||
valopt nacl-cross-path "" "NaCl SDK path (Pepper Canary is recommended). Must be absolute!"
|
|
||||||
valopt musl-root "/usr/local" "MUSL root installation directory (deprecated)"
|
|
||||||
valopt musl-root-x86_64 "" "x86_64-unknown-linux-musl install directory"
|
|
||||||
valopt musl-root-i686 "" "i686-unknown-linux-musl install directory"
|
|
||||||
valopt musl-root-arm "" "arm-unknown-linux-musleabi install directory"
|
|
||||||
valopt musl-root-armhf "" "arm-unknown-linux-musleabihf install directory"
|
|
||||||
valopt musl-root-armv7 "" "armv7-unknown-linux-musleabihf install directory"
|
|
||||||
valopt extra-filename "" "Additional data that is hashed and passed to the -C extra-filename flag"
|
|
||||||
valopt qemu-armhf-rootfs "" "rootfs in qemu testing, you probably don't want to use this"
|
|
||||||
valopt qemu-aarch64-rootfs "" "rootfs in qemu testing, you probably don't want to use this"
|
|
||||||
valopt experimental-targets "" "experimental LLVM targets to build"
|
|
||||||
|
|
||||||
if [ -e ${CFG_SRC_DIR}.git ]
|
|
||||||
then
|
|
||||||
valopt release-channel "dev" "the name of the release channel to build"
|
|
||||||
else
|
|
||||||
# If we have no git directory then we are probably a tarball distribution
|
|
||||||
# and should default to stable channel - Issue 28322
|
|
||||||
probe CFG_GIT git
|
|
||||||
msg "git: no git directory. Changing default release channel to stable"
|
|
||||||
valopt release-channel "stable" "the name of the release channel to build"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Used on systems where "cc" and "ar" are unavailable
|
|
||||||
valopt default-linker "cc" "the default linker"
|
|
||||||
valopt default-ar "ar" "the default ar"
|
|
||||||
|
|
||||||
# Many of these are saved below during the "writing configuration" step
|
|
||||||
# (others are conditionally saved).
|
|
||||||
opt_nosave manage-submodules 1 "let the build manage the git submodules"
|
|
||||||
opt_nosave clang 0 "prefer clang to gcc for building the runtime"
|
|
||||||
opt_nosave jemalloc 1 "build liballoc with jemalloc"
|
|
||||||
opt full-bootstrap 0 "build three compilers instead of two"
|
|
||||||
opt extended 0 "build an extended rust tool set"
|
|
||||||
|
|
||||||
valopt_nosave prefix "/usr/local" "set installation prefix"
|
|
||||||
valopt_nosave local-rust-root "/usr/local" "set prefix for local rust binary"
|
|
||||||
valopt_nosave host "${CFG_BUILD}" "GNUs ./configure syntax LLVM host triples"
|
|
||||||
valopt_nosave target "${CFG_HOST}" "GNUs ./configure syntax LLVM target triples"
|
|
||||||
valopt_nosave mandir "${CFG_PREFIX}/share/man" "install man pages in PATH"
|
|
||||||
valopt_nosave docdir "${CFG_PREFIX}/share/doc/rust" "install documentation in PATH"
|
|
||||||
valopt_nosave bindir "${CFG_PREFIX}/bin" "install binaries"
|
|
||||||
|
|
||||||
# On Windows this determines root of the subtree for target libraries.
|
|
||||||
# Host runtime libs always go to 'bin'.
|
|
||||||
valopt libdir "${CFG_PREFIX}/lib" "install libraries"
|
|
||||||
|
|
||||||
case "$CFG_LIBDIR" in
|
|
||||||
"$CFG_PREFIX"/*) CAT_INC=2;;
|
|
||||||
"$CFG_PREFIX"*) CAT_INC=1;;
|
|
||||||
*)
|
|
||||||
err "libdir must begin with the prefix. Use --prefix to set it accordingly.";;
|
|
||||||
esac
|
|
||||||
|
|
||||||
CFG_LIBDIR_RELATIVE=`echo ${CFG_LIBDIR} | cut -c$((${#CFG_PREFIX}+${CAT_INC}))-`
|
|
||||||
|
|
||||||
if [ $HELP -eq 1 ]
|
|
||||||
then
|
|
||||||
echo
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Validate Options
|
|
||||||
if [ -z "$CFG_DISABLE_OPTION_CHECKING" ]
|
|
||||||
then
|
|
||||||
step_msg "validating $CFG_SELF args"
|
|
||||||
validate_opt
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Validate the release channel, and configure options
|
|
||||||
case "$CFG_RELEASE_CHANNEL" in
|
|
||||||
nightly )
|
|
||||||
msg "overriding settings for $CFG_RELEASE_CHANNEL"
|
|
||||||
enable_if_not_disabled llvm-assertions
|
|
||||||
# FIXME(stage0) re-enable this on the next stage0 now that #35566 is
|
|
||||||
# fixed
|
|
||||||
case "$CFG_BUILD" in
|
|
||||||
*-pc-windows-gnu)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
enable_if_not_disabled debuginfo-lines
|
|
||||||
enable_if_not_disabled debuginfo-only-std
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
;;
|
|
||||||
beta | stable)
|
|
||||||
msg "overriding settings for $CFG_RELEASE_CHANNEL"
|
|
||||||
case "$CFG_BUILD" in
|
|
||||||
*-pc-windows-gnu)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
enable_if_not_disabled debuginfo-lines
|
|
||||||
enable_if_not_disabled debuginfo-only-std
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
dev)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
err "release channel must be 'dev', 'nightly', 'beta' or 'stable'"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Adjust perf and debug options for debug mode
|
|
||||||
if [ -n "$CFG_ENABLE_DEBUG" ]; then
|
|
||||||
msg "debug mode enabled, setting performance options"
|
|
||||||
if [ -z "$CFG_ENABLE_OPTIMIZE_PROVIDED" ]; then
|
|
||||||
msg "optimization not explicitly enabled, disabling optimization"
|
|
||||||
CFG_DISABLE_OPTIMIZE=1
|
|
||||||
CFG_DISABLE_OPTIMIZE_CXX=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set following variables to 1 unless setting already provided
|
|
||||||
enable_if_not_disabled debug-assertions
|
|
||||||
enable_if_not_disabled debug-jemalloc
|
|
||||||
enable_if_not_disabled debuginfo
|
|
||||||
enable_if_not_disabled llvm-assertions
|
|
||||||
fi
|
|
||||||
|
|
||||||
# OK, now write the debugging options
|
|
||||||
if [ -n "$CFG_DISABLE_OPTIMIZE" ]; then putvar CFG_DISABLE_OPTIMIZE; fi
|
|
||||||
if [ -n "$CFG_DISABLE_OPTIMIZE_CXX" ]; then putvar CFG_DISABLE_OPTIMIZE_CXX; fi
|
|
||||||
if [ -n "$CFG_DISABLE_OPTIMIZE_LLVM" ]; then putvar CFG_DISABLE_OPTIMIZE_LLVM; fi
|
|
||||||
if [ -n "$CFG_ENABLE_LLVM_ASSERTIONS" ]; then putvar CFG_ENABLE_LLVM_ASSERTIONS; fi
|
|
||||||
if [ -n "$CFG_ENABLE_DEBUG_ASSERTIONS" ]; then putvar CFG_ENABLE_DEBUG_ASSERTIONS; fi
|
|
||||||
if [ -n "$CFG_ENABLE_LLVM_RELEASE_DEBUGINFO" ]; then putvar CFG_ENABLE_LLVM_RELEASE_DEBUGINFO; fi
|
|
||||||
if [ -n "$CFG_ENABLE_DEBUGINFO" ]; then putvar CFG_ENABLE_DEBUGINFO; fi
|
|
||||||
if [ -n "$CFG_ENABLE_DEBUGINFO_LINES" ]; then putvar CFG_ENABLE_DEBUGINFO_LINES; fi
|
|
||||||
if [ -n "$CFG_ENABLE_DEBUGINFO_ONLY_STD" ]; then putvar CFG_ENABLE_DEBUGINFO_ONLY_STD; fi
|
|
||||||
if [ -n "$CFG_ENABLE_DEBUG_JEMALLOC" ]; then putvar CFG_ENABLE_DEBUG_JEMALLOC; fi
|
|
||||||
|
|
||||||
step_msg "looking for build programs"
|
|
||||||
|
|
||||||
probe_need CFG_CURL curl
|
|
||||||
if [ -z "$CFG_PYTHON_PROVIDED" ]; then
|
|
||||||
probe_need CFG_PYTHON python2.7 python2 python
|
|
||||||
fi
|
|
||||||
|
|
||||||
python_version=$($CFG_PYTHON -V 2>&1)
|
|
||||||
if [ $(echo $python_version | grep -c '^Python 2\.7') -ne 1 ]; then
|
|
||||||
err "Found $python_version, but Python 2.7 is required"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# the valgrind rpass tests will fail if you don't have a valgrind, but they're
|
|
||||||
# only disabled if you opt out.
|
|
||||||
if [ -z "$CFG_VALGRIND" ]
|
|
||||||
then
|
|
||||||
# If the user has explicitly asked for valgrind tests, then fail
|
|
||||||
if [ -n "$CFG_ENABLE_VALGRIND" ] && [ -n "$CFG_ENABLE_VALGRIND_PROVIDED" ]
|
|
||||||
then
|
|
||||||
err "No valgrind present, but valgrind tests explicitly requested"
|
|
||||||
else
|
|
||||||
CFG_DISABLE_VALGRIND_RPASS=1
|
|
||||||
putvar CFG_DISABLE_VALGRIND_RPASS
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Do some sanity checks if running on buildbot
|
|
||||||
# (these env vars are set by rust-buildbot)
|
|
||||||
if [ -n "$RUST_DIST_SERVER" -a -n "$ALLOW_NONZERO_RLIMIT_CORE" ]; then
|
|
||||||
# Frequently the llvm submodule directory is broken by the build
|
|
||||||
# being killed
|
|
||||||
llvm_lock="${CFG_SRC_DIR}/.git/modules/src/llvm/index.lock"
|
|
||||||
if [ -e "$llvm_lock" ]; then
|
|
||||||
step_msg "removing $llvm_lock"
|
|
||||||
rm -f "$llvm_lock"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
BIN_SUF=
|
|
||||||
if [ "$CFG_OSTYPE" = "pc-windows-gnu" ] || [ "$CFG_OSTYPE" = "pc-windows-msvc" ]
|
|
||||||
then
|
|
||||||
BIN_SUF=.exe
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --enable-local-rebuild implies --enable-local-rust too
|
|
||||||
if [ -n "$CFG_ENABLE_LOCAL_REBUILD" ]
|
|
||||||
then
|
|
||||||
if [ -z "$CFG_ENABLE_LOCAL_RUST" ]
|
|
||||||
then
|
|
||||||
CFG_ENABLE_LOCAL_RUST=1
|
|
||||||
putvar CFG_ENABLE_LOCAL_RUST
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$CFG_ENABLE_LOCAL_RUST" ]
|
|
||||||
then
|
|
||||||
system_rustc=$(which rustc)
|
|
||||||
if [ -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} ]
|
|
||||||
then
|
|
||||||
: # everything already configured
|
|
||||||
elif [ -n "$system_rustc" ]
|
|
||||||
then
|
|
||||||
# we assume that rustc is in a /bin directory
|
|
||||||
CFG_LOCAL_RUST_ROOT=${system_rustc%/bin/rustc}
|
|
||||||
else
|
|
||||||
err "no local rust to use"
|
|
||||||
fi
|
|
||||||
|
|
||||||
CMD="${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF}"
|
|
||||||
LRV=`LD_LIBRARY_PATH=${CFG_LOCAL_RUST_ROOT}/lib $CMD --version`
|
|
||||||
if [ $? -ne 0 ]
|
|
||||||
then
|
|
||||||
step_msg "failure while running $CMD --version"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: $LRV"
|
|
||||||
putvar CFG_LOCAL_RUST_ROOT
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Same with jemalloc. save the setting here.
|
|
||||||
if [ -n "$CFG_DISABLE_JEMALLOC" ]
|
|
||||||
then
|
|
||||||
putvar CFG_DISABLE_JEMALLOC
|
|
||||||
fi
|
|
||||||
|
|
||||||
# All safeguards based on $CFG_ENABLE_CLANG should occur before this
|
|
||||||
# point in the script; after this point, script logic should inspect
|
|
||||||
# $CFG_USING_CLANG rather than $CFG_ENABLE_CLANG.
|
|
||||||
|
|
||||||
# Set CFG_{CC,CXX,CPP,CFLAGS,CXXFLAGS,LDFLAGS}
|
|
||||||
envopt CC
|
|
||||||
envopt CXX
|
|
||||||
envopt CPP
|
|
||||||
envopt CFLAGS
|
|
||||||
envopt CXXFLAGS
|
|
||||||
envopt LDFLAGS
|
|
||||||
|
|
||||||
# a little post-processing of various config values
|
|
||||||
CFG_PREFIX=${CFG_PREFIX%/}
|
|
||||||
CFG_MANDIR=${CFG_MANDIR%/}
|
|
||||||
CFG_DOCDIR=${CFG_DOCDIR%/}
|
|
||||||
CFG_BINDIR=${CFG_BINDIR%/}
|
|
||||||
CFG_HOST="$(echo $CFG_HOST | tr ',' ' ')"
|
|
||||||
CFG_TARGET="$(echo $CFG_TARGET | tr ',' ' ')"
|
|
||||||
|
|
||||||
# copy build-triples to host-triples so that builds are a subset of hosts
|
|
||||||
V_TEMP=""
|
|
||||||
for i in $CFG_BUILD $CFG_HOST;
|
|
||||||
do
|
|
||||||
echo "$V_TEMP" | grep -qF $i || V_TEMP="$V_TEMP${V_TEMP:+ }$i"
|
|
||||||
done
|
|
||||||
CFG_HOST=$V_TEMP
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
step_msg "writing configuration"
|
|
||||||
|
|
||||||
putvar CFG_SRC_DIR
|
|
||||||
putvar CFG_SRC_DIR_RELATIVE
|
|
||||||
putvar CFG_BUILD_DIR
|
|
||||||
putvar CFG_OSTYPE
|
|
||||||
putvar CFG_CPUTYPE
|
|
||||||
putvar CFG_CONFIGURE_ARGS
|
|
||||||
putvar CFG_PREFIX
|
|
||||||
putvar CFG_HOST
|
|
||||||
putvar CFG_TARGET
|
|
||||||
putvar CFG_LIBDIR_RELATIVE
|
|
||||||
putvar CFG_DISABLE_MANAGE_SUBMODULES
|
|
||||||
putvar CFG_AARCH64_LINUX_ANDROID_NDK
|
|
||||||
putvar CFG_ARM_LINUX_ANDROIDEABI_NDK
|
|
||||||
putvar CFG_ARMV7_LINUX_ANDROIDEABI_NDK
|
|
||||||
putvar CFG_I686_LINUX_ANDROID_NDK
|
|
||||||
putvar CFG_X86_64_LINUX_ANDROID_NDK
|
|
||||||
putvar CFG_NACL_CROSS_PATH
|
|
||||||
putvar CFG_MANDIR
|
|
||||||
putvar CFG_DOCDIR
|
|
||||||
putvar CFG_BINDIR
|
|
||||||
putvar CFG_USING_LIBCPP
|
|
||||||
|
|
||||||
msg
|
|
||||||
copy_if_changed ${CFG_SRC_DIR}src/bootstrap/mk/Makefile.in ./Makefile
|
|
||||||
move_if_changed config.tmp config.mk
|
|
||||||
rm -f config.tmp
|
|
||||||
touch config.stamp
|
|
||||||
|
|
||||||
if [ -z "$CFG_ENABLE_DEBUG" ]; then
|
|
||||||
step_msg "configured in release mode. for development consider --enable-debug"
|
|
||||||
else
|
|
||||||
step_msg "complete"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$CFG_SRC_DIR" = `pwd` ]; then
|
|
||||||
X_PY=x.py
|
|
||||||
else
|
|
||||||
X_PY=${CFG_SRC_DIR_RELATIVE}x.py
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg "run \`python ${X_PY} --help\`"
|
|
||||||
msg
|
|
||||||
|
@ -76,10 +76,9 @@ The script accepts commands, flags, and arguments to determine what to do:
|
|||||||
There are currently two methods for configuring the rustbuild build system.
|
There are currently two methods for configuring the rustbuild build system.
|
||||||
|
|
||||||
First, rustbuild offers a TOML-based configuration system with a `config.toml`
|
First, rustbuild offers a TOML-based configuration system with a `config.toml`
|
||||||
file in the same location as `config.mk`. An example of this configuration can
|
file. An example of this configuration can be found at `config.toml.example`,
|
||||||
be found at `config.toml.example`, and the configuration file can also be passed
|
and the configuration file can also be passed as `--config path/to/config.toml`
|
||||||
as `--config path/to/config.toml` if the build system is being invoked manually
|
if the build system is being invoked manually (via the python script).
|
||||||
(via the python script).
|
|
||||||
|
|
||||||
Next, the `./configure` options serialized in `config.mk` will be
|
Next, the `./configure` options serialized in `config.mk` will be
|
||||||
parsed and read. That is, if any `./configure` options are passed, they'll be
|
parsed and read. That is, if any `./configure` options are passed, they'll be
|
||||||
|
@ -167,6 +167,141 @@ def format_build_time(duration):
|
|||||||
return str(datetime.timedelta(seconds=int(duration)))
|
return str(datetime.timedelta(seconds=int(duration)))
|
||||||
|
|
||||||
|
|
||||||
|
def default_build_triple():
|
||||||
|
"""Build triple as in LLVM"""
|
||||||
|
default_encoding = sys.getdefaultencoding()
|
||||||
|
try:
|
||||||
|
ostype = subprocess.check_output(
|
||||||
|
['uname', '-s']).strip().decode(default_encoding)
|
||||||
|
cputype = subprocess.check_output(
|
||||||
|
['uname', '-m']).strip().decode(default_encoding)
|
||||||
|
except (subprocess.CalledProcessError, OSError):
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
return 'x86_64-pc-windows-msvc'
|
||||||
|
err = "uname not found"
|
||||||
|
sys.exit(err)
|
||||||
|
|
||||||
|
# The goal here is to come up with the same triple as LLVM would,
|
||||||
|
# at least for the subset of platforms we're willing to target.
|
||||||
|
ostype_mapper = {
|
||||||
|
'Bitrig': 'unknown-bitrig',
|
||||||
|
'Darwin': 'apple-darwin',
|
||||||
|
'DragonFly': 'unknown-dragonfly',
|
||||||
|
'FreeBSD': 'unknown-freebsd',
|
||||||
|
'Haiku': 'unknown-haiku',
|
||||||
|
'NetBSD': 'unknown-netbsd',
|
||||||
|
'OpenBSD': 'unknown-openbsd'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Consider the direct transformation first and then the special cases
|
||||||
|
if ostype in ostype_mapper:
|
||||||
|
ostype = ostype_mapper[ostype]
|
||||||
|
elif ostype == 'Linux':
|
||||||
|
os_from_sp = subprocess.check_output(
|
||||||
|
['uname', '-o']).strip().decode(default_encoding)
|
||||||
|
if os_from_sp == 'Android':
|
||||||
|
ostype = 'linux-android'
|
||||||
|
else:
|
||||||
|
ostype = 'unknown-linux-gnu'
|
||||||
|
elif ostype == 'SunOS':
|
||||||
|
ostype = 'sun-solaris'
|
||||||
|
# On Solaris, uname -m will return a machine classification instead
|
||||||
|
# of a cpu type, so uname -p is recommended instead. However, the
|
||||||
|
# output from that option is too generic for our purposes (it will
|
||||||
|
# always emit 'i386' on x86/amd64 systems). As such, isainfo -k
|
||||||
|
# must be used instead.
|
||||||
|
try:
|
||||||
|
cputype = subprocess.check_output(
|
||||||
|
['isainfo', '-k']).strip().decode(default_encoding)
|
||||||
|
except (subprocess.CalledProcessError, OSError):
|
||||||
|
err = "isainfo not found"
|
||||||
|
sys.exit(err)
|
||||||
|
elif ostype.startswith('MINGW'):
|
||||||
|
# msys' `uname` does not print gcc configuration, but prints msys
|
||||||
|
# configuration. so we cannot believe `uname -m`:
|
||||||
|
# msys1 is always i686 and msys2 is always x86_64.
|
||||||
|
# instead, msys defines $MSYSTEM which is MINGW32 on i686 and
|
||||||
|
# MINGW64 on x86_64.
|
||||||
|
ostype = 'pc-windows-gnu'
|
||||||
|
cputype = 'i686'
|
||||||
|
if os.environ.get('MSYSTEM') == 'MINGW64':
|
||||||
|
cputype = 'x86_64'
|
||||||
|
elif ostype.startswith('MSYS'):
|
||||||
|
ostype = 'pc-windows-gnu'
|
||||||
|
elif ostype.startswith('CYGWIN_NT'):
|
||||||
|
cputype = 'i686'
|
||||||
|
if ostype.endswith('WOW64'):
|
||||||
|
cputype = 'x86_64'
|
||||||
|
ostype = 'pc-windows-gnu'
|
||||||
|
else:
|
||||||
|
err = "unknown OS type: {}".format(ostype)
|
||||||
|
sys.exit(err)
|
||||||
|
|
||||||
|
cputype_mapper = {
|
||||||
|
'BePC': 'i686',
|
||||||
|
'aarch64': 'aarch64',
|
||||||
|
'amd64': 'x86_64',
|
||||||
|
'arm64': 'aarch64',
|
||||||
|
'i386': 'i686',
|
||||||
|
'i486': 'i686',
|
||||||
|
'i686': 'i686',
|
||||||
|
'i786': 'i686',
|
||||||
|
'powerpc': 'powerpc',
|
||||||
|
'powerpc64': 'powerpc64',
|
||||||
|
'powerpc64le': 'powerpc64le',
|
||||||
|
'ppc': 'powerpc',
|
||||||
|
'ppc64': 'powerpc64',
|
||||||
|
'ppc64le': 'powerpc64le',
|
||||||
|
's390x': 's390x',
|
||||||
|
'x64': 'x86_64',
|
||||||
|
'x86': 'i686',
|
||||||
|
'x86-64': 'x86_64',
|
||||||
|
'x86_64': 'x86_64'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Consider the direct transformation first and then the special cases
|
||||||
|
if cputype in cputype_mapper:
|
||||||
|
cputype = cputype_mapper[cputype]
|
||||||
|
elif cputype in {'xscale', 'arm'}:
|
||||||
|
cputype = 'arm'
|
||||||
|
if ostype == 'linux-android':
|
||||||
|
ostype = 'linux-androideabi'
|
||||||
|
elif cputype == 'armv6l':
|
||||||
|
cputype = 'arm'
|
||||||
|
if ostype == 'linux-android':
|
||||||
|
ostype = 'linux-androideabi'
|
||||||
|
else:
|
||||||
|
ostype += 'eabihf'
|
||||||
|
elif cputype in {'armv7l', 'armv8l'}:
|
||||||
|
cputype = 'armv7'
|
||||||
|
if ostype == 'linux-android':
|
||||||
|
ostype = 'linux-androideabi'
|
||||||
|
else:
|
||||||
|
ostype += 'eabihf'
|
||||||
|
elif cputype == 'mips':
|
||||||
|
if sys.byteorder == 'big':
|
||||||
|
cputype = 'mips'
|
||||||
|
elif sys.byteorder == 'little':
|
||||||
|
cputype = 'mipsel'
|
||||||
|
else:
|
||||||
|
raise ValueError("unknown byteorder: {}".format(sys.byteorder))
|
||||||
|
elif cputype == 'mips64':
|
||||||
|
if sys.byteorder == 'big':
|
||||||
|
cputype = 'mips64'
|
||||||
|
elif sys.byteorder == 'little':
|
||||||
|
cputype = 'mips64el'
|
||||||
|
else:
|
||||||
|
raise ValueError('unknown byteorder: {}'.format(sys.byteorder))
|
||||||
|
# only the n64 ABI is supported, indicate it
|
||||||
|
ostype += 'abi64'
|
||||||
|
elif cputype == 'sparcv9':
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
err = "unknown cpu type: {}".format(cputype)
|
||||||
|
sys.exit(err)
|
||||||
|
|
||||||
|
return "{}-{}".format(cputype, ostype)
|
||||||
|
|
||||||
class RustBuild(object):
|
class RustBuild(object):
|
||||||
"""Provide all the methods required to build Rust"""
|
"""Provide all the methods required to build Rust"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -177,7 +312,6 @@ class RustBuild(object):
|
|||||||
self.build = ''
|
self.build = ''
|
||||||
self.build_dir = os.path.join(os.getcwd(), "build")
|
self.build_dir = os.path.join(os.getcwd(), "build")
|
||||||
self.clean = False
|
self.clean = False
|
||||||
self.config_mk = ''
|
|
||||||
self.config_toml = ''
|
self.config_toml = ''
|
||||||
self.printed = False
|
self.printed = False
|
||||||
self.rust_root = os.path.abspath(os.path.join(__file__, '../../..'))
|
self.rust_root = os.path.abspath(os.path.join(__file__, '../../..'))
|
||||||
@ -374,26 +508,6 @@ class RustBuild(object):
|
|||||||
return self.get_string(value) or value.strip()
|
return self.get_string(value) or value.strip()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_mk(self, key):
|
|
||||||
"""Returns the value of the given key in config.mk, otherwise returns None
|
|
||||||
|
|
||||||
>>> rb = RustBuild()
|
|
||||||
>>> rb.config_mk = 'key := value\\n'
|
|
||||||
>>> rb.get_mk('key')
|
|
||||||
'value'
|
|
||||||
|
|
||||||
If the key does not exists, the result is None:
|
|
||||||
|
|
||||||
>>> rb.get_mk('does_not_exists') == None
|
|
||||||
True
|
|
||||||
"""
|
|
||||||
for line in iter(self.config_mk.splitlines()):
|
|
||||||
if line.startswith(key + ' '):
|
|
||||||
var = line[line.find(':=') + 2:].strip()
|
|
||||||
if var != '':
|
|
||||||
return var
|
|
||||||
return None
|
|
||||||
|
|
||||||
def cargo(self):
|
def cargo(self):
|
||||||
"""Return config path for cargo"""
|
"""Return config path for cargo"""
|
||||||
return self.program_config('cargo')
|
return self.program_config('cargo')
|
||||||
@ -407,7 +521,6 @@ class RustBuild(object):
|
|||||||
|
|
||||||
>>> rb = RustBuild()
|
>>> rb = RustBuild()
|
||||||
>>> rb.config_toml = 'rustc = "rustc"\\n'
|
>>> rb.config_toml = 'rustc = "rustc"\\n'
|
||||||
>>> rb.config_mk = 'CFG_LOCAL_RUST_ROOT := /tmp/rust\\n'
|
|
||||||
>>> rb.program_config('rustc')
|
>>> rb.program_config('rustc')
|
||||||
'rustc'
|
'rustc'
|
||||||
>>> cargo_path = rb.program_config('cargo')
|
>>> cargo_path = rb.program_config('cargo')
|
||||||
@ -415,7 +528,6 @@ class RustBuild(object):
|
|||||||
... "bin", "cargo")
|
... "bin", "cargo")
|
||||||
True
|
True
|
||||||
>>> rb.config_toml = ''
|
>>> rb.config_toml = ''
|
||||||
>>> rb.config_mk = ''
|
|
||||||
>>> cargo_path = rb.program_config('cargo')
|
>>> cargo_path = rb.program_config('cargo')
|
||||||
>>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(),
|
>>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(),
|
||||||
... "bin", "cargo")
|
... "bin", "cargo")
|
||||||
@ -424,10 +536,6 @@ class RustBuild(object):
|
|||||||
config = self.get_toml(program)
|
config = self.get_toml(program)
|
||||||
if config:
|
if config:
|
||||||
return config
|
return config
|
||||||
config = self.get_mk('CFG_LOCAL_RUST_ROOT')
|
|
||||||
if config:
|
|
||||||
return os.path.join(config, "bin", "{}{}".format(
|
|
||||||
program, self.exe_suffix()))
|
|
||||||
return os.path.join(self.bin_root(), "bin", "{}{}".format(
|
return os.path.join(self.bin_root(), "bin", "{}{}".format(
|
||||||
program, self.exe_suffix()))
|
program, self.exe_suffix()))
|
||||||
|
|
||||||
@ -439,10 +547,14 @@ class RustBuild(object):
|
|||||||
'devel'
|
'devel'
|
||||||
"""
|
"""
|
||||||
start = line.find('"')
|
start = line.find('"')
|
||||||
if start == -1:
|
if start != -1:
|
||||||
return None
|
|
||||||
end = start + 1 + line[start + 1:].find('"')
|
end = start + 1 + line[start + 1:].find('"')
|
||||||
return line[start + 1:end]
|
return line[start + 1:end]
|
||||||
|
start = line.find('\'')
|
||||||
|
if start != -1:
|
||||||
|
end = start + 1 + line[start + 1:].find('\'')
|
||||||
|
return line[start + 1:end]
|
||||||
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def exe_suffix():
|
def exe_suffix():
|
||||||
@ -521,154 +633,12 @@ class RustBuild(object):
|
|||||||
config = self.get_toml('build')
|
config = self.get_toml('build')
|
||||||
if config:
|
if config:
|
||||||
return config
|
return config
|
||||||
config = self.get_mk('CFG_BUILD')
|
return default_build_triple()
|
||||||
if config:
|
|
||||||
return config
|
|
||||||
try:
|
|
||||||
ostype = subprocess.check_output(
|
|
||||||
['uname', '-s']).strip().decode(default_encoding)
|
|
||||||
cputype = subprocess.check_output(
|
|
||||||
['uname', '-m']).strip().decode(default_encoding)
|
|
||||||
except (subprocess.CalledProcessError, OSError):
|
|
||||||
if sys.platform == 'win32':
|
|
||||||
return 'x86_64-pc-windows-msvc'
|
|
||||||
err = "uname not found"
|
|
||||||
if self.verbose:
|
|
||||||
raise Exception(err)
|
|
||||||
sys.exit(err)
|
|
||||||
|
|
||||||
# The goal here is to come up with the same triple as LLVM would,
|
|
||||||
# at least for the subset of platforms we're willing to target.
|
|
||||||
ostype_mapper = {
|
|
||||||
'Bitrig': 'unknown-bitrig',
|
|
||||||
'Darwin': 'apple-darwin',
|
|
||||||
'DragonFly': 'unknown-dragonfly',
|
|
||||||
'FreeBSD': 'unknown-freebsd',
|
|
||||||
'Haiku': 'unknown-haiku',
|
|
||||||
'NetBSD': 'unknown-netbsd',
|
|
||||||
'OpenBSD': 'unknown-openbsd'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Consider the direct transformation first and then the special cases
|
|
||||||
if ostype in ostype_mapper:
|
|
||||||
ostype = ostype_mapper[ostype]
|
|
||||||
elif ostype == 'Linux':
|
|
||||||
os_from_sp = subprocess.check_output(
|
|
||||||
['uname', '-o']).strip().decode(default_encoding)
|
|
||||||
if os_from_sp == 'Android':
|
|
||||||
ostype = 'linux-android'
|
|
||||||
else:
|
|
||||||
ostype = 'unknown-linux-gnu'
|
|
||||||
elif ostype == 'SunOS':
|
|
||||||
ostype = 'sun-solaris'
|
|
||||||
# On Solaris, uname -m will return a machine classification instead
|
|
||||||
# of a cpu type, so uname -p is recommended instead. However, the
|
|
||||||
# output from that option is too generic for our purposes (it will
|
|
||||||
# always emit 'i386' on x86/amd64 systems). As such, isainfo -k
|
|
||||||
# must be used instead.
|
|
||||||
try:
|
|
||||||
cputype = subprocess.check_output(
|
|
||||||
['isainfo', '-k']).strip().decode(default_encoding)
|
|
||||||
except (subprocess.CalledProcessError, OSError):
|
|
||||||
err = "isainfo not found"
|
|
||||||
if self.verbose:
|
|
||||||
raise Exception(err)
|
|
||||||
sys.exit(err)
|
|
||||||
elif ostype.startswith('MINGW'):
|
|
||||||
# msys' `uname` does not print gcc configuration, but prints msys
|
|
||||||
# configuration. so we cannot believe `uname -m`:
|
|
||||||
# msys1 is always i686 and msys2 is always x86_64.
|
|
||||||
# instead, msys defines $MSYSTEM which is MINGW32 on i686 and
|
|
||||||
# MINGW64 on x86_64.
|
|
||||||
ostype = 'pc-windows-gnu'
|
|
||||||
cputype = 'i686'
|
|
||||||
if os.environ.get('MSYSTEM') == 'MINGW64':
|
|
||||||
cputype = 'x86_64'
|
|
||||||
elif ostype.startswith('MSYS'):
|
|
||||||
ostype = 'pc-windows-gnu'
|
|
||||||
elif ostype.startswith('CYGWIN_NT'):
|
|
||||||
cputype = 'i686'
|
|
||||||
if ostype.endswith('WOW64'):
|
|
||||||
cputype = 'x86_64'
|
|
||||||
ostype = 'pc-windows-gnu'
|
|
||||||
else:
|
|
||||||
err = "unknown OS type: {}".format(ostype)
|
|
||||||
if self.verbose:
|
|
||||||
raise ValueError(err)
|
|
||||||
sys.exit(err)
|
|
||||||
|
|
||||||
cputype_mapper = {
|
|
||||||
'BePC': 'i686',
|
|
||||||
'aarch64': 'aarch64',
|
|
||||||
'amd64': 'x86_64',
|
|
||||||
'arm64': 'aarch64',
|
|
||||||
'i386': 'i686',
|
|
||||||
'i486': 'i686',
|
|
||||||
'i686': 'i686',
|
|
||||||
'i786': 'i686',
|
|
||||||
'powerpc': 'powerpc',
|
|
||||||
'powerpc64': 'powerpc64',
|
|
||||||
'powerpc64le': 'powerpc64le',
|
|
||||||
'ppc': 'powerpc',
|
|
||||||
'ppc64': 'powerpc64',
|
|
||||||
'ppc64le': 'powerpc64le',
|
|
||||||
's390x': 's390x',
|
|
||||||
'x64': 'x86_64',
|
|
||||||
'x86': 'i686',
|
|
||||||
'x86-64': 'x86_64',
|
|
||||||
'x86_64': 'x86_64'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Consider the direct transformation first and then the special cases
|
|
||||||
if cputype in cputype_mapper:
|
|
||||||
cputype = cputype_mapper[cputype]
|
|
||||||
elif cputype in {'xscale', 'arm'}:
|
|
||||||
cputype = 'arm'
|
|
||||||
if ostype == 'linux-android':
|
|
||||||
ostype = 'linux-androideabi'
|
|
||||||
elif cputype == 'armv6l':
|
|
||||||
cputype = 'arm'
|
|
||||||
if ostype == 'linux-android':
|
|
||||||
ostype = 'linux-androideabi'
|
|
||||||
else:
|
|
||||||
ostype += 'eabihf'
|
|
||||||
elif cputype in {'armv7l', 'armv8l'}:
|
|
||||||
cputype = 'armv7'
|
|
||||||
if ostype == 'linux-android':
|
|
||||||
ostype = 'linux-androideabi'
|
|
||||||
else:
|
|
||||||
ostype += 'eabihf'
|
|
||||||
elif cputype == 'mips':
|
|
||||||
if sys.byteorder == 'big':
|
|
||||||
cputype = 'mips'
|
|
||||||
elif sys.byteorder == 'little':
|
|
||||||
cputype = 'mipsel'
|
|
||||||
else:
|
|
||||||
raise ValueError("unknown byteorder: {}".format(sys.byteorder))
|
|
||||||
elif cputype == 'mips64':
|
|
||||||
if sys.byteorder == 'big':
|
|
||||||
cputype = 'mips64'
|
|
||||||
elif sys.byteorder == 'little':
|
|
||||||
cputype = 'mips64el'
|
|
||||||
else:
|
|
||||||
raise ValueError('unknown byteorder: {}'.format(sys.byteorder))
|
|
||||||
# only the n64 ABI is supported, indicate it
|
|
||||||
ostype += 'abi64'
|
|
||||||
elif cputype == 'sparcv9':
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
err = "unknown cpu type: {}".format(cputype)
|
|
||||||
if self.verbose:
|
|
||||||
raise ValueError(err)
|
|
||||||
sys.exit(err)
|
|
||||||
|
|
||||||
return "{}-{}".format(cputype, ostype)
|
|
||||||
|
|
||||||
def update_submodules(self):
|
def update_submodules(self):
|
||||||
"""Update submodules"""
|
"""Update submodules"""
|
||||||
if (not os.path.exists(os.path.join(self.rust_root, ".git"))) or \
|
if (not os.path.exists(os.path.join(self.rust_root, ".git"))) or \
|
||||||
self.get_toml('submodules') == "false" or \
|
self.get_toml('submodules') == "false":
|
||||||
self.get_mk('CFG_DISABLE_MANAGE_SUBMODULES') == "1":
|
|
||||||
return
|
return
|
||||||
print('Updating submodules')
|
print('Updating submodules')
|
||||||
default_encoding = sys.getdefaultencoding()
|
default_encoding = sys.getdefaultencoding()
|
||||||
@ -680,11 +650,9 @@ class RustBuild(object):
|
|||||||
).decode(default_encoding).splitlines()]
|
).decode(default_encoding).splitlines()]
|
||||||
submodules = [module for module in submodules
|
submodules = [module for module in submodules
|
||||||
if not ((module.endswith("llvm") and
|
if not ((module.endswith("llvm") and
|
||||||
(self.get_toml('llvm-config') or
|
self.get_toml('llvm-config')) or
|
||||||
self.get_mk('CFG_LLVM_ROOT'))) or
|
|
||||||
(module.endswith("jemalloc") and
|
(module.endswith("jemalloc") and
|
||||||
(self.get_toml('jemalloc') or
|
self.get_toml('jemalloc')))]
|
||||||
self.get_mk('CFG_JEMALLOC_ROOT'))))]
|
|
||||||
run(["git", "submodule", "update",
|
run(["git", "submodule", "update",
|
||||||
"--init", "--recursive"] + submodules,
|
"--init", "--recursive"] + submodules,
|
||||||
cwd=self.rust_root, verbose=self.verbose)
|
cwd=self.rust_root, verbose=self.verbose)
|
||||||
@ -721,21 +689,15 @@ def bootstrap():
|
|||||||
build.config_toml = config.read()
|
build.config_toml = config.read()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
try:
|
|
||||||
build.config_mk = open('config.mk').read()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if '\nverbose = 2' in build.config_toml:
|
if '\nverbose = 2' in build.config_toml:
|
||||||
build.verbose = 2
|
build.verbose = 2
|
||||||
elif '\nverbose = 1' in build.config_toml:
|
elif '\nverbose = 1' in build.config_toml:
|
||||||
build.verbose = 1
|
build.verbose = 1
|
||||||
|
|
||||||
build.use_vendored_sources = '\nvendor = true' in build.config_toml or \
|
build.use_vendored_sources = '\nvendor = true' in build.config_toml
|
||||||
'CFG_ENABLE_VENDOR' in build.config_mk
|
|
||||||
|
|
||||||
build.use_locked_deps = '\nlocked-deps = true' in build.config_toml or \
|
build.use_locked_deps = '\nlocked-deps = true' in build.config_toml
|
||||||
'CFG_ENABLE_LOCKED_DEPS' in build.config_mk
|
|
||||||
|
|
||||||
if 'SUDO_USER' in os.environ and not build.use_vendored_sources:
|
if 'SUDO_USER' in os.environ and not build.use_vendored_sources:
|
||||||
if os.environ.get('USER') != os.environ['SUDO_USER']:
|
if os.environ.get('USER') != os.environ['SUDO_USER']:
|
||||||
|
@ -10,12 +10,12 @@
|
|||||||
|
|
||||||
//! Serialized configuration of a build.
|
//! Serialized configuration of a build.
|
||||||
//!
|
//!
|
||||||
//! This module implements parsing `config.mk` and `config.toml` configuration
|
//! This module implements parsing `config.toml` configuration files to tweak
|
||||||
//! files to tweak how the build runs.
|
//! how the build runs.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{self, File};
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process;
|
use std::process;
|
||||||
@ -23,7 +23,7 @@ use std::cmp;
|
|||||||
|
|
||||||
use num_cpus;
|
use num_cpus;
|
||||||
use toml;
|
use toml;
|
||||||
use util::{exe, push_exe_path};
|
use util::exe;
|
||||||
use cache::{INTERNER, Interned};
|
use cache::{INTERNER, Interned};
|
||||||
use flags::Flags;
|
use flags::Flags;
|
||||||
pub use flags::Subcommand;
|
pub use flags::Subcommand;
|
||||||
@ -124,14 +124,12 @@ pub struct Config {
|
|||||||
pub nodejs: Option<PathBuf>,
|
pub nodejs: Option<PathBuf>,
|
||||||
pub gdb: Option<PathBuf>,
|
pub gdb: Option<PathBuf>,
|
||||||
pub python: Option<PathBuf>,
|
pub python: Option<PathBuf>,
|
||||||
pub configure_args: Vec<String>,
|
|
||||||
pub openssl_static: bool,
|
pub openssl_static: bool,
|
||||||
|
pub configure_args: Vec<String>,
|
||||||
|
|
||||||
// These are either the stage0 downloaded binaries or the locally installed ones.
|
// These are either the stage0 downloaded binaries or the locally installed ones.
|
||||||
pub initial_cargo: PathBuf,
|
pub initial_cargo: PathBuf,
|
||||||
pub initial_rustc: PathBuf,
|
pub initial_rustc: PathBuf,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Per-target configuration stored in the global configuration structure.
|
/// Per-target configuration stored in the global configuration structure.
|
||||||
@ -190,6 +188,8 @@ struct Build {
|
|||||||
sanitizers: Option<bool>,
|
sanitizers: Option<bool>,
|
||||||
profiler: Option<bool>,
|
profiler: Option<bool>,
|
||||||
openssl_static: Option<bool>,
|
openssl_static: Option<bool>,
|
||||||
|
configure_args: Option<Vec<String>>,
|
||||||
|
local_rebuild: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TOML representation of various global install decisions.
|
/// TOML representation of various global install decisions.
|
||||||
@ -219,6 +219,7 @@ struct Llvm {
|
|||||||
targets: Option<String>,
|
targets: Option<String>,
|
||||||
experimental_targets: Option<String>,
|
experimental_targets: Option<String>,
|
||||||
link_jobs: Option<u32>,
|
link_jobs: Option<u32>,
|
||||||
|
link_shared: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Default, Clone)]
|
#[derive(Deserialize, Default, Clone)]
|
||||||
@ -265,6 +266,9 @@ struct Rust {
|
|||||||
debuginfo_tests: Option<bool>,
|
debuginfo_tests: Option<bool>,
|
||||||
codegen_tests: Option<bool>,
|
codegen_tests: Option<bool>,
|
||||||
ignore_git: Option<bool>,
|
ignore_git: Option<bool>,
|
||||||
|
debug: Option<bool>,
|
||||||
|
dist_src: Option<bool>,
|
||||||
|
quiet_tests: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TOML representation of how each build target is configured.
|
/// TOML representation of how each build target is configured.
|
||||||
@ -374,6 +378,8 @@ impl Config {
|
|||||||
set(&mut config.sanitizers, build.sanitizers);
|
set(&mut config.sanitizers, build.sanitizers);
|
||||||
set(&mut config.profiler, build.profiler);
|
set(&mut config.profiler, build.profiler);
|
||||||
set(&mut config.openssl_static, build.openssl_static);
|
set(&mut config.openssl_static, build.openssl_static);
|
||||||
|
set(&mut config.configure_args, build.configure_args);
|
||||||
|
set(&mut config.local_rebuild, build.local_rebuild);
|
||||||
config.verbose = cmp::max(config.verbose, flags.verbose);
|
config.verbose = cmp::max(config.verbose, flags.verbose);
|
||||||
|
|
||||||
if let Some(ref install) = toml.install {
|
if let Some(ref install) = toml.install {
|
||||||
@ -385,6 +391,17 @@ impl Config {
|
|||||||
config.mandir = install.mandir.clone().map(PathBuf::from);
|
config.mandir = install.mandir.clone().map(PathBuf::from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store off these values as options because if they're not provided
|
||||||
|
// we'll infer default values for them later
|
||||||
|
let mut llvm_assertions = None;
|
||||||
|
let mut debuginfo_lines = None;
|
||||||
|
let mut debuginfo_only_std = None;
|
||||||
|
let mut debug = None;
|
||||||
|
let mut debug_jemalloc = None;
|
||||||
|
let mut debuginfo = None;
|
||||||
|
let mut debug_assertions = None;
|
||||||
|
let mut optimize = None;
|
||||||
|
|
||||||
if let Some(ref llvm) = toml.llvm {
|
if let Some(ref llvm) = toml.llvm {
|
||||||
match llvm.ccache {
|
match llvm.ccache {
|
||||||
Some(StringOrBool::String(ref s)) => {
|
Some(StringOrBool::String(ref s)) => {
|
||||||
@ -397,31 +414,35 @@ impl Config {
|
|||||||
}
|
}
|
||||||
set(&mut config.ninja, llvm.ninja);
|
set(&mut config.ninja, llvm.ninja);
|
||||||
set(&mut config.llvm_enabled, llvm.enabled);
|
set(&mut config.llvm_enabled, llvm.enabled);
|
||||||
set(&mut config.llvm_assertions, llvm.assertions);
|
llvm_assertions = llvm.assertions;
|
||||||
set(&mut config.llvm_optimize, llvm.optimize);
|
set(&mut config.llvm_optimize, llvm.optimize);
|
||||||
set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo);
|
set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo);
|
||||||
set(&mut config.llvm_version_check, llvm.version_check);
|
set(&mut config.llvm_version_check, llvm.version_check);
|
||||||
set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp);
|
set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp);
|
||||||
|
set(&mut config.llvm_link_shared, llvm.link_shared);
|
||||||
config.llvm_targets = llvm.targets.clone();
|
config.llvm_targets = llvm.targets.clone();
|
||||||
config.llvm_experimental_targets = llvm.experimental_targets.clone();
|
config.llvm_experimental_targets = llvm.experimental_targets.clone();
|
||||||
config.llvm_link_jobs = llvm.link_jobs;
|
config.llvm_link_jobs = llvm.link_jobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref rust) = toml.rust {
|
if let Some(ref rust) = toml.rust {
|
||||||
set(&mut config.rust_debug_assertions, rust.debug_assertions);
|
debug = rust.debug;
|
||||||
set(&mut config.rust_debuginfo, rust.debuginfo);
|
debug_assertions = rust.debug_assertions;
|
||||||
set(&mut config.rust_debuginfo_lines, rust.debuginfo_lines);
|
debuginfo = rust.debuginfo;
|
||||||
set(&mut config.rust_debuginfo_only_std, rust.debuginfo_only_std);
|
debuginfo_lines = rust.debuginfo_lines;
|
||||||
set(&mut config.rust_optimize, rust.optimize);
|
debuginfo_only_std = rust.debuginfo_only_std;
|
||||||
|
optimize = rust.optimize;
|
||||||
|
debug_jemalloc = rust.debug_jemalloc;
|
||||||
set(&mut config.rust_optimize_tests, rust.optimize_tests);
|
set(&mut config.rust_optimize_tests, rust.optimize_tests);
|
||||||
set(&mut config.rust_debuginfo_tests, rust.debuginfo_tests);
|
set(&mut config.rust_debuginfo_tests, rust.debuginfo_tests);
|
||||||
set(&mut config.codegen_tests, rust.codegen_tests);
|
set(&mut config.codegen_tests, rust.codegen_tests);
|
||||||
set(&mut config.rust_rpath, rust.rpath);
|
set(&mut config.rust_rpath, rust.rpath);
|
||||||
set(&mut config.debug_jemalloc, rust.debug_jemalloc);
|
|
||||||
set(&mut config.use_jemalloc, rust.use_jemalloc);
|
set(&mut config.use_jemalloc, rust.use_jemalloc);
|
||||||
set(&mut config.backtrace, rust.backtrace);
|
set(&mut config.backtrace, rust.backtrace);
|
||||||
set(&mut config.channel, rust.channel.clone());
|
set(&mut config.channel, rust.channel.clone());
|
||||||
set(&mut config.ignore_git, rust.ignore_git);
|
set(&mut config.ignore_git, rust.ignore_git);
|
||||||
|
set(&mut config.rust_dist_src, rust.dist_src);
|
||||||
|
set(&mut config.quiet_tests, rust.quiet_tests);
|
||||||
config.rustc_default_linker = rust.default_linker.clone();
|
config.rustc_default_linker = rust.default_linker.clone();
|
||||||
config.rustc_default_ar = rust.default_ar.clone();
|
config.rustc_default_ar = rust.default_ar.clone();
|
||||||
config.musl_root = rust.musl_root.clone().map(PathBuf::from);
|
config.musl_root = rust.musl_root.clone().map(PathBuf::from);
|
||||||
@ -476,226 +497,28 @@ impl Config {
|
|||||||
None => stage0_root.join(exe("cargo", &config.build)),
|
None => stage0_root.join(exe("cargo", &config.build)),
|
||||||
};
|
};
|
||||||
|
|
||||||
// compat with `./configure` while we're still using that
|
// Now that we've reached the end of our configuration, infer the
|
||||||
if fs::metadata("config.mk").is_ok() {
|
// default values for all options that we haven't otherwise stored yet.
|
||||||
config.update_with_config_mk();
|
|
||||||
}
|
let default = config.channel == "nightly";
|
||||||
|
config.llvm_assertions = llvm_assertions.unwrap_or(default);
|
||||||
|
|
||||||
|
let default = match &config.channel[..] {
|
||||||
|
"stable" | "beta" | "nightly" => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
config.rust_debuginfo_lines = debuginfo_lines.unwrap_or(default);
|
||||||
|
config.rust_debuginfo_only_std = debuginfo_only_std.unwrap_or(default);
|
||||||
|
|
||||||
|
let default = debug == Some(true);
|
||||||
|
config.debug_jemalloc = debug_jemalloc.unwrap_or(default);
|
||||||
|
config.rust_debuginfo = debuginfo.unwrap_or(default);
|
||||||
|
config.rust_debug_assertions = debug_assertions.unwrap_or(default);
|
||||||
|
config.rust_optimize = optimize.unwrap_or(!default);
|
||||||
|
|
||||||
config
|
config
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "Temporary" routine to parse `config.mk` into this configuration.
|
|
||||||
///
|
|
||||||
/// While we still have `./configure` this implements the ability to decode
|
|
||||||
/// that configuration into this. This isn't exactly a full-blown makefile
|
|
||||||
/// parser, but hey it gets the job done!
|
|
||||||
fn update_with_config_mk(&mut self) {
|
|
||||||
let mut config = String::new();
|
|
||||||
File::open("config.mk").unwrap().read_to_string(&mut config).unwrap();
|
|
||||||
for line in config.lines() {
|
|
||||||
let mut parts = line.splitn(2, ":=").map(|s| s.trim());
|
|
||||||
let key = parts.next().unwrap();
|
|
||||||
let value = match parts.next() {
|
|
||||||
Some(n) if n.starts_with('\"') => &n[1..n.len() - 1],
|
|
||||||
Some(n) => n,
|
|
||||||
None => continue
|
|
||||||
};
|
|
||||||
|
|
||||||
macro_rules! check {
|
|
||||||
($(($name:expr, $val:expr),)*) => {
|
|
||||||
if value == "1" {
|
|
||||||
$(
|
|
||||||
if key == concat!("CFG_ENABLE_", $name) {
|
|
||||||
$val = true;
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if key == concat!("CFG_DISABLE_", $name) {
|
|
||||||
$val = false;
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
check! {
|
|
||||||
("MANAGE_SUBMODULES", self.submodules),
|
|
||||||
("COMPILER_DOCS", self.compiler_docs),
|
|
||||||
("DOCS", self.docs),
|
|
||||||
("LLVM_ASSERTIONS", self.llvm_assertions),
|
|
||||||
("LLVM_RELEASE_DEBUGINFO", self.llvm_release_debuginfo),
|
|
||||||
("OPTIMIZE_LLVM", self.llvm_optimize),
|
|
||||||
("LLVM_VERSION_CHECK", self.llvm_version_check),
|
|
||||||
("LLVM_STATIC_STDCPP", self.llvm_static_stdcpp),
|
|
||||||
("LLVM_LINK_SHARED", self.llvm_link_shared),
|
|
||||||
("OPTIMIZE", self.rust_optimize),
|
|
||||||
("DEBUG_ASSERTIONS", self.rust_debug_assertions),
|
|
||||||
("DEBUGINFO", self.rust_debuginfo),
|
|
||||||
("DEBUGINFO_LINES", self.rust_debuginfo_lines),
|
|
||||||
("DEBUGINFO_ONLY_STD", self.rust_debuginfo_only_std),
|
|
||||||
("JEMALLOC", self.use_jemalloc),
|
|
||||||
("DEBUG_JEMALLOC", self.debug_jemalloc),
|
|
||||||
("RPATH", self.rust_rpath),
|
|
||||||
("OPTIMIZE_TESTS", self.rust_optimize_tests),
|
|
||||||
("DEBUGINFO_TESTS", self.rust_debuginfo_tests),
|
|
||||||
("QUIET_TESTS", self.quiet_tests),
|
|
||||||
("LOCAL_REBUILD", self.local_rebuild),
|
|
||||||
("NINJA", self.ninja),
|
|
||||||
("CODEGEN_TESTS", self.codegen_tests),
|
|
||||||
("LOCKED_DEPS", self.locked_deps),
|
|
||||||
("VENDOR", self.vendor),
|
|
||||||
("FULL_BOOTSTRAP", self.full_bootstrap),
|
|
||||||
("EXTENDED", self.extended),
|
|
||||||
("SANITIZERS", self.sanitizers),
|
|
||||||
("PROFILER", self.profiler),
|
|
||||||
("DIST_SRC", self.rust_dist_src),
|
|
||||||
("CARGO_OPENSSL_STATIC", self.openssl_static),
|
|
||||||
}
|
|
||||||
|
|
||||||
match key {
|
|
||||||
"CFG_BUILD" if value.len() > 0 => self.build = INTERNER.intern_str(value),
|
|
||||||
"CFG_HOST" if value.len() > 0 => {
|
|
||||||
self.hosts.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
|
|
||||||
|
|
||||||
}
|
|
||||||
"CFG_TARGET" if value.len() > 0 => {
|
|
||||||
self.targets.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
|
|
||||||
}
|
|
||||||
"CFG_EXPERIMENTAL_TARGETS" if value.len() > 0 => {
|
|
||||||
self.llvm_experimental_targets = Some(value.to_string());
|
|
||||||
}
|
|
||||||
"CFG_MUSL_ROOT" if value.len() > 0 => {
|
|
||||||
self.musl_root = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_MUSL_ROOT_X86_64" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("x86_64-unknown-linux-musl");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.musl_root = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_MUSL_ROOT_I686" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("i686-unknown-linux-musl");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.musl_root = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_MUSL_ROOT_ARM" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("arm-unknown-linux-musleabi");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.musl_root = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_MUSL_ROOT_ARMHF" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("arm-unknown-linux-musleabihf");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.musl_root = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_MUSL_ROOT_ARMV7" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("armv7-unknown-linux-musleabihf");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.musl_root = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_DEFAULT_AR" if value.len() > 0 => {
|
|
||||||
self.rustc_default_ar = Some(value.to_string());
|
|
||||||
}
|
|
||||||
"CFG_DEFAULT_LINKER" if value.len() > 0 => {
|
|
||||||
self.rustc_default_linker = Some(value.to_string());
|
|
||||||
}
|
|
||||||
"CFG_GDB" if value.len() > 0 => {
|
|
||||||
self.gdb = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_RELEASE_CHANNEL" => {
|
|
||||||
self.channel = value.to_string();
|
|
||||||
}
|
|
||||||
"CFG_PREFIX" => {
|
|
||||||
self.prefix = Some(PathBuf::from(value));
|
|
||||||
}
|
|
||||||
"CFG_SYSCONFDIR" => {
|
|
||||||
self.sysconfdir = Some(PathBuf::from(value));
|
|
||||||
}
|
|
||||||
"CFG_DOCDIR" => {
|
|
||||||
self.docdir = Some(PathBuf::from(value));
|
|
||||||
}
|
|
||||||
"CFG_BINDIR" => {
|
|
||||||
self.bindir = Some(PathBuf::from(value));
|
|
||||||
}
|
|
||||||
"CFG_LIBDIR" => {
|
|
||||||
self.libdir = Some(PathBuf::from(value));
|
|
||||||
}
|
|
||||||
"CFG_LIBDIR_RELATIVE" => {
|
|
||||||
self.libdir_relative = Some(PathBuf::from(value));
|
|
||||||
}
|
|
||||||
"CFG_MANDIR" => {
|
|
||||||
self.mandir = Some(PathBuf::from(value));
|
|
||||||
}
|
|
||||||
"CFG_LLVM_ROOT" if value.len() > 0 => {
|
|
||||||
let target = self.target_config.entry(self.build.clone())
|
|
||||||
.or_insert(Target::default());
|
|
||||||
let root = parse_configure_path(value);
|
|
||||||
target.llvm_config = Some(push_exe_path(root, &["bin", "llvm-config"]));
|
|
||||||
}
|
|
||||||
"CFG_JEMALLOC_ROOT" if value.len() > 0 => {
|
|
||||||
let target = self.target_config.entry(self.build.clone())
|
|
||||||
.or_insert(Target::default());
|
|
||||||
target.jemalloc = Some(parse_configure_path(value).join("libjemalloc_pic.a"));
|
|
||||||
}
|
|
||||||
"CFG_ARM_LINUX_ANDROIDEABI_NDK" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("arm-linux-androideabi");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.ndk = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_ARMV7_LINUX_ANDROIDEABI_NDK" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("armv7-linux-androideabi");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.ndk = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_I686_LINUX_ANDROID_NDK" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("i686-linux-android");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.ndk = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_AARCH64_LINUX_ANDROID_NDK" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("aarch64-linux-android");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.ndk = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_X86_64_LINUX_ANDROID_NDK" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("x86_64-linux-android");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.ndk = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_LOCAL_RUST_ROOT" if value.len() > 0 => {
|
|
||||||
let path = parse_configure_path(value);
|
|
||||||
self.initial_rustc = push_exe_path(path.clone(), &["bin", "rustc"]);
|
|
||||||
self.initial_cargo = push_exe_path(path, &["bin", "cargo"]);
|
|
||||||
}
|
|
||||||
"CFG_PYTHON" if value.len() > 0 => {
|
|
||||||
let path = parse_configure_path(value);
|
|
||||||
self.python = Some(path);
|
|
||||||
}
|
|
||||||
"CFG_ENABLE_CCACHE" if value == "1" => {
|
|
||||||
self.ccache = Some(exe("ccache", &self.build));
|
|
||||||
}
|
|
||||||
"CFG_ENABLE_SCCACHE" if value == "1" => {
|
|
||||||
self.ccache = Some(exe("sccache", &self.build));
|
|
||||||
}
|
|
||||||
"CFG_CONFIGURE_ARGS" if value.len() > 0 => {
|
|
||||||
self.configure_args = value.split_whitespace()
|
|
||||||
.map(|s| s.to_string())
|
|
||||||
.collect();
|
|
||||||
}
|
|
||||||
"CFG_QEMU_ARMHF_ROOTFS" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("arm-unknown-linux-gnueabihf");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.qemu_rootfs = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
"CFG_QEMU_AARCH64_ROOTFS" if value.len() > 0 => {
|
|
||||||
let target = INTERNER.intern_str("aarch64-unknown-linux-gnu");
|
|
||||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
|
||||||
target.qemu_rootfs = Some(parse_configure_path(value));
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn verbose(&self) -> bool {
|
pub fn verbose(&self) -> bool {
|
||||||
self.verbose > 0
|
self.verbose > 0
|
||||||
}
|
}
|
||||||
@ -705,30 +528,6 @@ impl Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
fn parse_configure_path(path: &str) -> PathBuf {
|
|
||||||
path.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
fn parse_configure_path(path: &str) -> PathBuf {
|
|
||||||
// on windows, configure produces unix style paths e.g. /c/some/path but we
|
|
||||||
// only want real windows paths
|
|
||||||
|
|
||||||
use std::process::Command;
|
|
||||||
use build_helper;
|
|
||||||
|
|
||||||
// '/' is invalid in windows paths, so we can detect unix paths by the presence of it
|
|
||||||
if !path.contains('/') {
|
|
||||||
return path.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
let win_path = build_helper::output(Command::new("cygpath").arg("-w").arg(path));
|
|
||||||
let win_path = win_path.trim();
|
|
||||||
|
|
||||||
win_path.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set<T>(field: &mut T, val: Option<T>) {
|
fn set<T>(field: &mut T, val: Option<T>) {
|
||||||
if let Some(v) = val {
|
if let Some(v) = val {
|
||||||
*field = v;
|
*field = v;
|
||||||
|
408
src/bootstrap/configure.py
Executable file
408
src/bootstrap/configure.py
Executable file
@ -0,0 +1,408 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
# file at the top-level directory of this distribution and at
|
||||||
|
# http://rust-lang.org/COPYRIGHT.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
# option. This file may not be copied, modified, or distributed
|
||||||
|
# except according to those terms.
|
||||||
|
|
||||||
|
# ignore-tidy-linelength
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
rust_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
rust_dir = os.path.dirname(rust_dir)
|
||||||
|
rust_dir = os.path.dirname(rust_dir)
|
||||||
|
sys.path.append(os.path.join(rust_dir, "src", "bootstrap"))
|
||||||
|
import bootstrap
|
||||||
|
|
||||||
|
class Option:
|
||||||
|
def __init__(self, name, rustbuild, desc, value):
|
||||||
|
self.name = name
|
||||||
|
self.rustbuild = rustbuild
|
||||||
|
self.desc = desc
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
options = []
|
||||||
|
|
||||||
|
def o(*args):
|
||||||
|
options.append(Option(*args, value=False))
|
||||||
|
|
||||||
|
def v(*args):
|
||||||
|
options.append(Option(*args, value=True))
|
||||||
|
|
||||||
|
o("debug", "rust.debug", "debug mode; disables optimization unless `--enable-optimize` given")
|
||||||
|
o("docs", "build.docs", "build standard library documentation")
|
||||||
|
o("compiler-docs", "build.compiler-docs", "build compiler documentation")
|
||||||
|
o("optimize-tests", "rust.optimize-tests", "build tests with optimizations")
|
||||||
|
o("debuginfo-tests", "rust.debuginfo-tests", "build tests with debugger metadata")
|
||||||
|
o("quiet-tests", "rust.quiet-tests", "enable quieter output when running tests")
|
||||||
|
o("ccache", "llvm.ccache", "invoke gcc/clang via ccache to reuse object files between builds")
|
||||||
|
o("sccache", None, "invoke gcc/clang via sccache to reuse object files between builds")
|
||||||
|
o("local-rust", None, "use an installed rustc rather than downloading a snapshot")
|
||||||
|
v("local-rust-root", None, "set prefix for local rust binary")
|
||||||
|
o("local-rebuild", "build.local-rebuild", "assume local-rust matches the current version, for rebuilds; implies local-rust, and is implied if local-rust already matches the current version")
|
||||||
|
o("llvm-static-stdcpp", "llvm.static-libstdcpp", "statically link to libstdc++ for LLVM")
|
||||||
|
o("llvm-link-shared", "llvm.link-shared", "prefer shared linking to LLVM (llvm-config --link-shared)")
|
||||||
|
o("rpath", "rust.rpath", "build rpaths into rustc itself")
|
||||||
|
o("llvm-version-check", "llvm.version-check", "check if the LLVM version is supported, build anyway")
|
||||||
|
o("codegen-tests", "rust.codegen-tests", "run the src/test/codegen tests")
|
||||||
|
o("option-checking", None, "complain about unrecognized options in this configure script")
|
||||||
|
o("ninja", "llvm.ninja", "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)")
|
||||||
|
o("locked-deps", "build.locked-deps", "force Cargo.lock to be up to date")
|
||||||
|
o("vendor", "build.vendor", "enable usage of vendored Rust crates")
|
||||||
|
o("sanitizers", "build.sanitizers", "build the sanitizer runtimes (asan, lsan, msan, tsan)")
|
||||||
|
o("dist-src", "rust.dist-src", "when building tarballs enables building a source tarball")
|
||||||
|
o("cargo-openssl-static", "build.openssl-static", "static openssl in cargo")
|
||||||
|
o("profiler", "build.profiler", "build the profiler runtime")
|
||||||
|
|
||||||
|
# Optimization and debugging options. These may be overridden by the release
|
||||||
|
# channel, etc.
|
||||||
|
o("optimize", "rust.optimize", "build optimized rust code")
|
||||||
|
o("optimize-llvm", "llvm.optimize", "build optimized LLVM")
|
||||||
|
o("llvm-assertions", "llvm.assertions", "build LLVM with assertions")
|
||||||
|
o("debug-assertions", "rust.debug-assertions", "build with debugging assertions")
|
||||||
|
o("llvm-release-debuginfo", "llvm.release-debuginfo", "build LLVM with debugger metadata")
|
||||||
|
o("debuginfo", "rust.debuginfo", "build with debugger metadata")
|
||||||
|
o("debuginfo-lines", "rust.debuginfo-lines", "build with line number debugger metadata")
|
||||||
|
o("debuginfo-only-std", "rust.debuginfo-only-std", "build only libstd with debugging information")
|
||||||
|
o("debug-jemalloc", "rust.debug-jemalloc", "build jemalloc with --enable-debug --enable-fill")
|
||||||
|
|
||||||
|
v("prefix", "install.prefix", "set installation prefix")
|
||||||
|
v("localstatedir", "install.localstatedir", "local state directory")
|
||||||
|
v("datadir", "install.datadir", "install data")
|
||||||
|
v("sysconfdir", "install.sysconfdir", "install system configuration files")
|
||||||
|
v("infodir", "install.infodir", "install additional info")
|
||||||
|
v("libdir", "install.libdir", "install libraries")
|
||||||
|
v("mandir", "install.mandir", "install man pages in PATH")
|
||||||
|
v("docdir", "install.docdir", "install documentation in PATH")
|
||||||
|
v("bindir", "install.bindir", "install binaries")
|
||||||
|
|
||||||
|
v("llvm-root", None, "set LLVM root")
|
||||||
|
v("python", "build.python", "set path to python")
|
||||||
|
v("jemalloc-root", None, "set directory where libjemalloc_pic.a is located")
|
||||||
|
v("android-cross-path", "target.arm-linux-androideabi.android-ndk",
|
||||||
|
"Android NDK standalone path (deprecated)")
|
||||||
|
v("i686-linux-android-ndk", "target.i686-linux-android.android-ndk",
|
||||||
|
"i686-linux-android NDK standalone path")
|
||||||
|
v("arm-linux-androideabi-ndk", "target.arm-linux-androideabi.android-ndk",
|
||||||
|
"arm-linux-androideabi NDK standalone path")
|
||||||
|
v("armv7-linux-androideabi-ndk", "target.armv7-linux-androideabi.android-ndk",
|
||||||
|
"armv7-linux-androideabi NDK standalone path")
|
||||||
|
v("aarch64-linux-android-ndk", "target.aarch64-linux-android.android-ndk",
|
||||||
|
"aarch64-linux-android NDK standalone path")
|
||||||
|
v("x86_64-linux-android-ndk", "target.x86_64-linux-android.android-ndk",
|
||||||
|
"x86_64-linux-android NDK standalone path")
|
||||||
|
v("musl-root", "target.x86_64-unknown-linux-musl.musl-root",
|
||||||
|
"MUSL root installation directory (deprecated)")
|
||||||
|
v("musl-root-x86_64", "target.x86_64-unknown-linux-musl.musl-root",
|
||||||
|
"x86_64-unknown-linux-musl install directory")
|
||||||
|
v("musl-root-i686", "target.i686-unknown-linux-musl.musl-root",
|
||||||
|
"i686-unknown-linux-musl install directory")
|
||||||
|
v("musl-root-arm", "target.arm-unknown-linux-musleabi.musl-root",
|
||||||
|
"arm-unknown-linux-musleabi install directory")
|
||||||
|
v("musl-root-armhf", "target.arm-unknown-linux-musleabihf.musl-root",
|
||||||
|
"arm-unknown-linux-musleabihf install directory")
|
||||||
|
v("musl-root-armv7", "target.armv7-unknown-linux-musleabihf.musl-root",
|
||||||
|
"armv7-unknown-linux-musleabihf install directory")
|
||||||
|
v("qemu-armhf-rootfs", "target.arm-unknown-linux-gnueabihf.qemu-rootfs",
|
||||||
|
"rootfs in qemu testing, you probably don't want to use this")
|
||||||
|
v("qemu-aarch64-rootfs", "target.aarch64-unknown-linux-gnu.qemu-rootfs",
|
||||||
|
"rootfs in qemu testing, you probably don't want to use this")
|
||||||
|
v("experimental-targets", "llvm.experimental-targets",
|
||||||
|
"experimental LLVM targets to build")
|
||||||
|
v("release-channel", "rust.channel", "the name of the release channel to build")
|
||||||
|
|
||||||
|
# Used on systems where "cc" and "ar" are unavailable
|
||||||
|
v("default-linker", "rust.default-linker", "the default linker")
|
||||||
|
v("default-ar", "rust.default-ar", "the default ar")
|
||||||
|
|
||||||
|
# Many of these are saved below during the "writing configuration" step
|
||||||
|
# (others are conditionally saved).
|
||||||
|
o("manage-submodules", "build.submodules", "let the build manage the git submodules")
|
||||||
|
o("jemalloc", "rust.use-jemalloc", "build liballoc with jemalloc")
|
||||||
|
o("full-bootstrap", "build.full-bootstrap", "build three compilers instead of two")
|
||||||
|
o("extended", "build.extended", "build an extended rust tool set")
|
||||||
|
|
||||||
|
v("build", "build.build", "GNUs ./configure syntax LLVM build triple")
|
||||||
|
v("host", None, "GNUs ./configure syntax LLVM host triples")
|
||||||
|
v("target", None, "GNUs ./configure syntax LLVM target triples")
|
||||||
|
|
||||||
|
v("set", None, "set arbitrary key/value pairs in TOML configuration")
|
||||||
|
|
||||||
|
def p(msg):
|
||||||
|
print("configure: " + msg)
|
||||||
|
|
||||||
|
def err(msg):
|
||||||
|
print("configure: error: " + msg)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if '--help' in sys.argv or '-h' in sys.argv:
|
||||||
|
print('Usage: ./configure [options]')
|
||||||
|
print('')
|
||||||
|
print('Options')
|
||||||
|
for option in options:
|
||||||
|
if 'android' in option.name:
|
||||||
|
# no one needs to know about these obscure options
|
||||||
|
continue
|
||||||
|
if option.value:
|
||||||
|
print('\t{:30} {}'.format('--{}=VAL'.format(option.name), option.desc))
|
||||||
|
else:
|
||||||
|
print('\t{:30} {}'.format('--enable-{}'.format(option.name), option.desc))
|
||||||
|
print('')
|
||||||
|
print('This configure script is a thin configuration shim over the true')
|
||||||
|
print('configuration system, `config.toml`. You can explore the comments')
|
||||||
|
print('in `config.toml.example` next to this configure script to see')
|
||||||
|
print('more information about what each option is. Additionally you can')
|
||||||
|
print('pass `--set` as an argument to set arbitrary key/value pairs')
|
||||||
|
print('in the TOML configuration if desired')
|
||||||
|
print('')
|
||||||
|
print('Also note that all options which take `--enable` can similarly')
|
||||||
|
print('be passed with `--disable-foo` to forcibly disable the option')
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# Parse all command line arguments into one of these three lists, handling
|
||||||
|
# boolean and value-based options separately
|
||||||
|
unknown_args = []
|
||||||
|
need_value_args = []
|
||||||
|
known_args = {}
|
||||||
|
|
||||||
|
p("processing command line")
|
||||||
|
i = 1
|
||||||
|
while i < len(sys.argv):
|
||||||
|
arg = sys.argv[i]
|
||||||
|
i += 1
|
||||||
|
if not arg.startswith('--'):
|
||||||
|
unknown_args.append(arg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
found = False
|
||||||
|
for option in options:
|
||||||
|
value = None
|
||||||
|
if option.value:
|
||||||
|
keyval = arg[2:].split('=', 1)
|
||||||
|
key = keyval[0]
|
||||||
|
if option.name != key:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if len(keyval) > 1:
|
||||||
|
value = keyval[1]
|
||||||
|
elif i < len(sys.argv):
|
||||||
|
value = sys.argv[i]
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
need_value_args.append(arg)
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if arg[2:] == 'enable-' + option.name:
|
||||||
|
value = True
|
||||||
|
elif arg[2:] == 'disable-' + option.name:
|
||||||
|
value = False
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
found = True
|
||||||
|
if not option.name in known_args:
|
||||||
|
known_args[option.name] = []
|
||||||
|
known_args[option.name].append((option, value))
|
||||||
|
break
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
unknown_args.append(arg)
|
||||||
|
p("")
|
||||||
|
|
||||||
|
if 'option-checking' not in known_args or known_args['option-checking'][1]:
|
||||||
|
if len(unknown_args) > 0:
|
||||||
|
err("Option '" + unknown_args[0] + "' is not recognized")
|
||||||
|
if len(need_value_args) > 0:
|
||||||
|
err("Option '{0}' needs a value ({0}=val)".format(need_value_args[0]))
|
||||||
|
|
||||||
|
# Parse all known arguments into a configuration structure that reflects the
|
||||||
|
# TOML we're going to write out
|
||||||
|
config = {}
|
||||||
|
|
||||||
|
def build():
|
||||||
|
if 'build' in known_args:
|
||||||
|
return known_args['build'][0][1]
|
||||||
|
return bootstrap.default_build_triple()
|
||||||
|
|
||||||
|
def set(key, value):
|
||||||
|
s = "{:20} := {}".format(key, value)
|
||||||
|
if len(s) < 70:
|
||||||
|
p(s)
|
||||||
|
else:
|
||||||
|
p(s[:70] + " ...")
|
||||||
|
|
||||||
|
arr = config
|
||||||
|
parts = key.split('.')
|
||||||
|
for i, part in enumerate(parts):
|
||||||
|
if i == len(parts) - 1:
|
||||||
|
arr[part] = value
|
||||||
|
else:
|
||||||
|
if not part in arr:
|
||||||
|
arr[part] = {}
|
||||||
|
arr = arr[part]
|
||||||
|
|
||||||
|
for key in known_args:
|
||||||
|
# The `set` option is special and an be passed a bunch of times
|
||||||
|
if key == 'set':
|
||||||
|
for option, value in known_args[key]:
|
||||||
|
keyval = value.split('=', 1)
|
||||||
|
set(keyval[0], True if len(keyval) == 1 else keyval[1])
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Ensure each option is only passed once
|
||||||
|
arr = known_args[key]
|
||||||
|
if len(arr) > 1:
|
||||||
|
err("Option '{}' provided more than once".format(key))
|
||||||
|
option, value = arr[0]
|
||||||
|
|
||||||
|
# If we have a clear avenue to set our value in rustbuild, do so
|
||||||
|
if option.rustbuild is not None:
|
||||||
|
set(option.rustbuild, value)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Otherwise we're a "special" option and need some extra handling, so do
|
||||||
|
# that here.
|
||||||
|
if option.name == 'sccache':
|
||||||
|
set('llvm.ccache', 'sccache')
|
||||||
|
elif option.name == 'local-rust':
|
||||||
|
for path in os.environ['PATH'].split(os.pathsep):
|
||||||
|
if os.path.exists(path + '/rustc'):
|
||||||
|
set('build.rustc', path + '/rustc')
|
||||||
|
break
|
||||||
|
for path in os.environ['PATH'].split(os.pathsep):
|
||||||
|
if os.path.exists(path + '/cargo'):
|
||||||
|
set('build.cargo', path + '/cargo')
|
||||||
|
break
|
||||||
|
elif option.name == 'local-rust-root':
|
||||||
|
set('build.rustc', value + '/bin/rustc')
|
||||||
|
set('build.cargo', value + '/bin/cargo')
|
||||||
|
elif option.name == 'llvm-root':
|
||||||
|
set('target.{}.llvm-config'.format(build()), value + '/bin/llvm-config')
|
||||||
|
elif option.name == 'jemalloc-root':
|
||||||
|
set('target.{}.jemalloc'.format(build()), value + '/libjemalloc_pic.a')
|
||||||
|
elif option.name == 'host':
|
||||||
|
set('build.host', value.split(','))
|
||||||
|
elif option.name == 'target':
|
||||||
|
set('build.target', value.split(','))
|
||||||
|
elif option.name == 'option-checking':
|
||||||
|
# this was handled above
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise RuntimeError("unhandled option {}".format(option.name))
|
||||||
|
|
||||||
|
set('build.configure-args', sys.argv[1:])
|
||||||
|
|
||||||
|
# "Parse" the `config.toml.example` file into the various sections, and we'll
|
||||||
|
# use this as a template of a `config.toml` to write out which preserves
|
||||||
|
# all the various comments and whatnot.
|
||||||
|
#
|
||||||
|
# Note that the `target` section is handled separately as we'll duplicate it
|
||||||
|
# per configure dtarget, so there's a bit of special handling for that here.
|
||||||
|
sections = {}
|
||||||
|
cur_section = None
|
||||||
|
sections[None] = []
|
||||||
|
section_order = [None]
|
||||||
|
targets = {}
|
||||||
|
|
||||||
|
for line in open(rust_dir + '/config.toml.example').read().split("\n"):
|
||||||
|
if line.startswith('['):
|
||||||
|
cur_section = line[1:-1]
|
||||||
|
if cur_section.startswith('target'):
|
||||||
|
cur_section = 'target'
|
||||||
|
elif '.' in cur_section:
|
||||||
|
raise RuntimeError("don't know how to deal with section: {}".format(cur_section))
|
||||||
|
sections[cur_section] = [line]
|
||||||
|
section_order.append(cur_section)
|
||||||
|
else:
|
||||||
|
sections[cur_section].append(line)
|
||||||
|
|
||||||
|
# Fill out the `targets` array by giving all configured targets a copy of the
|
||||||
|
# `target` section we just loaded from the example config
|
||||||
|
configured_targets = [build()]
|
||||||
|
if 'build' in config:
|
||||||
|
if 'host' in config['build']:
|
||||||
|
configured_targets += config['build']['host']
|
||||||
|
if 'target' in config['build']:
|
||||||
|
configured_targets += config['build']['target']
|
||||||
|
if 'target' in config:
|
||||||
|
for target in config['target']:
|
||||||
|
configured_targets.append(target)
|
||||||
|
for target in configured_targets:
|
||||||
|
targets[target] = sections['target'][:]
|
||||||
|
targets[target][0] = targets[target][0].replace("x86_64-unknown-linux-gnu", target)
|
||||||
|
|
||||||
|
# Here we walk through the constructed configuration we have from the parsed
|
||||||
|
# command line arguemnts. We then apply each piece of configuration by
|
||||||
|
# basically just doing a `sed` to change the various configuration line to what
|
||||||
|
# we've got configure.
|
||||||
|
def to_toml(value):
|
||||||
|
if isinstance(value, bool):
|
||||||
|
if value:
|
||||||
|
return "true"
|
||||||
|
else:
|
||||||
|
return "false"
|
||||||
|
elif isinstance(value, list):
|
||||||
|
return '[' + ', '.join(map(to_toml, value)) + ']'
|
||||||
|
elif isinstance(value, str):
|
||||||
|
return "'" + value + "'"
|
||||||
|
else:
|
||||||
|
raise 'no toml'
|
||||||
|
|
||||||
|
def configure_section(lines, config):
|
||||||
|
for key in config:
|
||||||
|
value = config[key]
|
||||||
|
found = False
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if not line.startswith('#' + key + ' = '):
|
||||||
|
continue
|
||||||
|
found = True
|
||||||
|
lines[i] = "{} = {}".format(key, to_toml(value))
|
||||||
|
break
|
||||||
|
if not found:
|
||||||
|
raise RuntimeError("failed to find config line for {}".format(key))
|
||||||
|
|
||||||
|
for section_key in config:
|
||||||
|
section_config = config[section_key]
|
||||||
|
if not section_key in sections:
|
||||||
|
raise RuntimeError("config key {} not in sections".format(key))
|
||||||
|
|
||||||
|
if section_key == 'target':
|
||||||
|
for target in section_config:
|
||||||
|
configure_section(targets[target], section_config[target])
|
||||||
|
else:
|
||||||
|
configure_section(sections[section_key], section_config)
|
||||||
|
|
||||||
|
# Now that we've built up our `config.toml`, write it all out in the same
|
||||||
|
# order that we read it in.
|
||||||
|
p("")
|
||||||
|
p("writing `config.toml` in current directory")
|
||||||
|
with open('config.toml', 'w') as f:
|
||||||
|
for section in section_order:
|
||||||
|
if section == 'target':
|
||||||
|
for target in targets:
|
||||||
|
for line in targets[target]:
|
||||||
|
f.write(line + "\n")
|
||||||
|
else:
|
||||||
|
for line in sections[section]:
|
||||||
|
f.write(line + "\n")
|
||||||
|
|
||||||
|
with open('Makefile', 'w') as f:
|
||||||
|
contents = os.path.join(rust_dir, 'src', 'bootstrap', 'mk', 'Makefile.in')
|
||||||
|
contents = open(contents).read()
|
||||||
|
contents = contents.replace("$(CFG_SRC_DIR)", rust_dir + '/')
|
||||||
|
contents = contents.replace("$(CFG_PYTHON)", sys.executable)
|
||||||
|
f.write(contents)
|
||||||
|
|
||||||
|
# Finally, clean up with a bit of a help message
|
||||||
|
relpath = os.path.dirname(__file__)
|
||||||
|
if relpath == '':
|
||||||
|
relpath = '.'
|
||||||
|
|
||||||
|
p("")
|
||||||
|
p("run `python {}/x.py --help`".format(relpath))
|
||||||
|
p("")
|
@ -822,6 +822,7 @@ impl Step for PlainSourceTarball {
|
|||||||
"RELEASES.md",
|
"RELEASES.md",
|
||||||
"configure",
|
"configure",
|
||||||
"x.py",
|
"x.py",
|
||||||
|
"config.toml.example",
|
||||||
];
|
];
|
||||||
let src_dirs = [
|
let src_dirs = [
|
||||||
"man",
|
"man",
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
# option. This file may not be copied, modified, or distributed
|
# option. This file may not be copied, modified, or distributed
|
||||||
# except according to those terms.
|
# except according to those terms.
|
||||||
|
|
||||||
include config.mk
|
|
||||||
|
|
||||||
ifdef VERBOSE
|
ifdef VERBOSE
|
||||||
Q :=
|
Q :=
|
||||||
BOOTSTRAP_ARGS := -v
|
BOOTSTRAP_ARGS := -v
|
||||||
|
Loading…
Reference in New Issue
Block a user