美文网首页
BUCK - 使用BUCK编译iOS项目(3)

BUCK - 使用BUCK编译iOS项目(3)

作者: 西西的一天 | 来源:发表于2019-12-29 19:25 被阅读0次

    上一节中,使用BUCK编译了一个Cocoapods的三方依赖。本节中我们将使用BUCK来编译一个自定义的library,在此library中使用了Objective-C和C++;之后添加一个二进制的Framework,这里集成的是腾讯的mars日志框架。源码:https://github.com/iossocket/MyBuckSample-iOS/

    自定义Library

    1. 添加两个简单的类,一个是C++实现的,另一个是使用Objective-C实现,其中调用了C++中的功能,所以需要将.m文件改为.mm,目录结构及源码如下所示:
    MyBuckSample-iOS
      - App
      - Libraries
        - ObjcLib
          - Source
            - CppObject.cpp
            - CppObject.hpp
            - OCLabel.h
            - OCLabel.mm
          - BUCK
      - Pods
    
    #ifndef CppObject_hpp
    #define CppObject_hpp
    
    class CppObject {
    public:
        CppObject();
        int add(int a, int b);
        static int static_add(int a, int b);
    };
    
    #endif
    
    #include "CppObject.hpp"
    
    CppObject::CppObject() {}
    
    int CppObject::static_add(int num1, int num2) {
        return num1 + num2;
    }
    
    int CppObject::add(int num1, int num2) {
        return num1 + num2;
    }
    
    #import <UIKit/UIKit.h>
    
    @interface OCLabel : NSObject
    - (UILabel *)generateLabelByText:(NSString *)text;
    @end
    
    #import "OCLabel.h"
    #import "CppObject.hpp"
    
    @implementation OCLabel
    
    - (UILabel *)generateLabelByText:(NSString *)text {
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 44)];
        CppObject cpp = CppObject();
        int result = cpp.add(1, 2);
        [label setText:[NSString stringWithFormat:@"%@ - %d", text, result]];
        return label;
    }
    
    @end
    
    1. 接下来编写BUCK文件,来描述这个target,其中first_party_library是一个公用的函数,具体详见代码
    load("//Config:buck_rule_macros.bzl", "first_party_library")
    
    first_party_library(
        name = "ObjcLib",
        has_cpp = True,
        internal_headers = [
          "Sources/CppObject.hpp",
        ]
    )
    
    1. 让主App来依赖这个自定义Library,修改主App的BUCK文件,在deps中添加该依赖:
    ...
    apple_binary(
        name = "MyBuckSampleAppBinary",
        visibility = [
            "//App:",
            "//App/...",
        ],
        swift_version = "5",
        srcs = [
            "AppDelegate.swift",
            "ViewController.swift",
        ],
        configs = app_binary_configs("MyBuckSampleApp"),
        deps = [
            ":Resource",
            ":Assets",
            "//Pods:Alamofire",
            "//Libraries/ObjcLib:ObjcLib",
        ]
    )
    ...
    
    1. 在主App的实现中,来使用这个模块提供的功能:
    ...
    import ObjcLib
    ...
    override func viewDidLoad() {
      ...
      let ocLabel = OCLabel().generate(byText: "OC Label")!
      ocLabel.frame = CGRect(x: 62, y: 300, width: 200, height: 44)
      view.addSubview(ocLabel)
      ...
    }
    ...
    

    引入mars日志框架

    若需要使用Cocoapods来使用mars日志框架,详见链接,这里省去了mars的编译过程,也可参考这个链接。为了让iOS项目可以直接使用mars,这里也用了同样的方式,写了一个简单的wrapper。目录机构如下所示:

    MyBuckSample-iOS
      - App
      - Libraries
        - mars
          - BuckSupportFiles
            - Dummy.swift
          - mars.framework # 编译好的framework
          - BUCK
        - xlog # 这个就是mars的wrapper
          - Sources
          - BUCK
        - ObjcLib
      - Pods
    
    1. 拷贝mars.framework,并为其书写BUCK。这里用到了BUCK内置的rule:prebuilt_apple_framework,其他的没有什么特别。
    prebuilt_apple_framework(
        name = "mars",
        framework = "mars.framework",
        preferred_linkage = "shared",
        visibility = ["PUBLIC"],
    )
    
    1. 添加一个Dummy模块,并更新BUCK。这个Dummy模块,这个swift文件没有任何代码,添加它的目的只是为了使用buck生成xcode工程时不报错。
    load("//Config:buck_rule_macros.bzl", "apple_lib")
    prebuilt_apple_framework(
        name = "mars",
        framework = "mars.framework",
        preferred_linkage = "shared",
        visibility = ["PUBLIC"],
    )
    
    # Every BUCK file needs at least one library with source.
    apple_lib(
        name = "PreBuildProjectGeneratorHack",
        srcs = glob([
            "BuckSupportFiles/**/*.swift",
        ]),
    )
    
    1. 为mars添加一个wrapper target,方便iOS调用:
    load("//Config:buck_rule_macros.bzl", "first_party_library")
    
    first_party_library(
        name = "xlog",
        has_cpp = True,
        internal_headers = [
          "Sources/Utils/LogHelper.h",
          "Sources/Utils/LogUtil.h",
        ],
        deps = [
            "//Libraries/mars:mars",
        ],
        frameworks = [
            "$SDKROOT/System/Library/Frameworks/SystemConfiguration.framework",
            "$SDKROOT/System/Library/Frameworks/CoreTelephony.framework",
        ],
        libraries = [
            "$SDKROOT/usr/lib/libresolv.9.tbd",
            "$SDKROOT/usr/lib/libz.tbd",
        ]
    )
    

    这里声明了它依赖于mars,同时添加了四个系统的类库,添加它们是由于mars需要使用它们。

    1. 在主App中使用这个日志框架,添加BUCK依赖以及在ViewController中使用xlog。BUCK中添加了这个没用的依赖"//Libraries/mars:PreBuildProjectGeneratorHack",也只是为了创建xcode项目使用。
    ...
    apple_binary(
        name = "MyBuckSampleAppBinary",
        visibility = [
            "//App:",
            "//App/...",
        ],
        swift_version = "5",
        srcs = [
            "AppDelegate.swift",
            "ViewController.swift",
        ],
        configs = app_binary_configs("MyBuckSampleApp"),
        deps = [
            ":Resource",
            ":Assets",
            "//Pods:Alamofire",
            "//Libraries/ObjcLib:ObjcLib",
            "//Libraries/xlog:xlog",
            "//Libraries/mars:PreBuildProjectGeneratorHack"
        ]
    )
    ...
    

    修改ViewController调用日志库:

    ...
    import xlog
    ...
    MarsXLogger.sharedInstance()?.info("Hi", msg:"HiHi")
    ...
    

    到目前为止,我们以及使用BUCK完成了基本项目中所需要的功能,下一节中,我们开始使用BUCK添加React Native的依赖。Peace !

    相关文章

      网友评论

          本文标题:BUCK - 使用BUCK编译iOS项目(3)

          本文链接:https://www.haomeiwen.com/subject/ertuoctx.html