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, 6, 0):
13 sys
.stderr
.write("python 2.6 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
= optparse
.OptionParser()
81 parser
.add_option('-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
, args
= parser
.parse_args(args
[1:])
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 for _
, project
in parse_dsc
.GenerateProjects(tree
):
135 permissions
= project
.get('PERMISSIONS', [])
136 all_permissions
= MergeLists(all_permissions
, permissions
)
137 socket_permissions
= project
.get('SOCKET_PERMISSIONS', [])
138 all_socket_permissions
= MergeLists(all_socket_permissions
,
140 if all_socket_permissions
:
141 all_permissions
.append({'socket': all_socket_permissions
})
142 pretty_permissions
= json
.dumps(all_permissions
, sort_keys
=True, indent
=4)
144 for filename
in ['background.js', 'icon128.png']:
145 buildbot_common
.CopyFile(os
.path
.join(sdk_resources_dir
, filename
),
146 os
.path
.join(app_examples_dir
, filename
))
148 os
.environ
['NACL_SDK_ROOT'] = pepperdir
150 build_projects
.BuildProjects(app_dir
, tree
, deps
=False, clean
=False,
153 RemoveBuildCruft(app_dir
)
154 StripNexes(app_dir
, platform
, pepperdir
)
156 # Add manifest.json after RemoveBuildCruft... that function removes the
157 # manifest.json files for the individual examples.
158 name
= 'Native Client SDK'
160 name
+= ' (%s)' % options
.channel
163 'channel': options
.channel
,
165 'Native Client SDK examples, showing API use and key concepts.',
166 'key': False, # manifests with "key" are rejected when uploading to CWS.
167 'permissions': pretty_permissions
,
168 'version': build_version
.ChromeVersionNoTrunk()
170 easy_template
.RunTemplateFile(
171 os
.path
.join(sdk_resources_dir
, 'manifest.json.template'),
172 os
.path
.join(app_examples_dir
, 'manifest.json'),
175 app_zip
= os
.path
.join(app_dir
, 'examples.zip')
176 os
.chdir(app_examples_dir
)
177 oshelpers
.Zip([app_zip
, '-r', '*'])
182 if __name__
== '__main__':
183 sys
.exit(main(sys
.argv
))