libretro-super/libretro-build-common.sh

456 lines
13 KiB
Bash
Raw Permalink Normal View History

# vim: set ts=3 sw=3 noet ft=sh : bash
2015-03-27 19:45:38 -04:00
. "$BASE_DIR/script-modules/log.sh"
. "$BASE_DIR/script-modules/util.sh"
. "$BASE_DIR/script-modules/fetch-rules.sh"
. "$BASE_DIR/script-modules/cpu.sh"
. "$BASE_DIR/script-modules/module_base.sh"
. "$BASE_DIR/rules.d/core-rules.sh"
2015-02-26 17:43:29 -05:00
die() {
echo $1
#exit 1
}
#
# Regarding COMPILER... It didn't used to be safe. Now it is, provided that
# you are using it in a command line passed to echo_cmd without additional
# quoting, like so:
#
# echo_cmd "$MAKE TARGET=\"libretro\" $COMPILER OTHERVAR=\"$SOMETHING\""
#
if [ "${CC}" ] && [ "${CXX}" ]; then
COMPILER="CC=\"${CC}\" CXX=\"${CXX}\""
else
COMPILER=""
fi
echo "Compiler: CC=\"$CC\" CXX=\"$CXX\""
[[ "${ARM_NEON}" ]] && echo '=== ARM NEON opts enabled... ===' && export FORMAT_COMPILER_TARGET="$FORMAT_COMPILER_TARGET-neon"
[[ "${CORTEX_A8}" ]] && echo '=== Cortex A8 opts enabled... ===' && export FORMAT_COMPILER_TARGET="$FORMAT_COMPILER_TARGET-cortexa8"
[[ "${CORTEX_A9}" ]] && echo '=== Cortex A9 opts enabled... ===' && export FORMAT_COMPILER_TARGET="$FORMAT_COMPILER_TARGET-cortexa9"
[[ "${ARM_HARDFLOAT}" ]] && echo '=== ARM hardfloat ABI enabled... ===' && export FORMAT_COMPILER_TARGET="$FORMAT_COMPILER_TARGET-hardfloat"
[[ "${ARM_SOFTFLOAT}" ]] && echo '=== ARM softfloat ABI enabled... ===' && export FORMAT_COMPILER_TARGET="$FORMAT_COMPILER_TARGET-softfloat"
[[ "$X86" ]] && echo '=== x86 CPU detected... ==='
[[ "$X86" ]] && [[ "$X86_64" ]] && echo '=== x86_64 CPU detected... ==='
2014-07-13 19:54:37 -04:00
[[ "${IOS}" ]] && echo '=== iOS =='
echo "$FORMAT_COMPILER_TARGET"
echo "$FORMAT_COMPILER_TARGET_ALT"
RESET_FORMAT_COMPILER_TARGET=$FORMAT_COMPILER_TARGET
RESET_FORMAT_COMPILER_TARGET_ALT=$FORMAT_COMPILER_TARGET_ALT
# FIXME: We should use the theos toolchain without their make system which is
# buggy on Linux and doesn't do what we want anyway. It'd remove need
# for this and other hacks.
CORE_PREFIX=""
CORE_SUFFIX="_libretro${FORMAT}.$FORMAT_EXT"
if [ "$platform" = "theos_ios" ]; then
CORE_PREFIX="objs/obj/"
fi
2015-11-05 15:09:50 -05:00
post_error_log() {
error=`cat $WORKDIR/log/$1.log | tail -n 100`
2019-09-13 05:51:25 -04:00
haste=`curl -s -XPOST http://paste.libretro.com/ -d"$error"`
2015-11-05 15:09:50 -05:00
haste=`echo $haste | cut -d"\"" -f4`
2019-09-13 05:51:25 -04:00
echo "$1: [status: fail ] (platform: $FORMAT_COMPILER_TARGET) LOG: http://paste.libretro.com/$haste"
2015-11-05 15:09:50 -05:00
}
build_summary_log() {
2015-02-23 01:28:29 -05:00
# Trailing spaces are intentional here
if [ "$1" -eq "0" ]; then
2015-03-26 13:50:29 -04:00
export build_success="$build_success$2 "
else
2015-03-26 13:50:29 -04:00
export build_fail="$build_fail$2 "
2015-11-05 15:09:50 -05:00
#post_error_log $2
fi
}
2015-03-10 14:21:54 -04:00
copy_core_to_dist() {
[ -z "$1" ] && return 1
dest="${2:-$1}"
if [ "$FORMAT_ABI_ANDROID" = "yes" ]; then
echo_cmd "cp \"$CORE_PREFIX$1$CORE_SUFFIX\" \"$RARCH_DIST_DIR/${dest}_libretro_android.so\""
else
echo_cmd "cp \"$CORE_PREFIX$1$CORE_SUFFIX\" \"$RARCH_DIST_DIR/$dest$CORE_SUFFIX\""
fi
2015-03-10 14:21:54 -04:00
ret=$?
build_summary_log $ret "$dest"
return $ret
}
build_should_skip() {
[ -z "$SKIP_UNCHANGED" ] && return 1
[ -z "$BUILD_REVISIONS_DIR" ] && BUILD_REVISIONS_DIR="$WORKDIR/build-revisions"
build_revision_file="$BUILD_REVISIONS_DIR/$1"
[ ! -r "$build_revision_file" ] && return 1
read previous_revision < "$build_revision_file"
[ "$previous_revision" != "$(fetch_revision $2)" ] && return 1
return 0
}
build_save_revision() {
[ -z "$SKIP_UNCHANGED" ] && return
[ "$1" != "0" ] && return
echo $(fetch_revision) > "$BUILD_REVISIONS_DIR/$2"
}
check_opengl() {
if [ "$BUILD_LIBRETRO_GL" ]; then
if [ "$ENABLE_GLES" ]; then
echo '=== OpenGL ES enabled ==='
export FORMAT_COMPILER_TARGET="$FORMAT_COMPILER_TARGET-gles"
export FORMAT_COMPILER_TARGET_ALT="$FORMAT_COMPILER_TARGET"
else
echo '=== OpenGL enabled ==='
export FORMAT_COMPILER_TARGET="$FORMAT_COMPILER_TARGET-opengl"
export FORMAT_COMPILER_TARGET_ALT="$FORMAT_COMPILER_TARGET"
fi
else
echo '=== OpenGL disabled in build ==='
return 1
fi
return 0
}
2013-07-13 18:10:43 -04:00
reset_compiler_targets() {
export FORMAT_COMPILER_TARGET=$RESET_FORMAT_COMPILER_TARGET
export FORMAT_COMPILER_TARGET_ALT=$RESET_FORMAT_COMPILER_TARGET_ALT
}
2015-02-06 07:00:22 -05:00
# $1 is corename
# $2 is subcorename
# $3 is subdir. In case there is no subdir, enter "." here
# $4 is Makefile name
# $5 is preferred platform
build_libretro_generic_makefile_subcore() {
build_dir="$WORKDIR/libretro-$1"
if [ -d "$build_dir" ]; then
echo "=== Building $2 ==="
2015-02-22 23:29:29 -05:00
echo_cmd "cd \"$build_dir/$3\""
if [ -z "$NOCLEAN" ]; then
2015-02-23 01:28:29 -05:00
echo_cmd "$MAKE -f \"$4\" platform=$5 -j$JOBS clean" || die "Failed to clean $2"
fi
2015-02-23 01:28:29 -05:00
echo_cmd "$MAKE -f $4 platform=$5 -j$JOBS" || die "Failed to build $2"
2015-03-10 14:21:54 -04:00
copy_core_to_dist "$2"
fi
2015-02-06 07:00:22 -05:00
}
2015-02-12 22:13:25 -05:00
build_libretro_generic() {
2015-02-22 23:29:29 -05:00
echo_cmd "cd \"$5/$2\""
2015-02-06 07:00:22 -05:00
if [ -z "$NOCLEAN" ]; then
2015-02-23 01:28:29 -05:00
echo_cmd "$MAKE -f \"$3\" platform=\"$4\" \"-j$JOBS\" clean" || die "Failed to clean $1"
fi
echo_cmd "$MAKE -f \"$3\" platform=\"$4\" $COMPILER \"-j$JOBS\"" || die "Failed to build $1"
2015-02-06 07:00:22 -05:00
}
# build_libretro_generic_makefile
#
# $1 Name of the core
# $2 Subdirectory of makefile (use "." for none)
# $3 Name of makefile
# $4 Either FORMAT_COMPILER_TARGET or an alternative
# $5 Skip copying (for cores that don't produce exactly one core)
2015-02-12 22:13:25 -05:00
build_libretro_generic_makefile() {
build_dir="$WORKDIR/libretro-$1"
if build_should_skip $1 "$build_dir"; then
echo "Core $1 is already built, skipping..."
return
fi
if [ -d "$build_dir" ]; then
echo "=== Building $1 ==="
build_libretro_generic $1 "$2" "$3" $4 "$build_dir"
if [ -z "$5" ]; then
copy_core_to_dist $1
build_save_revision $? $1
fi
else
echo "$1 not fetched, skipping ..."
fi
2015-02-12 22:13:25 -05:00
}
2015-02-26 17:43:29 -05:00
# build_makefile
#
# $core_build_subdir Subdir of the makefile (if any)
# $core_build_makefile Name of the makefile (if not {GNUm,m,M}akefile)
# $core_build_args Extra arguments to make
# $core_build_platform Usually some variant of $FORMAT_COMPILER_TARGET
# $core_build_cores A list of cores produced by the builds
2015-02-26 17:43:29 -05:00
build_makefile() {
[ -n "$core_build_subdir" ] && core_build_subdir="/$core_build_subdir"
make_cmdline="$MAKE"
if [ -n "$core_build_makefile" ]; then
make_cmdline="$make_cmdline -f $core_build_makefile"
fi
# TODO: Do $platform type stuff better (requires modding each core)
make_cmdline="$make_cmdline platform=\"$core_build_platform\""
2015-02-26 17:43:29 -05:00
2016-02-05 09:45:48 -05:00
[ -n "$STATIC_LINKING" ] && make_cmdline="$make_cmdline STATIC_LINKING=1"
2015-02-26 17:43:29 -05:00
[ -n "$JOBS" ] && make_cmdline="$make_cmdline -j$JOBS"
[ -n "$DEBUG" ] && make_cmdline="$make_cmdline DEBUG=$DEBUG"
2015-02-26 17:43:29 -05:00
build_dir="$WORKDIR/$core_dir$core_build_subdir"
if build_should_skip $1 "$build_dir"; then
echo "Core $1 is already built, skipping..."
return
fi
if [ -d "$build_dir" ]; then
echo_cmd "cd \"$build_dir\""
2015-03-12 10:41:03 -04:00
$core_build_configure
2015-02-26 17:43:29 -05:00
if [ -z "$NOCLEAN" ]; then
$core_build_preclean
echo_cmd "$make_cmdline $core_build_args clean"
2015-02-26 17:43:29 -05:00
fi
make_cmdline="$make_cmdline $COMPILER"
2015-03-12 10:41:03 -04:00
$core_build_prebuild
echo_cmd "$make_cmdline $core_build_args"
2015-02-26 17:43:29 -05:00
2015-03-12 10:41:03 -04:00
# TODO: Make this a separate stage/package rule
$core_build_prepkg
for a in $core_build_cores; do
copy_core_to_dist ${core_build_products:+$core_build_products/}$a $a
done
2015-02-26 17:43:29 -05:00
else
echo "$1 not fetched, skipping ..."
fi
}
# build_cmake
#
# $core_build_subdir Subdir of the makefile (if any)
# $core_build_args Extra arguments to cmake
# $core_build_extradir Location of the binary under build/
# $core_build_cores A list of cores produced by the builds
build_cmake() {
[ -n "$core_build_subdir" ] && core_build_subdir="/$core_build_subdir"
make_cmdline="cmake"
build_dir="$WORKDIR/$core_dir$core_build_subdir"
if build_should_skip $1 "$build_dir"; then
echo "Core $1 is already built, skipping..."
return
fi
if [ -d "$build_dir" ]; then
echo_cmd "cd \"$build_dir\""
$core_build_configure
if [ -z "$NOCLEAN" ]; then
$core_build_preclean
echo_cmd "$make_cmdline --build build --target clean"
fi
make_cmdline1="$make_cmdline $core_build_args . -Bbuild"
make_cmdline2="$make_cmdline --build build/ --target $core_cmake_target --config Release -- "
[ -n "$JOBS" ] && make_cmdline2="$make_cmdline2 -j$JOBS"
[ -n "$DEBUG" ] && make_cmdline2="$make_cmdline2 DEBUG=$DEBUG"
$core_build_prebuild
echo_cmd "$make_cmdline1"
echo_cmd "$make_cmdline2"
# TODO: Make this a separate stage/package rule
$core_build_prepkg
for a in $core_build_cores; do
copy_core_to_dist ${core_build_products:+$core_build_products/}build/${core_build_extradir:-}$a $a
done
else
echo "$1 not fetched, skipping ..."
fi
}
2015-02-26 17:43:29 -05:00
# libretro_build_core: Build the given core using its build rules
#
# $1 Name of the core to build
libretro_build_core() {
local opengl_type
if [ -n "${LIBRETRO_LOG_MODULE}" ]; then
printf -v log_module "$LIBRETRO_LOG_DIR/$LIBRETRO_LOG_MODULE" "$1"
[ -z "$LIBRETRO_LOG_APPEND" ] && : > "$log_module"
Implement log truncation, now ready for testing What (should) work): - LIBRETRO_DEVELOPER (default 1) to output all build progress - LIBRETRO_LOG_DIR (default $WORKDIR/log) to change WHERE logs get written. Useful for buildbots that have multiple WORKDIRs to put logs in roughly the same place. - LIBRETRO_LOG_SUPER (default libretro-super.log) to change the name of libretro-build.sh's log file. No log would be written if unset, but script-modules/log.sh sets it if unset for now. - LIBRETRO_LOG_CORE (default %s.log) to change the name pattern for a core log file. The %s is replaced with the "safe" core name used by libretro-super's rules. - LIBRETRO_LOG_APPEND (default ""), if set, would not clobber the log files the next time you ran libretro-super. Caution: mame's output is 34 megabytes on its own for a single successful build What doesn't work yet: - You should be able to unset LIBRETRO_LOG_SUPER and LIBRETRO_LOG_CORE and have your decision mean something. This is the #1 thing I must change, and I will do so in the next day or so. - We assume that if you want output to screen and log, you'll have the tee command. What if you don't? We choose log over screen in that case, but tee is such a trivial tool to implement, perhaps we should? - Currently logs lack date stamps. Bash's built-in printf has a way to do this, but Apple STUPIDLY disables it because Apple. Turns out that bash 2.05a didn't have the feature anyway. You may not have the UNIX date command on Windows if you're somehow running bash from cmd.exe. Worse, you have a command of the same name that requires a /t argument to do half of what date does on UNIX. Running into limits of bash here, easily solved using most anything else.
2015-03-27 22:31:19 -04:00
fi
2015-03-27 21:31:51 -04:00
eval "core_name=\${libretro_${1}_name:-$1}"
echo "$(color 34)=== $(color 1)$core_name$(color)"
2015-03-27 21:31:51 -04:00
lecho "=== $core_name"
2015-02-26 17:43:29 -05:00
eval "core_build_rule=\${libretro_${1}_build_rule:-generic_makefile}"
eval "core_dir=\${libretro_${1}_dir:-libretro-$1}"
2015-02-26 17:43:29 -05:00
eval "core_build_opengl=\$libretro_${1}_build_opengl"
if [ -n "$core_build_opengl" ]; then
if [[ "$core_build_opengl" = "yes" || "$core_build_opengl" = "optional" ]]; then
if [ -n "$BUILD_LIBRETRO_GL" ]; then
if [ -n "$ENABLE_GLES" ]; then
opengl_type="-gles"
else
opengl_type="-opengl"
fi
else
if [ "$core_build_opengl" = "yes" ]; then
echo "$1 requires OpenGL (which is disabled), skipping..."
return 0
fi
fi
else
echo "libretro_build_core:Unknown OpenGL setting for $1: \"$core_build_opengl\"."
return 1
fi
fi
2015-03-27 21:31:51 -04:00
echo "Building ${1}..."
lecho "Building ${1}..."
if [ -n "$log_module" ]; then
exec 6>&1
echo "Building ${1}..." >> "$log_module"
# TODO: Possibly a shell function for tee?
if [[ -n "$LIBRETRO_DEVELOPER" && -n "${cmd_tee:=$(find_tool "tee")}" ]]; then
exec > >($cmd_tee -a "$log_module")
else
exec > "$log_module"
fi
fi
case "$core_build_rule" in
generic_makefile)
# As of right now, only configure is used for now...
if [ "$(type -t libretro_${1}_configure 2> /dev/null)" = "function" ]; then
eval "core_configure=libretro_${1}_configure"
else
eval "core_configure=do_nothing"
fi
eval "core_build_makefile=\$libretro_${1}_build_makefile"
eval "core_build_subdir=\$libretro_${1}_build_subdir"
eval "core_build_args=\$libretro_${1}_build_args"
# TODO: Really, change how all of this is done...
eval "core_build_platform=\${libretro_${1}_build_platform:-$FORMAT_COMPILER_TARGET}$opengl_type"
eval "core_build_cores=\${libretro_${1}_build_cores:-$1}"
eval "core_build_products=\$libretro_${1}_build_products"
build_makefile $1 2>&1
;;
cmake)
# As of right now, only configure is used for now...
if [ "$(type -t libretro_${1}_configure 2> /dev/null)" = "function" ]; then
eval "core_configure=libretro_${1}_configure"
else
eval "core_configure=do_nothing"
fi
eval "core_build_subdir=\$libretro_${1}_build_subdir"
eval "core_build_extradir=\$libretro_${1}_build_extradir"
eval "core_build_args=\$libretro_${1}_build_args"
# TODO: Really, change how all of this is done...
eval "core_build_platform=\${libretro_${1}_build_platform:-$FORMAT_COMPILER_TARGET}$opengl_type"
eval "core_build_cores=\${libretro_${1}_build_cores:-$1}"
eval "core_build_products=\$libretro_${1}_build_products"
eval "core_cmake_target=${1}_libretro"
build_cmake $1 2>&1
;;
legacy)
eval "core_build_legacy=\$libretro_${1}_build_legacy"
if [ -n "$core_build_legacy" ]; then
echo "Warning: $1 hasn't been ported to a modern build rule yet."
echo " Will build it using legacy \"$core_build_legacy\"..."
$core_build_legacy 2>&1
fi
;;
none)
echo "Don't have a build rule for $1, skipping..."
;;
*)
echo "libretro_build_core:Unknown build rule for $1: \"$core_build_rule\"." >&2
exit 1
;;
esac
if [ -n "$log_module" ]; then
exec 1>&6 6>&-
2015-03-27 21:31:51 -04:00
fi
2015-02-26 17:43:29 -05:00
}
build_libretro_test() {
2015-03-10 14:21:54 -04:00
build_dir="$WORKDIR/retroarch"
if build_should_skip "test" "$build_dir"; then
2019-05-11 16:13:47 -04:00
echo 'Core test is already built, skipping...'
return
fi
if [ -d "$build_dir" ]; then
2019-05-11 16:13:47 -04:00
echo '=== Building RetroArch test cores ==='
if check_opengl; then
2015-07-29 21:35:10 -04:00
build_libretro_generic "retroarch" "cores/libretro-test-gl" "Makefile" $FORMAT_COMPILER_TARGET "$build_dir"
copy_core_to_dist "testgl"
fi
2015-07-29 21:35:10 -04:00
build_libretro_generic "retroarch" "cores/libretro-test" "Makefile" $FORMAT_COMPILER_TARGET "$build_dir"
copy_core_to_dist "test"
# TODO: Check for more than test here...
build_save_revision $? "test"
else
echo "$1 not fetched, skipping ..."
fi
2015-02-12 22:13:25 -05:00
}
2015-03-27 19:45:38 -04:00
summary() {
2015-03-27 21:31:51 -04:00
# fmt is external and may not be available
fmt_output="$(find_tool "fmt")"
local num_success="$(numwords $build_success)"
local fmt_success="${fmt_output:+$(echo " $build_success" | $fmt_output)}"
local num_fail="$(numwords $build_fail)"
local fmt_fail="${fmt_output:+$(echo " $build_fail" | $fmt_output)}"
if [[ -z "$build_success" && -z "$build_fail" ]]; then
lsecho "No build actions performed."
return
fi
2015-03-27 19:45:38 -04:00
if [ -n "$build_success" ]; then
secho "$(color 32)$num_success core(s)$(color) successfully processed:"
lecho "$num_success core(s) successfully processed:"
lsecho "$fmt_success"
fi
if [ -n "$build_fail" ]; then
secho "$(color 31)$num_fail core(s)$(color) failed:"
lecho "$num_fail core(s) failed:"
lsecho "$fmt_fail"
fi
}
create_dist_dir() {
mkdir -p "$RARCH_DIST_DIR"
}
create_dist_dir