2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
12 if sys
.version_info
< (2, 7, 0):
13 sys
.stderr
.write("python 2.7 or later is required run this script\n")
16 import buildbot_common
22 from build_paths
import SDK_SRC_DIR
, OUT_DIR
, SDK_RESOURCE_DIR
24 sys
.path
.append(os
.path
.join(SDK_SRC_DIR
, 'tools'))
29 def RemoveBuildCruft(outdir
):
30 for root
, _
, files
in os
.walk(outdir
):
32 path
= os
.path
.join(root
, f
)
33 ext
= os
.path
.splitext(path
)[1]
34 # Remove unwanted files from the package. Also remove manifest.json files
35 # (which we usually want). These ones are the manifests of the invidual
36 # examples, though, which CWS complains about. The master manifest.json
37 # is generated after we call RemoveBuildCruft.
38 if (ext
in ('.d', '.o') or
40 f
== 'manifest.json' or
41 re
.search(r
'_unstripped_.*?\.nexe', f
)):
42 buildbot_common
.RemoveFile(path
)
45 def StripNexes(outdir
, platform
, pepperdir
):
46 for root
, _
, files
in os
.walk(outdir
):
48 path
= os
.path
.join(root
, f
)
49 m
= re
.search(r
'lib(32|64).*\.so', path
)
52 # System .so file. Must be x86, because ARM doesn't support glibc yet.
53 arch
= 'x86_' + m
.group(1)
55 basename
, ext
= os
.path
.splitext(f
)
56 if ext
in ('.nexe', '.so'):
57 # We can get the arch from the filename...
58 valid_arches
= ('x86_64', 'x86_32', 'arm')
59 for a
in valid_arches
:
60 if basename
.endswith(a
):
66 strip
= GetStrip(pepperdir
, platform
, arch
, 'newlib')
67 buildbot_common
.Run([strip
, path
])
70 def GetStrip(pepperdir
, platform
, arch
, toolchain
):
71 base_arch
= {'x86_32': 'x86', 'x86_64': 'x86', 'arm': 'arm'}[arch
]
72 bin_dir
= os
.path
.join(pepperdir
, 'toolchain',
73 '%s_%s_%s' % (platform
, base_arch
, toolchain
), 'bin')
74 strip_prefix
= {'x86_32': 'i686', 'x86_64': 'x86_64', 'arm': 'arm'}[arch
]
75 strip_name
= '%s-nacl-strip' % strip_prefix
76 return os
.path
.join(bin_dir
, strip_name
)
80 parser
= argparse
.ArgumentParser()
81 parser
.add_argument('-c', '--channel',
82 help='Channel to display in the name of the package.')
84 # To setup bash completion for this command first install optcomplete
85 # and then add this line to your .bashrc:
86 # complete -F _optcomplete build_app.py
89 optcomplete
.autocomplete(parser
)
93 options
= parser
.parse_args(args
)
96 if options
.channel
not in ('Dev', 'Beta'):
97 parser
.error('Unknown channel: %s' % options
.channel
)
99 toolchains
= ['newlib', 'glibc']
101 pepper_ver
= str(int(build_version
.ChromeMajorVersion()))
102 pepperdir
= os
.path
.join(OUT_DIR
, 'pepper_' + pepper_ver
)
103 app_dir
= os
.path
.join(OUT_DIR
, 'naclsdk_app')
104 app_examples_dir
= os
.path
.join(app_dir
, 'examples')
105 sdk_resources_dir
= SDK_RESOURCE_DIR
106 platform
= getos
.GetPlatform()
108 buildbot_common
.RemoveDir(app_dir
)
109 buildbot_common
.MakeDir(app_dir
)
111 # Add some dummy directories so build_projects doesn't complain...
112 buildbot_common
.MakeDir(os
.path
.join(app_dir
, 'tools'))
113 buildbot_common
.MakeDir(os
.path
.join(app_dir
, 'toolchain'))
118 filters
['DISABLE_PACKAGE'] = False
119 filters
['EXPERIMENTAL'] = False
120 filters
['TOOLS'] = toolchains
121 filters
['DEST'] = ['examples/api', 'examples/getting_started',
122 'examples/demo', 'examples/tutorial']
123 tree
= parse_dsc
.LoadProjectTree(SDK_SRC_DIR
, include
=filters
)
124 build_projects
.UpdateHelpers(app_dir
, clobber
=True)
125 build_projects
.UpdateProjects(app_dir
, tree
, clobber
=False,
126 toolchains
=toolchains
, configs
=[config
],
127 first_toolchain
=True)
129 # Collect permissions from each example, and aggregate them.
130 def MergeLists(list1
, list2
):
131 return list1
+ [x
for x
in list2
if x
not in list1
]
133 all_socket_permissions
= []
134 all_filesystem_permissions
= []
135 for _
, project
in parse_dsc
.GenerateProjects(tree
):
136 permissions
= project
.get('PERMISSIONS', [])
137 all_permissions
= MergeLists(all_permissions
, permissions
)
138 socket_permissions
= project
.get('SOCKET_PERMISSIONS', [])
139 all_socket_permissions
= MergeLists(all_socket_permissions
,
141 filesystem_permissions
= project
.get('FILESYSTEM_PERMISSIONS', [])
142 all_filesystem_permissions
= MergeLists(all_filesystem_permissions
,
143 filesystem_permissions
)
144 if all_socket_permissions
:
145 all_permissions
.append({'socket': all_socket_permissions
})
146 if all_filesystem_permissions
:
147 all_permissions
.append({'fileSystem': all_filesystem_permissions
})
148 pretty_permissions
= json
.dumps(all_permissions
, sort_keys
=True, indent
=4)
150 for filename
in ['background.js', 'icon128.png']:
151 buildbot_common
.CopyFile(os
.path
.join(sdk_resources_dir
, filename
),
152 os
.path
.join(app_examples_dir
, filename
))
154 os
.environ
['NACL_SDK_ROOT'] = pepperdir
156 build_projects
.BuildProjects(app_dir
, tree
, deps
=False, clean
=False,
159 RemoveBuildCruft(app_dir
)
160 StripNexes(app_dir
, platform
, pepperdir
)
162 # Add manifest.json after RemoveBuildCruft... that function removes the
163 # manifest.json files for the individual examples.
164 name
= 'Native Client SDK'
166 name
+= ' (%s)' % options
.channel
169 'channel': options
.channel
,
171 'Native Client SDK examples, showing API use and key concepts.',
172 'key': False, # manifests with "key" are rejected when uploading to CWS.
173 'permissions': pretty_permissions
,
174 'version': build_version
.ChromeVersionNoTrunk()
176 easy_template
.RunTemplateFile(
177 os
.path
.join(sdk_resources_dir
, 'manifest.json.template'),
178 os
.path
.join(app_examples_dir
, 'manifest.json'),
181 app_zip
= os
.path
.join(app_dir
, 'examples.zip')
182 os
.chdir(app_examples_dir
)
183 oshelpers
.Zip([app_zip
, '-r', '*'])
188 if __name__
== '__main__':
189 sys
.exit(main(sys
.argv
[1:]))