Files
telegram-tui/scripts/build-tdlib-ios.sh
2026-05-21 15:27:59 +03:00

188 lines
6.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
tdlib_version="${TDLIB_VERSION:-1.8.29}"
tdlib_commit="${TDLIB_COMMIT:-af69dd4397b6dc1bf23ba0fd0bf429fcba6454f6}"
tdlib_repo="${TDLIB_REPO:-https://github.com/tdlib/td.git}"
source_dir="${TDLIB_SOURCE_DIR:-${repo_root}/.build/tdlib-src}"
build_root="${TDLIB_BUILD_ROOT:-${repo_root}/.build/tdlib-ios-build}"
output_root="${TDLIB_OUTPUT_ROOT:-${repo_root}/.build/tdlib-ios}"
platforms="${TDLIB_IOS_PLATFORMS:-iOS iOS-simulator}"
openssl_platforms="${TDLIB_OPENSSL_PLATFORMS:-iOS iOS-simulator}"
ios_deployment_target="${TDLIB_IOS_DEPLOYMENT_TARGET:-17.0}"
jobs="${TDLIB_BUILD_JOBS:-3}"
if [[ -z "${DEVELOPER_DIR:-}" && -d /Applications/Xcode.app/Contents/Developer ]]; then
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
fi
require_tool() {
if ! command -v "$1" >/dev/null 2>&1; then
printf 'Required tool not found: %s\n' "$1" >&2
return 1
fi
}
missing=0
for tool in git cmake c++ gperf make perl rsync xcodebuild xcrun install_name_tool; do
require_tool "${tool}" || missing=1
done
if [[ "${missing}" -ne 0 ]]; then
printf '\nInstall missing TDLib build dependencies on macOS with:\n' >&2
printf ' brew install cmake gperf coreutils\n' >&2
exit 1
fi
if ! xcrun --sdk iphoneos --show-sdk-path >/dev/null; then
printf 'The iphoneos SDK is unavailable through xcrun.\n' >&2
printf 'Set DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer and install the iOS platform in Xcode.\n' >&2
exit 1
fi
mkdir -p "$(dirname "${source_dir}")" "${build_root}" "${output_root}"
if [[ ! -d "${source_dir}/.git" ]]; then
git clone "${tdlib_repo}" "${source_dir}"
fi
git -C "${source_dir}" fetch --depth 1 origin "${tdlib_commit}"
git -C "${source_dir}" checkout --detach "${tdlib_commit}"
openssl_root="${source_dir}/example/ios/third_party/openssl"
python_apple_support_dir="${source_dir}/example/ios/Python-Apple-support"
prepare_python_apple_support() {
if [[ ! -d "${python_apple_support_dir}/.git" ]]; then
git clone https://github.com/beeware/Python-Apple-support "${python_apple_support_dir}"
fi
git -C "${python_apple_support_dir}" checkout 6f43aba0ddd5a9f52f39775d0141bd4363614020
git -C "${python_apple_support_dir}" reset --hard
(
cd "${python_apple_support_dir}"
git apply ../Python-Apple-support.patch
# Python-Apple-support at this revision emits apple-ios-simulator-simulator
# under newer Xcode SDK naming. Use the base OS name before appending
# "-simulator" to the target triple.
perl -pi -e 's/apple-\$\$\(OS_LOWER-\$\(target\)\)-simulator/apple-\$\$\(patsubst %-simulator,%,\$\$\(OS_LOWER-\$\(target\)\)\)-simulator/' Makefile
)
}
prepare_td_auto_sources() {
local host_build_dir="${build_root}/build-host-generate"
local td_auto_dir="${source_dir}/td/generate/auto/td/telegram"
local mime_auto_dir="${source_dir}/tdutils/generate/auto"
if [[ -f "${td_auto_dir}/td_api.cpp" \
&& -f "${td_auto_dir}/td_api_json.cpp" \
&& -f "${mime_auto_dir}/mime_type_to_extension.cpp" \
&& -f "${mime_auto_dir}/extension_to_mime_type.cpp" ]]; then
return 0
fi
ZERO_AR_DATE=1 cmake -S "${source_dir}" -B "${host_build_dir}" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_MAKE_PROGRAM=make
cmake --build "${host_build_dir}" --target prepare_cross_compiling -- -j"${jobs}"
}
prepare_openssl_platform() {
local platform="$1"
local output_dir="${openssl_root}/${platform}"
if [[ -f "${output_dir}/lib/libcrypto.a" && -f "${output_dir}/lib/libssl.a" ]]; then
return 0
fi
prepare_python_apple_support
(
cd "${python_apple_support_dir}"
rm -rf "build/${platform}" "install/${platform}" "merge/${platform}"
make "OpenSSL-${platform}"
)
rm -rf "${output_dir}"
mkdir -p "${output_dir}/lib"
cp "${python_apple_support_dir}/merge/${platform}/openssl/lib/libcrypto.a" "${output_dir}/lib/"
cp "${python_apple_support_dir}/merge/${platform}/openssl/lib/libssl.a" "${output_dir}/lib/"
cp -R "${python_apple_support_dir}/merge/${platform}/openssl/include" "${output_dir}/include"
}
if [[ ! -f "${openssl_root}/iOS/lib/libcrypto.a" || ! -f "${openssl_root}/iOS-simulator/lib/libcrypto.a" ]]; then
printf 'OpenSSL for iOS was not found under %s.\n' "${openssl_root}" >&2
printf 'Building only required OpenSSL platforms: %s\n' "${openssl_platforms}"
for platform in ${openssl_platforms}; do
prepare_openssl_platform "${platform}"
done
fi
prepare_td_auto_sources
build_platform() {
local td_platform="$1"
local ios_platform
local out_platform
case "${td_platform}" in
iOS)
ios_platform="OS"
out_platform="iphoneos"
;;
iOS-simulator)
ios_platform="SIMULATOR"
out_platform="iphonesimulator"
;;
*)
printf 'Unsupported TDLib iOS platform: %s\n' "${td_platform}" >&2
return 1
;;
esac
local openssl_path="${openssl_root}/${td_platform}"
local openssl_crypto_library="${openssl_path}/lib/libcrypto.a"
local openssl_ssl_library="${openssl_path}/lib/libssl.a"
local build_dir="${build_root}/build-${td_platform}"
local install_dir="${build_root}/install-${td_platform}"
local output_dir="${output_root}/${out_platform}"
if [[ ! -f "${openssl_crypto_library}" || ! -f "${openssl_ssl_library}" ]]; then
printf 'OpenSSL libraries are missing for %s under %s\n' "${td_platform}" "${openssl_path}" >&2
return 1
fi
rm -rf "${build_dir}" "${install_dir}" "${output_dir}"
mkdir -p "${build_dir}" "${install_dir}" "${output_dir}/include" "${output_dir}/lib"
ZERO_AR_DATE=1 cmake -S "${source_dir}" -B "${build_dir}" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_INSTALL_PREFIX="${install_dir}" \
-DCMAKE_TOOLCHAIN_FILE="${source_dir}/CMake/iOS.cmake" \
-DIOS_PLATFORM="${ios_platform}" \
-DIOS_DEPLOYMENT_TARGET="${ios_deployment_target}" \
-DCMAKE_MAKE_PROGRAM=make \
-DOPENSSL_FOUND=1 \
-DOPENSSL_CRYPTO_LIBRARY="${openssl_crypto_library}" \
-DOPENSSL_SSL_LIBRARY="${openssl_ssl_library}" \
-DOPENSSL_INCLUDE_DIR="${openssl_path}/include" \
-DOPENSSL_LIBRARIES="${openssl_crypto_library};${openssl_ssl_library}"
cmake --build "${build_dir}" --target install -- -j"${jobs}"
install_name_tool -id @rpath/libtdjson.dylib "${install_dir}/lib/libtdjson.dylib"
rsync -a "${install_dir}/include/" "${output_dir}/include/"
cp "${install_dir}/lib/libtdjson.dylib" "${output_dir}/lib/libtdjson.dylib"
cp "${install_dir}/lib/libtdjson.dylib" "${output_dir}/lib/libtdjson.${tdlib_version}.dylib"
printf 'Installed TDLib %s for %s at %s\n' "${tdlib_version}" "${td_platform}" "${output_dir}"
}
for platform in ${platforms}; do
build_platform "${platform}"
done