@ -27,37 +27,41 @@
# Need to set the path or we won't find cmake
PATH = ${ PATH } :/usr/local/bin:/opt/homebrew/bin:/sbin/md5
SHOULD_AUTO_INIT_SUBMODULES = ${ 1 :- false }
exec 3>& 1 # Save original stdout
# Ensure the build directory exists (in case we need it before XCode creates it)
mkdir -p " ${ TARGET_BUILD_DIR } "
mkdir -p " ${ TARGET_BUILD_DIR } /libSessionUtil "
# Remove any old build errors
rm -rf " ${ TARGET_BUILD_DIR } /libsession_util_error.log "
rm -rf " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_output.log "
# Restore stdout and stderr and redirect it to the 'libsession_util_output.log' file
exec & > " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_output.log "
# Define a function to echo a message.
function echo_message( ) {
exec 1>& 3 # Restore stdout
echo " $1 "
exec >> " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_output.log " # Redirect all output to the log file
}
echo_message "info: Validating build requirements"
# First ensure cmake is installed (store the error in a log and exit with a success status - xcode will output the error)
echo "info: Validating build requirements"
set -x
# Ensure the build directory exists (in case we need it before XCode creates it)
mkdir -p " ${ TARGET_BUILD_DIR } "
if ! which cmake > /dev/null; then
touch " ${ TARGET_BUILD_DIR } /libsession_util_error.log "
echo "error: cmake is required to build, please install (can install via homebrew with 'brew install cmake')."
echo "error: cmake is required to build, please install (can install via homebrew with 'brew install cmake')." > " ${ TARGET_BUILD_DIR } /libsession_util_error.log "
echo_message "error: cmake is required to build, please install (can install via homebrew with 'brew install cmake')."
exit 0
fi
# Check if we have the `LibSession-Util` submodule checked out and if not (depending on the 'SHOULD_AUTO_INIT_SUBMODULES' argument) perform the checkout
if [ ! -d " ${ SRCROOT } /LibSession-Util " ] || [ ! -d " ${ SRCROOT } /LibSession-Util/src " ] || [ ! " $( ls -A " ${ SRCROOT } /LibSession-Util " ) " ] ; then
if [ " ${ SHOULD_AUTO_INIT_SUBMODULES } " != "false" ] & command -v git >/dev/null 2>& 1; then
echo "info: LibSession-Util submodule doesn't exist, resetting and checking out recusively now"
git submodule foreach --recursive git reset --hard
git submodule update --init --recursive
echo "info: Checkout complete"
else
touch " ${ TARGET_BUILD_DIR } /libsession_util_error.log "
echo "error: Need to fetch LibSession-Util submodule (git submodule update --init --recursive)."
echo "error: Need to fetch LibSession-Util submodule (git submodule update --init --recursive)." > " ${ TARGET_BUILD_DIR } /libsession_util_error.log "
exit 0
fi
echo_message "error: Need to fetch LibSession-Util submodule (git submodule update --init --recursive)."
exit 0
else
are_submodules_valid( ) {
local PARENT_PATH = $1
@ -82,7 +86,7 @@ else
# If the child path doesn't exist then it's invalid
if [ ! -d " ${ PARENT_PATH } / ${ CHILD_PATH } " ] ; then
echo " info: Submodule ' ${ RELATIVE_PATH } / ${ CHILD_PATH } ' doesn't exist. "
echo_message " info: Submodule ' ${ RELATIVE_PATH } / ${ CHILD_PATH } ' doesn't exist. "
return 1
fi
@ -90,7 +94,7 @@ else
local RESULT = $?
if [ " ${ RESULT } " -eq 1 ] ; then
echo " info: Submodule ' ${ RELATIVE_PATH } / ${ CHILD_PATH } ' is in an invalid state. "
echo_message " info: Submodule ' ${ RELATIVE_PATH } / ${ CHILD_PATH } ' is in an invalid state. "
return 1
fi
done
@ -104,18 +108,8 @@ else
HAS_INVALID_SUBMODULE = $?
if [ " ${ HAS_INVALID_SUBMODULE } " -eq 1 ] ; then
if [ " ${ SHOULD_AUTO_INIT_SUBMODULES } " != "false" ] && command -v git >/dev/null 2>& 1; then
echo "info: Submodules are in an invalid state, resetting and checking out recusively now"
cd " ${ SRCROOT } /LibSession-Util "
git submodule foreach --recursive git reset --hard
git submodule update --init --recursive
echo "info: Checkout complete"
else
touch " ${ TARGET_BUILD_DIR } /libsession_util_error.log "
echo "error: Submodules are in an invalid state, please delete 'LibSession-Util' and run 'git submodule update --init --recursive'."
echo "error: Submodules are in an invalid state, please delete 'LibSession-Util' and run 'git submodule update --init --recursive'." > " ${ TARGET_BUILD_DIR } /libsession_util_error.log "
exit 0
fi
echo_message "error: Submodules are in an invalid state, please delete 'LibSession-Util' and run 'git submodule update --init --recursive'."
exit 0
fi
fi
@ -125,49 +119,143 @@ echo "info: Checking for changes to source"
NEW_SOURCE_HASH = $( find " ${ SRCROOT } /LibSession-Util/src " -type f -exec md5 { } + | awk '{print $NF}' | sort | md5 | awk '{print $NF}' )
NEW_HEADER_HASH = $( find " ${ SRCROOT } /LibSession-Util/include " -type f -exec md5 { } + | awk '{print $NF}' | sort | md5 | awk '{print $NF}' )
if [ -f " ${ TARGET_BUILD_DIR } /libsession_util_source_hash.log " ] ; then
read -r OLD_SOURCE_HASH < " ${ TARGET_BUILD_DIR } /libsession_util_source_hash.log "
if [ -f " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_source_hash.log " ] ; then
read -r OLD_SOURCE_HASH < " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_source_hash.log "
fi
if [ -f " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_header_hash.log " ] ; then
read -r OLD_HEADER_HASH < " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_header_hash.log "
fi
if [ -f " ${ TARGET_BUILD_DIR } /libsession_util_header_hash.log " ] ; then
read -r OLD_HEADER_HASH < " ${ TARGET_BUILD_DIR } /libsession_util_header_hash.log "
if [ -f " ${ TARGET_BUILD_DIR } /lib SessionUtil/libsession_util_archs .log" ] ; then
read -r OLD_ARCHS < " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_archs .log"
fi
if [ -f " ${ TARGET_BUILD_DIR } /libsession_util_archs.log " ] ; then
read -r OLD_ARCHS < " ${ TARGET_BUILD_DIR } /libsession_util_archs.log "
# If all of the hashes match, the archs match and there is a library file then we can just stop here
if [ " ${ NEW_SOURCE_HASH } " = = " ${ OLD_SOURCE_HASH } " ] && [ " ${ NEW_HEADER_HASH } " = = " ${ OLD_HEADER_HASH } " ] && [ " ${ ARCHS [*] } " = = " ${ OLD_ARCHS } " ] && [ -f " ${ TARGET_BUILD_DIR } /libSessionUtil/libSessionUtil.a " ] ; then
echo_message "info: Build is up-to-date"
exit 0
fi
# Start the libSession-util build if it doesn't already exists
if [ " ${ NEW_SOURCE_HASH } " != " ${ OLD_SOURCE_HASH } " ] || [ " ${ NEW_HEADER_HASH } " != " ${ OLD_HEADER_HASH } " ] || [ " ${ ARCHS [*] } " != " ${ OLD_ARCHS } " ] || [ ! -d " ${ TARGET_BUILD_DIR } /libsession-util.xcframework " ] ; then
echo "info: Build is not up-to-date - creating new build"
echo ""
# If any of the above differ then we need to rebuild
echo_message "info: Build is not up-to-date - creating new build"
# Remove any existing build files (just to be safe)
rm -rf " ${ TARGET_BUILD_DIR } /libsession-util.a "
rm -rf " ${ TARGET_BUILD_DIR } /libsession-util.xcframework "
rm -rf " ${ BUILD_DIR } /libsession-util.xcframework "
# Import settings from XCode (defaulting values if not present)
VALID_SIM_ARCHS = ( arm64 x86_64)
VALID_DEVICE_ARCHS = ( arm64)
VALID_SIM_ARCH_PLATFORMS = ( SIMULATORARM64 SIMULATOR64)
VALID_DEVICE_ARCH_PLATFORMS = ( OS64)
# Trigger the new build
cd " ${ SRCROOT } /LibSession-Util "
result = $( ./utils/ios.sh "libsession-util" false )
OUTPUT_DIR = " ${ TARGET_BUILD_DIR } "
IPHONEOS_DEPLOYMENT_TARGET = ${ IPHONEOS_DEPLOYMENT_TARGET }
ENABLE_BITCODE = ${ ENABLE_BITCODE }
if [ $? -ne 0 ] ; then
touch " ${ TARGET_BUILD_DIR } /libsession_util_error.log "
echo " error: Failed to build libsession-util (See details in ' ${ TARGET_BUILD_DIR } /pre-action-output.log'). "
echo " error: Failed to build libsession-util (See details in ' ${ TARGET_BUILD_DIR } /pre-action-output.log'). " > " ${ TARGET_BUILD_DIR } /libsession_util_error.log "
exit 0
fi
# Generate the target architectures we want to build for
TARGET_ARCHS = ( )
TARGET_PLATFORMS = ( )
TARGET_SIM_ARCHS = ( )
TARGET_DEVICE_ARCHS = ( )
# Save the updated source hash to disk to prevent rebuilds when there were no changes
echo " ${ NEW_SOURCE_HASH } " > " ${ TARGET_BUILD_DIR } /libsession_util_source_hash.log "
echo " ${ NEW_HEADER_HASH } " > " ${ TARGET_BUILD_DIR } /libsession_util_header_hash.log "
echo " ${ ARCHS [*] } " > " ${ TARGET_BUILD_DIR } /libsession_util_archs.log "
echo ""
echo "info: Build complete"
else
echo "info: Build is up-to-date"
if [ -z $PLATFORM_NAME ] || [ $PLATFORM_NAME = "iphonesimulator" ] ; then
for i in " ${ !VALID_SIM_ARCHS[@] } " ; do
ARCH = " ${ VALID_SIM_ARCHS [ $i ] } "
ARCH_PLATFORM = " ${ VALID_SIM_ARCH_PLATFORMS [ $i ] } "
if [ [ " ${ ARCHS [*] } " = ~ " ${ ARCH } " ] ] ; then
TARGET_ARCHS += ( " sim- ${ ARCH } " )
TARGET_PLATFORMS += ( " ${ ARCH_PLATFORM } " )
TARGET_SIM_ARCHS += ( " sim- ${ ARCH } " )
fi
done
fi
if [ -z $PLATFORM_NAME ] || [ $PLATFORM_NAME = "iphoneos" ] ; then
for i in " ${ !VALID_DEVICE_ARCHS[@] } " ; do
ARCH = " ${ VALID_DEVICE_ARCHS [ $i ] } "
ARCH_PLATFORM = " ${ VALID_DEVICE_ARCH_PLATFORMS [ $i ] } "
if [ [ " ${ ARCHS [*] } " = ~ " ${ ARCH } " ] ] ; then
TARGET_ARCHS += ( " ios- ${ ARCH } " )
TARGET_PLATFORMS += ( " ${ ARCH_PLATFORM } " )
TARGET_DEVICE_ARCHS += ( " ios- ${ ARCH } " )
fi
done
fi
# Build the individual architectures
for i in " ${ !TARGET_ARCHS[@] } " ; do
build = " ${ TARGET_BUILD_DIR } /libSessionUtil/ ${ TARGET_ARCHS [ $i ] } "
platform = " ${ TARGET_PLATFORMS [ $i ] } "
echo_message " Building ${ TARGET_ARCHS [ $i ] } for $platform in $build "
cd " ${ SRCROOT } /LibSession-Util "
./utils/static-bundle.sh " $build " "" \
-DCMAKE_TOOLCHAIN_FILE= " ${ SRCROOT } /LibSession-Util/external/ios-cmake/ios.toolchain.cmake " \
-DPLATFORM= $platform \
-DDEPLOYMENT_TARGET= $IPHONEOS_DEPLOYMENT_TARGET \
-DENABLE_BITCODE= $ENABLE_BITCODE
if [ $? -ne 0 ] ; then
LAST_OUTPUT = $( tail -n 4 " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_output.log " | head -n 1)
echo_message " error: $LAST_OUTPUT "
exit 1
fi
done
# Remove the old static library file
rm -rf " ${ TARGET_BUILD_DIR } /libSessionUtil/libSessionUtil.a "
rm -rf " ${ TARGET_BUILD_DIR } /libSessionUtil/Headers "
# If needed combine simulator builds into a multi-arch lib
if [ " ${# TARGET_SIM_ARCHS [@] } " -eq "1" ] ; then
# Single device build
cp " ${ TARGET_BUILD_DIR } /libSessionUtil/ ${ TARGET_SIM_ARCHS [0] } /libsession-util.a " " ${ TARGET_BUILD_DIR } /libSessionUtil/libSessionUtil.a "
elif [ " ${# TARGET_SIM_ARCHS [@] } " -gt "1" ] ; then
# Combine multiple device builds into a multi-arch lib
echo_message "info: Built multiple architectures, merging into single static library"
lipo -create " ${ TARGET_BUILD_DIR } /libSessionUtil " /sim-*/libsession-util.a -output " ${ TARGET_BUILD_DIR } /libSessionUtil/libSessionUtil.a "
fi
# If needed combine device builds into a multi-arch lib
if [ " ${# TARGET_DEVICE_ARCHS [@] } " -eq "1" ] ; then
cp " ${ TARGET_BUILD_DIR } /libSessionUtil/ ${ TARGET_DEVICE_ARCHS [0] } /libsession-util.a " " ${ TARGET_BUILD_DIR } /libSessionUtil/libSessionUtil.a "
elif [ " ${# TARGET_DEVICE_ARCHS [@] } " -gt "1" ] ; then
# Combine multiple device builds into a multi-arch lib
echo_message "info: Built multiple architectures, merging into single static library"
lipo -create " ${ TARGET_BUILD_DIR } /libSessionUtil " /ios-*/libsession-util.a -output " ${ TARGET_BUILD_DIR } /libSessionUtil/libSessionUtil.a "
fi
# Save the updated hashes to disk to prevent rebuilds when there were no changes
echo " ${ NEW_SOURCE_HASH } " > " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_source_hash.log "
echo " ${ NEW_HEADER_HASH } " > " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_header_hash.log "
echo " ${ ARCHS [*] } " > " ${ TARGET_BUILD_DIR } /libSessionUtil/libsession_util_archs.log "
echo_message "info: Build complete"
# Copy the headers across
echo_message "info: Copy headers and prepare modulemap"
mkdir -p " ${ TARGET_BUILD_DIR } /libSessionUtil/Headers "
cp -r " ${ SRCROOT } /LibSession-Util/include/session " " ${ TARGET_BUILD_DIR } /libSessionUtil/Headers "
# The 'module.modulemap' is needed for XCode to be able to find the headers
modmap = " ${ TARGET_BUILD_DIR } /libSessionUtil/Headers/module.modulemap "
echo "module SessionUtil {" >" $modmap "
echo " module capi {" >>" $modmap "
for x in $( cd include && find session -name '*.h' ) ; do
echo " header \" $x \" " >>" $modmap "
done
echo -e " export *\n }" >>" $modmap "
if false; then
# If we include the cpp headers like this then Xcode will try to load them as C headers (which
# of course breaks) and doesn't provide any way to only load the ones you need (because this is
# Apple land, why would anything useful be available?). So we include the headers in the
# archive but can't let xcode discover them because it will do it wrong.
echo -e "\n module cppapi {" >>" $modmap "
for x in $( cd include && find session -name '*.hpp' ) ; do
echo " header \" $x \" " >>" $modmap "
done
echo -e " export *\n }" >>" $modmap "
fi
echo "}" >>" $modmap "
# Move the target-specific libSession-util build to the parent build directory (so XCode can have a reference to a single build)
rm -rf " ${ BUILD_DIR } /libsession-util.xcframework "
cp -r " ${ TARGET_BUILD_DIR } /libsession-util.xcframework " " ${ BUILD_DIR } /libsession-util.xcframework "
# Output to XCode just so the output is good
echo_message "info: libSessionUtil Ready"