| 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 |