1448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org#!/usr/bin/env python 2448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org 3448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org# Copyright (c) 2012 Google Inc. All rights reserved. 4448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org# Use of this source code is governed by a BSD-style license that can be 5448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org# found in the LICENSE file. 6448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org 7448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org""" 8448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.orgMake sure we generate a manifest file when linking binaries, including 9448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.orghandling AdditionalManifestFiles. 10448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org""" 11448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org 12448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.orgimport TestGyp 13448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org 14448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.orgimport sys 15448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org 16448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.orgif sys.platform == 'win32': 177509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org import pywintypes 187509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org import win32api 197509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org import winerror 207509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org 217509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org RT_MANIFEST = 24 227509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org 237509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org class LoadLibrary(object): 247509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org """Context manager for loading and releasing binaries in Windows. 257509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org Yields the handle of the binary loaded.""" 267509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org def __init__(self, path): 277509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org self._path = path 287509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org self._handle = None 297509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org 307509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org def __enter__(self): 317509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org self._handle = win32api.LoadLibrary(self._path) 327509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org return self._handle 337509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org 347509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org def __exit__(self, type, value, traceback): 357509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org win32api.FreeLibrary(self._handle) 367509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org 377509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org def extract_manifest(path, resource_name): 387509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org """Reads manifest from |path| and returns it as a string. 397509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org Returns None is there is no such manifest.""" 407509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org with LoadLibrary(path) as handle: 417509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org try: 427509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org return win32api.LoadResource(handle, RT_MANIFEST, resource_name) 437509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org except pywintypes.error as error: 447509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org if error.args[0] == winerror.ERROR_RESOURCE_DATA_NOT_FOUND: 457509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org return None 467509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org else: 477509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org raise 487509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org 49448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org test = TestGyp.TestGyp(formats=['msvs', 'ninja']) 50448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org 51448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org CHDIR = 'linker-flags' 52448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org test.run_gyp('generate-manifest.gyp', chdir=CHDIR) 53448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org test.build('generate-manifest.gyp', test.ALL, chdir=CHDIR) 54448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org 5578d5366f3040ddfd2fcdcde6e2e4dde87c102850scottmg@chromium.org # Make sure that generation of .generated.manifest does not cause a relink. 5678d5366f3040ddfd2fcdcde6e2e4dde87c102850scottmg@chromium.org test.run_gyp('generate-manifest.gyp', chdir=CHDIR) 5778d5366f3040ddfd2fcdcde6e2e4dde87c102850scottmg@chromium.org test.up_to_date('generate-manifest.gyp', test.ALL, chdir=CHDIR) 5878d5366f3040ddfd2fcdcde6e2e4dde87c102850scottmg@chromium.org 597509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org def test_manifest(filename, generate_manifest, embedded_manifest, 607509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org extra_manifest): 617509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org exe_file = test.built_file_path(filename, chdir=CHDIR) 627509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org if not generate_manifest: 637509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test.must_not_exist(exe_file + '.manifest') 647509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org manifest = extract_manifest(exe_file, 1) 657509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test.fail_test(manifest) 667509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org return 677509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org if embedded_manifest: 687509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org manifest = extract_manifest(exe_file, 1) 697509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test.fail_test(not manifest) 707509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org else: 717509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test.must_exist(exe_file + '.manifest') 727509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org manifest = test.read(exe_file + '.manifest') 737509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test.fail_test(not manifest) 747509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test.fail_test(extract_manifest(exe_file, 1)) 757509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org if generate_manifest: 767509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test.must_contain_any_line(manifest, 'requestedExecutionLevel') 777509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org if extra_manifest: 787509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test.must_contain_any_line(manifest, 797509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org '35138b9a-5d96-4fbd-8e2d-a2440225f93a') 807509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test.must_contain_any_line(manifest, 817509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org 'e2011457-1546-43c5-a5fe-008deee3d3f0') 827509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org 837509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test_manifest('test_generate_manifest_true.exe', 847509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org generate_manifest=True, 857509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org embedded_manifest=False, 867509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org extra_manifest=False) 877509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test_manifest('test_generate_manifest_false.exe', 887509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org generate_manifest=False, 897509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org embedded_manifest=False, 907509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org extra_manifest=False) 917509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test_manifest('test_generate_manifest_default.exe', 927509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org generate_manifest=True, 937509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org embedded_manifest=False, 947509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org extra_manifest=False) 957509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test_manifest('test_generate_manifest_true_as_embedded.exe', 967509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org generate_manifest=True, 977509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org embedded_manifest=True, 987509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org extra_manifest=False) 997509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test_manifest('test_generate_manifest_false_as_embedded.exe', 1007509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org generate_manifest=False, 1017509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org embedded_manifest=True, 1027509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org extra_manifest=False) 1037509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test_manifest('test_generate_manifest_default_as_embedded.exe', 1047509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org generate_manifest=True, 1057509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org embedded_manifest=True, 1067509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org extra_manifest=False) 1077509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test_manifest('test_generate_manifest_true_with_extra_manifest.exe', 1087509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org generate_manifest=True, 1097509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org embedded_manifest=False, 1107509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org extra_manifest=True) 1117509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test_manifest('test_generate_manifest_false_with_extra_manifest.exe', 1127509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org generate_manifest=False, 1137509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org embedded_manifest=False, 1147509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org extra_manifest=True) 1157509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test_manifest('test_generate_manifest_true_with_extra_manifest_list.exe', 1167509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org generate_manifest=True, 1177509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org embedded_manifest=False, 1187509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org extra_manifest=True) 1197509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org test_manifest('test_generate_manifest_false_with_extra_manifest_list.exe', 1207509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org generate_manifest=False, 1217509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org embedded_manifest=False, 1227509f5f9cd770e1ae1a4d1b720dda59ca60c5524yukawa@chromium.org extra_manifest=True) 12367e1e1f46d9b534543c4da6c27988aca0ef5c475scottmg@chromium.org test_manifest('test_generate_manifest_default_embed_default.exe', 12467e1e1f46d9b534543c4da6c27988aca0ef5c475scottmg@chromium.org generate_manifest=True, 12567e1e1f46d9b534543c4da6c27988aca0ef5c475scottmg@chromium.org embedded_manifest=True, 12667e1e1f46d9b534543c4da6c27988aca0ef5c475scottmg@chromium.org extra_manifest=False) 127448a52dfe9691d2b24f152b950b773c59e8b0ee6scottmg@chromium.org test.pass_test() 128