Experimental new redoconf C/C++ build/autoconfiguration system.
To test it out, try this: ./do -j10 build cd docs/cookbook/c redo -j10 test It should detect all the compilers on your system and make three separate builds for each one: normal, debug, and optimized. Then it tries to run a test program under each one. If there are windows cross compilers and you also have 'wine' installed, it'll try running the test program under wine as well. redoconf currently has no documentation other than the example program. We'll fix that later.
This commit is contained in:
parent
5db883ac58
commit
6dae51f4d2
67 changed files with 1777 additions and 1 deletions
240
redoconf/rc.sh
Normal file
240
redoconf/rc.sh
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
# This script starts with $PWD=output dir, $S=input dir.
|
||||
REDOCONF="$S/redoconf"
|
||||
if [ ! -d "$S" ] || [ ! -f "$REDOCONF/default.do.sh" ]; then
|
||||
echo "default.do.sh: \$S is not set correctly." >&2
|
||||
exit 99
|
||||
fi
|
||||
. "$REDOCONF/utils.sh"
|
||||
RC_TARGET="$1"
|
||||
rm -f "$RC_TARGET.log"
|
||||
|
||||
redo-ifchange "$REDOCONF/rc.sh" "$REDOCONF/utils.sh"
|
||||
|
||||
_rc_exit_check() {
|
||||
if [ -z "$RC_INCLUDE_RAN" ]; then
|
||||
echo "Fatal: used redoconf/rc.sh but didn't call rc_include." >&2
|
||||
exit 99
|
||||
elif [ -n "$RC_QUEUE" ]; then
|
||||
echo "Fatal: must call rc_save or rc_undo before ending." >&2
|
||||
exit 99
|
||||
fi
|
||||
}
|
||||
trap _rc_exit_check EXIT
|
||||
|
||||
rc_hook() {
|
||||
# nothing by default; can be overridden
|
||||
:
|
||||
}
|
||||
|
||||
# Declare that a variable *named* $1 is used
|
||||
# as input for the current script, and provide
|
||||
# a help message in $2 for use with
|
||||
# configure --help-flags.
|
||||
helpmsg() {
|
||||
# Nothing to do by default
|
||||
rc_hook "$1"
|
||||
}
|
||||
|
||||
# Assign the string $2 to the global variable
|
||||
# *named* by $1.
|
||||
replaceln() {
|
||||
rc_hook "$1"
|
||||
eval $1=\$2
|
||||
}
|
||||
|
||||
# If $2 is nonempty, append a newline and $2 to
|
||||
# the global variable *named* by $1
|
||||
appendln() {
|
||||
rc_hook "$1"
|
||||
eval local tmp=\"\$$1\$NL\$2\"
|
||||
eval $1='${tmp#$NL}'
|
||||
}
|
||||
|
||||
# Write a command line that calls "uses $1",
|
||||
# including proper sh-escaping.
|
||||
rc_helpmsg() {
|
||||
local cmd="helpmsg"
|
||||
cmd="helpmsg $1 $(shquote "$2")"
|
||||
eval "$cmd"
|
||||
appendln RC_HELP_QUEUE "$cmd"
|
||||
}
|
||||
|
||||
_rc_record() {
|
||||
if ! contains_line "$RC_CHANGED" "$1"; then
|
||||
local oldv=
|
||||
eval oldv="\$$1"
|
||||
eval "old$1=\$oldv"
|
||||
RC_CHANGED="$RC_CHANGED$NL$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Write a command line that calls "appendln $1 $2",
|
||||
# including properly sh-escaping $2.
|
||||
rc_appendln() {
|
||||
RC_LOG="$RC_LOG $1 += $(shquote "$2")$NL"
|
||||
_rc_record "$1"
|
||||
local cmd="appendln $1 $(shquote "$2")"
|
||||
eval "$cmd"
|
||||
appendln RC_QUEUE "$cmd"
|
||||
}
|
||||
|
||||
# Write a command line that replaces $1 with $2,
|
||||
# including properly sh-escaping $2.
|
||||
# This is good for variables like CC and CXX, where
|
||||
# appending isn't what we want.
|
||||
rc_replaceln() {
|
||||
RC_LOG="$RC_LOG $1 = $(shquote "$2")$NL"
|
||||
_rc_record "$1"
|
||||
local cmd="replaceln $1 $(shquote "$2")"
|
||||
eval "$cmd"
|
||||
appendln RC_QUEUE "$cmd"
|
||||
}
|
||||
|
||||
# Read compiler variables from _init.rc and the listed .rc files.
|
||||
# Runs redo-ifchange to generate the .rc files as needed.
|
||||
rc_include() {
|
||||
local d="" want="" target="$RC_TARGET" ops4="$PS4"
|
||||
RC_INCLUDE_RAN=1
|
||||
for d in rc/_init.rc "$@"; do
|
||||
if [ "$d" = "${d%.rc}" ]; then
|
||||
xecho "$0: rc_include: '$d' must end in .rc" >&2
|
||||
exit 99
|
||||
fi
|
||||
if ! contains_line "$RC_INCLUDES" "$d"; then
|
||||
want="$want$NL$d"
|
||||
RC_INCLUDES="$RC_INCLUDES$NL$d"
|
||||
fi
|
||||
done
|
||||
want="${want#$NL}"
|
||||
if [ -n "$want" ]; then
|
||||
xIFS="$IFS"
|
||||
IFS="$NL"
|
||||
set -f
|
||||
redo-ifchange $want
|
||||
for d in $want; do
|
||||
IFS="$xIFS"
|
||||
set +f
|
||||
RC_TARGET="$d"
|
||||
PS4="$PS4[$d] "
|
||||
[ ! -e "$d" ] || { :; . "./$d"; }
|
||||
PS4="$ops4"
|
||||
done
|
||||
IFS="$xIFS"
|
||||
set +f
|
||||
fi
|
||||
unset RC_QUEUE
|
||||
PS4="$ops4"
|
||||
RC_TARGET="$target"
|
||||
}
|
||||
|
||||
# Undo the currently enqueued rc_appendln and rc_replaceln
|
||||
# actions, restoring the affected variables back to their
|
||||
# original values.
|
||||
rc_undo() {
|
||||
local xIFS="$IFS" v=
|
||||
IFS="$NL"
|
||||
for k in $RC_CHANGED; do
|
||||
eval v="\$old$k"
|
||||
eval "$k=\$v"
|
||||
done
|
||||
unset RC_CHANGED
|
||||
unset RC_QUEUE
|
||||
unset RC_LOG
|
||||
}
|
||||
|
||||
# Write the currently active rc_include,
|
||||
# rc_replaceln, and rc_appendln commands to stdout,
|
||||
# to produce the final .rc file.
|
||||
rc_save() {
|
||||
printf '%s' "${RC_LOG}" >&2
|
||||
if [ -n "$RC_INCLUDES" ]; then
|
||||
(
|
||||
xIFS="$IFS"
|
||||
IFS="$NL"
|
||||
printf 'rc_include '
|
||||
for d in $RC_INCLUDES; do
|
||||
printf '%s ' "$d"
|
||||
done
|
||||
printf '\n'
|
||||
)
|
||||
fi
|
||||
xecho "$RC_HELP_QUEUE"
|
||||
xecho "$RC_QUEUE"
|
||||
unset RC_QUEUE
|
||||
unset RC_CHANGED
|
||||
}
|
||||
|
||||
rc_compile() {
|
||||
redo-ifchange "$REDOCONF/trycompile"
|
||||
( . "$REDOCONF/trycompile" "$@" ) >>"$RC_TARGET.log" 2>&1
|
||||
}
|
||||
|
||||
_pkg_config() {
|
||||
(
|
||||
IFS="$NL"
|
||||
set -f
|
||||
$PKG_CONFIG $PKG_CONFIG_FLAGS "$@"
|
||||
)
|
||||
}
|
||||
|
||||
_rc_pkg_add() {
|
||||
local var="$1" vvar= want=
|
||||
shift
|
||||
if [ -n "$HAVE_PKG_CONFIG" ]; then
|
||||
for d in "$@"; do
|
||||
if _pkg_config --exists "$d"; then
|
||||
want="$want $d"
|
||||
fi
|
||||
done
|
||||
if [ -n "$want" ]; then
|
||||
rc_appendln CPPFLAGS \
|
||||
"$(rc_splitwords \
|
||||
"$(_pkg_config --cflags $want)")"
|
||||
vvar="$(rc_splitwords \
|
||||
"$(_pkg_config --libs $want)")"
|
||||
rc_appendln "$var" "$vvar"
|
||||
fi
|
||||
else
|
||||
echo "(pkg-config is missing)" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
# Determine whether packages listed in $2 all exists and are functional,
|
||||
# by finding them using pkg-config and running the command in $3..$n.
|
||||
#
|
||||
# If the package works:
|
||||
# HAVE_$1 is set to 1
|
||||
# CPPFLAGS and the variable named by $1 are updated with compiler and
|
||||
# linker flags, respectively.
|
||||
# else:
|
||||
# HAVE_$1 is set to blank.
|
||||
#
|
||||
# Returns success in either case. Check detection results in the
|
||||
# HAVE_$1 variable if needed.
|
||||
rc_pkg_detect() {
|
||||
if ! contains_line "$RC_INCLUDES" rc/pkg-config.rc; then
|
||||
echo "Error: include pkg-config.rc before using rc_pkg_*" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ "$#" -lt 3 ]; then
|
||||
echo "Error: rc_pkg_detect needs a command to test." >&2
|
||||
return 1
|
||||
fi
|
||||
local var="$1" vvar="" pkgs="$2"
|
||||
shift
|
||||
shift
|
||||
eval vvar="\$$var"
|
||||
rc_helpmsg "$var" "Extra linker options for '$pkgs'"
|
||||
if [ -z "$vvar" ]; then
|
||||
_rc_pkg_add "$var" $pkgs
|
||||
eval vvar="\$$var"
|
||||
fi
|
||||
appendln LIBS "$vvar"
|
||||
if ("$@"); then
|
||||
rc_replaceln "HAVE_$var" 1
|
||||
else
|
||||
rc_undo
|
||||
rc_replaceln "HAVE_$var" ""
|
||||
rc_replaceln "$var" ""
|
||||
fi
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue