0%

telegram不知多少次的重编译

鼎鼎大名的telegram,前后不知道编译几次了,虽然都成功了,一是基本编译完就相当于看完源码😂,二是也没有记录编译的过程,部分内容是重复的。
看自己这次能走到哪里,希望比编译完成走的远一点。
隔天上午终于编译成功了,这次不会随便升级系统和xcode了。

环境

  • big sur 11.1
  • xcode 12.3
  • telegram v7.2
  • buck version 47bf9aaad4fe33fd913f62737f7e581454f80b01

目录

  1. JAVA 11以及版本切换
  2. BUCK 安装使用
  3. WatchMan 安装
  4. Telegram 源码下载及编译
    1. 生成 Telegram_Buck.xcworkspace
    2. 打开生成的 workspace 然后 build

JAVA 11以及版本切换

使用 homebrew 安装 openjdk

  1. 添加到brew
    brew tap adoptopenjdk/openjdk

  2. 查看jdk版本
    brew search jdk

  3. install

    brew cask install adoptopenjdk8     ##Install JDK 8`
    brew cask install adoptopenjdk9 ##Install JDK 9
    brew cask install adoptopenjdk10 ##Install JDK 10
    brew cask install adoptopenjdk11 ##Install JDK 11
    brew cask install adoptopenjdk12 ##Install JDK 12
    brew cask install adoptopenjdk13 ##Install JDK 13
    brew cask install adoptopenjdk14 ##Install JDK 14
    brew cask install adoptopenjdk15 ##Install JDK 15
  4. 查看当前 java 版本

    $ java -version
    openjdk version "11.0.9.1" 2020-11-04
    OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.9.1+1)
    OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.9.1+1, mixed mode)

java版本切换

  1. 查看当前已安装的java版本

    $ /usr/libexec/java_home -V 
    Matching Java Virtual Machines (2):
    11.0.9.1 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 11" /Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
    1.8.0_265 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 8" /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
    /Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
  2. 准备切换脚本,放到当前shell配置文件里,用的 zsh,放在 ~/.zshrc

    export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8)
    export JAVA_11_HOME=$(/usr/libexec/java_home -v11)
    alias java8='export JAVA_HOME=$JAVA_8_HOME'
    alias java11='export JAVA_HOME=$JAVA_11_HOME'
  3. 生效配置文件及切换版本

    $source ~/.zshrc
    $java8 #切换到 8
    $java11 #切换到 11

BUCK 安装使用

到目前为止2021-01-14,使用 homebrew 安装 BUCK 都是失败的。
搜索发现可以使用直接预编译好的版本。

Addepar currently maintains a Java 11 / Python2 fork of Buck: avalible buck link. This might be helpful.

下载这个版本,然后 chmod 755 buck.pex 就可以直接执行了。
之前是使用 buck 现在直接用 buck.pex 比较麻烦的是带上下载地址的路径,因为没有安装到系统路径,所以需要指定路径比如 ~/Downloads/buck.pex

WatchMan 安装

这个还是简单的,使用 homebrew 直接搞定。

$brew update
$brew install watchman

Telegram 源码下载及编译

可以指定版本下载,这次使用的是 7.2

git clone --recursive --branch release-7.2  https://github.com/TelegramMessenger/Telegram-iOS.git
cd telegram-ios

下载完成后,开始编译。
参考经典的两个链接 #219Build and Run Telegram-iOS v7.2 in Xcode 12.x Simulator

生成 Telegram_Buck.xcworkspace

  1. Insert before include Utils.makefile in the Makefile file:

    export BUCK=buck
    export TELEGRAM_ENV_SET=1
    export DEVELOPMENT_CODE_SIGN_IDENTITY=iPhone Distribution: Digital Fortress LLC (C67CF9S4VU)
    export DISTRIBUTION_CODE_SIGN_IDENTITY=iPhone Distribution: Digital Fortress LLC (C67CF9S4VU)
    export DEVELOPMENT_TEAM=C67CF9S4VU
    export API_ID=8
    export API_HASH=7245de8e747a0d6fbe11f7cc14fcc0bb
    export BUNDLE_ID=ph.telegra.Telegraph
    export IS_INTERNAL_BUILD=false
    export IS_APPSTORE_BUILD=true
    export APPSTORE_ID=686449807
    export APP_SPECIFIC_URL_SCHEME=tgapp
    export BUILD_NUMBER=199
    export ENTITLEMENTS_APP=Telegram-iOS/Telegram-iOS-AppStoreLLC.entitlements
    export DEVELOPMENT_PROVISIONING_PROFILE_APP=match Development ph.telegra.Telegraph
    export DISTRIBUTION_PROVISIONING_PROFILE_APP=match AppStore ph.telegra.Telegraph
    export ENTITLEMENTS_EXTENSION_SHARE=Share/Share-AppStoreLLC.entitlements
    export DEVELOPMENT_PROVISIONING_PROFILE_EXTENSION_SHARE=match Development ph.telegra.Telegraph.Share
    export DISTRIBUTION_PROVISIONING_PROFILE_EXTENSION_SHARE=match AppStore ph.telegra.Telegraph.Share
    export ENTITLEMENTS_EXTENSION_WIDGET=Widget/Widget-AppStoreLLC.entitlements
    export DEVELOPMENT_PROVISIONING_PROFILE_EXTENSION_WIDGET=match Development ph.telegra.Telegraph.Widget
    export DISTRIBUTION_PROVISIONING_PROFILE_EXTENSION_WIDGET=match AppStore ph.telegra.Telegraph.Widget
    export ENTITLEMENTS_EXTENSION_NOTIFICATIONSERVICE=NotificationService/NotificationService-AppStoreLLC.entitlements
    export DEVELOPMENT_PROVISIONING_PROFILE_EXTENSION_NOTIFICATIONSERVICE=match Development ph.telegra.Telegraph.NotificationService
    export DISTRIBUTION_PROVISIONING_PROFILE_EXTENSION_NOTIFICATIONSERVICE=match AppStore ph.telegra.Telegraph.NotificationService
    export ENTITLEMENTS_EXTENSION_NOTIFICATIONCONTENT=NotificationContent/NotificationContent-AppStoreLLC.entitlements
    export DEVELOPMENT_PROVISIONING_PROFILE_EXTENSION_NOTIFICATIONCONTENT=match Development ph.telegra.Telegraph.NotificationContent
    export DISTRIBUTION_PROVISIONING_PROFILE_EXTENSION_NOTIFICATIONCONTENT=match AppStore ph.telegra.Telegraph.NotificationContent
    export ENTITLEMENTS_EXTENSION_INTENTS=SiriIntents/SiriIntents-AppStoreLLC.entitlements
    export DEVELOPMENT_PROVISIONING_PROFILE_EXTENSION_INTENTS=match Development ph.telegra.Telegraph.SiriIntents
    export DISTRIBUTION_PROVISIONING_PROFILE_EXTENSION_INTENTS=match AppStore ph.telegra.Telegraph.SiriIntents
    export DEVELOPMENT_PROVISIONING_PROFILE_WATCH_APP=match Development ph.telegra.Telegraph.watchkitapp
    export DISTRIBUTION_PROVISIONING_PROFILE_WATCH_APP=match AppStore ph.telegra.Telegraph.watchkitapp
    export DEVELOPMENT_PROVISIONING_PROFILE_WATCH_EXTENSION=match Development ph.telegra.Telegraph.watchkitapp.watchkitextension
    export DISTRIBUTION_PROVISIONING_PROFILE_WATCH_EXTENSION=match AppStore ph.telegra.Telegraph.watchkitapp.watchkitextension
    export BUILDBOX_DIR=buildbox
    export CODESIGNING_PROFILES_VARIANT=appstore
    export PACKAGE_METHOD=appstore
  2. Insert in SHARED_CONFIGS of Config/utils.bzl file:

    diff --git a/Config/utils.bzl b/Config/utils.bzl
    index ca0271275..26570381c 100644
    --- a/Config/utils.bzl
    +++ b/Config/utils.bzl
    @@ -50,6 +50,7 @@ SHARED_CONFIGS = {
    "ONLY_ACTIVE_ARCH": "YES",
    "LD_RUNPATH_SEARCH_PATHS": "@executable_path/Frameworks",
    "ENABLE_BITCODE": "NO",
    + "DEAD_CODE_STRIPPING": "YES",
    }
  3. mozjpeg 修改, Inside third-party/mozjpeg/BUCK, it declares two targets of arm64 andarmv7. We can change armv7 to x86_64 as we don’t need armv7 in Simulator and on most devices.

    diff --git a/third-party/mozjpeg/BUCK b/third-party/mozjpeg/BUCK
    index 379603ce4..708e0201f 100644
    --- a/third-party/mozjpeg/BUCK
    +++ b/third-party/mozjpeg/BUCK
    @@ -48,7 +48,7 @@ genrule(
    cp $BUILD_DIR/mozjpeg/jmorecfg.h "$OUT/Public/mozjpeg/"
    cp $BUILD_DIR/build/jconfig.h "$OUT/Public/mozjpeg/"

    - BUILD_ARCH="armv7"
    + BUILD_ARCH="x86_64"

    BUILD_DIR="$OUT/$BUILD_ARCH"
    rm -rf "$BUILD_DIR"
    @@ -62,8 +62,8 @@ genrule(

    PATH="$PATH:$CMAKE_DIR/bin" sh $BUILD_DIR/build-mozjpeg-buck.sh $BUILD_ARCH "$BUILD_DIR/mozjpeg" "$BUILD_DIR"

    - lipo -create $OUT/arm64/build/libjpeg.a $OUT/armv7/build/libjpeg.a -output $OUT/Public/lib/libjpeg.a
    - lipo -create $OUT/arm64/build/libturbojpeg.a $OUT/armv7/build/libturbojpeg.a -output $OUT/Public/lib/libturbojpeg.a
    + lipo -create $OUT/arm64/build/libjpeg.a $OUT/x86_64/build/libjpeg.a -output $OUT/Public/lib/libjpeg.a
    + lipo -create $OUT/arm64/build/libturbojpeg.a $OUT/x86_64/build/libturbojpeg.a -output $OUT/Public/lib/libturbojpeg.a
    """,
    out = "libmozjpeg",
    visibility = [
  4. webrtc-ios 修改。

    Telegram-iOS builds its video calls upon webrtc-ios, which is a gigantic module imported this year. It’s supposed to be built to a framework by buck before generating workspace files. Unfortunately, the code in the official repo doesn’t compile with Xcode 12.x and doesn’t support thex86_64 target.

    The first change is on a python script find_sdk.py which is a part of webrtc-ios build system. It helps to locate the SDK path in Xcode.app. The original regular expression ^MacOSX(10.\d+).sdk$ doesn’t work against Xcode 12.x, as the SDK pathname has been changed to Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk. We need to change the expression to ^MacOSX(1[01].\d+).sdk$, which matches both MacOSX10 and MacOSX11 SDK names.

    diff --git a/third-party/webrtc/webrtc-ios/src/build/mac/find_sdk.py b/third-party/webrtc/webrtc-ios/src/build/mac/find_sdk.py
    index 38c28832..44cb85c0 100755
    --- a/third-party/webrtc/webrtc-ios/src/build/mac/find_sdk.py
    +++ b/third-party/webrtc/webrtc-ios/src/build/mac/find_sdk.py
    @@ -88,7 +88,7 @@ def main():
    raise SdkError('Install Xcode, launch it, accept the license ' +
    'agreement, and run `sudo xcode-select -s /path/to/Xcode.app` ' +
    'to continue.')
    - sdks = [re.findall('^MacOSX(10\.\d+)\.sdk$', s) for s in os.listdir(sdk_dir)]
    + sdks = [re.findall('^MacOSX(1[01]\.\d+)\.sdk$', s) for s in os.listdir(sdk_dir)]
    sdks = [s[0] for s in sdks if s] # [['10.5'], ['10.6']] => ['10.5', '10.6']
    sdks = [s for s in sdks # ['10.5', '10.6'] => ['10.6']
    if parse_version(s) >= parse_version(min_sdk_version)]

    The other fix is to add x86_64 target as following:

    diff --git a/third-party/webrtc/BUCK b/third-party/webrtc/BUCK
    index 6762598ed..28bd2f3bd 100644
    --- a/third-party/webrtc/BUCK
    +++ b/third-party/webrtc/BUCK
    @@ -37,11 +37,11 @@ genrule(

    sh $SRCDIR/build-webrtc-buck.sh "$BUILD_DIR" $BUILD_ARCH

    - BUILD_ARCH=arm
    + BUILD_ARCH=x64

    - BUILD_DIR_ARMV7="$SRCDIR/$BUILD_ARCH"
    + BUILD_DIR_X64="$SRCDIR/$BUILD_ARCH"

    - BUILD_DIR="$BUILD_DIR_ARMV7"
    + BUILD_DIR="$BUILD_DIR_X64"

    rm -rf "$BUILD_DIR"
    mkdir -p "$BUILD_DIR"
    @@ -61,7 +61,7 @@ genrule(
    sh $SRCDIR/build-webrtc-buck.sh "$BUILD_DIR" $BUILD_ARCH

    mkdir -p "$OUT"
    - lipo -create "$BUILD_DIR_ARMV7/webrtc-ios/src/out/ios/obj/sdk/libframework_objc_static.a" "$BUILD_DIR_ARM64/webrtc-ios/src/out/ios_64/obj/sdk/libframework_objc_static.a" -output "$OUT/libframework_objc_static.a"
    + lipo -create "$BUILD_DIR_X64/webrtc-ios/src/out/ios_sim/obj/sdk/libframework_objc_static.a" "$BUILD_DIR_ARM64/webrtc-ios/src/out/ios_64/obj/sdk/libframework_objc_static.a" -output "$OUT/libframework_objc_static.a"
    """,
    out = "libwebrtc",
    visibility = ["PUBLIC"]
  5. 生成 workspace file make project

打开生成的 workspace 然后 build

编译的时候会遇到这个问题,主要是 pointerInteraction.swift 导致的,这里提供一个改正好的文件内容,提供参考,主要是注释掉相关语句。

Undefined symbols for architecture x86_64:
"static UIKit.UIPointerShape.defaultCornerRadius.getter : CoreGraphics.CGFloat", referenced from:
Display.(PointerInteractionImpl in _B39DD7E7F85F24DF4F7212BCFE28692F).pointerInteraction(_: __C.UIPointerInteraction, styleFor: __C.UIPointerRegion) -> __C.UIPointerStyle? in PointerInteraction.o
"enum case for UIKit.UIPointerShape.roundedRect(UIKit.UIPointerShape.Type) -> (__C.CGRect, CoreGraphics.CGFloat) -> UIKit.UIPointerShape", referenced from:
Display.(PointerInteractionImpl in _B39DD7E7F85F24DF4F7212BCFE28692F).pointerInteraction(_: __C.UIPointerInteraction, styleFor: __C.UIPointerRegion) -> __C.UIPointerStyle? in PointerInteraction.o
"enum case for UIKit.UIPointerEffect.highlight(UIKit.UIPointerEffect.Type) -> (__C.UITargetedPreview) -> UIKit.UIPointerEffect", referenced from:
Display.(PointerInteractionImpl in _B39DD7E7F85F24DF4F7212BCFE28692F).pointerInteraction(_: __C.UIPointerInteraction, styleFor: __C.UIPointerRegion) -> __C.UIPointerStyle? in PointerInteraction.o
import UIKit
import AsyncDisplayKit

public enum PointerStyle {
case `default`
case rectangle(CGSize)
case circle
case caret
case lift
case hover
}

@available(iOSApplicationExtension 13.4, iOS 13.4, *)
private final class PointerInteractionImpl: NSObject, UIPointerInteractionDelegate {
// weak var pointerInteraction: UIPointerInteraction?

// private let style: PointerStyle

// private let willEnter: () -> Void
// private let willExit: () -> Void

// init(style: PointerStyle, willEnter: @escaping () -> Void, willExit: @escaping () -> Void) {
// self.style = style
// self.willEnter = willEnter
// self.willExit = willExit

// super.init()
// }

// deinit {
// if let pointerInteraction = self.pointerInteraction {
// pointerInteraction.view?.removeInteraction(pointerInteraction)
// }
// }

func setup(view: UIView) {
// let pointerInteraction = UIPointerInteraction(delegate: self)
// view.addInteraction(pointerInteraction)
// self.pointerInteraction = pointerInteraction
}

// func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? {
// var pointerStyle: UIPointerStyle? = nil
// if let interactionView = interaction.view {
// let targetedPreview = UITargetedPreview(view: interactionView)
// switch self.style {
// case .default:
// let horizontalPadding: CGFloat = 10.0
// let verticalPadding: CGFloat = 4.0
// let minHeight: CGFloat = 40.0
// let size: CGSize = CGSize(width: targetedPreview.size.width + horizontalPadding * 2.0, height: max(minHeight, targetedPreview.size.height + verticalPadding * 2.0))
// pointerStyle = UIPointerStyle(effect: .highlight(targetedPreview), shape: .roundedRect(CGRect(origin: CGPoint(x: targetedPreview.view.center.x - size.width / 2.0, y: targetedPreview.view.center.y - size.height / 2.0), size: size), radius: UIPointerShape.defaultCornerRadius))
// case let .rectangle(size):
// pointerStyle = UIPointerStyle(effect: .highlight(targetedPreview), shape: .roundedRect(CGRect(origin: CGPoint(x: targetedPreview.view.center.x - size.width / 2.0, y: targetedPreview.view.center.y - size.height / 2.0), size: size), radius: UIPointerShape.defaultCornerRadius))
// case .circle:
// let maxSide = max(targetedPreview.size.width, targetedPreview.size.height)
// pointerStyle = UIPointerStyle(effect: .highlight(targetedPreview), shape: .path(UIBezierPath(ovalIn: CGRect(origin: CGPoint(), size: CGSize(width: maxSide, height: maxSide)))))
// case .caret:
// pointerStyle = UIPointerStyle(shape: .verticalBeam(length: 24.0), constrainedAxes: .vertical)
// case .lift:
// pointerStyle = UIPointerStyle(effect: .lift(targetedPreview))
// case .hover:
// pointerStyle = UIPointerStyle(effect: .hover(targetedPreview, preferredTintMode: .none, prefersShadow: false, prefersScaledContent: false))
// }
// }
// return pointerStyle
// }

// func pointerInteraction(_ interaction: UIPointerInteraction, willEnter region: UIPointerRegion, animator: UIPointerInteractionAnimating) {
// guard let _ = interaction.view else {
// return
// }

// animator.addAnimations {
// self.willEnter()
// }
// }

// func pointerInteraction(_ interaction: UIPointerInteraction, willExit region: UIPointerRegion, animator: UIPointerInteractionAnimating) {
// guard let _ = interaction.view else {
// return
// }

// animator.addAnimations {
// self.willExit()
// }
// }
}

public final class PointerInteraction {
private var impl: AnyObject?
private let style: PointerStyle

private let willEnter: () -> Void
private let willExit: () -> Void

@available(iOSApplicationExtension 13.4, iOS 13.4, *)
private func withImpl(_ f: (PointerInteractionImpl) -> Void) {
// if self.impl == nil {
// self.impl = PointerInteractionImpl(style: self.style, willEnter: self.willEnter, willExit: self.willExit)
// }
// f(self.impl as! PointerInteractionImpl)
}

public convenience init(node: ASDisplayNode, style: PointerStyle = .default, willEnter: @escaping () -> Void = {}, willExit: @escaping () -> Void = {}) {
self.init(view: node.view, style: style, willEnter: willEnter, willExit: willExit)
}

public init(view: UIView, style: PointerStyle = .default, willEnter: @escaping () -> Void = {}, willExit: @escaping () -> Void = {}) {
self.style = style
self.willEnter = willEnter
self.willExit = willExit
if #available(iOSApplicationExtension 13.4, iOS 13.4, *) {
self.withImpl { impl in
impl.setup(view: view)
}
}
}
}