#!/bin/sh
#
# This script is used to build wxWidgets on Mac OS X in a way that pwsafe will
# run on as many MacOS versions as possible when built on that machine.  That
# also means the wxWidgets build generated by this script would depend on the
# compilers and SDKs supported on the version of OS X it is running on.
# 
# If was initially written for building wx2.8 on Snow Leopard such that the
# pwsafe binary would run on OS X 10.4+.  It followed the documentation here:
# http://wiki.wxwidgets.org/Development:_wxMac
#
# See the sections "Building on Snow Leopard for Snow Leopard" and "Building on
# Snow Leopard for Snow Leopard"
#
# As of April 2023, this script (and the release build) have been updated to
# mainly support macOS 10.14 and above, Xcode 14.x, and wxWidgets 3.2.1 and
# above.  As a result, references and procedures for older platforms have
# fallen out of maintenance.  If an older version is needed, it might be best
# to pull it from an older GitHub release tag.
#
# For more information on using this script, see: README.MAC.DEVELOPERS.md
#

# Build release configuration by default
WX_DEBUG_FLAG=--disable-debug

# If unspecified, assume the user is building wxWidgets inside a subdir of its root dir
CONF_SCRIPT=../configure

# GUI toolkit to use.  Could be "carbon" or "cocoa".
TOOLKIT=undefined

# In a dry run, we just echo the commands
DRY_RUN=

# The 10.4 SDK path, if not in the default location (i.e. /Developer/SDKs/MacOSX10.4u.sdk/
SDKPATH=

# This is where gcc, g++ and ld, required to build with the 10.4 SDK, should be located.
TOOLCHAIN_DIR=

# "make install" base directory.  For safety, we set it to pwd and don't recommend using "make install".
# You might want to use /usr/local if you intend to install the resulting wxWidgwts build.
WX_PREFIX=`pwd`

# Architectures to build, default comes from the workflow file but can be overriden
# here or with the -a option.
WX_ARCH=

# Build options for the ./configure command.  The defaults are taken from the workflow file
# but can be overriden here.  Setting this overrides all other options, specify all of the configure
# options here.
CONF_OPTS=

# Workflow file for the GitHub release build.  We will fetch some parameters from it.
# Can be overriden with the -w option.
WORKFLOW=`dirname $0`/../.github/workflows/macos-latest.yml



usage() {
    cat <<__END_USAGE__

`basename $1`: Runs wxWidgets configure script appropriately for building pwsafe
              You then run make to actually build it

Usage (all flags are optional):
	-a (arm64|x86_64)
	    Build for a single, specified architecture.  The default is to build a Universal Binary.

	-d
	    Create Debug configuration.  Absence of this flag creates the Release configuration

	-c <path to wxWidgets configure script>
	    Default is to assume it is in the parent directory of current dir

	-t (carbon|cocoa)
	    The OS X GUI toolkit to be used, either "carbon" or "cocoa".  wx2.8 only supports carbon

	-n
	    Dry run.  Will just echo the command(s) to be used to build wxWidgets

	-k <SDK directory path>
	    You can get the path to any installed SDK that Xcode is aware of like this
	    xcodebuild -version -sdk macosx10.9 Path

     -w <Path to macos-latest.yml>
        Path to the GitHub workflow file from which to retrieve build parameters.  The default
        is relative to the location of this script.

	-T <toolchain dir>
	    Directory where gcc-4.0, g++4.0, etc. should be.  Only required for building wx2.8 on OS X 10.9
__END_USAGE__
}

error() {
	echo "$*" 1>&2
	exit 1
}



while getopts "a:dc:t:nk:T:w:" opt; do
	case $opt in
		a)
			case "$OPTARG" in
				arm64|x86_64) WX_ARCH=$OPTARG;;
				*) error "Unexpected architecture: \"$OPTARG\". Its either \"arm64\" or \"x86_64\" (default is both)"
				;;
			esac
			;;
		d)
			WX_DEBUG_FLAG="--enable-debug --enable-debug_info"
			;;
		c)
			if [ -x $OPTARG ]
			then
				CONF_SCRIPT=$OPTARG
			else
				error "Missing or non-executable configure script: $OPTARG"
			fi
			;;
		t)
			case "$OPTARG" in
				carbon) TOOLKIT=CARBON;;
				cocoa)  TOOLKIT=COCOA;;
				*)      error "Unexpected toolkit: \"$OPTARG\". Its either \"carbon\" or \"cocoa\" (default)"
				;;
			esac
			;;	
		k)
			if [ -d $OPTARG ]
			then
				SDKPATH=$OPTARG
			else
				error "Invalid directory passed for SDK path: $OPTARG"
			fi
			;;
		T)
			if [ -d $OPTARG ]
			then
				TOOLCHAIN_DIR=$OPTARG
			else
				error "Invalid directory passed for toolchain dir: $OPTARG"
			fi
			;;
		n)
			DRY_RUN="echo "
			;;
        w)
            WORKFLOW=$OPTARG
            ;;
		?)
			usage $0
			exit 1
			;;
	esac
done

# Get the version of wxWidgets source we are building
WX_VER=`$CONF_SCRIPT -V | grep 'wxWidgets configure' | cut -d' ' -f3`

#
# This is to build the wxOSX/Cocoa version of wxWidgets, which is what is supported on macOS 10.10 and up.
# This code tries to build wxWidgets the same way the Github workflow builds the distribution. 
#
doCocoaBuild() {

    # If the user edited the CONF_OPTS variable, they are responsible for all of it.
    # Othewise, we build it from the GitHub workflow file and any command line options.
    if [ -z $CONF_OPTS ]
    then
        if [ ! -f $WORKFLOW ]
        then
            error "Cannot locate the workflow file: $WORKFLOW"
        fi
        # This is actually where 'make install' will put things.
        WX_BUILD_DIR=$WX_PREFIX

        # Fetch some parameters from the macos-latest.yaml workflow
        if [ -z $WX_ARCH ]
        then
            eval `grep WX_ARCH= $WORKFLOW | sed -E -e 's/^.*"(.*)".*$/\1/'`
        fi
        eval `grep MACOS_VER_MIN= $WORKFLOW | sed -E -e 's/^.*"(.*)".*$/\1/'`

        # The configure command in the workflow file uses the above variables.
        # This trick will expand them into the CONF_OPTS variable
        CONF_OPTS=`grep "./configure --enable-universal_binary=" $WORKFLOW | cut -w -f 3-`
        CONF_OPTS=`eval echo $CONF_OPTS`

        # This is about the only cocoa build customization we support because everything
        # else is taken care of via "deployment target" in pwsafe-xcode6.xcodeproj
        SDKFLAG=
        if [ -n "$SDKPATH" ]
        then
            SDKFLAG="--with-macosx-sdk=$SDKPATH"
        fi

        echo "=============================="
        echo "osx-build-wx options:"
        echo "WX_VER" = $WX_VER
        echo "WX_ARCH" = $WX_ARCH
        echo "WX_BUILD_DIR" = $WX_BUILD_DIR
        echo "WX_DEBUG_FLAG" = $WX_DEBUG_FLAG
        echo "MACOS_VER_MIN" = $MACOS_VER_MIN
        echo "SDKFLAG" = $SDKFLAG
        echo "CONF_OPTS" = $CONF_OPTS
        echo "=============================="
    else
        echo "=============================="
        echo "CONF_OPTS" = $CONF_OPTS
        echo "=============================="
    fi

	$DRY_RUN $CONF_SCRIPT $CONF_OPTS $SDKFLAG


# These are some old configure options used with 3.0.x, just for reference...
#                              $SDKFLAG                          \
#                              --with-osx_cocoa                  \
#                              --disable-shared                  \
#                              --enable-unicode                  \
#                              --enable-aui                      \
#                              --with-macosx-version-min=10.10   \
#                              $COMPATFLAG                       \
#                              --without-liblzma                 \
#                              --enable-cxx11                    \
#	                          --enable-universal-binary=`uname -m`   \
#                              $ZLIBFLAG

}

#
# This is old code that built wxOSX/Carbon for old versions of Pwsafe and macOS.
# This is no longer supported or tested an is almost certainly useless but 
# it's kept here as a reference just in case someone needs it.
#
doCarbonBuild() {
	# This might be required for 10.7 & 10.8 as well
	OSX_VER=`sw_vers -productVersion`
	if [ "$OSX_VER" = "10.9" -o "$OSX_VER" \> "10.9" ]
	then
		if [ -z "$TOOLCHAIN_DIR" ]
		then
			# This is where gcc-4.x etc. will be found
			TOOLCHAIN_DIR=/Developer/usr/bin
		fi
	fi

	# Homebrew include path
	if [ -d "/opt/homebrew/include" ]
	then
		# This is the HomeBrew default include path on arm64
		homebrew_path="-I/opt/homebrew/include"
	else
		if [ -d  "/usr/local/include" ]
		then
			# The default is where HomeBrew include files are installed on x86_64
			homebrew_path="-I/usr/local/include"
		else
			echo "Could not find path to HomeBrew include files"
			exit 1
		fi
	fi

    if [ -z "$SDKPATH" ]
    then
        SDKPATH=/Developer/SDKs/MacOSX10.4u.sdk
    fi

    if [ ! -d "$SDKPATH" ]
    then
        error "You must specify a valid SDK directory with Carbon headers/libs for building wxWidgets version $WX_VER on OS X $OSX_VER"
    fi

    CC=gcc-4.0
    CXX=g++-4.0
    LD=g++-4.0

    if [ -n "$TOOLCHAIN_DIR" ]
    then
        CC=$TOOLCHAIN_DIR/$CC
        CXX=$TOOLCHAIN_DIR/$CXX
        LD=$TOOLCHAIN_DIR/$LD
    fi

    # There is only one way to build wx2.8.  It doesn't require a "toolkit" flag
    # see http://wiki.wxwidgets.org/Development:_wxMac#Building_under_10.6_Snow_Leopard
    MIN_OSX_VER=`/usr/libexec/PlistBuddy -c "Print :DefaultProperties:MACOSX_DEPLOYMENT_TARGET" $SDKPATH/SDKSettings.plist`

    arch_flags="-arch `uname -m`"
    sdk_flags="-mmacosx-version-min=$MIN_OSX_VER -isysroot $SDKPATH"

    CFLAGS="     $arch_flags $sdk_flags"
    CXXFLAGS="   $arch_flags $sdk_flags $homebrew_path"
    CPPFLAGS="               $sdk_flags"
    OBJCFLAGS="  $arch_flags $sdk_flags"
    OBJCXXFLAGS="$arch_flags $sdk_flags"

	$DRY_RUN $CONF_SCRIPT --prefix=`pwd`            \
                            CC=$CC                      \
                            CXX=$CXX                    \
                            LD=$LD                      \
                            CFLAGS="$CFLAGS"            \
                            CXXFLAGS="$CXXFLAGS"        \
                            CPPFLAGS="$CPPFLAGS"        \
                            LDFLAGS="$arch_flags"       \
                            OBJCFLAGS="$OBJCFLAGS"      \
                            OBJCXXFLAGS="$OBJCXXFLAGS"  \
                            $WX_DEBUG_FLAG              \
                            --disable-shared            \
                            --disable-compat24          \
                            --enable-unicode            \
                            --enable-aui                \
                            --enable-universal-binary=`uname -m`   \
                            --with-osx_carbon           \
                            --with-macosx-sdk=$SDKPATH  \
                            --with-macosx-version-min=$MIN_OSX_VER
}

if [ "$WX_VER" \< "2.9.0" ]
then
	echo Building wxWidgets 2.8.X \(or earlier\): $WX_VER on OSX $OSX_VER
	if [ "$TOOLKIT" = "COCOA" ]
	then
		error wxWidgets $WX_VER does not support Cocoa
	else
		doCarbonBuild
	fi
else
	echo Building wxWidgets 3: $WX_VER on OSX $OSX_VER

	if [ "$TOOLKIT" = "CARBON" ]
	then
		echo Please let PasswordSafe devs know why supporting carbon builds of wx3 makes sense
	else
		doCocoaBuild
	fi
fi
