快速入门
例子介绍
本章通过一个小例子使你对bazel在iOS下的使用快速入门。现在我们有两个独立的项目HelloBazel和AFNetworking,HelloBazel是一个单视图app项目,AFNetworking是一个静态库项目,HelloWorld需要引用AFNetworking进行网络访问。将两个项目置于JingoalBuild文件夹下,结构如下:
组织bazel构建层次
1.根目录
bazel根目录使用WORKSAPCE文件标识,构建过程从含有WORKSPACE的文件夹开始进行目录层次的查找,运行如下命令创建WORKSPACE.
$ cd JingoalBuild
$ touch WORKSPACE
2.含有源代码的构建目录
bazel构建目录为含有build文件的子文件夹,bazel使用buld文件中的配置来编译该目录下的所有源代码文件,bazel将含有build文件的文件夹称为一个package,package是用来进行资源定位和依赖查找的一种手段。分别进入AFNetworking和HelloBazel进行BUILD的创建,这里只演示HelloBazel的过程,AFNetworking执行相同的操作。
$ cd HelloBazel
$ touch BUILD
$ chmod +x BUILD (变成可执行文件,google例子均为这样)
3.创建完成后的目录如下:
添加构建代码
1.准备工作
将iOS_Third_Party_Source/lib/AFNetworking/AFNetworking/AFNetworking 下的源代码加入AFNetworking项目
在HelloBazel的ViewController.m引入网络访问代码:
#import "AFNetworking.h"
- (void)viewDidLoad {
[super viewDidLoad];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"http://httpbin.org/get"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"%@ %@", response, responseObject);
}
}];
[dataTask resume];
}
注意: 在IDE开发流程中直接引入头文件会出现查找错误,你需要引入依赖项目,或者导入依赖项目的库文件和头文件,在bazel构建中,IDE的依赖配置对我们的构建过程没有影响,后面我们将看到这一点。
2.添加AFNetworking的构建代码
打开AFNetworking下的BUILD文件,加入如下代码:
objc_library(
name = "AFNetworkingLib",
srcs = glob(["AFNetworking/*.m"]),
hdrs = glob(["AFNetworking/*.h"]),
sdk_frameworks = ["Foundation","CoreGraphics","SystemConfiguration","Security","MobileCoreServices","CFNetwork"],
visibility = ["//visibility:public"]
)
objc_library : 指明当前package构建一个.a结尾的iOS库文件,为一个规则,更多关于iOS的详细规则看这里
name : 该依赖规则名称,bazel在指定依赖关系时使用
srcs : 该依赖规则使用的.m文件,glob函数会自动匹配AFNetworking文件夹下所有的.m文件,如要递归匹配所有的子文件夹可以使用glob(["*/.m"])
hdrs : 该依赖规则使用的头文件
sdk_frameworks : 该依赖规则使用的系统库
visibility : 该依赖规则的访问权限,public指明所有其他的package都可访问
3.添加HelloBazel的构建代码
打开HelloBazel下的BUILD文件添加如下代码:
ios_application( #该规则指明当前构建最终生成可在模拟器或真机运行的app
name = "HelloBazel-app",
binary = "HelloBazel-app-binary",#依赖的二进制
infoplist = "HelloBazel/Info.plist" #同iOS
)
objc_binary(#二进制文件一般为main.m文件
name = "HelloBazel-app-binary",
srcs = [
"HelloBazel/main.m"
],
deps = [
":HelloBazelLib",#二进制文件依赖的库文件,":"冒号指明依赖是在当前规则中
],
)
objc_library(//同AFNetworking下的objc_library规则
name = "HelloBazelLib",
srcs = [
"HelloBazel/AppDelegate.m",
"HelloBazel/ViewController.m"
],
deps = ["//AFNetworking:AFNetworkingLib"],
includes = ["../AFNetworking/AFNetworking"],
storyboards = ["HelloBazel/Base.lproj/Main.storyboard"],
)
注意 :
objc_library中的deps指明了一个外部依赖,"//"表示该依赖从根文件夹也就是含有WORKSPACE的文件夹开始查找(当前例子就是JingoalBuild),"//AFNetworking:AFNetworkingLib"表示依赖位于根文件夹的AFNetworking文件夹中,依赖名称为"AFNetworkingLib" 以"//"开始的依赖查找路径的最终文件夹,也就是冒号左边第一个文件夹,必须含有BUILD(本例中为AFNetworking,也是一个package),冒号右边为BUILD中的规则名称。
includes用来将外部库的头文件查找路径包含入当前规则,否则将出现找不到头文件,和你在xcode中添加的外部依赖或导入的头文件一样,文件的定位以当前规则所在的BUILD文件为准,只能使用相对路径不能使用绝对路径。
开始构建
进入HelloBazel文件夹,执行下列代码:
bazel build --ios_sdk_version=9.3 //HelloBazel:HelloBazel-app
将得到如下输出:
INFO: Found 1 target...
Target //HelloBazel:HelloBazel-app up-to-date:
bazel-bin/HelloBazel/HelloBazel-app.ipa
bazel-bin/HelloBazel/HelloBazel-app.xcodeproj/project.pbxproj
INFO: Elapsed time: 7.193s, Critical Path: 6.96s
其中ios_sdk_version根据机器安装xcode的版本进行指定 编译过的整合项目将出现在根目录的bazel-bin文件夹下,详细的路径可看上方日志。