13
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
14
# See the License for the specific language governing permissions and
15
15
# limitations under the License.
16
- """
17
- Standalone self-sufficient (no external dependencies) python script that can ease
18
- building desktop apps depending on Firebase, by either using the Firebase cpp
19
- source (firebase-cpp-sdk github repo) or the prebuilt release Firebase libraries.
16
+ """Standalone script to build desktops apps with Firebase.
17
+
18
+ Standalone self-sufficient (no external dependencies) python script that can
19
+ ease building desktop apps with Firebase, by either using the C++ source
20
+ (firebase-cpp-sdk github repo) or the prebuilt release Firebase libraries.
20
21
21
22
Note that this script works with only Python3 (3.6+).
22
23
Also note, that since this script runs a cmake configure step, it is advised to
23
24
run it with a fresh clean build directory.
24
25
25
26
Known side effects:
26
27
If building against Firebase cpp source, this script might checkout a specific
27
- branch on github containing vcpkg. This will not be required once vcpkg is in the
28
- main branch.
28
+ branch on github containing vcpkg. This will not be required once vcpkg is in
29
+ the main branch.
29
30
30
31
Example usage:
31
32
Let's say we want to build the quickstart cpp example for Firebase database.
32
33
As specified above, there are 2 options - build against the Firebase source or
33
34
prebuilt Firebase libraries.
34
35
35
36
# Build against the Firebase cpp sdk source
36
- python3 scripts/build_desktop_app_with_firebase.py --app_dir ~/quickstart-cpp/database/testapp
37
- --sdk_dir . --build_dir build_source
37
+ python3 scripts/build_desktop_app_with_firebase.py
38
+ --app_dir ~/quickstart-cpp/database/testapp
39
+ --sdk_dir .
40
+ --build_dir build_source
38
41
39
42
(or)
40
43
41
44
# Build against the prebuilt released Firebase libraries
42
- python3 scripts/build_desktop_app_with_firebase.py --app_dir ~/quickstart-cpp/database/testapp
43
- --sdk_dir ~/prebuilt/firebase_cpp_sdk_6.15.1/
44
- --build_dir build_prebuilt
45
+ python3 scripts/build_desktop_app_with_firebase.py
46
+ --app_dir ~/quickstart-cpp/database/testapp
47
+ --sdk_dir ~/prebuilt/firebase_cpp_sdk_6.15.1/
48
+ --build_dir build_prebuilt
45
49
46
50
# If the script ran successfully, it will print the path to the build directory.
51
+ # The output looks like the following,
47
52
Build successful!
48
- Please find your executables in build directory: /Users/<user>/quickstart-cpp/database/testapp/build_source
53
+ Please find your executables in build directory:
54
+ /Users/<user>/quickstart-cpp/database/testapp/build_source
49
55
50
56
# Running the built example
51
57
$ ./Users/<user>/quickstart-cpp/database/testapp/build_source/desktop_testapp
52
58
"""
53
59
import argparse
54
- import distutils .spawn
55
60
import os
56
61
import platform
57
62
import subprocess
58
63
import sys
59
64
65
+
60
66
def is_path_valid_for_cmake (path ):
61
- """Check if specified path is setup for cmake"""
67
+ """Check if specified path is setup for cmake. """
62
68
return os .path .exists (os .path .join (path , 'CMakeLists.txt' ))
63
69
70
+
64
71
def is_sdk_path_source (sdk_dir ):
65
- """Validate if Firebase sdk dir is Firebase cpp source dir"""
66
- # Not the most reliable way to detect if the sdk path is source or prebuilt but
67
- # should work for our purpose.
72
+ """Validate if Firebase sdk dir is Firebase cpp source dir. """
73
+ # Not the most reliable way to detect if the sdk path is source or prebuilt
74
+ # but should work for our purpose.
68
75
return os .path .exists (os .path .join (sdk_dir , 'build_tools' ))
69
76
77
+
70
78
def validate_prebuilt_args (arch , config ):
71
- """Validate cmd line args for build with prebuilt libraries"""
79
+ """Validate cmd line args for build with prebuilt libraries. """
72
80
# Some options are not available when using prebuilt libraries.
73
81
if platform .system () == 'Darwin' :
74
82
if arch == 'x86' or config == 'Debug' :
75
- raise ValueError ("Prebuilt mac Firebase libraries are built for x64 and Release mode only. "
76
- "Please fix the command line arguments and try again" )
83
+ raise ValueError ('Prebuilt mac Firebase libraries are built for x64 and '
84
+ 'Release mode only. '
85
+ 'Please fix the command line arguments and try again' )
77
86
78
87
if platform .system () == 'Linux' :
79
88
if config == 'Debug' :
80
- raise ValueError ("Prebuilt linux Firebase libraries are built with Release mode only. "
81
- "Please fix the --config command line argument and try again." )
89
+ raise ValueError ('Prebuilt linux Firebase libraries are built with '
90
+ 'Release mode only. Please fix the --config command '
91
+ 'line argument and try again.' )
92
+
82
93
83
94
def get_vcpkg_triplet (arch , msvc_runtime_library = 'static' ):
84
- """ Get vcpkg target triplet (platform definition).
95
+ """Get vcpkg target triplet (platform definition).
85
96
86
97
Args:
87
98
arch (str): Architecture (eg: 'x86', 'x64').
88
- msvc_runtime_library (str): Runtime library for MSVC (eg: 'static', 'dynamic').
99
+ msvc_runtime_library (str): Runtime library for MSVC.
100
+ (eg: 'static', 'dynamic').
89
101
90
102
Raises:
91
103
ValueError: If current OS is not win, mac or linux.
@@ -105,34 +117,39 @@ def get_vcpkg_triplet(arch, msvc_runtime_library='static'):
105
117
elif platform .system () == 'Linux' :
106
118
triplet_name .append ('linux' )
107
119
else :
108
- raise ValueError (" Unsupported platform. "
109
- "This function works only on Windows, Linux or Mac platforms." )
120
+ raise ValueError (' Unsupported platform. This function works only on '
121
+ ' Windows, Linux or Mac platforms.' )
110
122
111
123
triplet_name = '-' .join (triplet_name )
112
- print (" Using vcpkg triplet: {0}" .format (triplet_name ))
124
+ print (' Using vcpkg triplet: {0}' .format (triplet_name ))
113
125
return triplet_name
114
126
127
+
115
128
def build_source_vcpkg_dependencies (sdk_source_dir , arch , msvc_runtime_library ):
116
129
"""Build C++ dependencies for Firebase source SDK using vcpkg.
117
130
118
131
Args:
119
132
sdk_source_dir (str): Path to Firebase C++ source directory.
120
- arch (str): Platform Architecture (example: 'x64').
121
- msvc_runtime_library (str): Runtime library for MSVC (eg: 'static', 'dynamic').
133
+ arch (str): Platform Architecture (eg: 'x64').
134
+ msvc_runtime_library (str): Runtime library for MSVC.
135
+ (eg: 'static', 'dynamic').
122
136
"""
123
- # TODO: Remove this once dev branch of firebase-cpp-sdk repo has been merged
124
- # onto main branch. This is required because vcpkg lives only in dev branch currently.
125
- # b/174141707 .
137
+ # TODO(b/174141707) : Remove this once dev branch of firebase-cpp-sdk repo has
138
+ # been merged onto main branch. This is required because vcpkg lives only in
139
+ # dev branch currently .
126
140
subprocess .run (['git' , 'checkout' , 'dev' ],
127
141
cwd = sdk_source_dir , check = True )
128
142
subprocess .run (['git' , 'pull' ], cwd = sdk_source_dir , check = True )
129
143
130
- python_exe = 'python3' if distutils .spawn .find_executable ('python3' ) else 'python'
131
- subprocess .run ([python_exe , "scripts/gha/install_prereqs_desktop.py" ],
144
+ # sys.executable should point to the python bin running this script. We use
145
+ # the same executable to execute these subprocess python scripts.
146
+ subprocess .run ([sys .executable , 'scripts/gha/install_prereqs_desktop.py' ],
132
147
cwd = sdk_source_dir , check = True )
133
- subprocess .run ([python_exe , "scripts/gha/build_desktop.py" , "--arch" , arch ,
134
- "--msvc_runtime_library" , msvc_runtime_library ,
135
- "--vcpkg_step_only" ], cwd = sdk_source_dir , check = True )
148
+ subprocess .run ([sys .executable , 'scripts/gha/build_desktop.py' ,
149
+ '--arch' , arch ,
150
+ '--msvc_runtime_library' , msvc_runtime_library ,
151
+ '--vcpkg_step_only' ], cwd = sdk_source_dir , check = True )
152
+
136
153
137
154
def build_app_with_source (app_dir , sdk_source_dir , build_dir , arch ,
138
155
msvc_runtime_library = 'static' , config = None ,
@@ -144,19 +161,22 @@ def build_app_with_source(app_dir, sdk_source_dir, build_dir, arch,
144
161
145
162
Args:
146
163
app_dir (str): Path to directory containing application's CMakeLists.txt.
147
- sdk_source_dir (str): Path to Firebase C++ SDK source directory (root of github repo).
164
+ sdk_source_dir (str): Path to Firebase C++ SDK source directory.
165
+ (root of firebase-cpp-sdk github repo).
148
166
build_dir (str): Output build directory.
149
167
arch (str): Platform Architecture (example: 'x64').
150
- msvc_runtime_library (str): Runtime library for MSVC (eg: 'static', 'dynamic').
168
+ msvc_runtime_library (str): Runtime library for MSVC.
169
+ (eg: 'static', 'dynamic').
151
170
config (str): Release/Debug config.
152
- If its not specified, cmake's default is used (most likely Debug).
153
- target_format (str): If specified, build for this targetformat ('frameworks' or 'libraries').
171
+ If it's not specified, cmake's default is used (most likely Debug).
172
+ target_format (str): If specified, build for this target format.
173
+ ('frameworks' or 'libraries').
154
174
"""
155
175
# Cmake configure.
156
176
cmd = ['cmake' , '-S' , '.' , '-B' , build_dir ]
157
177
cmd .append ('-DFIREBASE_CPP_SDK_DIR={0}' .format (sdk_source_dir ))
158
178
159
- # If generator is not specifed , default for platform is used by cmake, else
179
+ # If generator is not specified , default for platform is used by cmake, else
160
180
# use the specified value.
161
181
if config :
162
182
cmd .append ('-DCMAKE_BUILD_TYPE={0}' .format (config ))
@@ -165,12 +185,13 @@ def build_app_with_source(app_dir, sdk_source_dir, build_dir, arch,
165
185
166
186
if platform .system () == 'Linux' and arch == 'x86' :
167
187
# Use a separate cmake toolchain for cross compiling linux x86 builds.
168
- vcpkg_toolchain_file_path = os .path .join (sdk_source_dir , 'external' , 'vcpkg' ,
169
- 'scripts' , 'buildsystems' , 'linux_32.cmake' )
188
+ vcpkg_toolchain_file_path = os .path .join (sdk_source_dir , 'external' ,
189
+ 'vcpkg' , 'scripts' ,
190
+ 'buildsystems' , 'linux_32.cmake' )
170
191
else :
171
192
vcpkg_toolchain_file_path = os .path .join (sdk_source_dir , 'external' ,
172
- 'vcpkg' , 'scripts' ,
173
- 'buildsystems' , 'vcpkg.cmake' )
193
+ 'vcpkg' , 'scripts' ,
194
+ 'buildsystems' , 'vcpkg.cmake' )
174
195
175
196
cmd .append ('-DCMAKE_TOOLCHAIN_FILE={0}' .format (vcpkg_toolchain_file_path ))
176
197
@@ -182,23 +203,25 @@ def build_app_with_source(app_dir, sdk_source_dir, build_dir, arch,
182
203
# Since the default architecture for cmake varies from machine to machine,
183
204
# it is a good practice to specify it all the time (even for x64).
184
205
cmd .append ('-A' )
185
- cmd .append ('Win32' ) if arch == 'x86' else cmd .append ('x64' )
206
+ windows_cmake_arch_flag_value = 'Win32' if arch == 'x86' else 'x64'
207
+ cmd .append (windows_cmake_arch_flag_value )
186
208
187
- # Use our special cmake option for /MD (dynamic).
188
- # If this option is not specified, the default value is /MT (static).
189
- if msvc_runtime_library == "static" :
209
+ # Use our special cmake option to specify /MD (dynamic) vs /MT (static).
210
+ if msvc_runtime_library == 'static' :
190
211
cmd .append ('-DMSVC_RUNTIME_LIBRARY_STATIC=ON' )
191
212
192
- if ( target_format ) :
213
+ if target_format :
193
214
cmd .append ('-DFIREBASE_XCODE_TARGET_FORMAT={0}' .format (target_format ))
194
- print (" Running {0}" .format (' ' .join (cmd )))
215
+ print (' Running {0}' .format (' ' .join (cmd )))
195
216
subprocess .run (cmd , cwd = app_dir , check = True )
196
217
197
- #CMake build.
198
- cmd = ['cmake' , '--build' , build_dir , '-j' , str (os .cpu_count ()), '--config' , config ]
199
- print ("Running {0}" .format (' ' .join (cmd )))
218
+ # CMake build.
219
+ num_cpus = str (os .cpu_count ())
220
+ cmd = ['cmake' , '--build' , build_dir , '-j' , num_cpus , '--config' , config ]
221
+ print ('Running {0}' .format (' ' .join (cmd )))
200
222
subprocess .run (cmd , cwd = app_dir , check = True )
201
223
224
+
202
225
def build_app_with_prebuilt (app_dir , sdk_prebuilt_dir , build_dir , arch ,
203
226
msvc_runtime_library = 'static' , config = None ):
204
227
"""Build desktop app directly against the prebuilt Firebase C++ libraries.
@@ -211,9 +234,10 @@ def build_app_with_prebuilt(app_dir, sdk_prebuilt_dir, build_dir, arch,
211
234
sdk_prebuilt_dir (str): Path to prebuilt Firebase C++ libraries.
212
235
build_dir (str): Output build directory.
213
236
arch (str): Platform Architecture (eg: 'x64').
214
- msvc_runtime_library (str): Runtime library for MSVC (eg: 'static', 'dynamic').
237
+ msvc_runtime_library (str): Runtime library for MSVC.
238
+ (eg: 'static', 'dynamic').
215
239
config (str): Release/Debug config (eg: 'Release', 'Debug')
216
- If its not specified, cmake's default is used (most likely Debug).
240
+ If it's not specified, cmake's default is used (most likely Debug).
217
241
"""
218
242
219
243
cmd = ['cmake' , '-S' , '.' , '-B' , build_dir ]
@@ -230,54 +254,71 @@ def build_app_with_prebuilt(app_dir, sdk_prebuilt_dir, build_dir, arch,
230
254
if config :
231
255
cmd .append ('-DCMAKE_BUILD_TYPE={0}' .format (config ))
232
256
233
- print (" Running {0}" .format (' ' .join (cmd )))
257
+ print (' Running {0}' .format (' ' .join (cmd )))
234
258
subprocess .run (cmd , cwd = app_dir , check = True )
235
259
236
- #CMake build.
237
- cmd = ['cmake' , '--build' , build_dir , '-j' , str (os .cpu_count ()), '--config' , config ]
238
- print ("Running {0}" .format (' ' .join (cmd )))
260
+ # CMake build.
261
+ num_cpus = str (os .cpu_count ())
262
+ cmd = ['cmake' , '--build' , build_dir , '-j' , num_cpus , '--config' , config ]
263
+ print ('Running {0}' .format (' ' .join (cmd )))
239
264
subprocess .run (cmd , cwd = app_dir , check = True )
240
265
266
+
241
267
def main ():
242
268
args = parse_cmdline_args ()
243
269
244
270
if not is_path_valid_for_cmake (args .sdk_dir ):
245
- print ("SDK path provided is not valid. Could not find a CMakeLists.txt at the root level.\n "
246
- "Please check the argument to '--sdk_dir'" )
271
+ print ('SDK path provided is not valid. '
272
+ 'Could not find a CMakeLists.txt at the root level.\n '
273
+ 'Please check the argument to "--sdk_dir".' )
247
274
sys .exit (1 )
248
275
249
276
if not is_path_valid_for_cmake (args .app_dir ):
250
- print ("App path provided is not valid. Could not find a CMakeLists.txt at the root level.\n "
251
- "Please check the argument to '--app_dir'" )
277
+ print ('App path provided is not valid. '
278
+ 'Could not find a CMakeLists.txt at the root level.\n '
279
+ 'Please check the argument to "--app_dir"' )
252
280
sys .exit (1 )
253
281
254
282
if is_sdk_path_source (args .sdk_dir ):
255
- print ("SDK path provided is a Firebase C++ source directory. Building..." )
256
- build_source_vcpkg_dependencies (args .sdk_dir , args .arch , args .msvc_runtime_library )
283
+ print ('SDK path provided is a Firebase C++ source directory. Building...' )
284
+ build_source_vcpkg_dependencies (args .sdk_dir , args .arch ,
285
+ args .msvc_runtime_library )
257
286
build_app_with_source (args .app_dir , args .sdk_dir , args .build_dir , args .arch ,
258
- args .msvc_runtime_library , args .config , args .target_format )
287
+ args .msvc_runtime_library , args .config ,
288
+ args .target_format )
259
289
else :
260
290
validate_prebuilt_args (args .arch , args .config )
261
- print ("SDK path provided is Firebase C++ prebuilt libraries. Building..." )
262
- build_app_with_prebuilt (args .app_dir , args .sdk_dir , args .build_dir , args .arch ,
263
- args .msvc_runtime_library , args .config )
291
+ print ('SDK path provided is Firebase C++ prebuilt libraries. Building...' )
292
+ build_app_with_prebuilt (args .app_dir , args .sdk_dir , args .build_dir ,
293
+ args .arch , args .msvc_runtime_library , args .config )
294
+
295
+ print ('Build successful!\n '
296
+ 'Please find your executables in the build directory: {0}' .format (
297
+ os .path .join (args .app_dir , args .build_dir )))
264
298
265
- print ("Build successful!\n "
266
- "Please find your executables in the build directory: {0}" .format
267
- (os .path .join (args .app_dir , args .build_dir )))
268
299
269
300
def parse_cmdline_args ():
270
- parser = argparse .ArgumentParser (description = 'Install Prerequisites for building cpp sdk' )
271
- parser .add_argument ('--sdk_dir' , help = 'Path to Firebase SDK - source or prebuilt libraries.' ,
301
+ """Parse command line arguments."""
302
+ parser = argparse .ArgumentParser (description = 'Install Prerequisites for '
303
+ 'building cpp sdk.' )
304
+ parser .add_argument ('--sdk_dir' , help = 'Path to Firebase SDK - source or '
305
+ 'prebuilt libraries.' ,
272
306
type = os .path .abspath )
273
- parser .add_argument ('--app_dir' , help = "Path to application to build (directory containing app's CMakeLists.txt" ,
307
+ parser .add_argument ('--app_dir' , help = "Path to application to build "
308
+ "(directory containing application's CMakeLists.txt" ,
274
309
type = os .path .abspath )
275
- parser .add_argument ('-a' , '--arch' , default = 'x64' , help = 'Platform architecture (x64, x86)' )
310
+ parser .add_argument ('-a' , '--arch' , default = 'x64' ,
311
+ help = 'Platform architecture (x64, x86)' )
276
312
parser .add_argument ('--msvc_runtime_library' , default = 'static' ,
277
- help = 'Runtime library for MSVC (static(/MT) or dynamic(/MD)' )
278
- parser .add_argument ('--build_dir' , default = 'build' , help = 'Output build directory' )
279
- parser .add_argument ('--config' , default = 'Release' , help = 'Release/Debug config' )
280
- parser .add_argument ('--target_format' , default = None , help = '(Mac only) whether to output frameworks (default) or libraries.' )
313
+ help = 'Runtime library for MSVC '
314
+ '(static(/MT) or dynamic(/MD)' )
315
+ parser .add_argument ('--build_dir' , default = 'build' ,
316
+ help = 'Output build directory' )
317
+ parser .add_argument ('--config' , default = 'Release' ,
318
+ help = 'Release/Debug config' )
319
+ parser .add_argument ('--target_format' , default = None ,
320
+ help = '(Mac only) whether to output frameworks (default)'
321
+ 'or libraries.' )
281
322
args = parser .parse_args ()
282
323
return args
283
324
0 commit comments