Ver código fonte

Migrate from framework to xcframework in order to support Apple Silicon (#90)

* migrate from framework to xcframework in order to support Apple Silicon

* remove history framework info

* remove useless install
yujinqiu 2 anos atrás
pai
commit
5c5b6195a5
4 arquivos alterados com 973 adições e 409 exclusões
  1. 91 0
      .gitignore
  2. 117 105
      build-ios.sh
  3. 34 10
      ios-swift/SherpaNcnn/SherpaNcnn.xcodeproj/project.pbxproj
  4. 731 294
      toolchains/ios.toolchain.cmake

+ 91 - 0
.gitignore

@@ -8,3 +8,94 @@ dist/
 tags
 *.jar
 sherpa-ncnn-conv-emformer-transducer-2022-12-06
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## User settings
+xcuserdata/
+
+## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
+*.xcscmblueprint
+*.xccheckout
+
+## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
+build/
+DerivedData/
+*.moved-aside
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+
+## Obj-C/Swift specific
+*.hmap
+
+## App packaging
+*.ipa
+*.dSYM.zip
+*.dSYM
+
+## Playgrounds
+timeline.xctimeline
+playground.xcworkspace
+
+# Swift Package Manager
+#
+# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
+# Packages/
+# Package.pins
+# Package.resolved
+# *.xcodeproj
+#
+# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
+# hence it is not needed unless you have added a package configuration file to your project
+# .swiftpm
+
+.build/
+
+# CocoaPods
+#
+# We recommend against adding the Pods directory to your .gitignore. However
+# you should judge for yourself, the pros and cons are mentioned at:
+# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
+#
+# Pods/
+#
+# Add this line if you want to avoid checking in source code from the Xcode workspace
+# *.xcworkspace
+
+# Carthage
+#
+# Add this line if you want to avoid checking in source code from Carthage dependencies.
+# Carthage/Checkouts
+
+Carthage/Build/
+
+# Accio dependency management
+Dependencies/
+.accio/
+
+# fastlane
+#
+# It is recommended to not store the screenshots in the git repo.
+# Instead, use fastlane to re-generate the screenshots whenever they are needed.
+# For more information about the recommended setup visit:
+# https://docs.fastlane.tools/best-practices/source-control/#source-control
+
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots/**/*.png
+fastlane/test_output
+
+# Code Injection
+#
+# After new code Injection tools there's a generated folder /iOSInjectionProject
+# https://github.com/johnno1962/injectionforxcode
+
+iOSInjectionProject/
+.DS_Store

+ 117 - 105
build-ios.sh

@@ -18,25 +18,46 @@ if [ ! -d openmp-11.0.0.src ]; then
   popd
 fi
 
-if [ ! -f openmp-11.0.0.src/build-simulator/install/include/omp.h ]; then
+if [ ! -f openmp-11.0.0.src/build/os64/install/include/omp.h ]; then
   pushd openmp-11.0.0.src
 
-  mkdir -p build-simulator
-  cd build-simulator
+  mkdir -p build
 
-  cmake \
-    -DCMAKE_TOOLCHAIN_FILE=../../../toolchains/ios.toolchain.cmake \
+  # iOS & simulator running on arm64 & x86_64
+  cmake -S . \
+    -DCMAKE_TOOLCHAIN_FILE=../../toolchains/ios.toolchain.cmake \
     -DCMAKE_BUILD_TYPE=Release \
     -DCMAKE_INSTALL_PREFIX=install \
-    -DIOS_PLATFORM=SIMULATOR -DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=0 -DIOS_ARCH="i386;x86_64" \
+    -DPLATFORM=OS64 \
+    -DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=0 \
     -DPERL_EXECUTABLE=$(which perl) \
     -DLIBOMP_ENABLE_SHARED=OFF \
     -DLIBOMP_OMPT_SUPPORT=OFF \
     -DLIBOMP_USE_HWLOC=OFF \
-    ..
+    -B build/os64
+
+  cmake -S . \
+    -DCMAKE_TOOLCHAIN_FILE=../../toolchains/ios.toolchain.cmake \
+    -DCMAKE_BUILD_TYPE=Release \
+    -DPLATFORM=SIMULATORARM64 \
+    -DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=0 \
+    -DPERL_EXECUTABLE=$(which perl) \
+    -DLIBOMP_ENABLE_SHARED=OFF \
+    -DLIBOMP_OMPT_SUPPORT=OFF \
+    -DLIBOMP_USE_HWLOC=OFF \
+    -B build/simulator_arm64
+
+  cmake -S . \
+    -DCMAKE_TOOLCHAIN_FILE=../../toolchains/ios.toolchain.cmake \
+    -DCMAKE_BUILD_TYPE=Release \
+    -DPLATFORM=SIMULATOR64 \
+    -DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=0 \
+    -DPERL_EXECUTABLE=$(which perl) \
+    -DLIBOMP_ENABLE_SHARED=OFF \
+    -DLIBOMP_OMPT_SUPPORT=OFF \
+    -DLIBOMP_USE_HWLOC=OFF \
+    -B build/simulator_x86_64
 
-  cmake --build . -j 3
-  cmake --build . --target install
   # It generates the following files in the directory install
   # .
   # ├── include
@@ -47,40 +68,37 @@ if [ ! -f openmp-11.0.0.src/build-simulator/install/include/omp.h ]; then
   #     └── libomp.a
   #
   # 2 directories, 4 files
+  cmake --build ./build/os64 -j 4
+  # Generate header for sharper-ncnn.xcframework
+  cmake --build ./build/os64 --target install
+  cmake --build ./build/simulator_arm64 -j 4
+  cmake --build ./build/simulator_x86_64 -j 4
+
+  mkdir -p "./build/simulator/openmp"
+  lipo -create build/simulator_x86_64/runtime/src/libomp.a \
+               build/simulator_arm64/runtime/src/libomp.a \
+       -output build/simulator/openmp/libomp.a
+
+  # Return to parent directory to create xcframework
   popd
-fi
 
-if [ ! -f openmp-11.0.0.src/build-arm64/install/include/omp.h ]; then
-  pushd openmp-11.0.0.src
-
-  mkdir -p build-arm64
-  cd build-arm64
-
-  cmake \
-    -DCMAKE_TOOLCHAIN_FILE=../../../toolchains/ios.toolchain.cmake \
-    -DCMAKE_BUILD_TYPE=Release \
-    -DCMAKE_INSTALL_PREFIX=install \
-    -DIOS_PLATFORM=OS -DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=0 -DIOS_ARCH="arm64;arm64e" \
-    -DPERL_EXECUTABLE=$(which perl) \
-    -DLIBOMP_ENABLE_SHARED=OFF \
-    -DLIBOMP_OMPT_SUPPORT=OFF \
-    -DLIBOMP_USE_HWLOC=OFF \
-    ..
-
-  cmake --build . -j 3
-  cmake --build . --target install
-
-  popd
+  rm -rf  openmp.xcframework 
+  xcodebuild -create-xcframework \
+        -library "openmp-11.0.0.src/build/os64/runtime/src/libomp.a" \
+        -library "openmp-11.0.0.src/build/simulator/openmp/libomp.a" \
+        -output openmp.xcframework
+  # Copy Headers
+  mkdir -p openmp.xcframework/Headers
+  cp -v openmp-11.0.0.src/install/include/omp.h openmp.xcframework/Headers
 fi
 
-export CPLUS_INCLUDE_PATH=$PWD/openmp-11.0.0.src/build-arm64/install/include:$CPLUS_INCLUDE_PATH
-mkdir -p build-arm64
-pushd build-arm64
 
-cmake \
-  -DCMAKE_TOOLCHAIN_FILE=../../toolchains/ios.toolchain.cmake \
-  -DIOS_PLATFORM=OS \
-  -DIOS_ARCH="arm64;arm64e" \
+export CPLUS_INCLUDE_PATH=$PWD/openmp.xcframework/Headers/:$CPLUS_INCLUDE_PATH
+mkdir -p build
+
+cmake -S .. \
+  -DCMAKE_TOOLCHAIN_FILE=./toolchains/ios.toolchain.cmake \
+  -DPLATFORM=OS64 \
   -DENABLE_BITCODE=0 \
   -DENABLE_ARC=0 \
   -DENABLE_VISIBILITY=0 \
@@ -88,8 +106,7 @@ cmake \
   -DOpenMP_CXX_FLAGS="-Xclang -fopenmp" \
   -DOpenMP_C_LIB_NAMES="libomp" \
   -DOpenMP_CXX_LIB_NAMES="libomp" \
-  -DOpenMP_libomp_LIBRARY="$PWD/../openmp-11.0.0.src/build-arm64/install/lib/libomp.a" \
-  \
+  -DOpenMP_libomp_LIBRARY="$PWD/openmp.xcframework/ios-arm64/libomp.a" \
   -DCMAKE_INSTALL_PREFIX=./install \
   -DCMAKE_BUILD_TYPE=Release \
   -DBUILD_SHARED_LIBS=OFF \
@@ -99,27 +116,32 @@ cmake \
   -DSHERPA_NCNN_ENABLE_BINARY=OFF \
   -DSHERPA_NCNN_ENABLE_TEST=OFF \
   -DSHERPA_NCNN_ENABLE_C_API=ON \
-  ../..
+  -B build/os64 
 
-make VERBOSE=1 -j4
-make install
-rm -rf install/lib/cmake
-rm -rf install/lib/pkgconfig
-rm -rf install/include/ncnn
-rm -rf install/include/kaldi-native-fbank
-
-popd
-
-echo "pwd: $PWD"
-
-export CPLUS_INCLUDE_PATH=$PWD/openmp-11.0.0.src/build-simulator/install/include:$CPLUS_INCLUDE_PATH
-mkdir -p build-simulator
-pushd build-simulator
+cmake -S .. \
+  -DCMAKE_TOOLCHAIN_FILE=./toolchains/ios.toolchain.cmake \
+  -DPLATFORM=SIMULATORARM64 \
+  -DENABLE_BITCODE=0 \
+  -DENABLE_ARC=0 \
+  -DENABLE_VISIBILITY=0 \
+  -DOpenMP_C_FLAGS="-Xclang -fopenmp" \
+  -DOpenMP_CXX_FLAGS="-Xclang -fopenmp" \
+  -DOpenMP_C_LIB_NAMES="libomp" \
+  -DOpenMP_CXX_LIB_NAMES="libomp" \
+  -DOpenMP_libomp_LIBRARY="$PWD/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a" \
+  -DCMAKE_BUILD_TYPE=Release \
+  -DBUILD_SHARED_LIBS=OFF \
+  -DSHERPA_NCNN_ENABLE_PYTHON=OFF \
+  -DSHERPA_NCNN_ENABLE_PORTAUDIO=OFF \
+  -DSHERPA_NCNN_ENABLE_JNI=OFF \
+  -DSHERPA_NCNN_ENABLE_BINARY=OFF \
+  -DSHERPA_NCNN_ENABLE_TEST=OFF \
+  -DSHERPA_NCNN_ENABLE_C_API=ON \
+  -B build/simulator_arm64
 
-cmake \
-  -DCMAKE_TOOLCHAIN_FILE=../../toolchains/ios.toolchain.cmake \
-  -DIOS_PLATFORM=SIMULATOR \
-  -DIOS_ARCH="i386;x86_64" \
+cmake -S .. \
+  -DCMAKE_TOOLCHAIN_FILE=./toolchains/ios.toolchain.cmake \
+  -DPLATFORM=SIMULATOR64 \
   -DENABLE_BITCODE=0 \
   -DENABLE_ARC=0 \
   -DENABLE_VISIBILITY=0 \
@@ -127,9 +149,7 @@ cmake \
   -DOpenMP_CXX_FLAGS="-Xclang -fopenmp" \
   -DOpenMP_C_LIB_NAMES="libomp" \
   -DOpenMP_CXX_LIB_NAMES="libomp" \
-  -DOpenMP_libomp_LIBRARY="$PWD/../openmp-11.0.0.src/build-simulator/install/lib/libomp.a" \
-  \
-  -DCMAKE_INSTALL_PREFIX=./install \
+  -DOpenMP_libomp_LIBRARY="$PWD/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a" \
   -DCMAKE_BUILD_TYPE=Release \
   -DBUILD_SHARED_LIBS=OFF \
   -DSHERPA_NCNN_ENABLE_PYTHON=OFF \
@@ -138,58 +158,50 @@ cmake \
   -DSHERPA_NCNN_ENABLE_BINARY=OFF \
   -DSHERPA_NCNN_ENABLE_TEST=OFF \
   -DSHERPA_NCNN_ENABLE_C_API=ON \
-  ../..
+  -B build/simulator_x86_64
 
-make VERBOSE=1 -j4
-make install
+cmake --build build/os64 -j 4
+# Generate headers for sherpa-ncnn.xcframework
+cmake --build build/os64 --target install
+# Clean files
 rm -rf install/lib/cmake
 rm -rf install/lib/pkgconfig
 rm -rf install/include/ncnn
 rm -rf install/include/kaldi-native-fbank
+cmake --build build/simulator_arm64 -j 8
+cmake --build build/simulator_x86_64 -j 8
 
-popd
-
-# For openmp.framework
-rm -rf openmp.framework
-mkdir -p openmp.framework/Versions/A/Headers
-mkdir -p openmp.framework/Versions/A/Resources
-ln -s A openmp.framework/Versions/Current
-ln -s Versions/Current/Headers openmp.framework/Headers
-ln -s Versions/Current/Resources openmp.framework/Resources
-ln -s Versions/Current/openmp openmp.framework/openmp
-
-lipo -create \
-  openmp-11.0.0.src/build-arm64/install/lib/libomp.a \
-  openmp-11.0.0.src/build-simulator/install/lib/libomp.a \
-  -o openmp.framework/Versions/A/openmp
-
-cp -a openmp-11.0.0.src/build-simulator/install/include/* openmp.framework/Versions/A/Headers/
-sed -e 's/__NAME__/openmp/g' -e 's/__IDENTIFIER__/org.llvm.openmp/g' -e 's/__VERSION__/11.0/g' ../Info.plist > openmp.framework/Versions/A/Resources/Info.plist
-
-# For sherpa-ncnn.framework
-rm -rf sherpa-ncnn.framework
-mkdir -p sherpa-ncnn.framework/Versions/A/Headers
-mkdir -p sherpa-ncnn.framework/Versions/A/Headers
-mkdir -p sherpa-ncnn.framework/Versions/A/Resources
-ln -s A sherpa-ncnn.framework/Versions/Current
-ln -s Versions/Current/Headers sherpa-ncnn.framework/Headers
-ln -s Versions/Current/Resources sherpa-ncnn.framework/Resources
-ln -s Versions/Current/sherpa-ncnn sherpa-ncnn.framework/sherpa-ncnn
+# For sherpa-ncnn.xcframework
+rm -rf sherpa-ncnn.xcframework
+
+libtool -static -o build/os64/sherpa-ncnn.a \
+  build/os64/lib/libncnn.a \
+  build/os64/lib/libsherpa-ncnn-c-api.a \
+  build/os64/lib/libsherpa-ncnn-core.a \
+  build/os64/lib/libkaldi-native-fbank-core.a
+
+mkdir -p "build/simulator/lib"
 
 for f in libncnn.a libsherpa-ncnn-c-api.a libsherpa-ncnn-core.a libkaldi-native-fbank-core.a; do
-  lipo -create \
-    build-arm64/install/lib/$f \
-    build-simulator/install/lib/$f \
-    -o sherpa-ncnn.framework/Versions/A/$f
+  lipo -create build/simulator_arm64/lib/${f} \
+               build/simulator_x86_64/lib/${f} \
+       -output build/simulator/lib/${f}
 done
 
-libtool -static -o sherpa-ncnn.framework/Versions/A/sherpa-ncnn \
-  sherpa-ncnn.framework/Versions/A/libncnn.a \
-  sherpa-ncnn.framework/Versions/A/libsherpa-ncnn-c-api.a \
-  sherpa-ncnn.framework/Versions/A/libsherpa-ncnn-core.a \
-  sherpa-ncnn.framework/Versions/A/libkaldi-native-fbank-core.a
+# Merge archive first, because the following xcodebuild create xcframework 
+# cann't accept multi archive with the same architecture.
+libtool -static -o build/simulator/sherpa-ncnn.a \
+  build/simulator/lib/libncnn.a \
+  build/simulator/lib/libsherpa-ncnn-c-api.a \
+  build/simulator/lib/libsherpa-ncnn-core.a \
+  build/simulator/lib/libkaldi-native-fbank-core.a
+
 
-rm -v sherpa-ncnn.framework/Versions/A/lib*.a
+xcodebuild -create-xcframework \
+      -library "build/os64/sherpa-ncnn.a" \
+      -library "build/simulator/sherpa-ncnn.a" \
+      -output sherpa-ncnn.xcframework
 
-cp -a build-simulator/install/include/* sherpa-ncnn.framework/Versions/A/Headers/
-sed -e 's/__NAME__/sherpa-ncnn/g' -e 's/__IDENTIFIER__/com.k2-fsa.org/g' -e 's/__VERSION__/1.3.2/g' ../Info.plist > sherpa-ncnn.framework/Versions/A/Resources/Info.plist
+# Copy Headers
+mkdir -p sherpa-ncnn.xcframework/Headers
+cp -av install/include/* sherpa-ncnn.xcframework/Headers

+ 34 - 10
ios-swift/SherpaNcnn/SherpaNcnn.xcodeproj/project.pbxproj

@@ -17,9 +17,11 @@
 		C9D7D147298520A100F25DB7 /* SherpaNcnnUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D7D146298520A100F25DB7 /* SherpaNcnnUITests.swift */; };
 		C9D7D149298520A100F25DB7 /* SherpaNcnnUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D7D148298520A100F25DB7 /* SherpaNcnnUITestsLaunchTests.swift */; };
 		C9D7D15729853D8C00F25DB7 /* SherpaNcnn.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D7D15529853D8C00F25DB7 /* SherpaNcnn.swift */; };
-		C9D7D15A29853E9A00F25DB7 /* sherpa-ncnn.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9D7D15929853E9A00F25DB7 /* sherpa-ncnn.framework */; };
-		C9D7D15C29853EB400F25DB7 /* openmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9D7D15B29853EB300F25DB7 /* openmp.framework */; };
 		C9D7D15E298540D500F25DB7 /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D7D15D298540D500F25DB7 /* Model.swift */; };
+		DE11931E298770A700BFE75B /* sherpa-ncnn.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DE11931C298770A700BFE75B /* sherpa-ncnn.xcframework */; };
+		DE11931F298770A700BFE75B /* sherpa-ncnn.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DE11931C298770A700BFE75B /* sherpa-ncnn.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		DE119320298770A700BFE75B /* openmp.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DE11931D298770A700BFE75B /* openmp.xcframework */; };
+		DE119321298770A700BFE75B /* openmp.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DE11931D298770A700BFE75B /* openmp.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -39,6 +41,21 @@
 		};
 /* End PBXContainerItemProxy section */
 
+/* Begin PBXCopyFilesBuildPhase section */
+		DE119322298770A700BFE75B /* Embed Frameworks */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 10;
+			files = (
+				DE119321298770A700BFE75B /* openmp.xcframework in Embed Frameworks */,
+				DE11931F298770A700BFE75B /* sherpa-ncnn.xcframework in Embed Frameworks */,
+			);
+			name = "Embed Frameworks";
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
 /* Begin PBXFileReference section */
 		C9D7D122298520A000F25DB7 /* SherpaNcnn.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SherpaNcnn.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		C9D7D125298520A000F25DB7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -55,9 +72,9 @@
 		C9D7D148298520A100F25DB7 /* SherpaNcnnUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SherpaNcnnUITestsLaunchTests.swift; sourceTree = "<group>"; };
 		C9D7D15529853D8C00F25DB7 /* SherpaNcnn.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SherpaNcnn.swift; path = "../../../swift-api-examples/SherpaNcnn.swift"; sourceTree = "<group>"; };
 		C9D7D15629853D8C00F25DB7 /* SherpaNcnn-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "SherpaNcnn-Bridging-Header.h"; path = "../../../swift-api-examples/SherpaNcnn-Bridging-Header.h"; sourceTree = "<group>"; };
-		C9D7D15929853E9A00F25DB7 /* sherpa-ncnn.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "sherpa-ncnn.framework"; path = "../../build-ios/sherpa-ncnn.framework"; sourceTree = "<group>"; };
-		C9D7D15B29853EB300F25DB7 /* openmp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = openmp.framework; path = "../../build-ios/openmp.framework"; sourceTree = "<group>"; };
 		C9D7D15D298540D500F25DB7 /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = "<group>"; };
+		DE11931C298770A700BFE75B /* sherpa-ncnn.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = "sherpa-ncnn.xcframework"; path = "../../build-ios/sherpa-ncnn.xcframework"; sourceTree = "<group>"; };
+		DE11931D298770A700BFE75B /* openmp.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = openmp.xcframework; path = "../../build-ios/openmp.xcframework"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -65,8 +82,8 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				C9D7D15C29853EB400F25DB7 /* openmp.framework in Frameworks */,
-				C9D7D15A29853E9A00F25DB7 /* sherpa-ncnn.framework in Frameworks */,
+				DE119320298770A700BFE75B /* openmp.xcframework in Frameworks */,
+				DE11931E298770A700BFE75B /* sherpa-ncnn.xcframework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -145,6 +162,8 @@
 		C9D7D15829853E9A00F25DB7 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				DE11931D298770A700BFE75B /* openmp.xcframework */,
+				DE11931C298770A700BFE75B /* sherpa-ncnn.xcframework */,
 				C9D7D15B29853EB300F25DB7 /* openmp.framework */,
 				C9D7D15929853E9A00F25DB7 /* sherpa-ncnn.framework */,
 			);
@@ -161,6 +180,7 @@
 				C9D7D11E298520A000F25DB7 /* Sources */,
 				C9D7D11F298520A000F25DB7 /* Frameworks */,
 				C9D7D120298520A000F25DB7 /* Resources */,
+				DE119322298770A700BFE75B /* Embed Frameworks */,
 			);
 			buildRules = (
 			);
@@ -461,12 +481,13 @@
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 1;
-				DEVELOPMENT_TEAM = N5ZH3Z63A6;
+				DEVELOPMENT_TEAM = "";
 				FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../build-ios/";
 				GENERATE_INFOPLIST_FILE = YES;
-				HEADER_SEARCH_PATHS = "${PROJECT_DIR}/../../build-ios/sherpa-ncnn.framework/Headers/";
+				HEADER_SEARCH_PATHS = "${PROJECT_DIR}/../../build-ios/sherpa-ncnn.xcframework/Headers/";
 				INFOPLIST_FILE = SherpaNcnn/Info.plist;
 				INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
 				INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
@@ -482,6 +503,7 @@
 				OTHER_LDFLAGS = "-lc++";
 				PRODUCT_BUNDLE_IDENTIFIER = "com.k2-fsa.org.SherpaNcnn";
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				PROVISIONING_PROFILE_SPECIFIER = "";
 				SWIFT_EMIT_LOC_STRINGS = YES;
 				SWIFT_OBJC_BRIDGING_HEADER = "${PROJECT_DIR}/../../swift-api-examples/SherpaNcnn-Bridging-Header.h";
 				SWIFT_VERSION = 5.0;
@@ -494,12 +516,13 @@
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 1;
-				DEVELOPMENT_TEAM = N5ZH3Z63A6;
+				DEVELOPMENT_TEAM = "";
 				FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../build-ios/";
 				GENERATE_INFOPLIST_FILE = YES;
-				HEADER_SEARCH_PATHS = "${PROJECT_DIR}/../../build-ios/sherpa-ncnn.framework/Headers/";
+				HEADER_SEARCH_PATHS = "${PROJECT_DIR}/../../build-ios/sherpa-ncnn.xcframework/Headers/";
 				INFOPLIST_FILE = SherpaNcnn/Info.plist;
 				INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
 				INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
@@ -516,6 +539,7 @@
 				OTHER_LDFLAGS = "-lc++";
 				PRODUCT_BUNDLE_IDENTIFIER = "com.k2-fsa.org.SherpaNcnn";
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				PROVISIONING_PROFILE_SPECIFIER = "";
 				SWIFT_EMIT_LOC_STRINGS = YES;
 				SWIFT_OBJC_BRIDGING_HEADER = "${PROJECT_DIR}/../../swift-api-examples/SherpaNcnn-Bridging-Header.h";
 				SWIFT_VERSION = 5.0;

+ 731 - 294
toolchains/ios.toolchain.cmake

@@ -1,8 +1,6 @@
-#
-# Copied from
-# https://github.com/Tencent/ncnn/blob/master/toolchains/ios.toolchain.cmake
-#
 # This file is part of the ios-cmake project. It was retrieved from
+# https://github.com/leetal/ios-cmake.git, which is a fork of
+# https://github.com/gerstrong/ios-cmake.git, which is a fork of
 # https://github.com/cristeab/ios-cmake.git, which is a fork of
 # https://code.google.com/p/ios-cmake/. Which in turn is based off of
 # the Platform/Darwin.cmake and Platform/UnixPaths.cmake files which
@@ -53,43 +51,70 @@
 #
 #                           INFORMATION / HELP
 #
-# The following variables control the behaviour of this toolchain:
+# The following options control the behaviour of this toolchain:
 #
-# IOS_PLATFORM: OS (default) or SIMULATOR or SIMULATOR64 or TVOS or SIMULATOR_TVOS or WATCHOS or SIMULATOR_WATCHOS
+# PLATFORM: (default "OS64")
 #    OS = Build for iPhoneOS.
-#    OS64 = Build for arm64 arm64e iPhoneOS.
-#    SIMULATOR = Build for x86 i386 iPhone Simulator.
-#    SIMULATOR64 = Build for x86_64 iPhone Simulator.
-#    TVOS = Build for AppleTVOS.
-#    SIMULATOR_TVOS = Build for x86_64 AppleTV Simulator.
-#    WATCHOS = Build for armv7k arm64_32 for WatchOS.
-#    SIMULATOR_WATCHOS = Build for x86_64 for Watch Simulator.
-# CMAKE_OSX_SYSROOT: Path to the iOS SDK to use.  By default this is
-#    automatically determined from IOS_PLATFORM and xcodebuild, but
+#    OS64 = Build for arm64 iphoneOS.
+#    OS64COMBINED = Build for arm64 x86_64 iphoneOS. Combined into FAT STATIC lib (supported on 3.14+ of CMakewith "-G Xcode" argument ONLY)
+#    SIMULATOR = Build for x86 i386 iphoneOS Simulator.
+#    SIMULATOR64 = Build for x86_64 iphoneOS Simulator.
+#    SIMULATORARM64 = Build for arm64 iphoneOS Simulator.
+#    TVOS = Build for arm64 tvOS.
+#    TVOSCOMBINED = Build for arm64 x86_64 tvOS. Combined into FAT STATIC lib (supported on 3.14+ of CMake with "-G Xcode" argument ONLY)
+#    SIMULATOR_TVOS = Build for x86_64 tvOS Simulator.
+#    WATCHOS = Build for armv7k arm64_32 for watchOS.
+#    WATCHOSCOMBINED = Build for armv7k arm64_32 x86_64 watchOS. Combined into FAT STATIC lib (supported on 3.14+ of CMake with "-G Xcode" argument ONLY)
+#    SIMULATOR_WATCHOS = Build for x86_64 for watchOS Simulator.
+#    MAC = Build for x86_64 macOS.
+#    MAC_ARM64 = Build for Apple Silicon macOS.
+#    MAC_CATALYST = Build for x86_64 macOS with Catalyst support (iOS toolchain on macOS).
+#                   Note: The build argument "MACOSX_DEPLOYMENT_TARGET" can be used to control min-version of macOS
+#    MAC_CATALYST_ARM64 = Build for Apple Silicon macOS with Catalyst support (iOS toolchain on macOS).
+#                         Note: The build argument "MACOSX_DEPLOYMENT_TARGET" can be used to control min-version of macOS
+#
+# CMAKE_OSX_SYSROOT: Path to the SDK to use.  By default this is
+#    automatically determined from PLATFORM and xcodebuild, but
 #    can also be manually specified (although this should not be required).
-# CMAKE_IOS_DEVELOPER_ROOT: Path to the Developer directory for the iOS platform
+#
+# CMAKE_DEVELOPER_ROOT: Path to the Developer directory for the platform
 #    being compiled for.  By default this is automatically determined from
 #    CMAKE_OSX_SYSROOT, but can also be manually specified (although this should
 #    not be required).
+#
+# DEPLOYMENT_TARGET: Minimum SDK version to target. Default 2.0 on watchOS and 9.0 on tvOS+iOS
+#
 # ENABLE_BITCODE: (1|0) Enables or disables bitcode support. Default 1 (true)
+#
 # ENABLE_ARC: (1|0) Enables or disables ARC support. Default 1 (true, ARC enabled by default)
+#
 # ENABLE_VISIBILITY: (1|0) Enables or disables symbol visibility support. Default 0 (false, visibility hidden by default)
-# IOS_ARCH: (armv7 armv7s armv7k arm64 arm64e arm64_32 i386 x86_64) If specified, will override the default architectures for the given IOS_PLATFORM
-#    OS = armv7 armv7s arm64 arm64e (if applicable)
-#    OS64 = arm64 arm64e (if applicable)
-#    SIMULATOR = i386 x86_64
+#
+# ENABLE_STRICT_TRY_COMPILE: (1|0) Enables or disables strict try_compile() on all Check* directives (will run linker
+#    to actually check if linking is possible). Default 0 (false, will set CMAKE_TRY_COMPILE_TARGET_TYPE to STATIC_LIBRARY)
+#
+# ARCHS: (armv7 armv7s armv7k arm64 arm64_32 i386 x86_64) If specified, will override the default architectures for the given PLATFORM
+#    OS = armv7 armv7s arm64 (if applicable)
+#    OS64 = arm64 (if applicable)
+#    SIMULATOR = i386
 #    SIMULATOR64 = x86_64
+#    SIMULATORARM64 = arm64
 #    TVOS = arm64
 #    SIMULATOR_TVOS = x86_64 (i386 has since long been deprecated)
 #    WATCHOS = armv7k arm64_32 (if applicable)
 #    SIMULATOR_WATCHOS = x86_64 (i386 has since long been deprecated)
+#    MAC = x86_64
+#    MAC_ARM64 = arm64
+#    MAC_CATALYST = x86_64
+#    MAC_CATALYST_ARM64 = arm64
 #
-# This toolchain defines the following variables for use externally:
+# This toolchain defines the following properties (available via get_property()) for use externally:
 #
+# PLATFORM: The currently targeted platform.
 # XCODE_VERSION: Version number (not including Build version) of Xcode detected.
-# IOS_SDK_VERSION: Version of iOS SDK being used.
-# CMAKE_OSX_ARCHITECTURES: Architectures being compiled for (generated from
-#    IOS_PLATFORM).
+# SDK_VERSION: Version of SDK being used.
+# OSX_ARCHITECTURES: Architectures being compiled for (generated from PLATFORM).
+# APPLE_TARGET_TRIPLE: Used by autoconf build systems. NOTE: If "ARCHS" are overridden, this will *NOT* be set!
 #
 # This toolchain defines the following macros for use externally:
 #
@@ -100,8 +125,102 @@
 #
 # find_host_package (PROGRAM ARGS)
 #   A macro used to find executable programs on the host system, not within the
-#   iOS environment.  Thanks to the android-cmake project for providing the
+#   environment. Thanks to the android-cmake project for providing the
 #   command.
+#
+
+cmake_minimum_required(VERSION 3.8.0)
+
+# CMake invokes the toolchain file twice during the first build, but only once during subsequent rebuilds.
+if(IOS_TOOLCHAIN_HAS_RUN)
+  return()
+endif(IOS_TOOLCHAIN_HAS_RUN)
+set(IOS_TOOLCHAIN_HAS_RUN true)
+
+###############################################################################
+#                                  OPTIONS                                    #
+###############################################################################
+
+option(DROP_32_BIT "Drops the 32-bit targets universally." YES)
+
+###############################################################################
+#                                END OPTIONS                                  #
+###############################################################################
+
+# List of supported platform values
+list(APPEND _supported_platforms
+        "OS" "OS64" "OS64COMBINED" "SIMULATOR" "SIMULATOR64" "SIMULATORARM64"
+        "TVOS" "TVOSCOMBINED" "SIMULATOR_TVOS"
+        "WATCHOS" "WATCHOSCOMBINED" "SIMULATOR_WATCHOS"
+        "MAC" "MAC_ARM64"
+        "MAC_CATALYST" "MAC_CATALYST_ARM64")
+
+# Cache what generator is used
+set(USED_CMAKE_GENERATOR "${CMAKE_GENERATOR}")
+
+# Check if using a CMake version capable of building combined FAT builds (simulator and target slices combined in one static lib)
+if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14")
+  set(MODERN_CMAKE YES)
+endif()
+
+# Get the Xcode version being used.
+# Problem: CMake runs toolchain files multiple times, but can't read cache variables on some runs.
+# Workaround: On first run (in which cache variables are always accessible), set an intermediary environment variable.
+#
+# NOTE: This pattern is used i many places in this toolchain to speed up checks of all sorts
+if(DEFINED XCODE_VERSION_INT)
+  # Environment variables are always preserved.
+  set(ENV{_XCODE_VERSION_INT} "${XCODE_VERSION_INT}")
+elseif(DEFINED ENV{_XCODE_VERSION_INT})
+  set(XCODE_VERSION_INT "$ENV{_XCODE_VERSION_INT}")
+elseif(NOT DEFINED XCODE_VERSION_INT)
+  find_program(XCODEBUILD_EXECUTABLE xcodebuild)
+  if(NOT XCODEBUILD_EXECUTABLE)
+    message(FATAL_ERROR "xcodebuild not found. Please install either the standalone commandline tools or Xcode.")
+  endif()
+  execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -version
+          OUTPUT_VARIABLE XCODE_VERSION_INT
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+  string(REGEX MATCH "Xcode [0-9\\.]+" XCODE_VERSION_INT "${XCODE_VERSION_INT}")
+  string(REGEX REPLACE "Xcode ([0-9\\.]+)" "\\1" XCODE_VERSION_INT "${XCODE_VERSION_INT}")
+  set(XCODE_VERSION_INT "${XCODE_VERSION_INT}" CACHE INTERNAL "")
+endif()
+
+# Assuming that xcode 12.0 is installed you most probably have ios sdk 14.0 or later installed (tested on Big Sur)
+# if you don't set a deployment target it will be set the way you only get 64-bit builds
+if(NOT DEFINED DEPLOYMENT_TARGET AND XCODE_VERSION_INT VERSION_GREATER 12.0)
+  # Temporarily fix the arm64 issues in CMake install-combined by excluding arm64 for simulator builds (needed for Apple Silicon...)
+  set(CMAKE_XCODE_ATTRIBUTE_EXCLUDED_ARCHS[sdk=iphonesimulator*] "arm64")
+endif()
+
+# Check if the platform variable is set
+if(DEFINED PLATFORM)
+  # Environment variables are always preserved.
+  set(ENV{_PLATFORM} "${PLATFORM}")
+elseif(DEFINED ENV{_PLATFORM})
+  set(PLATFORM "$ENV{_PLATFORM}")
+elseif(NOT DEFINED PLATFORM)
+  message(FATAL_ERROR "PLATFORM argument not set. Bailing configure since I don't know what target you want to build for!")
+endif ()
+
+# Safeguard that the platform value is set and is one of the supported values
+list(FIND _supported_platforms ${PLATFORM} contains_PLATFORM)
+if("${contains_PLATFORM}" EQUAL "-1")
+  string(REPLACE ";"  "\n * " _supported_platforms_formatted "${_supported_platforms}")
+  message(FATAL_ERROR " Invalid PLATFORM specified! Current value: ${PLATFORM}.\n"
+          " Supported PLATFORM values: \n * ${_supported_platforms_formatted}")
+endif()
+
+# Check if Apple Silicon is supported
+if(PLATFORM MATCHES "^(MAC_ARM64)$|^(MAC_CATALYST_ARM64)$" AND ${CMAKE_VERSION} VERSION_LESS "3.19.5")
+  message(FATAL_ERROR "Apple Silicon builds requires a minimum of CMake 3.19.5")
+endif()
+
+# Touch toolchain variable to suppress "unused variable" warning.
+# This happens if CMake is invoked with the same command line the second time.
+if(CMAKE_TOOLCHAIN_FILE)
+endif()
 
 # Fix for PThread library not in path
 set(CMAKE_THREAD_LIBS_INIT "-lpthread")
@@ -109,221 +228,432 @@ set(CMAKE_HAVE_THREADS_LIBRARY 1)
 set(CMAKE_USE_WIN32_THREADS_INIT 0)
 set(CMAKE_USE_PTHREADS_INIT 1)
 
-# Get the Xcode version being used.
-execute_process(COMMAND xcodebuild -version
-  OUTPUT_VARIABLE XCODE_VERSION
-  ERROR_QUIET
-  OUTPUT_STRIP_TRAILING_WHITESPACE)
-string(REGEX MATCH "Xcode [0-9\\.]+" XCODE_VERSION "${XCODE_VERSION}")
-string(REGEX REPLACE "Xcode ([0-9\\.]+)" "\\1" XCODE_VERSION "${XCODE_VERSION}")
-message(STATUS "Building with Xcode version: ${XCODE_VERSION}")
-# Default to building for iPhoneOS if not specified otherwise, and we cannot
-# determine the platform from the CMAKE_OSX_ARCHITECTURES variable. The use
-# of CMAKE_OSX_ARCHITECTURES is such that try_compile() projects can correctly
-# determine the value of IOS_PLATFORM from the root project, as
-# CMAKE_OSX_ARCHITECTURES is propagated to them by CMake.
-if (NOT DEFINED IOS_PLATFORM)
-  if (CMAKE_OSX_ARCHITECTURES)
-    if (CMAKE_OSX_ARCHITECTURES MATCHES ".*arm.*")
-      set(IOS_PLATFORM "OS")
-    elseif (CMAKE_OSX_ARCHITECTURES MATCHES "i386")
-      set(IOS_PLATFORM "SIMULATOR")
-    elseif (CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
-      set(IOS_PLATFORM "SIMULATOR64")
-    elseif (CMAKE_OSX_ARCHITECTURES MATCHES "armv7k")
-      set(IOS_PLATFORM "WATCHOS")
-    endif()
-  endif()
-  if (NOT IOS_PLATFORM)
-    set(IOS_PLATFORM "OS")
+# Specify minimum version of deployment target.
+if(NOT DEFINED DEPLOYMENT_TARGET)
+  if (PLATFORM MATCHES "WATCHOS")
+    # Unless specified, SDK version 4.0 is used by default as minimum target version (watchOS).
+    set(DEPLOYMENT_TARGET "4.0")
+  elseif(PLATFORM STREQUAL "MAC")
+    # Unless specified, SDK version 10.13 (High sierra) is used by default as minimum target version (macos).
+    set(DEPLOYMENT_TARGET "10.13")
+  elseif(PLATFORM STREQUAL "MAC_ARM64")
+    # Unless specified, SDK version 11.0 (Big Sur) is used by default as minimum target version (macos on arm).
+    set(DEPLOYMENT_TARGET "11.0")
+  elseif(PLATFORM STREQUAL "MAC_CATALYST" OR PLATFORM STREQUAL "MAC_CATALYST_ARM64")
+    # Unless specified, SDK version 13.0 is used by default as minimum target version (mac catalyst minimum requirement).
+    set(DEPLOYMENT_TARGET "13.0")
+  else()
+    # Unless specified, SDK version 11.0 is used by default as minimum target version (iOS, tvOS).
+    set(DEPLOYMENT_TARGET "11.0")
   endif()
+  message(STATUS "[DEFAULTS] Using the default min-version since DEPLOYMENT_TARGET not provided!")
+elseif(DEFINED DEPLOYMENT_TARGET AND PLATFORM STREQUAL "MAC_CATALYST" AND ${DEPLOYMENT_TARGET} VERSION_LESS "13.0")
+  message(FATAL_ERROR "Mac Catalyst builds requires a minimum deployment target of 13.0!")
+endif()
+
+# Store the DEPLOYMENT_TARGET in the cache
+set(DEPLOYMENT_TARGET "${DEPLOYMENT_TARGET}" CACHE INTERNAL "")
+
+# Handle the case where we are targeting iOS and a version above 10.3.4 (32-bit support dropped officially)
+if(PLATFORM STREQUAL "OS" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.3.4)
+  set(PLATFORM "OS64")
+  message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.")
+elseif(PLATFORM STREQUAL "SIMULATOR" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.3.4)
+  set(PLATFORM "SIMULATOR64")
+  message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.")
+endif()
+
+set(PLATFORM_INT "${PLATFORM}")
+
+if(DEFINED ARCHS)
+  string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}")
 endif()
-set(IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING
-  "Type of iOS platform for which to build.")
+
 # Determine the platform name and architectures for use in xcodebuild commands
-# from the specified IOS_PLATFORM name.
-if (IOS_PLATFORM STREQUAL "OS")
-  set(XCODE_IOS_PLATFORM iphoneos)
-  if(NOT IOS_ARCH)
-    if (XCODE_VERSION VERSION_GREATER 10.0)
-      set(IOS_ARCH armv7 armv7s arm64 arm64e)
+# from the specified PLATFORM_INT name.
+if(PLATFORM_INT STREQUAL "OS")
+  set(SDK_NAME iphoneos)
+  if(NOT ARCHS)
+    set(ARCHS armv7 armv7s arm64)
+    set(APPLE_TARGET_TRIPLE_INT arm-apple-ios)
+  endif()
+elseif(PLATFORM_INT STREQUAL "OS64")
+  set(SDK_NAME iphoneos)
+  if(NOT ARCHS)
+    if (XCODE_VERSION_INT VERSION_GREATER 10.0)
+      set(ARCHS arm64) # Add arm64e when Apple have fixed the integration issues with it, libarclite_iphoneos.a is currently missung bitcode markers for example
     else()
-      set(IOS_ARCH armv7 armv7s arm64)
+      set(ARCHS arm64)
     endif()
+    set(APPLE_TARGET_TRIPLE_INT aarch64-apple-ios)
+  else()
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios)
   endif()
- elseif (IOS_PLATFORM STREQUAL "OS64")
-  set(XCODE_IOS_PLATFORM iphoneos)
-  if(NOT IOS_ARCH)
-    if (XCODE_VERSION VERSION_GREATER 10.0)
-      set(IOS_ARCH arm64 arm64e)
+elseif(PLATFORM_INT STREQUAL "OS64COMBINED")
+  set(SDK_NAME iphoneos)
+  if(MODERN_CMAKE)
+    if(NOT ARCHS)
+      if (XCODE_VERSION_INT VERSION_GREATER 10.0)
+        set(ARCHS arm64 x86_64) # Add arm64e when Apple have fixed the integration issues with it, libarclite_iphoneos.a is currently missung bitcode markers for example
+        set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64")
+        set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64")
+        set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "arm64")
+        set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64")
+      else()
+        set(ARCHS arm64 x86_64)
+        set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64")
+        set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64")
+        set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "arm64")
+        set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64")
+      endif()
+      set(APPLE_TARGET_TRIPLE_INT aarch64-x86_64-apple-ios)
     else()
-      set(IOS_ARCH arm64)
+      set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios)
     endif()
+  else()
+    message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the OS64COMBINED setting work")
   endif()
-elseif (IOS_PLATFORM STREQUAL "SIMULATOR")
-  set(XCODE_IOS_PLATFORM iphonesimulator)
-  if(NOT IOS_ARCH)
-    set(IOS_ARCH i386 x86_64)
+elseif(PLATFORM_INT STREQUAL "SIMULATOR")
+  set(SDK_NAME iphonesimulator)
+  if(NOT ARCHS)
+    set(ARCHS i386)
+    set(APPLE_TARGET_TRIPLE_INT i386-apple-ios)
+  else()
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios)
   endif()
-elseif(IOS_PLATFORM STREQUAL "SIMULATOR64")
-  set(XCODE_IOS_PLATFORM iphonesimulator)
-  if(NOT IOS_ARCH)
-    set(IOS_ARCH x86_64)
+  message(DEPRECATION "SIMULATOR IS DEPRECATED. Consider using SIMULATOR64 instead.")
+elseif(PLATFORM_INT STREQUAL "SIMULATOR64")
+  set(SDK_NAME iphonesimulator)
+  if(NOT ARCHS)
+    set(ARCHS x86_64)
+    set(APPLE_TARGET_TRIPLE_INT x86_64-apple-ios)
+  else()
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios)
   endif()
-elseif (IOS_PLATFORM STREQUAL "TVOS")
-  set(XCODE_IOS_PLATFORM appletvos)
-  if(NOT IOS_ARCH)
-    set(IOS_ARCH arm64)
+elseif(PLATFORM_INT STREQUAL "SIMULATORARM64")
+  set(SDK_NAME iphonesimulator)
+  if(NOT ARCHS)
+    set(ARCHS arm64)
+    set(APPLE_TARGET_TRIPLE_INT aarch64-apple-ios)
+  else()
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios)
   endif()
-elseif (IOS_PLATFORM STREQUAL "SIMULATOR_TVOS")
-  set(XCODE_IOS_PLATFORM appletvsimulator)
-  if(NOT IOS_ARCH)
-    set(IOS_ARCH x86_64)
+elseif(PLATFORM_INT STREQUAL "TVOS")
+  set(SDK_NAME appletvos)
+  if(NOT ARCHS)
+    set(ARCHS arm64)
+    set(APPLE_TARGET_TRIPLE_INT aarch64-apple-tvos)
+  else()
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos)
   endif()
-elseif (IOS_PLATFORM STREQUAL "WATCHOS")
-  set(XCODE_IOS_PLATFORM watchos)
-  if(NOT IOS_ARCH)
-    if (XCODE_VERSION VERSION_GREATER 10.0)
-      set(IOS_ARCH armv7k arm64_32)
+elseif (PLATFORM_INT STREQUAL "TVOSCOMBINED")
+  set(SDK_NAME appletvos)
+  if(MODERN_CMAKE)
+    if(NOT ARCHS)
+      set(ARCHS arm64 x86_64)
+      set(APPLE_TARGET_TRIPLE_INT aarch64-x86_64-apple-tvos)
+      set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=appletvos*] "arm64")
+      set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=appletvsimulator*] "x86_64")
+      set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=appletvos*] "arm64")
+      set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=appletvsimulator*] "x86_64")
     else()
-      set(IOS_ARCH armv7k)
+      set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos)
     endif()
+  else()
+    message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the TVOSCOMBINED setting work")
   endif()
-elseif (IOS_PLATFORM STREQUAL "SIMULATOR_WATCHOS")
-  set(XCODE_IOS_PLATFORM watchsimulator)
-  if(NOT IOS_ARCH)
-    set(IOS_ARCH x86_64)
+elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS")
+  set(SDK_NAME appletvsimulator)
+  if(NOT ARCHS)
+    set(ARCHS x86_64)
+    set(APPLE_TARGET_TRIPLE_INT x86_64-apple-tvos)
+  else()
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos)
+  endif()
+elseif(PLATFORM_INT STREQUAL "WATCHOS")
+  set(SDK_NAME watchos)
+  if(NOT ARCHS)
+    if (XCODE_VERSION_INT VERSION_GREATER 10.0)
+      set(ARCHS armv7k arm64_32)
+      set(APPLE_TARGET_TRIPLE_INT aarch64_32-apple-watchos)
+    else()
+      set(ARCHS armv7k)
+      set(APPLE_TARGET_TRIPLE_INT arm-apple-watchos)
+    endif()
+  else()
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos)
+  endif()
+elseif(PLATFORM_INT STREQUAL "WATCHOSCOMBINED")
+  set(SDK_NAME watchos)
+  if(MODERN_CMAKE)
+    if(NOT ARCHS)
+      if (XCODE_VERSION_INT VERSION_GREATER 10.0)
+        set(ARCHS armv7k arm64_32 i386)
+        set(APPLE_TARGET_TRIPLE_INT aarch64_32-i386-apple-watchos)
+        set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchos*] "armv7k arm64_32")
+        set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchsimulator*] "i386")
+        set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchos*] "armv7k arm64_32")
+        set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchsimulator*] "i386")
+      else()
+        set(ARCHS armv7k i386)
+        set(APPLE_TARGET_TRIPLE_INT arm-i386-apple-watchos)
+        set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchos*] "armv7k")
+        set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchsimulator*] "i386")
+        set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchos*] "armv7k")
+        set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchsimulator*] "i386")
+      endif()
+    else()
+      set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos)
+    endif()
+  else()
+    message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the WATCHOSCOMBINED setting work")
+  endif()
+elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS")
+  set(SDK_NAME watchsimulator)
+  if(NOT ARCHS)
+    set(ARCHS i386)
+    set(APPLE_TARGET_TRIPLE_INT i386-apple-watchos)
+  else()
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos)
+  endif()
+elseif(PLATFORM_INT STREQUAL "MAC" OR PLATFORM_INT STREQUAL "MAC_CATALYST")
+  set(SDK_NAME macosx)
+  if(NOT ARCHS)
+    set(ARCHS x86_64)
+  endif()
+  string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}")
+  if(PLATFORM_INT STREQUAL "MAC")
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-macosx)
+  elseif(PLATFORM_INT STREQUAL "MAC_CATALYST")
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-macabi)
+  endif()
+elseif(PLATFORM_INT MATCHES "^(MAC_ARM64)$|^(MAC_CATALYST_ARM64)$")
+  set(SDK_NAME macosx)
+  if(NOT ARCHS)
+    set(ARCHS arm64)
+  endif()
+  string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}")
+  if(PLATFORM_INT STREQUAL "MAC_ARM64")
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-macosx)
+  elseif(PLATFORM_INT STREQUAL "MAC_CATALYST_ARM64")
+    set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-macabi)
   endif()
 else()
-  message(FATAL_ERROR "Invalid IOS_PLATFORM: ${IOS_PLATFORM}")
+  message(FATAL_ERROR "Invalid PLATFORM: ${PLATFORM_INT}")
 endif()
-message(STATUS "Configuring iOS build for platform: ${IOS_PLATFORM}, "
-  "architecture(s): ${IOS_ARCH}")
-# If user did not specify the SDK root to use, then query xcodebuild for it.
-execute_process(COMMAND xcodebuild -version -sdk ${XCODE_IOS_PLATFORM} Path
-    OUTPUT_VARIABLE CMAKE_OSX_SYSROOT_INT
-     OUTPUT_QUIET ERROR_QUIET
-    OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+if(MODERN_CMAKE AND PLATFORM_INT MATCHES ".*COMBINED" AND NOT CMAKE_GENERATOR MATCHES "Xcode")
+  message(FATAL_ERROR "The COMBINED options only work with Xcode generator, -G Xcode")
+endif()
+
+if(CMAKE_GENERATOR MATCHES "Xcode" AND PLATFORM_INT MATCHES "MAC_CATALYST_.*")
+  set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
+  set(CMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "macosx")
+  set(CMAKE_XCODE_EFFECTIVE_PLATFORMS "-maccatalyst")
+  if(NOT DEFINED MACOSX_DEPLOYMENT_TARGET)
+    set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET "10.15")
+  else()
+    set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET "${MACOSX_DEPLOYMENT_TARGET}")
+  endif()
+elseif(CMAKE_GENERATOR MATCHES "Xcode")
+  set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "${DEPLOYMENT_TARGET}")
+  if(NOT PLATFORM_INT MATCHES ".*COMBINED")
+    set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=${SDK_NAME}*] "${ARCHS}")
+    set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=${SDK_NAME}*] "${ARCHS}")
+  endif()
+endif()
+
 # If user did not specify the SDK root to use, then query xcodebuild for it.
-if (NOT DEFINED CMAKE_OSX_SYSROOT OR (NOT CMAKE_OSX_SYSROOT STREQUAL CMAKE_OSX_SYSROOT_INT))
-  execute_process(COMMAND xcodebuild -version -sdk ${XCODE_IOS_PLATFORM} Path
-    OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
-    ERROR_QUIET
-    OUTPUT_STRIP_TRAILING_WHITESPACE)
+if(DEFINED CMAKE_OSX_SYSROOT_INT)
+  # Environment variables are always preserved.
+  set(ENV{_CMAKE_OSX_SYSROOT_INT} "${CMAKE_OSX_SYSROOT_INT}")
+elseif(DEFINED ENV{_CMAKE_OSX_SYSROOT_INT})
+  set(CMAKE_OSX_SYSROOT_INT "$ENV{_CMAKE_OSX_SYSROOT_INT}")
+elseif(NOT DEFINED CMAKE_OSX_SYSROOT_INT)
+  execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -version -sdk ${SDK_NAME} Path
+          OUTPUT_VARIABLE CMAKE_OSX_SYSROOT_INT
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
 endif()
-if (NOT EXISTS ${CMAKE_OSX_SYSROOT})
+
+if (NOT DEFINED CMAKE_OSX_SYSROOT_INT AND NOT DEFINED CMAKE_OSX_SYSROOT)
   message(SEND_ERROR "Please make sure that Xcode is installed and that the toolchain"
-  "is pointing to the correct path. Please run:"
-  "sudo xcode-select -s /Applications/Xcode.app/Contents/Developer"
-  "and see if that fixes the problem for you.")
+          "is pointing to the correct path. Please run:"
+          "sudo xcode-select -s /Applications/Xcode.app/Contents/Developer"
+          "and see if that fixes the problem for you.")
   message(FATAL_ERROR "Invalid CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT} "
-  "does not exist.")
-elseif(DEFINED CMAKE_OSX_SYSROOT)
-  message(STATUS "Using manually set SDK path: ${CMAKE_OSX_SYSROOT} for platform: ${IOS_PLATFORM}")
-else()
-   message(STATUS "Using SDK: ${CMAKE_OSX_SYSROOT} for platform: ${IOS_PLATFORM}")
-endif()
-# Specify minimum version of deployment target.
-if (NOT DEFINED IOS_DEPLOYMENT_TARGET)
-  if (IOS_PLATFORM STREQUAL "WATCHOS" OR IOS_PLATFORM STREQUAL "SIMULATOR_WATCHOS")
-    # Unless specified, SDK version 2.0 is used by default as minimum target version (watchOS).
-    set(IOS_DEPLOYMENT_TARGET "2.0"
-            CACHE STRING "Minimum iOS version to build for." )
-  else()
-    # Unless specified, SDK version 9.0 is used by default as minimum target version (iOS, tvOS).
-    set(IOS_DEPLOYMENT_TARGET "9.0"
-              CACHE STRING "Minimum iOS version to build for." )
-  endif()
-  message(STATUS "Using the default min-version since IOS_DEPLOYMENT_TARGET not provided!")
+          "does not exist.")
+elseif(DEFINED CMAKE_OSX_SYSROOT_INT)
+  set(CMAKE_OSX_SYSROOT_INT "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "")
+  # Specify the location or name of the platform SDK to be used in CMAKE_OSX_SYSROOT.
+  set(CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "")
 endif()
+
 # Use bitcode or not
-if (NOT DEFINED ENABLE_BITCODE AND NOT IOS_ARCH MATCHES "((^|, )(i386|x86_64))+")
+if(NOT DEFINED ENABLE_BITCODE AND NOT ARCHS MATCHES "((^|;|, )(i386|x86_64))+")
   # Unless specified, enable bitcode support by default
-  set(ENABLE_BITCODE TRUE CACHE BOOL "Whether or not to enable bitcode")
-  message(STATUS "Enabling bitcode support by default. ENABLE_BITCODE not provided!")
-endif()
-if (NOT DEFINED ENABLE_BITCODE)
-  message(STATUS "Disabling bitcode support by default on simulators. ENABLE_BITCODE not provided for override!")
+  message(STATUS "[DEFAULTS] Enabling bitcode support by default. ENABLE_BITCODE not provided!")
+  set(ENABLE_BITCODE TRUE)
+elseif(NOT DEFINED ENABLE_BITCODE)
+  message(STATUS "[DEFAULTS] Disabling bitcode support by default on simulators. ENABLE_BITCODE not provided for override!")
+  set(ENABLE_BITCODE FALSE)
 endif()
+set(ENABLE_BITCODE_INT ${ENABLE_BITCODE} CACHE BOOL
+        "Whether or not to enable bitcode" FORCE)
 # Use ARC or not
-if (NOT DEFINED ENABLE_ARC)
+if(NOT DEFINED ENABLE_ARC)
   # Unless specified, enable ARC support by default
-  set(ENABLE_ARC TRUE CACHE BOOL "Whether or not to enable ARC")
-  message(STATUS "Enabling ARC support by default. ENABLE_ARC not provided!")
+  set(ENABLE_ARC TRUE)
+  message(STATUS "[DEFAULTS] Enabling ARC support by default. ENABLE_ARC not provided!")
 endif()
+set(ENABLE_ARC_INT ${ENABLE_ARC} CACHE BOOL "Whether or not to enable ARC" FORCE)
 # Use hidden visibility or not
-if (NOT DEFINED ENABLE_VISIBILITY)
+if(NOT DEFINED ENABLE_VISIBILITY)
   # Unless specified, disable symbols visibility by default
-  set(ENABLE_VISIBILITY FALSE CACHE BOOL "Whether or not to hide symbols (-fvisibility=hidden)")
-  message(STATUS "Hiding symbols visibility by default. ENABLE_VISIBILITY not provided!")
+  set(ENABLE_VISIBILITY FALSE)
+  message(STATUS "[DEFAULTS] Hiding symbols visibility by default. ENABLE_VISIBILITY not provided!")
+endif()
+set(ENABLE_VISIBILITY_INT ${ENABLE_VISIBILITY} CACHE BOOL "Whether or not to hide symbols from the dynamic linker (-fvisibility=hidden)" FORCE)
+# Set strict compiler checks or not
+if(NOT DEFINED ENABLE_STRICT_TRY_COMPILE)
+  # Unless specified, disable strict try_compile()
+  set(ENABLE_STRICT_TRY_COMPILE FALSE)
+  message(STATUS "[DEFAULTS] Using NON-strict compiler checks by default. ENABLE_STRICT_TRY_COMPILE not provided!")
 endif()
+set(ENABLE_STRICT_TRY_COMPILE_INT ${ENABLE_STRICT_TRY_COMPILE} CACHE BOOL
+        "Whether or not to use strict compiler checks" FORCE)
+
 # Get the SDK version information.
-execute_process(COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version SDKVersion
-  OUTPUT_VARIABLE IOS_SDK_VERSION
-  ERROR_QUIET
-  OUTPUT_STRIP_TRAILING_WHITESPACE)
+if(DEFINED SDK_VERSION)
+  # Environment variables are always preserved.
+  set(ENV{_SDK_VERSION} "${SDK_VERSION}")
+elseif(DEFINED ENV{_SDK_VERSION})
+  set(SDK_VERSION "$ENV{_SDK_VERSION}")
+elseif(NOT DEFINED SDK_VERSION)
+  execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -sdk ${CMAKE_OSX_SYSROOT_INT} -version SDKVersion
+          OUTPUT_VARIABLE SDK_VERSION
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+endif()
+
 # Find the Developer root for the specific iOS platform being compiled for
 # from CMAKE_OSX_SYSROOT.  Should be ../../ from SDK specified in
-# CMAKE_OSX_SYSROOT.  There does not appear to be a direct way to obtain
+# CMAKE_OSX_SYSROOT. There does not appear to be a direct way to obtain
 # this information from xcrun or xcodebuild.
-if (NOT CMAKE_IOS_DEVELOPER_ROOT)
-  get_filename_component(IOS_PLATFORM_SDK_DIR ${CMAKE_OSX_SYSROOT} PATH)
-  get_filename_component(CMAKE_IOS_DEVELOPER_ROOT ${IOS_PLATFORM_SDK_DIR} PATH)
-endif()
-if (NOT EXISTS ${CMAKE_IOS_DEVELOPER_ROOT})
-  message(FATAL_ERROR "Invalid CMAKE_IOS_DEVELOPER_ROOT: "
-    "${CMAKE_IOS_DEVELOPER_ROOT} does not exist.")
+if (NOT DEFINED CMAKE_DEVELOPER_ROOT AND NOT CMAKE_GENERATOR MATCHES "Xcode")
+  get_filename_component(PLATFORM_SDK_DIR ${CMAKE_OSX_SYSROOT_INT} PATH)
+  get_filename_component(CMAKE_DEVELOPER_ROOT ${PLATFORM_SDK_DIR} PATH)
+  if (NOT EXISTS "${CMAKE_DEVELOPER_ROOT}")
+    message(FATAL_ERROR "Invalid CMAKE_DEVELOPER_ROOT: ${CMAKE_DEVELOPER_ROOT} does not exist.")
+  endif()
 endif()
+
 # Find the C & C++ compilers for the specified SDK.
-if (NOT CMAKE_C_COMPILER)
-  execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang
-    OUTPUT_VARIABLE CMAKE_C_COMPILER
-    ERROR_QUIET
-    OUTPUT_STRIP_TRAILING_WHITESPACE)
-  message(STATUS "Using C compiler: ${CMAKE_C_COMPILER}")
-endif()
-if (NOT CMAKE_CXX_COMPILER)
-  execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang++
-    OUTPUT_VARIABLE CMAKE_CXX_COMPILER
-    ERROR_QUIET
-    OUTPUT_STRIP_TRAILING_WHITESPACE)
-  message(STATUS "Using CXX compiler: ${CMAKE_CXX_COMPILER}")
+if(DEFINED CMAKE_C_COMPILER)
+  # Environment variables are always preserved.
+  set(ENV{_CMAKE_C_COMPILER} "${CMAKE_C_COMPILER}")
+elseif(DEFINED ENV{_CMAKE_C_COMPILER})
+  set(CMAKE_C_COMPILER "$ENV{_CMAKE_C_COMPILER}")
+elseif(NOT DEFINED CMAKE_C_COMPILER)
+  execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find clang
+          OUTPUT_VARIABLE CMAKE_C_COMPILER
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+endif()
+if(DEFINED CMAKE_CXX_COMPILER)
+  # Environment variables are always preserved.
+  set(ENV{_CMAKE_CXX_COMPILER} "${CMAKE_CXX_COMPILER}")
+elseif(DEFINED ENV{_CMAKE_CXX_COMPILER})
+  set(CMAKE_CXX_COMPILER "$ENV{_CMAKE_CXX_COMPILER}")
+elseif(NOT DEFINED CMAKE_CXX_COMPILER)
+  execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find clang++
+          OUTPUT_VARIABLE CMAKE_CXX_COMPILER
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
 endif()
 # Find (Apple's) libtool.
-execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find libtool
-  OUTPUT_VARIABLE IOS_LIBTOOL
-  ERROR_QUIET
-  OUTPUT_STRIP_TRAILING_WHITESPACE)
-message(STATUS "Using libtool: ${IOS_LIBTOOL}")
+if(DEFINED BUILD_LIBTOOL)
+  # Environment variables are always preserved.
+  set(ENV{_BUILD_LIBTOOL} "${BUILD_LIBTOOL}")
+elseif(DEFINED ENV{_BUILD_LIBTOOL})
+  set(BUILD_LIBTOOL "$ENV{_BUILD_LIBTOOL}")
+elseif(NOT DEFINED BUILD_LIBTOOL)
+  execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find libtool
+          OUTPUT_VARIABLE BUILD_LIBTOOL
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+endif()
+# Find the toolchain's provided install_name_tool if none is found on the host
+if(DEFINED CMAKE_INSTALL_NAME_TOOL)
+  # Environment variables are always preserved.
+  set(ENV{_CMAKE_INSTALL_NAME_TOOL} "${CMAKE_INSTALL_NAME_TOOL}")
+elseif(DEFINED ENV{_CMAKE_INSTALL_NAME_TOOL})
+  set(CMAKE_INSTALL_NAME_TOOL "$ENV{_CMAKE_INSTALL_NAME_TOOL}")
+elseif(NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
+  execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find install_name_tool
+          OUTPUT_VARIABLE CMAKE_INSTALL_NAME_TOOL_INT
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+  set(CMAKE_INSTALL_NAME_TOOL ${CMAKE_INSTALL_NAME_TOOL_INT} CACHE INTERNAL "")
+endif()
+
 # Configure libtool to be used instead of ar + ranlib to build static libraries.
 # This is required on Xcode 7+, but should also work on previous versions of
 # Xcode.
-set(CMAKE_C_CREATE_STATIC_LIBRARY
-  "${IOS_LIBTOOL} -static -o <TARGET> <LINK_FLAGS> <OBJECTS> ")
-set(CMAKE_CXX_CREATE_STATIC_LIBRARY
-  "${IOS_LIBTOOL} -static -o <TARGET> <LINK_FLAGS> <OBJECTS> ")
-# Get the version of Darwin (OS X) of the host.
-execute_process(COMMAND uname -r
-  OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION
-  ERROR_QUIET
-  OUTPUT_STRIP_TRAILING_WHITESPACE)
+get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
+foreach(lang ${languages})
+  set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "${BUILD_LIBTOOL} -static -o <TARGET> <LINK_FLAGS> <OBJECTS> " CACHE INTERNAL "")
+endforeach()
+
+# CMake 3.14+ support building for iOS, watchOS and tvOS out of the box.
+if(MODERN_CMAKE)
+  if(SDK_NAME MATCHES "iphone")
+    set(CMAKE_SYSTEM_NAME iOS)
+  elseif(SDK_NAME MATCHES "macosx")
+    set(CMAKE_SYSTEM_NAME Darwin)
+  elseif(SDK_NAME MATCHES "appletv")
+    set(CMAKE_SYSTEM_NAME tvOS)
+  elseif(SDK_NAME MATCHES "watch")
+    set(CMAKE_SYSTEM_NAME watchOS)
+  endif()
+  # Provide flags for a combined FAT library build on newer CMake versions
+  if(PLATFORM_INT MATCHES ".*COMBINED")
+    set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO")
+    set(CMAKE_IOS_INSTALL_COMBINED YES)
+    message(STATUS "Will combine built (static) artifacts into FAT lib...")
+  endif()
+elseif(NOT DEFINED CMAKE_SYSTEM_NAME AND ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.10")
+  # Legacy code path prior to CMake 3.14 or fallback if no CMAKE_SYSTEM_NAME specified
+  set(CMAKE_SYSTEM_NAME iOS)
+elseif(NOT DEFINED CMAKE_SYSTEM_NAME)
+  # Legacy code path prior to CMake 3.14 or fallback if no CMAKE_SYSTEM_NAME specified
+  set(CMAKE_SYSTEM_NAME Darwin)
+endif()
 # Standard settings.
-set(CMAKE_SYSTEM_NAME Darwin CACHE INTERNAL "")
-set(CMAKE_SYSTEM_VERSION ${IOS_SDK_VERSION} CACHE INTERNAL "")
+set(CMAKE_SYSTEM_VERSION ${SDK_VERSION} CACHE INTERNAL "")
 set(UNIX TRUE CACHE BOOL "")
 set(APPLE TRUE CACHE BOOL "")
-set(IOS TRUE CACHE BOOL "")
+if(PLATFORM STREQUAL "MAC" OR PLATFORM STREQUAL "MAC_ARM64")
+  set(IOS FALSE CACHE BOOL "")
+  set(MACOS TRUE CACHE BOOL "")
+elseif(PLATFORM STREQUAL "MAC_CATALYST" OR PLATFORM STREQUAL "MAC_CATALYST_ARM64")
+  set(IOS TRUE CACHE BOOL "")
+  set(MACOS TRUE CACHE BOOL "")
+else()
+  set(IOS TRUE CACHE BOOL "")
+endif()
 set(CMAKE_AR ar CACHE FILEPATH "" FORCE)
 set(CMAKE_RANLIB ranlib CACHE FILEPATH "" FORCE)
-# Force unset of OS X-specific deployment target (otherwise autopopulated),
-# required as of cmake 2.8.10.
-set(CMAKE_OSX_DEPLOYMENT_TARGET "" CACHE STRING
-  "Must be empty for iOS builds." FORCE)
+set(CMAKE_STRIP strip CACHE FILEPATH "" FORCE)
 # Set the architectures for which to build.
-set(CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING "Build architecture for iOS")
-# Change the type of target generated for try_compile() so it'll work when cross-compiling
-set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+set(CMAKE_OSX_ARCHITECTURES ${ARCHS} CACHE INTERNAL "")
+# Change the type of target generated for try_compile() so it'll work when cross-compiling, weak compiler checks
+if(NOT ENABLE_STRICT_TRY_COMPILE_INT)
+  set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+endif()
 # All iOS/Darwin specific settings - some may be redundant.
+set(CMAKE_MACOSX_BUNDLE YES)
+set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
 set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
 set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")
 set(CMAKE_SHARED_MODULE_PREFIX "lib")
@@ -339,152 +669,259 @@ set(CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ")
 set(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}")
 set(CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}")
 
-if(IOS_ARCH MATCHES "((^|, )(arm64|arm64e|x86_64))+")
+if(ARCHS MATCHES "((^|;|, )(arm64|arm64e|x86_64))+")
   set(CMAKE_C_SIZEOF_DATA_PTR 8)
   set(CMAKE_CXX_SIZEOF_DATA_PTR 8)
-  message(STATUS "Using a data_ptr size of 8")
+  if(ARCHS MATCHES "((^|;|, )(arm64|arm64e))+")
+    set(CMAKE_SYSTEM_PROCESSOR "aarch64")
+  else()
+    set(CMAKE_SYSTEM_PROCESSOR "x86_64")
+  endif()
 else()
   set(CMAKE_C_SIZEOF_DATA_PTR 4)
   set(CMAKE_CXX_SIZEOF_DATA_PTR 4)
-  message(STATUS "Using a data_ptr size of 4")
+  set(CMAKE_SYSTEM_PROCESSOR "arm")
 endif()
 
-message(STATUS "Building for minimum iOS version: ${IOS_DEPLOYMENT_TARGET}"
-               " (SDK version: ${IOS_SDK_VERSION})")
 # Note that only Xcode 7+ supports the newer more specific:
-# -m${XCODE_IOS_PLATFORM}-version-min flags, older versions of Xcode use:
+# -m${SDK_NAME}-version-min flags, older versions of Xcode use:
 # -m(ios/ios-simulator)-version-min instead.
-if (IOS_PLATFORM STREQUAL "OS" OR IOS_PLATFORM STREQUAL "OS64")
-  if (XCODE_VERSION VERSION_LESS 7.0)
-    set(XCODE_IOS_PLATFORM_VERSION_FLAGS
-      "-mios-version-min=${IOS_DEPLOYMENT_TARGET}")
+if(${CMAKE_VERSION} VERSION_LESS "3.11")
+  if(PLATFORM_INT STREQUAL "OS" OR PLATFORM_INT STREQUAL "OS64")
+    if(XCODE_VERSION_INT VERSION_LESS 7.0)
+      set(SDK_NAME_VERSION_FLAGS
+              "-mios-version-min=${DEPLOYMENT_TARGET}")
+    else()
+      # Xcode 7.0+ uses flags we can build directly from SDK_NAME.
+      set(SDK_NAME_VERSION_FLAGS
+              "-m${SDK_NAME}-version-min=${DEPLOYMENT_TARGET}")
+    endif()
+  elseif(PLATFORM_INT STREQUAL "TVOS")
+    set(SDK_NAME_VERSION_FLAGS
+            "-mtvos-version-min=${DEPLOYMENT_TARGET}")
+  elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS")
+    set(SDK_NAME_VERSION_FLAGS
+            "-mtvos-simulator-version-min=${DEPLOYMENT_TARGET}")
+  elseif(PLATFORM_INT STREQUAL "WATCHOS")
+    set(SDK_NAME_VERSION_FLAGS
+            "-mwatchos-version-min=${DEPLOYMENT_TARGET}")
+  elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS")
+    set(SDK_NAME_VERSION_FLAGS
+            "-mwatchos-simulator-version-min=${DEPLOYMENT_TARGET}")
+  elseif(PLATFORM_INT STREQUAL "MAC")
+    set(SDK_NAME_VERSION_FLAGS
+            "-mmacosx-version-min=${DEPLOYMENT_TARGET}")
   else()
-    # Xcode 7.0+ uses flags we can build directly from XCODE_IOS_PLATFORM.
-    set(XCODE_IOS_PLATFORM_VERSION_FLAGS
-      "-m${XCODE_IOS_PLATFORM}-version-min=${IOS_DEPLOYMENT_TARGET}")
+    # SIMULATOR or SIMULATOR64 both use -mios-simulator-version-min.
+    set(SDK_NAME_VERSION_FLAGS
+            "-mios-simulator-version-min=${DEPLOYMENT_TARGET}")
   endif()
-elseif (IOS_PLATFORM STREQUAL "TVOS")
-  set(XCODE_IOS_PLATFORM_VERSION_FLAGS
-    "-mtvos-version-min=${IOS_DEPLOYMENT_TARGET}")
-elseif (IOS_PLATFORM STREQUAL "SIMULATOR_TVOS")
-  set(XCODE_IOS_PLATFORM_VERSION_FLAGS
-    "-mtvos-simulator-version-min=${IOS_DEPLOYMENT_TARGET}")
-elseif (IOS_PLATFORM STREQUAL "WATCHOS")
-  set(XCODE_IOS_PLATFORM_VERSION_FLAGS
-    "-mwatchos-version-min=${IOS_DEPLOYMENT_TARGET}")
-elseif (IOS_PLATFORM STREQUAL "SIMULATOR_WATCHOS")
-  set(XCODE_IOS_PLATFORM_VERSION_FLAGS
-    "-mwatchos-simulator-version-min=${IOS_DEPLOYMENT_TARGET}")
-else()
-  # SIMULATOR or SIMULATOR64 both use -mios-simulator-version-min.
-  set(XCODE_IOS_PLATFORM_VERSION_FLAGS
-    "-mios-simulator-version-min=${IOS_DEPLOYMENT_TARGET}")
+elseif(NOT PLATFORM_INT STREQUAL "MAC_CATALYST")
+  # Newer versions of CMake sets the version min flags correctly, skip this for Mac Catalyst targets
+  set(CMAKE_OSX_DEPLOYMENT_TARGET ${DEPLOYMENT_TARGET})
+endif()
+
+if(DEFINED APPLE_TARGET_TRIPLE_INT)
+  set(APPLE_TARGET_TRIPLE ${APPLE_TARGET_TRIPLE_INT} CACHE INTERNAL "")
 endif()
-message(STATUS "Version flags set to: ${XCODE_IOS_PLATFORM_VERSION_FLAGS}")
 
-if (ENABLE_BITCODE)
+if(PLATFORM_INT STREQUAL "MAC_CATALYST")
+  set(C_TARGET_FLAGS "-target ${APPLE_TARGET_TRIPLE_INT} -isystem ${CMAKE_OSX_SYSROOT_INT}/System/iOSSupport/usr/include")
+endif()
+
+if(ENABLE_BITCODE_INT)
   set(BITCODE "-fembed-bitcode")
-  set(HEADER_PAD "")
-  message(STATUS "Enabling bitcode support.")
+  set(CMAKE_XCODE_ATTRIBUTE_BITCODE_GENERATION_MODE "bitcode")
+  set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
 else()
   set(BITCODE "")
-  set(HEADER_PAD "-headerpad_max_install_names")
-  message(STATUS "Disabling bitcode support.")
+  set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
 endif()
 
-if (ENABLE_ARC)
+if(ENABLE_ARC_INT)
   set(FOBJC_ARC "-fobjc-arc")
-  message(STATUS "Enabling ARC support.")
+  set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES")
 else()
   set(FOBJC_ARC "-fno-objc-arc")
-  message(STATUS "Disabling ARC support.")
+  set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "NO")
 endif()
 
-if (NOT ENABLE_VISIBILITY)
-  set(VISIBILITY "-fvisibility=hidden")
-  message(STATUS "Hiding symbols (-fvisibility=hidden).")
+if(NOT ENABLE_VISIBILITY_INT)
+  foreach(lang ${languages})
+    set(CMAKE_${lang}_VISIBILITY_PRESET "hidden" CACHE INTERNAL "")
+  endforeach()
+  set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "YES")
+  set(VISIBILITY "-fvisibility=hidden -fvisibility-inlines-hidden")
 else()
-  set(VISIBILITY "")
-endif()
-
-set(CMAKE_C_FLAGS
-"${XCODE_IOS_PLATFORM_VERSION_FLAGS} ${BITCODE} -fobjc-abi-version=2 ${FOBJC_ARC} ${CMAKE_C_FLAGS}")
-# Hidden visibilty is required for C++ on iOS.
-set(CMAKE_CXX_FLAGS
-"${XCODE_IOS_PLATFORM_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} -fvisibility-inlines-hidden -fobjc-abi-version=2 ${FOBJC_ARC} ${CMAKE_CXX_FLAGS}")
-set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -DNDEBUG -Os -ffast-math ${BITCODE} ${CMAKE_CXX_FLAGS_MINSIZEREL}")
-set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG -O2 -g -ffast-math ${BITCODE} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
-set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG -O3 -ffast-math ${BITCODE} ${CMAKE_CXX_FLAGS_RELEASE}")
-set(CMAKE_C_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}")
-set(CMAKE_CXX_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS}  -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}")
-
-# In order to ensure that the updated compiler flags are used in try_compile()
-# tests, we have to forcibly set them in the CMake cache, not merely set them
-# in the local scope.
-list(APPEND VARS_TO_FORCE_IN_CACHE
-  CMAKE_C_FLAGS
-  CMAKE_CXX_FLAGS
-  CMAKE_CXX_FLAGS_RELWITHDEBINFO
-  CMAKE_CXX_FLAGS_MINSIZEREL
-  CMAKE_CXX_FLAGS_RELEASE
-  CMAKE_C_LINK_FLAGS
-  CMAKE_CXX_LINK_FLAGS)
-foreach(VAR_TO_FORCE ${VARS_TO_FORCE_IN_CACHE})
-  set(${VAR_TO_FORCE} "${${VAR_TO_FORCE}}" CACHE STRING "")
-endforeach()
+  foreach(lang ${languages})
+    set(CMAKE_${lang}_VISIBILITY_PRESET "default" CACHE INTERNAL "")
+  endforeach()
+  set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "NO")
+  set(VISIBILITY "-fvisibility=default")
+endif()
+
+#Check if Xcode generator is used, since that will handle these flags automagically
+if(CMAKE_GENERATOR MATCHES "Xcode")
+  message(STATUS "Not setting any manual command-line buildflags, since Xcode is selected as generator.")
+else()
+  # Hidden visibility is required for C++ on iOS.
+  set(CMAKE_C_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} ${BITCODE} -fobjc-abi-version=2 ${FOBJC_ARC} ${CMAKE_C_FLAGS}")
+  set(CMAKE_CXX_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} -fobjc-abi-version=2 ${FOBJC_ARC} ${CMAKE_CXX_FLAGS}")
+  set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -g ${CMAKE_CXX_FLAGS_DEBUG}")
+  set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -DNDEBUG -Os -ffast-math ${CMAKE_CXX_FLAGS_MINSIZEREL}")
+  set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG -O2 -g -ffast-math ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
+  set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG -O3 -ffast-math ${CMAKE_CXX_FLAGS_RELEASE}")
+  set(CMAKE_C_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}")
+  set(CMAKE_CXX_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS}  -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}")
+  set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp -arch ${CMAKE_OSX_ARCHITECTURES}")
+endif()
+
+## Print status messages to inform of the current state
+message(STATUS "Configuring ${SDK_NAME} build for platform: ${PLATFORM_INT}, architecture(s): ${ARCHS}")
+message(STATUS "Using SDK: ${CMAKE_OSX_SYSROOT_INT}")
+message(STATUS "Using C compiler: ${CMAKE_C_COMPILER}")
+message(STATUS "Using CXX compiler: ${CMAKE_CXX_COMPILER}")
+message(STATUS "Using libtool: ${BUILD_LIBTOOL}")
+message(STATUS "Using install name tool: ${CMAKE_INSTALL_NAME_TOOL}")
+if(DEFINED APPLE_TARGET_TRIPLE)
+  message(STATUS "Autoconf target triple: ${APPLE_TARGET_TRIPLE}")
+endif()
+message(STATUS "Using minimum deployment version: ${DEPLOYMENT_TARGET}"
+        " (SDK version: ${SDK_VERSION})")
+if(MODERN_CMAKE)
+  message(STATUS "Merging integrated CMake 3.14+ iOS,tvOS,watchOS,macOS toolchain(s) with this toolchain!")
+endif()
+if(CMAKE_GENERATOR MATCHES "Xcode")
+  message(STATUS "Using Xcode version: ${XCODE_VERSION_INT}")
+endif()
+message(STATUS "CMake version: ${CMAKE_VERSION}")
+if(DEFINED SDK_NAME_VERSION_FLAGS)
+  message(STATUS "Using version flags: ${SDK_NAME_VERSION_FLAGS}")
+endif()
+message(STATUS "Using a data_ptr size of: ${CMAKE_CXX_SIZEOF_DATA_PTR}")
+if(ENABLE_BITCODE_INT)
+  message(STATUS "Bitcode: Enabled")
+else()
+  message(STATUS "Bitcode: Disabled")
+endif()
+
+if(ENABLE_ARC_INT)
+  message(STATUS "ARC: Enabled")
+else()
+  message(STATUS "ARC: Disabled")
+endif()
+
+if(ENABLE_VISIBILITY_INT)
+  message(STATUS "Hiding symbols: Disabled")
+else()
+  message(STATUS "Hiding symbols: Enabled")
+endif()
+
+# Set global properties
+set_property(GLOBAL PROPERTY PLATFORM "${PLATFORM}")
+set_property(GLOBAL PROPERTY APPLE_TARGET_TRIPLE "${APPLE_TARGET_TRIPLE_INT}")
+set_property(GLOBAL PROPERTY SDK_VERSION "${SDK_VERSION}")
+set_property(GLOBAL PROPERTY XCODE_VERSION "${XCODE_VERSION_INT}")
+set_property(GLOBAL PROPERTY OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}")
+
+# Export configurable variables for the try_compile() command.
+set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
+        PLATFORM
+        XCODE_VERSION_INT
+        SDK_VERSION
+        DEPLOYMENT_TARGET
+        CMAKE_DEVELOPER_ROOT
+        CMAKE_OSX_SYSROOT_INT
+        ENABLE_BITCODE
+        ENABLE_ARC
+        CMAKE_C_COMPILER
+        CMAKE_CXX_COMPILER
+        BUILD_LIBTOOL
+        CMAKE_INSTALL_NAME_TOOL
+        CMAKE_C_FLAGS
+        CMAKE_CXX_FLAGS
+        CMAKE_CXX_FLAGS_DEBUG
+        CMAKE_CXX_FLAGS_MINSIZEREL
+        CMAKE_CXX_FLAGS_RELWITHDEBINFO
+        CMAKE_CXX_FLAGS_RELEASE
+        CMAKE_C_LINK_FLAGS
+        CMAKE_CXX_LINK_FLAGS
+        CMAKE_ASM_FLAGS
+        )
 
 set(CMAKE_PLATFORM_HAS_INSTALLNAME 1)
-set (CMAKE_SHARED_LINKER_FLAGS "-rpath @executable_path/Frameworks -rpath @loader_path/Frameworks")
-set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib ${HEADER_PAD}")
-set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle ${HEADER_PAD}")
+set(CMAKE_SHARED_LINKER_FLAGS "-rpath @executable_path/Frameworks -rpath @loader_path/Frameworks")
+set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
+set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -Wl,-headerpad_max_install_names")
 set(CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,")
 set(CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,")
-set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
-
-# Hack: if a new cmake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old
-# build tree (where install_name_tool was hardcoded) and where
-# CMAKE_INSTALL_NAME_TOOL isn't in the cache and still cmake didn't fail in
-# CMakeFindBinUtils.cmake (because it isn't rerun) hardcode
-# CMAKE_INSTALL_NAME_TOOL here to install_name_tool, so it behaves as it did
-# before, Alex.
-if (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
-  find_program(CMAKE_INSTALL_NAME_TOOL install_name_tool)
-endif (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
-
-# Set the find root to the iOS developer roots and to user defined paths.
-set(CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_OSX_SYSROOT}
-  ${CMAKE_PREFIX_PATH} CACHE STRING  "iOS find search path root" FORCE)
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".tbd" ".dylib" ".so" ".a")
+set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name")
+
+# Set the find root to the SDK developer roots.
+# Note: CMAKE_FIND_ROOT_PATH is only useful when cross-compiling. Thus, do not set on macOS builds.
+if(NOT PLATFORM_INT STREQUAL "MAC" AND NOT PLATFORM_INT STREQUAL "MAC_ARM64")
+  list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "")
+  set(CMAKE_IGNORE_PATH "/System/Library/Frameworks;/usr/local/lib" CACHE INTERNAL "")
+endif()
+
 # Default to searching for frameworks first.
 set(CMAKE_FIND_FRAMEWORK FIRST)
+
 # Set up the default search directories for frameworks.
-set(CMAKE_SYSTEM_FRAMEWORK_PATH
-  ${CMAKE_OSX_SYSROOT}/System/Library/Frameworks
-  ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks
-  ${CMAKE_OSX_SYSROOT}/Developer/Library/Frameworks)
-# Only search the specified iOS SDK, not the remainder of the host filesystem.
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-# This little macro lets you set any XCode specific property.
+if(PLATFORM_INT MATCHES "MAC_CATALYST.*")
+  set(CMAKE_FRAMEWORK_PATH
+          ${CMAKE_DEVELOPER_ROOT}/Library/PrivateFrameworks
+          ${CMAKE_OSX_SYSROOT_INT}/System/Library/Frameworks
+          ${CMAKE_OSX_SYSROOT_INT}/System/iOSSupport/System/Library/Frameworks
+          ${CMAKE_FRAMEWORK_PATH} CACHE INTERNAL "")
+else()
+  set(CMAKE_FRAMEWORK_PATH
+          ${CMAKE_DEVELOPER_ROOT}/Library/PrivateFrameworks
+          ${CMAKE_OSX_SYSROOT_INT}/System/Library/Frameworks
+          ${CMAKE_FRAMEWORK_PATH} CACHE INTERNAL "")
+endif()
+
+# By default, search both the specified iOS SDK and the remainder of the host filesystem.
+if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
+  set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH CACHE INTERNAL "")
+endif()
+if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
+  set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH CACHE INTERNAL "")
+endif()
+if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
+  set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH CACHE INTERNAL "")
+endif()
+if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
+  set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH CACHE INTERNAL "")
+endif()
+
+#
+# Some helper-macros below to simplify and beautify the CMakeFile
+#
+
+# This little macro lets you set any Xcode specific property.
 macro(set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE XCODE_RELVERSION)
   set(XCODE_RELVERSION_I "${XCODE_RELVERSION}")
-  if (XCODE_RELVERSION_I STREQUAL "All")
-    set_property(TARGET ${TARGET} PROPERTY
-    XCODE_ATTRIBUTE_${XCODE_PROPERTY} "${XCODE_VALUE}")
+  if(XCODE_RELVERSION_I STREQUAL "All")
+    set_property(TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} "${XCODE_VALUE}")
   else()
-    set_property(TARGET ${TARGET} PROPERTY
-    XCODE_ATTRIBUTE_${XCODE_PROPERTY}[variant=${XCODE_RELVERSION_I}] "${XCODE_VALUE}")
+    set_property(TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY}[variant=${XCODE_RELVERSION_I}] "${XCODE_VALUE}")
   endif()
 endmacro(set_xcode_property)
+
 # This macro lets you find executable programs on the host system.
 macro(find_host_package)
   set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
   set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER)
   set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER)
+  set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER)
+  set(_TOOLCHAIN_IOS ${IOS})
   set(IOS FALSE)
   find_package(${ARGN})
-  set(IOS TRUE)
-  set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
-  set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-  set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+  set(IOS ${_TOOLCHAIN_IOS})
+  set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
+  set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
+  set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
+  set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
 endmacro(find_host_package)