OLD | NEW |
| (Empty) |
1 #!/usr/bin/python2.4 | |
2 # | |
3 # Copyright 2009-2010 Google Inc. | |
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 # ======================================================================== | |
17 | |
18 """Build a meta-installer for Omaha's client installations. | |
19 | |
20 The only function in this module creates an Omaha meta-installer, which is | |
21 an executable whose only job is to extract its payload (the actual installer | |
22 executable and a number of resource dlls), then launch the dropped installer | |
23 to finish the installation. | |
24 | |
25 BuildMetaInstaller(): Build a meta-installer. | |
26 """ | |
27 | |
28 | |
29 def BuildMetaInstaller( | |
30 env, | |
31 target_name, | |
32 omaha_version_info, | |
33 empty_metainstaller_path, | |
34 omaha_files_path, | |
35 prefix='', | |
36 suffix='', | |
37 additional_payload_contents=None, | |
38 additional_payload_contents_dependencies=None, | |
39 output_dir='$STAGING_DIR', | |
40 installers_sources_path='$MAIN_DIR/installers', | |
41 lzma_path='$MAIN_DIR/third_party/lzma/v4_65/files/lzma.exe', | |
42 resmerge_path='$MAIN_DIR/tools/resmerge.exe', | |
43 bcj2_path='$OBJ_ROOT/mi_exe_stub/x86_encoder/bcj2.exe'): | |
44 """Build a meta-installer. | |
45 | |
46 Builds a full meta-installer, which is a meta-installer containing a full | |
47 list of required files (the payload), ie. language resourse dlls, installer | |
48 executables, etc. | |
49 | |
50 Args: | |
51 env: environment to build with | |
52 target_name: name to use for the target executable | |
53 omaha_version_info: info about the version of the Omaha files | |
54 empty_metainstaller_path: path to the base (empty) meta-installer executable | |
55 omaha_files_path: path to the resource dlls to build into the | |
56 target executable | |
57 prefix: target file name prefix, used to distinguish different targets | |
58 suffix: target file name suffix, used to distinguish different targets | |
59 additional_payload_contents: any additional resources to build into the | |
60 executable, beyond the normal payload files | |
61 additional_payload_contents_dependencies: extra dependencies to be used to | |
62 ensure the executable is rebuilt when required | |
63 output_dir: path to the directory that will contain the metainstaller | |
64 installers_sources_path: path to the directory containing the source files | |
65 for building the metainstaller | |
66 lzma_path: path to lzma.exe | |
67 resmerge_path: path to resmerge.exe | |
68 bcj2_path: path to bcj2.exe | |
69 | |
70 Returns: | |
71 Target nodes. | |
72 | |
73 Raises: | |
74 Nothing. | |
75 """ | |
76 | |
77 # Payload .tar.lzma | |
78 tarball_filename = '%spayload%s.tar' % (prefix, suffix) | |
79 payload_filename = tarball_filename + '.lzma' | |
80 | |
81 # Collect a list of all the files to include in the payload | |
82 payload_file_names = omaha_version_info.GetMetainstallerPayloadFilenames() | |
83 | |
84 payload_contents = [omaha_files_path + '/' + file_name | |
85 for file_name in payload_file_names] | |
86 if additional_payload_contents: | |
87 payload_contents += additional_payload_contents | |
88 | |
89 # Create the tarball | |
90 tarball_output = env.Command( | |
91 target=tarball_filename, # Archive filename | |
92 source=payload_contents, # List of files to include in tarball | |
93 action='python.exe %s -o $TARGET $SOURCES' % ( | |
94 env.File(installers_sources_path + '/generate_tarball.py').abspath), | |
95 ) | |
96 | |
97 # Add potentially hidden dependencies | |
98 if additional_payload_contents_dependencies: | |
99 env.Depends(tarball_output, additional_payload_contents_dependencies) | |
100 | |
101 # Preprocess the tarball to increase compressibility | |
102 bcj_filename = '%spayload%s.tar.bcj' % (prefix, suffix) | |
103 # TODO(omaha): Add the bcj2 path as an optional parameter. | |
104 bcj_output = env.Command( | |
105 target=bcj_filename, | |
106 source=tarball_output, | |
107 action='%s "$SOURCES" "$TARGET"' % bcj2_path, | |
108 ) | |
109 env.Depends(bcj_output, bcj2_path) | |
110 | |
111 # Compress the tarball | |
112 lzma_env = env.Clone() | |
113 lzma_env.Append( | |
114 LZMAFLAGS=[], | |
115 ) | |
116 lzma_output = lzma_env.Command( | |
117 target=payload_filename, | |
118 source=bcj_output, | |
119 action='%s e $SOURCES $TARGET $LZMAFLAGS' % lzma_path, | |
120 ) | |
121 | |
122 # Construct the resource generation script | |
123 manifest_path = installers_sources_path + '/installers.manifest' | |
124 res_command = 'python.exe %s -i %s -o $TARGET -p $SOURCES -m %s -r %s' % ( | |
125 env.File(installers_sources_path + '/generate_resource_script.py' | |
126 ).abspath, | |
127 env.File(installers_sources_path + '/resource.rc.in').abspath, | |
128 env.File(manifest_path).abspath, | |
129 env.File(installers_sources_path + '/resource.h').abspath | |
130 ) | |
131 | |
132 # Generate the .rc file | |
133 rc_output = env.Command( | |
134 target='%sresource%s.rc' % (prefix, suffix), | |
135 source=lzma_output, | |
136 action=res_command, | |
137 ) | |
138 | |
139 # .res intermediate file | |
140 res_file = env.RES(rc_output) | |
141 | |
142 # For some reason, RES() does not cause the .res file to depend on .rc input. | |
143 # It also does not detect the dependencies in the .rc file. | |
144 # This does not cause a rebuild for rarely changing files in res_command. | |
145 env.Depends(res_file, [rc_output, manifest_path, lzma_output]) | |
146 | |
147 # Resource DLL | |
148 dll_env = env.Clone(COMPONENT_STATIC=False) | |
149 dll_env['LINKFLAGS'] += ['/noentry'] | |
150 | |
151 dll_inputs = [ | |
152 installers_sources_path + '/resource_only_dll.def', | |
153 res_file | |
154 ] | |
155 | |
156 dll_output = dll_env.ComponentLibrary( | |
157 lib_name='%spayload%s' % (prefix, suffix), | |
158 source=dll_inputs, | |
159 ) | |
160 | |
161 # Get only the dll itself from the output (ie. ignore .pdb, etc.) | |
162 dll_output_name = [f for f in dll_output if f.suffix == '.dll'] | |
163 | |
164 # Build the target setup executable by merging the empty metafile | |
165 # with the resource DLL built above. | |
166 merged_output = env.Command( | |
167 target='unsigned_' + target_name, | |
168 source=[empty_metainstaller_path, dll_output_name], | |
169 action= '%s --copyappend $SOURCES $TARGET' % resmerge_path | |
170 ) | |
171 | |
172 signed_exe = env.SignedBinary( | |
173 target=target_name, | |
174 source=merged_output, | |
175 ) | |
176 | |
177 return env.Replicate(output_dir, signed_exe) | |
OLD | NEW |