Skip to content

Commit c1070e1

Browse files
cynthiajoanCynthia Jiangfirebase-workflow-trigger-bot
authored
Create build python script to replace shell build script (#215)
create build_zips.py, currently handle linux/macOS/iOS build. Co-authored-by: Cynthia Jiang <[email protected]> Co-authored-by: firebase-workflow-trigger-bot <[email protected]>
1 parent 17acab9 commit c1070e1

File tree

1 file changed

+271
-0
lines changed

1 file changed

+271
-0
lines changed

scripts/build_scripts/build_zips.py

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
#!/usr/bin/python
2+
#
3+
# Copyright 2022 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
"""Build SDK for certain platform into zip file
17+
18+
19+
Example usage:
20+
python build_zips.py --platform=macos --targets=auth --targets=firestore
21+
"""
22+
import os
23+
import re
24+
import subprocess
25+
import shutil
26+
27+
from absl import app
28+
from absl import flags
29+
from absl import logging
30+
31+
SUPPORT_PLATFORMS = ("linux", "macos", "windows", "ios", "android")
32+
SUPPORT_TARGETS = [
33+
"analytics", "auth", "crashlytics", "database", "dynamic_links",
34+
"firestore", "functions", "installations", "messaging", "remote_config",
35+
"storage"
36+
]
37+
SUPPORT_DEVICE = ["device", "simulator"]
38+
39+
IOS_SUPPORT_ARCHITECTURE = ["arm64", "armv7", "x86_64", "i386"]
40+
IOS_DEVICE_ARCHITECTURE = ["arm64", "armv7"]
41+
IOS_SIMULATOR_ARCHITECTURE = ["arm64", "x86_64", "i386"]
42+
43+
IOS_CONFIG_DICT = {
44+
"device": {
45+
"architecture": ["arm64", "armv7"],
46+
"ios_platform_location": "iPhoneOS.platform",
47+
"osx_sysroot": "iphoneos",
48+
},
49+
"simulator": {
50+
"architecture": ["arm64", "x86_64", "i386"],
51+
"ios_platform_location": "iPhoneSimulator.platform",
52+
"osx_sysroot": "iphonesimulator",
53+
}
54+
}
55+
56+
ANDROID_SUPPORT_ARCHITECTURE = ["armeabi-v7a", "arm64-v8a", "x86", "x86_64"]
57+
58+
FLAGS = flags.FLAGS
59+
flags.DEFINE_string(
60+
'platform', None,
61+
'Which platform to build SDK on. Required one entry from ({})'.format(
62+
",".join(SUPPORT_PLATFORMS)))
63+
flags.DEFINE_string(
64+
'unity_root', None,
65+
"The root dir for Unity Engine. If not set, cmake will try to guess in the default unity installation location."
66+
)
67+
flags.DEFINE_multi_string(
68+
"targets", None,
69+
("Target product to includes in the build. List items pick from"
70+
"({})".format(",".join(SUPPORT_TARGETS))))
71+
flags.DEFINE_multi_string(
72+
"device", None,
73+
"To build on device or simulator. If not set, built on both. Only take affect for ios and android build"
74+
)
75+
flags.DEFINE_multi_string(
76+
"architecture", None, "Which architectures in build on.\n"
77+
"For iOS device ({}).\n"
78+
"For iOS simulator ({}).\n"
79+
"For android ({}).".format(",".join(IOS_CONFIG_DICT["device"]["architecture"]),
80+
",".join(
81+
IOS_CONFIG_DICT["simulator"]["architecture"]),
82+
",".join(ANDROID_SUPPORT_ARCHITECTURE)))
83+
flags.DEFINE_multi_string('cmake_extras', None,
84+
"Any extra arguments wants to pass into cmake.")
85+
flags.DEFINE_bool("clean_build", False, "Whether to clean the build folder")
86+
87+
88+
def get_build_path(platform, clean_build=False):
89+
"""Get the folder that cmake configure and build in.
90+
91+
Args:
92+
platform: linux, macos, windows, ios, android.
93+
clean_build: If True, delete the build folder and build from clean.
94+
95+
Returns:
96+
The folder path to build sdk inside.
97+
"""
98+
platform_path = os.path.join(os.getcwd(), platform + "_unity")
99+
if os.path.exists(platform_path) and clean_build:
100+
shutil.rmtree(platform_path)
101+
if not os.path.exists(platform_path):
102+
os.makedirs(platform_path)
103+
return platform_path
104+
105+
106+
def get_cpp_folder_args():
107+
"""Get the cmake args to pass in local Firebase C++ SDK folder.
108+
If not found, will download from Firebase C++ git repo.
109+
110+
Returns:
111+
cmake args with the folder path of local Firebase C++ SDK.
112+
Empty string if not found.
113+
"""
114+
cpp_folder = os.path.join(os.getcwd(), "..", "firebase-cpp-sdk")
115+
if os.path.exists(cpp_folder):
116+
return "-DFIREBASE_CPP_SDK_DIR=" + os.path.realpath(cpp_folder)
117+
else:
118+
return ""
119+
120+
121+
def get_unity_engine_folder_args(unity_root):
122+
"""Get the cmake args to pass in Unity engine folder. If not passed in
123+
through the parameter, cmake will try to find using logic in
124+
cmake/FindUnity.cmake
125+
126+
Args:
127+
unity_root: folder path of the Unity Engine.
128+
Returns:
129+
camke args with the folder path of Unity Engine. Empty string if not set.
130+
"""
131+
if unity_root and os.path.exists(unity_root):
132+
return "-DUNITY_ROOT_DIR=" + unity_root
133+
else:
134+
return ""
135+
136+
137+
def get_targets_args(targets):
138+
"""Get the cmake args to pass in built targets of Firebase products.
139+
140+
Args:
141+
targets: list of target names defined in SUPPORT_TARGETS.
142+
Returns:
143+
camke args included targets.
144+
"""
145+
result_args = []
146+
if targets:
147+
# check if all the entries are valid
148+
for target in targets:
149+
if target not in SUPPORT_TARGETS:
150+
raise app.UsageError(
151+
'Wrong target "{}", please pick from {}'.format(
152+
target, ",".join(SUPPORT_TARGETS)))
153+
for target in SUPPORT_TARGETS:
154+
if target in targets:
155+
result_args.append("-DFIREBASE_INCLUDE_" + target.upper() +
156+
"=ON")
157+
else:
158+
result_args.append("-DFIREBASE_INCLUDE_" + target.upper() +
159+
"=OFF")
160+
logging.debug("get target args are:" + ",".join(result_args))
161+
return result_args
162+
163+
164+
def get_ios_args(source_path):
165+
"""Get the cmake args for iOS platform specific.
166+
167+
Args:
168+
source_path: root source folder to find toolchain file.
169+
Returns:
170+
camke args for iOS platform.
171+
"""
172+
result_args = []
173+
toolchain_path = os.path.join(source_path, "cmake", "unity_ios.cmake")
174+
# toolchain args is required
175+
result_args.append("-DCMAKE_TOOLCHAIN_FILE=" + toolchain_path)
176+
# check device input
177+
if FLAGS.device:
178+
for device in FLAGS.device:
179+
if device not in SUPPORT_DEVICE:
180+
raise app.UsageError(
181+
'Wrong device type {}, please pick from {}'.format(
182+
device, ",".join(SUPPORT_DEVICE)))
183+
devices = FLAGS.device
184+
else:
185+
devices = SUPPORT_DEVICE
186+
187+
# check architecture input
188+
if (len(devices) > 1):
189+
archs_to_check = IOS_SUPPORT_ARCHITECTURE
190+
else:
191+
archs_to_check = IOS_CONFIG_DICT[devices[0]]["architecture"]
192+
if FLAGS.architecture:
193+
for arch in FLAGS.architecture:
194+
if arch not in archs_to_check:
195+
raise app.UsageError(
196+
'Wrong architecture "{}" for device type {}, please pick from {}'.format(
197+
arch, ",".join(devices), ",".join(archs_to_check)))
198+
archs = FLAGS.architecture
199+
else:
200+
archs = archs_to_check
201+
202+
if len(archs) != len(IOS_SUPPORT_ARCHITECTURE):
203+
# Need to override only if the archs are not default
204+
result_args.append("-DCMAKE_OSX_ARCHITECTURES=" + ";".join(archs))
205+
206+
if len(devices) != len(SUPPORT_DEVICE):
207+
# Need to override if only passed in device or simulator
208+
result_args.append("-DCMAKE_OSX_SYSROOT=" +
209+
IOS_CONFIG_DICT[devices[0]]["osx_sysroot"])
210+
result_args.append("-DCMAKE_XCODE_EFFECTIVE_PLATFORMS=" +
211+
"-"+IOS_CONFIG_DICT[devices[0]]["osx_sysroot"])
212+
result_args.append("-DIOS_PLATFORM_LOCATION=" +
213+
IOS_CONFIG_DICT[devices[0]]["ios_platform_location"])
214+
return result_args
215+
216+
217+
def main(argv):
218+
if len(argv) > 1:
219+
raise app.UsageError('Too many command-line arguments.')
220+
platform = FLAGS.platform
221+
if platform not in SUPPORT_PLATFORMS:
222+
raise app.UsageError('Wrong platform "{}", please pick from {}'.format(
223+
platform, ",".join(SUPPORT_PLATFORMS)))
224+
225+
cmake_cpp_folder_args = get_cpp_folder_args()
226+
build_path = get_build_path(platform, FLAGS.clean_build)
227+
228+
source_path = os.getcwd()
229+
230+
os.chdir(build_path)
231+
cmake_setup_args = [
232+
"cmake",
233+
"..",
234+
"-DFIREBASE_INCLUDE_UNITY=ON",
235+
"-DFIREBASE_UNITY_BUILD_TESTS=ON",
236+
"-DFIREBASE_CPP_BUILD_STUB_TESTS=ON",
237+
]
238+
239+
unity_root_args = get_unity_engine_folder_args(FLAGS.unity_root)
240+
if unity_root_args:
241+
cmake_setup_args.append(unity_root_args)
242+
if cmake_cpp_folder_args:
243+
cmake_setup_args.append(cmake_cpp_folder_args)
244+
245+
target_arg_list = get_targets_args(FLAGS.targets)
246+
if target_arg_list:
247+
cmake_setup_args.extend(target_arg_list)
248+
249+
if FLAGS.cmake_extras:
250+
cmake_setup_args.extend(FLAGS.cmake_extras)
251+
252+
if platform == "ios":
253+
cmake_setup_args.extend(get_ios_args(source_path))
254+
255+
logging.info("cmake_setup_args is: " + " ".join(cmake_setup_args))
256+
257+
subprocess.call(cmake_setup_args)
258+
subprocess.call("make")
259+
260+
cmake_pack_args = [
261+
"cpack",
262+
".",
263+
]
264+
subprocess.call(cmake_pack_args)
265+
266+
os.chdir(source_path)
267+
268+
269+
if __name__ == '__main__':
270+
flags.mark_flag_as_required("platform")
271+
app.run(main)

0 commit comments

Comments
 (0)