diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-02 20:50:56 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-02 20:50:56 +0000 |
commit | 2ac1e7ca438583c681cbb686122f3ec69fa1d5ff (patch) | |
tree | 500afab56a65e9f61e311ee42c5e1e969cf5915a /third_party | |
parent | de945c861f68df1f16d58b0570332976fed57f7d (diff) | |
download | chromium_src-2ac1e7ca438583c681cbb686122f3ec69fa1d5ff.zip chromium_src-2ac1e7ca438583c681cbb686122f3ec69fa1d5ff.tar.gz chromium_src-2ac1e7ca438583c681cbb686122f3ec69fa1d5ff.tar.bz2 |
Generate stubs for OpenMAX IL
Generate stubs for OpenMAX IL so we don't need a real OpenMAX library for
building. The actual library is loaded during runtime.
TEST=Build is green
TEST=Running omx_test works on hardware with OpenMAX support
Review URL: http://codereview.chromium.org/661135
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40418 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rwxr-xr-x | third_party/ffmpeg/ffmpeg.gyp | 2 | ||||
-rwxr-xr-x | third_party/ffmpeg/generate_stubs.py | 968 | ||||
-rwxr-xr-x | third_party/ffmpeg/generate_stubs_unittest.py | 283 | ||||
-rw-r--r-- | third_party/openmax/il.sigs | 11 | ||||
-rw-r--r-- | third_party/openmax/il_stub_headers.fragment | 8 | ||||
-rw-r--r-- | third_party/openmax/openmax.gyp | 78 |
6 files changed, 77 insertions, 1273 deletions
diff --git a/third_party/ffmpeg/ffmpeg.gyp b/third_party/ffmpeg/ffmpeg.gyp index 1886d63..b093a75 100755 --- a/third_party/ffmpeg/ffmpeg.gyp +++ b/third_party/ffmpeg/ffmpeg.gyp @@ -592,7 +592,7 @@ 'targets': [ { 'variables': { - 'generate_stubs_script': 'generate_stubs.py', + 'generate_stubs_script': '../../tools/generate_stubs/generate_stubs.py', 'sig_files': [ # Note that these must be listed in dependency order. # (i.e. if A depends on B, then B must be listed before A.) diff --git a/third_party/ffmpeg/generate_stubs.py b/third_party/ffmpeg/generate_stubs.py deleted file mode 100755 index e1ba671..0000000 --- a/third_party/ffmpeg/generate_stubs.py +++ /dev/null @@ -1,968 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2009 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Creates windows and posix stub files for a given set of signatures. - -For libraries that need to be loaded outside of the standard executable startup -path mechanism, stub files need to be generated for the wanted functions. In -windows, this is done via "def" files and the delay load mechanism. On a posix -system, a set of stub functions need to be generated that dispatch to functions -found via dlsym. - -This script takes a set of files, where each file is a list of C-style -signatures (one signature per line). The output is either a windows def file, -or a header + implementation file of stubs suitable for use in a posix system. -""" - -__author__ = 'ajwong@chromium.org (Albert J. Wong)' - -import optparse -import os -import re -import string -import subprocess - - -class Error(Exception): - pass - - -class BadSignatureError(Error): - pass - - -class SubprocessError(Error): - def __init__(self, message, error_code): - Error.__init__(self) - self.message = message - self.error_code = error_code - - def __str__(self): - return 'Failed with code %s: %s' % (self.message, repr(self.error_code)) - - -# Regular expression used to parse signatures in the input files. The regex -# is built around identifying the "identifier" for the function name. We -# consider the identifier to be the string that follows these constraints: -# -# 1) Starts with [_a-ZA-Z] (C++ spec 2.10). -# 2) Continues with [_a-ZA-Z0-9] (C++ spec 2.10). -# 3) Preceeds an opening parenthesis by 0 or more whitespace chars. -# -# From that, all preceeding characters are considered the return value. -# Trailing characters should have a substring matching the form (.*). That -# is considered the arguments. -SIGNATURE_REGEX = re.compile('(?P<return_type>.+?)' - '(?P<name>[_a-zA-Z][_a-zA-Z0-9]+)\s*' - '\((?P<params>.*?)\)') - -# Used for generating C++ identifiers. -INVALID_C_IDENT_CHARS = re.compile('[^_a-zA-Z0-9]') - -# Constants defning the supported file types options. -FILE_TYPE_WIN = 'windows_lib' -FILE_TYPE_POSIX_STUB = 'posix_stubs' - -# Template for generating a stub function definition. Includes a forward -# declaration marking the symbol as weak. This template takes the following -# named parameters. -# return_type: The return type. -# name: The name of the function. -# params: The parameters to the function. -# return_prefix: 'return ' if this function is not void. '' otherwise. -# arg_list: The arguments used to call the stub function. -STUB_FUNCTION_DEFINITION = ( - """extern %(return_type)s %(name)s(%(params)s) __attribute__((weak)); -%(return_type)s %(name)s(%(params)s) { - %(return_prefix)s%(name)s_ptr(%(arg_list)s); -}""") - -# Template for the preamble for the stub header file with the header guards, -# standard set of includes, and namespace opener. This template takes the -# following named parameters: -# guard_name: The macro to use as the header guard. -# namespace: The namespace for the stub functions. -STUB_HEADER_PREAMBLE = """// This is generated file. Do not modify directly. - -#ifndef %(guard_name)s -#define %(guard_name)s - -#include <map> -#include <string> -#include <vector> - -namespace %(namespace)s { -""" - -# Template for the end of the stub header. This closes the namespace and the -# header guards. This template takes the following named parameters: -# guard_name: The macro to use as the header guard. -# namespace: The namespace for the stub functions. -STUB_HEADER_CLOSER = """} // namespace %(namespace)s - -#endif // %(guard_name)s -""" - -# The standard includes needed for the stub implementation file. Takes one -# string substition with the path to the associated stub header file. -IMPLEMENTATION_PREAMBLE = """// This is generated file. Do not modify directly. - -#include "%s" - -#include <stdlib.h> // For NULL. -#include <dlfcn.h> // For dysym, dlopen. - -#include <map> -#include <vector> -""" - -# The start and end templates for the enum definitions used by the Umbrella -# initializer. -UMBRELLA_ENUM_START = """// Enum and typedef for umbrella initializer. -enum StubModules { -""" -UMBRELLA_ENUM_END = """ kNumStubModules -}; - -""" - -# Start and end of the extern "C" section for the implementation contents. -IMPLEMENTATION_CONTENTS_C_START = """extern "C" { - -""" -IMPLEMENTATION_CONTENTS_C_END = """ -} // extern "C" - - -""" - -# Templates for the start and end of a namespace. Takes one parameter, the -# namespace name. -NAMESPACE_START = """namespace %s { - -""" -NAMESPACE_END = """} // namespace %s - -""" - -# Comment to include before the section declaring all the function pointers -# used by the stub functions. -FUNCTION_POINTER_SECTION_COMMENT = ( - """// Static pointers that will hold the location of the real function -// implementations after the module has been loaded. -""") - -# Template for the module initialization check function. This template -# takes two parameteres: the function name, and the conditional used to -# verify the module's initialization. -MODULE_INITIALIZATION_CHECK_FUNCTION = ( - """// Returns true if all stubs have been properly initialized. -bool %s() { - if (%s) { - return true; - } else { - return false; - } -} - -""") - -# Template for the line that initialize the stub pointer. This template takes -# the following named parameters: -# name: The name of the function. -# return_type: The return type. -# params: The parameters to the function. -STUB_POINTER_INITIALIZER = """ %(name)s_ptr = - reinterpret_cast<%(return_type)s (*)(%(parameters)s)>( - dlsym(module, "%(name)s")); -""" - -# Template for module initializer function start and end. This template takes -# one parameter which is the initializer function name. -MODULE_INITIALIZE_START = """// Initializes the module stubs. -void %s(void* module) { -""" -MODULE_INITIALIZE_END = """} - -""" - -# Template for module uninitializer function start and end. This template -# takes one parameter which is the initializer function name. -MODULE_UNINITIALIZE_START = ( - """// Uninitialize the module stubs. Reset pointers to NULL. -void %s() { -""") -MODULE_UNINITIALIZE_END = """} - -""" - - -# Open namespace and add typedef for internal data structures used by the -# umbrella initializer. -UMBRELLA_INITIALIZER_START = """namespace %s { -typedef std::map<StubModules, void*> StubHandleMap; -""" - -# Function close DSOs on error and clean up dangling references. -UMBRELLA_INITIALIZER_CLEANUP_FUNCTION = ( - """static void CloseLibraries(StubHandleMap* stub_handles) { - for (StubHandleMap::const_iterator it = stub_handles->begin(); - it != stub_handles->end(); - ++it) { - dlclose(it->second); - } - - stub_handles->clear(); -} -""") - -# Function to initialize each DSO for the given paths. -UMBRELLA_INITIALIZER_INITIALIZE_FUNCTION_START = ( - """bool InitializeStubs(const StubPathMap& path_map) { - StubHandleMap opened_libraries; - for (int i = 0; i < kNumStubModules; ++i) { - StubModules cur_module = static_cast<StubModules>(i); - // If a module is missing, we fail. - StubPathMap::const_iterator it = path_map.find(cur_module); - if (it == path_map.end()) { - CloseLibraries(&opened_libraries); - return false; - } - - // Otherwise, attempt to dlopen the library. - const std::vector<std::string>& paths = it->second; - bool module_opened = false; - for (std::vector<std::string>::const_iterator dso_path = paths.begin(); - !module_opened && dso_path != paths.end(); - ++dso_path) { - void* handle = dlopen(dso_path->c_str(), RTLD_LAZY); - if (handle != NULL) { - module_opened = true; - opened_libraries[cur_module] = handle; - } - } - - if (!module_opened) { - CloseLibraries(&opened_libraries); - return false; - } - } -""") - -# Template to generate code to check if each module initializer correctly -# completed, and cleanup on failures. This template takes the following -# named parameters. -# conditional: The conditional expression for successful initialization. -# uninitializers: The statements needed to uninitialize the modules. -UMBRELLA_INITIALIZER_CHECK_AND_CLEANUP = ( - """ // Check that each module is initialized correctly. - // Close all previously opened libraries on failure. - if (%(conditional)s) { - %(uninitializers)s; - CloseLibraries(&opened_libraries); - return false; - } - - return true; -} -""") - -# Template for Initialize, Unininitialize, and IsInitialized functions for each -# module. This template takes the following named parameters: -# initialize: Name of the Initialize function. -# uninitialize: Name of the Uninitialize function. -# is_initialized: Name of the IsInitialized function. -MODULE_FUNCTION_PROTOTYPES = """bool %(is_initialized)s(); -void %(initialize)s(void* module); -void %(uninitialize)s(); - -""" - -# Template for umbrella initializer declaration and associated datatypes. -UMBRELLA_INITIALIZER_PROTOTYPE = ( - """typedef std::map<StubModules, std::vector<std::string> > StubPathMap; - -// Umbrella initializer for all the modules in this stub file. -bool InitializeStubs(const StubPathMap& path_map); -""") - - -def ExtractModuleName(infile_path): - """Infers the module name from the input file path. - - The input filename is supposed to be in the form "ModuleName.sigs". - This function splits the filename from the extention on that basename of - the path and returns that as the module name. - - Args: - infile_path: String holding the path to the input file. - - Returns: - The module name as a string. - """ - basename = os.path.basename(infile_path) - return os.path.splitext(basename)[0] - - -def ParseSignatures(infile): - """Parses function signatures in the input file. - - This function parses a file of signatures into a list of dictionaries that - represent the function signatures in the input file. Each dictionary has - the following keys: - return_type: A string with the return type. - name: A string with the name of the function. - params: A list of each function parameter declaration (type + name) - - The format of the input file is one C-style function signature per line, no - trailing semicolon. Empty lines are allowed. An empty line is a line that - consists purely of whitespace. Lines that begin with a # are considered - comment lines and are ignored. - - We assume that "int foo(void)" is the same as "int foo()", which is not - true in C where "int foo()" is equivalent to "int foo(...)". Our generated - code is C++, and we do not handle varargs, so this is a case that can be - ignored for now. - - Args: - infile: File object holding a text file of function signatures. - - Returns: - A list of dictionaries, where each dictionary represents one function - signature. - - Raises: - BadSignatureError: A line could not be parsed as a signature. - """ - signatures = [] - for line in infile: - line = line.strip() - if line and line[0] != '#': - m = SIGNATURE_REGEX.match(line) - if m is None: - raise BadSignatureError('Unparsable line: %s' % line) - signatures.append( - {'return_type': m.group('return_type').strip(), - 'name': m.group('name').strip(), - 'params': [arg.strip() for arg in m.group('params').split(',')]}) - return signatures - - -def WriteWindowsDefFile(module_name, signatures, outfile): - """Writes a windows def file to the given output file object. - - The def file format is basically a list of function names. Generation is - simple. After outputting the LIBRARY and EXPORTS lines, print out each - function name, one to a line, preceeded by 2 spaces. - - Args: - module_name: The name of the module we are writing a stub for. - signatures: The list of signature hashes, as produced by ParseSignatures, - to create stubs for. - outfile: File handle to populate with definitions. - """ - outfile.write('LIBRARY %s\n' % module_name) - outfile.write('EXPORTS\n') - - for sig in signatures: - outfile.write(' %s\n' % sig['name']) - - -def CreateWindowsLib(module_name, signatures, intermediate_dir, outdir_path): - """Creates a windows library file. - - Calling this function will create a lib file in the outdir_path that exports - the signatures passed into the object. A temporary def file will be created - in the intermediate_dir. - - Args: - module_name: The name of the module we are writing a stub for. - signatures: The list of signature hashes, as produced by ParseSignatures, - to create stubs for. - intermediate_dir: The directory where the generated .def files should go. - outdir_path: The directory where generated .lib files should go. - - Raises: - SubprocessError: If invoking the windows "lib" tool fails, this is raised - with the error code. - """ - def_file_path = os.path.join(intermediate_dir, - module_name + '.def') - lib_file_path = os.path.join(outdir_path, - module_name + '.lib') - outfile = open(def_file_path, 'w') - try: - WriteWindowsDefFile(module_name, signatures, outfile) - finally: - outfile.close() - - # Invoke the "lib" program on Windows to create stub .lib files for the - # generated definitions. These .lib files can then be used during - # delayloading of the dynamic libraries. - ret = subprocess.call(['lib', '/nologo', '/machine:X86', - '/def:' + def_file_path, - '/out:' + lib_file_path]) - if ret != 0: - raise SubprocessError( - 'Failed creating %s for %s' % (lib_file_path, def_file_path), - ret) - - -class PosixStubWriter(object): - """Creates a file of stub functions for a library that is opened via dlopen. - - Windows provides a function in their compiler known as delay loading, which - effectively generates a set of stub functions for a dynamic library that - delays loading of the dynamic library/resolution of the symbols until one of - the needed functions are accessed. - - In posix, RTLD_LAZY does something similar with DSOs. This is the default - link mode for DSOs. However, even though the symbol is not resolved until - first usage, the DSO must be present at load time of the main binary. - - To simulate the windows delay load procedure, we need to create a set of - stub functions that allow for correct linkage of the main binary, but - dispatch to the dynamically resolved symbol when the module is initialized. - - This class takes a list of function signatures, and generates a set of stub - functions plus initialization code for them. - """ - - def __init__(self, module_name, signatures): - """Initializes PosixStubWriter for this set of signatures and module_name. - - Args: - module_name: The name of the module we are writing a stub for. - signatures: The list of signature hashes, as produced by ParseSignatures, - to create stubs for. - """ - self.signatures = signatures - self.module_name = module_name - - @classmethod - def CStyleIdentifier(cls, identifier): - """Generates a C style identifier. - - The module_name has all invalid identifier characters removed (anything - that's not [_a-zA-Z0-9]) and is run through string.capwords to try - and approximate camel case. - - Args: - identifier: The string with the module name to turn to C-style. - - Returns: - A string that can be used as part of a C identifier. - """ - return string.capwords(re.sub(INVALID_C_IDENT_CHARS, '', identifier)) - - @classmethod - def EnumName(cls, module_name): - """Gets the enum name for the module. - - Takes the module name and creates a suitable enum name. The module_name - is munged to be a valid C identifier then prefixed with the string - "kModule" to generate a Google style enum name. - - Args: - module_name: The name of the module to generate an enum name for. - - Returns: - A string with the name of the enum value representing this module. - """ - return 'kModule%s' % PosixStubWriter.CStyleIdentifier(module_name) - - @classmethod - def IsInitializedName(cls, module_name): - """Gets the name of function that checks initialization of this module. - - The name is in the format IsModuleInitialized. Where "Module" is replaced - with the module name, munged to be a valid C identifier. - - Args: - module_name: The name of the module to generate the function name for. - - Returns: - A string with the name of the initialization check function. - """ - return 'Is%sInitialized' % PosixStubWriter.CStyleIdentifier(module_name) - - @classmethod - def InitializeModuleName(cls, module_name): - """Gets the name of the function that initializes this module. - - The name is in the format InitializeModule. Where "Module" is replaced - with the module name, munged to be a valid C identifier. - - Args: - module_name: The name of the module to generate the function name for. - - Returns: - A string with the name of the initialization function. - """ - return 'Initialize%s' % PosixStubWriter.CStyleIdentifier(module_name) - - @classmethod - def UninitializeModuleName(cls, module_name): - """Gets the name of the function that uninitializes this module. - - The name is in the format UninitializeModule. Where "Module" is replaced - with the module name, munged to be a valid C identifier. - - Args: - module_name: The name of the module to generate the function name for. - - Returns: - A string with the name of the uninitialization function. - """ - return 'Uninitialize%s' % PosixStubWriter.CStyleIdentifier(module_name) - - @classmethod - def StubFunctionPointer(cls, signature): - """Generates a function pointer declaration for the given signature. - - Args: - signature: A signature hash, as produced by ParseSignatures, - representating the function signature. - - Returns: - A string with the declaration of the function pointer for the signature. - """ - return 'static %s (*%s_ptr)(%s) = NULL;' % (signature['return_type'], - signature['name'], - ', '.join(signature['params'])) - - @classmethod - def StubFunction(cls, signature): - """Generates a stub function definition for the given signature. - - The function definitions are created with __attribute__((weak)) so that - they may be overridden by a real static link or mock versions to be used - when testing. - - Args: - signature: A signature hash, as produced by ParseSignatures, - representating the function signature. - - Returns: - A string with the stub function definition. - """ - return_prefix = '' - if signature['return_type'] != 'void': - return_prefix = 'return ' - - # Generate the argument list. - arguments = [re.split('[\*& ]', arg)[-1].strip() for arg in - signature['params']] - arg_list = ', '.join(arguments) - if arg_list == 'void': - arg_list = '' - - return STUB_FUNCTION_DEFINITION % { - 'return_type': signature['return_type'], - 'name': signature['name'], - 'params': ', '.join(signature['params']), - 'return_prefix': return_prefix, - 'arg_list': arg_list} - - @classmethod - def WriteImplementationPreamble(cls, header_path, outfile): - """Write the necessary includes for the implementation file. - - Args: - header_path: The path to the header file. - outfile: The file handle to populate. - """ - outfile.write(IMPLEMENTATION_PREAMBLE % header_path) - - @classmethod - def WriteUmbrellaInitializer(cls, module_names, namespace, outfile): - """Writes a single function that will open + initialize each module. - - This intializer will take in an stl map of that lists the correct - dlopen target for each module. The map type is - std::map<enum StubModules, vector<std::string>> which matches one module - to a list of paths to try in dlopen. - - This function is an all-or-nothing function. If any module fails to load, - all other modules are dlclosed, and the function returns. Though it is - not enforced, this function should only be called once. - - Args: - module_names: A list with the names of the modules in this stub file. - namespace: The namespace these functions should be in. - outfile: The file handle to populate with pointer definitions. - """ - outfile.write(UMBRELLA_INITIALIZER_START % namespace) - outfile.write(UMBRELLA_INITIALIZER_CLEANUP_FUNCTION) - - # Create the initializaiton function that calls all module initializers, - # checks if they succeeded, and backs out module loads on an error. - outfile.write(UMBRELLA_INITIALIZER_INITIALIZE_FUNCTION_START) - outfile.write( - '\n // Initialize each module if we have not already failed.\n') - for module in module_names: - outfile.write(' %s(opened_libraries[%s]);\n' % - (PosixStubWriter.InitializeModuleName(module), - PosixStubWriter.EnumName(module))) - outfile.write('\n') - - # Output code to check the initialization status, clean up on error. - initializer_checks = ['!%s()' % PosixStubWriter.IsInitializedName(name) - for name in module_names] - uninitializers = ['%s()' % PosixStubWriter.UninitializeModuleName(name) - for name in module_names] - outfile.write(UMBRELLA_INITIALIZER_CHECK_AND_CLEANUP % { - 'conditional': ' ||\n '.join(initializer_checks), - 'uninitializers': ';\n '.join(uninitializers)}) - outfile.write('\n} // namespace %s\n' % namespace) - - @classmethod - def WriteHeaderContents(cls, module_names, namespace, header_guard, outfile): - """Writes a header file for the stub file generated for module_names. - - The header file exposes the following: - 1) An enum, StubModules, listing with an entry for each enum. - 2) A typedef for a StubPathMap allowing for specification of paths to - search for each module. - 3) The IsInitialized/Initialize/Uninitialize functions for each module. - 4) An umbrella initialize function for all modules. - - Args: - module_names: A list with the names of each module in this stub file. - namespace: The namespace these functions should be in. - header_guard: The macro to use as our header guard. - outfile: The output handle to populate. - """ - outfile.write(STUB_HEADER_PREAMBLE % - {'guard_name': header_guard, 'namespace': namespace}) - - # Generate the Initializer protoypes for each module. - outfile.write('// Individual module initializer functions.\n') - for name in module_names: - outfile.write(MODULE_FUNCTION_PROTOTYPES % { - 'is_initialized': PosixStubWriter.IsInitializedName(name), - 'initialize': PosixStubWriter.InitializeModuleName(name), - 'uninitialize': PosixStubWriter.UninitializeModuleName(name)}) - - # Generate the enum for umbrella initializer. - outfile.write(UMBRELLA_ENUM_START) - outfile.write(' %s = 0,\n' % PosixStubWriter.EnumName(module_names[0])) - for name in module_names[1:]: - outfile.write(' %s,\n' % PosixStubWriter.EnumName(name)) - outfile.write(UMBRELLA_ENUM_END) - - outfile.write(UMBRELLA_INITIALIZER_PROTOTYPE) - outfile.write(STUB_HEADER_CLOSER % { - 'namespace': namespace, 'guard_name': - header_guard}) - - def WriteImplementationContents(self, namespace, outfile): - """Given a file handle, write out the stub definitions for this module. - - Args: - namespace: The namespace these functions should be in. - outfile: The file handle to populate. - """ - outfile.write(IMPLEMENTATION_CONTENTS_C_START) - self.WriteFunctionPointers(outfile) - self.WriteStubFunctions(outfile) - outfile.write(IMPLEMENTATION_CONTENTS_C_END) - - outfile.write(NAMESPACE_START % namespace) - self.WriteModuleInitializeFunctions(outfile) - outfile.write(NAMESPACE_END % namespace) - - def WriteFunctionPointers(self, outfile): - """Write the function pointer declarations needed by the stubs. - - We need function pointers to hold the actual location of the function - implementation returned by dlsym. This function outputs a pointer - definition for each signature in the module. - - Pointers will be named with the following pattern "FuntionName_ptr". - - Args: - outfile: The file handle to populate with pointer definitions. - """ - outfile.write(FUNCTION_POINTER_SECTION_COMMENT) - - for sig in self.signatures: - outfile.write('%s\n' % PosixStubWriter.StubFunctionPointer(sig)) - outfile.write('\n') - - def WriteStubFunctions(self, outfile): - """Write the function stubs to handle dispatching to real implementations. - - Functions that have a return type other than void will look as follows: - - ReturnType FunctionName(A a) { - return FunctionName_ptr(a); - } - - Functions with a return type of void will look as follows: - - void FunctionName(A a) { - FunctionName_ptr(a); - } - - Args: - outfile: The file handle to populate. - """ - outfile.write('// Stubs that dispatch to the real implementations.\n') - for sig in self.signatures: - outfile.write('%s\n' % PosixStubWriter.StubFunction(sig)) - - def WriteModuleInitializeFunctions(self, outfile): - """Write functions to initialize/query initlialization of the module. - - This creates 2 functions IsModuleInitialized and InitializeModule where - "Module" is replaced with the module name, first letter capitalized. - - The InitializeModule function takes a handle that is retrieved from dlopen - and attempts to assign each function pointer above via dlsym. - - The IsModuleInitialized returns true if none of the required functions - pointers are NULL. - - Args: - outfile: The file handle to populate. - """ - ptr_names = ['%s_ptr' % sig['name'] for sig in self.signatures] - - # Construct the conditional expression to check the initialization of - # all the function pointers above. It should generate a conjuntion - # with each pointer on its own line, indented by six spaces to match - # the indentation level of MODULE_INITIALIZATION_CHECK_FUNCTION. - initialization_conditional = ' &&\n '.join(ptr_names) - - outfile.write(MODULE_INITIALIZATION_CHECK_FUNCTION % ( - PosixStubWriter.IsInitializedName(self.module_name), - initialization_conditional)) - - # Create function that initializes the module. - outfile.write(MODULE_INITIALIZE_START % - PosixStubWriter.InitializeModuleName(self.module_name)) - for sig in self.signatures: - outfile.write(STUB_POINTER_INITIALIZER % { - 'name': sig['name'], - 'return_type': sig['return_type'], - 'parameters': ', '.join(sig['params'])}) - outfile.write(MODULE_INITIALIZE_END) - - # Create function that uninitializes the module (sets all pointers to - # NULL). - outfile.write(MODULE_UNINITIALIZE_START % - PosixStubWriter.UninitializeModuleName(self.module_name)) - for sig in self.signatures: - outfile.write(' %s_ptr = NULL;\n' % sig['name']) - outfile.write(MODULE_UNINITIALIZE_END) - - -def CreateOptionParser(): - """Creates an OptionParser for the configuration options of script. - - Returns: - A OptionParser object. - """ - parser = optparse.OptionParser(usage='usage: %prog [options] input') - parser.add_option('-o', - '--output', - dest='out_dir', - default=None, - help='Output location.') - parser.add_option('-i', - '--intermediate_dir', - dest='intermediate_dir', - default=None, - help='Locaiton of intermediate files.') - parser.add_option('-t', - '--type', - dest='type', - default=None, - help=('Type of file. Either "%s" or "%s"' % - (FILE_TYPE_POSIX_STUB, FILE_TYPE_WIN))) - parser.add_option('-s', - '--stubfile_name', - dest='stubfile_name', - default=None, - help=('Name of posix_stubs output file. Ignored for ' - '%s type.' % FILE_TYPE_WIN)) - parser.add_option('-p', - '--path_from_source', - dest='path_from_source', - default=None, - help=('The relative path from the project root that the ' - 'generated file should consider itself part of (eg. ' - 'third_party/ffmpeg). This is used to generate the ' - 'header guard and namespace for our initializer ' - 'functions and does NOT affect the physical output ' - 'location of the file like -o does. Ignored for ' - ' %s type.' % FILE_TYPE_WIN)) - parser.add_option('-e', - '--extra_stub_header', - dest='extra_stub_header', - default=None, - help=('File to insert after the system includes in the ' - 'generated stub implemenation file. Ignored for ' - '%s type.' % FILE_TYPE_WIN)) - return parser - - -def ParseOptions(): - """Parses the options and terminates program if they are not sane. - - Returns: - The pair (optparse.OptionValues, [string]), that is the output of - a successful call to parser.parse_args(). - """ - parser = CreateOptionParser() - options, args = parser.parse_args() - - if not args: - parser.error('No inputs specified') - - if options.out_dir is None: - parser.error('Output location not specified') - - if options.type not in [FILE_TYPE_WIN, FILE_TYPE_POSIX_STUB]: - parser.error('Invalid output file type') - - if options.type == FILE_TYPE_POSIX_STUB: - if options.stubfile_name is None: - parser.error('Output file name need for %s' % FILE_TYPE_POSIX_STUB) - if options.path_from_source is None: - parser.error('Path from source needed for %s' % FILE_TYPE_POSIX_STUB) - - return options, args - - -def CreateOutputDirectories(options): - """Creates the intermediate and final output directories. - - Given the parsed options, create the intermediate and final output - directories if they do not exist. Returns the paths to both directories - as a pair. - - Args: - options: An OptionParser.OptionValues object with the parsed options. - - Returns: - The pair (out_dir, intermediate_dir), both of which are strings. - """ - out_dir = os.path.normpath(options.out_dir) - intermediate_dir = os.path.normpath(options.intermediate_dir) - if intermediate_dir is None: - intermediate_dir = out_dir - - if not os.path.exists(out_dir): - os.makedirs(out_dir) - if not os.path.exists(intermediate_dir): - os.makedirs(intermediate_dir) - - return out_dir, intermediate_dir - - -def CreateWindowsLibForSigFiles(sig_files, out_dir, intermediate_dir): - """For each signature file, create a windows lib. - - Args: - sig_files: Array of Strings with the paths to each signature file. - out_dir: String holding path to directory where the generated libs go. - intermediate_dir: String holding path to directory generated intermdiate - artifacts. - """ - for input_path in sig_files: - infile = open(input_path, 'r') - try: - signatures = ParseSignatures(infile) - module_name = ExtractModuleName(os.path.basename(input_path)) - CreateWindowsLib(module_name, signatures, intermediate_dir, out_dir) - finally: - infile.close() - - -def CreatePosixStubsForSigFiles(sig_files, stub_name, out_dir, - intermediate_dir, path_from_source, - extra_stub_header): - """Create a posix stub library with a module for each signature file. - - Args: - sig_files: Array of Strings with the paths to each signature file. - stub_name: String with the basename of the generated stub file. - out_dir: String holding path to directory for the .h files. - intermediate_dir: String holding path to directory for the .cc files. - path_from_source: String with relative path of generated files from the - project root. - extra_stub_header: String with path to file of extra lines to insert - into the generated header for the stub library. - """ - header_base_name = stub_name + '.h' - header_path = os.path.join(out_dir, header_base_name) - impl_path = os.path.join(intermediate_dir, stub_name + '.cc') - - module_names = [ExtractModuleName(path) for path in sig_files] - namespace = path_from_source.replace('/', '_').lower() - header_guard = '%s_' % namespace.upper() - header_include_path = os.path.join(path_from_source, header_base_name) - - # First create the implementation file. - impl_file = open(impl_path, 'w') - try: - # Open the file, and create the preamble which consists of a file - # header plus any necessary includes. - PosixStubWriter.WriteImplementationPreamble(header_include_path, - impl_file) - if extra_stub_header is not None: - extra_header_file = open(extra_stub_header, 'r') - try: - impl_file.write('\n') - for line in extra_header_file: - impl_file.write(line) - impl_file.write('\n') - finally: - extra_header_file.close() - - # For each signature file, generate the stub population functions - # for that file. Each file represents one module. - for input_path in sig_files: - name = ExtractModuleName(input_path) - infile = open(input_path, 'r') - try: - signatures = ParseSignatures(infile) - finally: - infile.close() - writer = PosixStubWriter(name, signatures) - writer.WriteImplementationContents(namespace, impl_file) - - # Lastly, output the umbrella function for the file. - PosixStubWriter.WriteUmbrellaInitializer(module_names, namespace, - impl_file) - finally: - impl_file.close() - - # Then create the associated header file. - header_file = open(header_path, 'w') - try: - PosixStubWriter.WriteHeaderContents(module_names, namespace, - header_guard, header_file) - finally: - header_file.close() - - -def main(): - options, args = ParseOptions() - out_dir, intermediate_dir = CreateOutputDirectories(options) - - if options.type == FILE_TYPE_WIN: - CreateWindowsLibForSigFiles(args, out_dir, intermediate_dir) - elif options.type == FILE_TYPE_POSIX_STUB: - CreatePosixStubsForSigFiles(args, options.stubfile_name, out_dir, - intermediate_dir, options.path_from_source, - options.extra_stub_header) - - -if __name__ == '__main__': - main() diff --git a/third_party/ffmpeg/generate_stubs_unittest.py b/third_party/ffmpeg/generate_stubs_unittest.py deleted file mode 100755 index cfab996..0000000 --- a/third_party/ffmpeg/generate_stubs_unittest.py +++ /dev/null @@ -1,283 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2009 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Unittest for the generate_stubs.py. - -Since generate_stubs.py is a code generator, it is hard to do a very good -test. Instead of creating a golden-file test, which might be flakey, this -test elects instead to verify that various components "exist" within the -generated file as a sanity check. In particular, there is a simple hit -test to make sure that umbrella functions, etc., do try and include every -function they are responsible for invoking. Missing an invocation is quite -easily missed. - -There is no attempt to verify ordering of different components, or whether -or not those components are going to parse incorrectly because of prior -errors or positioning. Most of that should be caught really fast anyways -during any attempt to use a badly behaving script. -""" - -import re -import StringIO -import unittest -import generate_stubs as gs - - -def _MakeSignature(return_type, name, params): - return {'return_type': return_type, - 'name': name, - 'params': params} - - -SIMPLE_SIGNATURES = [ - ('int foo(int a)', _MakeSignature('int', 'foo', ['int a'])), - ('int bar(int a, double b)', _MakeSignature('int', 'bar', - ['int a', 'double b'])), - ('int baz(void)', _MakeSignature('int', 'baz', ['void'])), - ('void quux(void)', _MakeSignature('void', 'quux', ['void'])), - ('void waldo(void);', _MakeSignature('void', 'waldo', ['void'])), - ('int corge(void);', _MakeSignature('int', 'corge', ['void'])), - ] - -TRICKY_SIGNATURES = [ - ('const struct name *foo(int a, struct Test* b); ', - _MakeSignature('const struct name *', - 'foo', - ['int a', 'struct Test* b'])), - ('const struct name &foo(int a, struct Test* b);', - _MakeSignature('const struct name &', - 'foo', - ['int a', 'struct Test* b'])), - ('const struct name &_foo(int a, struct Test* b);', - _MakeSignature('const struct name &', - '_foo', - ['int a', 'struct Test* b'])), - ('struct name const * const _foo(int a, struct Test* b) ' - '__attribute__((inline));', - _MakeSignature('struct name const * const', - '_foo', - ['int a', 'struct Test* b'])) - ] - -INVALID_SIGNATURES = ['I am bad', 'Seriously bad(', ';;;'] - - -class GenerateStubModuleFunctionsUnittest(unittest.TestCase): - def testExtractModuleName(self): - self.assertEqual('somefile-2', gs.ExtractModuleName('somefile-2.ext')) - - def testParseSignatures_EmptyFile(self): - # Empty file just generates empty signatures. - infile = StringIO.StringIO() - signatures = gs.ParseSignatures(infile) - self.assertEqual(0, len(signatures)) - - def testParseSignatures_SimpleSignatures(self): - file_contents = '\n'.join([x[0] for x in SIMPLE_SIGNATURES]) - infile = StringIO.StringIO(file_contents) - signatures = gs.ParseSignatures(infile) - self.assertEqual(len(SIMPLE_SIGNATURES), len(signatures)) - - # We assume signatures are in order. - for i in xrange(len(SIMPLE_SIGNATURES)): - self.assertEqual(SIMPLE_SIGNATURES[i][1], signatures[i], - msg='Expected %s\nActual %s\nFor %s' % - (SIMPLE_SIGNATURES[i][1], - signatures[i], - SIMPLE_SIGNATURES[i][0])) - - def testParseSignatures_TrickySignatures(self): - file_contents = '\n'.join([x[0] for x in TRICKY_SIGNATURES]) - infile = StringIO.StringIO(file_contents) - signatures = gs.ParseSignatures(infile) - self.assertEqual(len(TRICKY_SIGNATURES), len(signatures)) - - # We assume signatures are in order. - for i in xrange(len(TRICKY_SIGNATURES)): - self.assertEqual(TRICKY_SIGNATURES[i][1], signatures[i], - msg='Expected %s\nActual %s\nFor %s' % - (TRICKY_SIGNATURES[i][1], - signatures[i], - TRICKY_SIGNATURES[i][0])) - - def testParseSignatures_InvalidSignatures(self): - for i in INVALID_SIGNATURES: - infile = StringIO.StringIO(i) - self.assertRaises(gs.BadSignatureError, gs.ParseSignatures, infile) - - def testParseSignatures_CommentsIgnored(self): - my_sigs = [] - my_sigs.append('# a comment') - my_sigs.append(SIMPLE_SIGNATURES[0][0]) - my_sigs.append('# another comment') - my_sigs.append(SIMPLE_SIGNATURES[0][0]) - my_sigs.append('# a third comment') - my_sigs.append(SIMPLE_SIGNATURES[0][0]) - - file_contents = '\n'.join(my_sigs) - infile = StringIO.StringIO(file_contents) - signatures = gs.ParseSignatures(infile) - self.assertEqual(3, len(signatures)) - - -class WindowsLibUnittest(unittest.TestCase): - def testWriteWindowsDefFile(self): - module_name = 'my_module-1' - signatures = [sig[1] for sig in SIMPLE_SIGNATURES] - outfile = StringIO.StringIO() - gs.WriteWindowsDefFile(module_name, signatures, outfile) - contents = outfile.getvalue() - - # Check that the file header is correct. - self.assertTrue(contents.startswith("""LIBRARY %s -EXPORTS -""" % module_name)) - - # Check that the signatures were exported. - for sig in signatures: - pattern = '\n %s\n' % sig['name'] - self.assertTrue(re.search(pattern, contents), - msg='Expected match of "%s" in %s' % (pattern, contents)) - - -class PosixStubWriterUnittest(unittest.TestCase): - def setUp(self): - self.module_name = 'my_module-1' - self.signatures = [sig[1] for sig in SIMPLE_SIGNATURES] - self.out_dir = 'out_dir' - self.writer = gs.PosixStubWriter(self.module_name, self.signatures) - - def testEnumName(self): - self.assertEqual('kModuleMy_module1', - gs.PosixStubWriter.EnumName(self.module_name)) - - def testIsInitializedName(self): - self.assertEqual('IsMy_module1Initialized', - gs.PosixStubWriter.IsInitializedName(self.module_name)) - - def testInitializeModuleName(self): - self.assertEqual( - 'InitializeMy_module1', - gs.PosixStubWriter.InitializeModuleName(self.module_name)) - - def testUninitializeModuleName(self): - self.assertEqual( - 'UninitializeMy_module1', - gs.PosixStubWriter.UninitializeModuleName(self.module_name)) - - def testStubFunctionPointer(self): - self.assertEqual( - 'static int (*foo_ptr)(int a) = NULL;', - gs.PosixStubWriter.StubFunctionPointer(SIMPLE_SIGNATURES[0][1])) - - def testStubFunction(self): - # Test for a signature with a return value and a parameter. - self.assertEqual("""extern int foo(int a) __attribute__((weak)); -int foo(int a) { - return foo_ptr(a); -}""", gs.PosixStubWriter.StubFunction(SIMPLE_SIGNATURES[0][1])) - - # Test for a signature with a void return value and no parameters. - self.assertEqual("""extern void waldo(void) __attribute__((weak)); -void waldo(void) { - waldo_ptr(); -}""", gs.PosixStubWriter.StubFunction(SIMPLE_SIGNATURES[4][1])) - - def testWriteImplemenationContents(self): - outfile = StringIO.StringIO() - self.writer.WriteImplementationContents('my_namespace', outfile) - contents = outfile.getvalue() - - # Verify namespace exists somewhere. - self.assertTrue(contents.find('namespace my_namespace {') != -1) - - # Verify that each signature has an _ptr and a function call in the file. - # Check that the signatures were exported. - for sig in self.signatures: - decl = gs.PosixStubWriter.StubFunctionPointer(sig) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - - # Verify that each signature has an stub function generated for it. - for sig in self.signatures: - decl = gs.PosixStubWriter.StubFunction(sig) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - - # Find module initializer functions. Make sure all 3 exist. - decl = gs.PosixStubWriter.InitializeModuleName(self.module_name) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - decl = gs.PosixStubWriter.UninitializeModuleName(self.module_name) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - decl = gs.PosixStubWriter.IsInitializedName(self.module_name) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - - def testWriteHeaderContents(self): - # Data for header generation. - module_names = ['oneModule', 'twoModule'] - - # Make the header. - outfile = StringIO.StringIO() - self.writer.WriteHeaderContents(module_names, 'my_namespace', 'GUARD_', - outfile) - contents = outfile.getvalue() - - # Check for namespace and header guard. - self.assertTrue(contents.find('namespace my_namespace {') != -1) - self.assertTrue(contents.find('#ifndef GUARD_') != -1) - - # Check for umbrella initializer. - self.assertTrue(contents.find('InitializeStubs(') != -1) - - # Check per-module declarations. - for name in module_names: - # Check for enums. - decl = gs.PosixStubWriter.EnumName(name) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - - # Check for module initializer functions. - decl = gs.PosixStubWriter.IsInitializedName(name) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - decl = gs.PosixStubWriter.InitializeModuleName(name) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - decl = gs.PosixStubWriter.UninitializeModuleName(name) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - - def testWriteUmbrellaInitializer(self): - # Data for header generation. - module_names = ['oneModule', 'twoModule'] - - # Make the header. - outfile = StringIO.StringIO() - self.writer.WriteUmbrellaInitializer(module_names, 'my_namespace', outfile) - contents = outfile.getvalue() - - # Check for umbrella initializer declaration. - self.assertTrue(contents.find('bool InitializeStubs(') != -1) - - # If the umbrella initializer is correctly written, each module will have - # its initializer called, checked, and uninitialized on failure. Sanity - # check that here. - for name in module_names: - # Check for module initializer functions. - decl = gs.PosixStubWriter.IsInitializedName(name) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - decl = gs.PosixStubWriter.InitializeModuleName(name) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - decl = gs.PosixStubWriter.UninitializeModuleName(name) - self.assertTrue(contents.find(decl) != -1, - msg='Expected "%s" in %s' % (decl, contents)) - -if __name__ == '__main__': - unittest.main() diff --git a/third_party/openmax/il.sigs b/third_party/openmax/il.sigs new file mode 100644 index 0000000..20d6b98 --- /dev/null +++ b/third_party/openmax/il.sigs @@ -0,0 +1,11 @@ +# Copyright (c) 2010 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Functions from OpenMAX IL used in Chromium code. + +OMX_ERRORTYPE OMX_Init(void); +OMX_ERRORTYPE OMX_Deinit(void); +OMX_ERRORTYPE OMX_GetHandle(OMX_HANDLETYPE* pHandle, OMX_STRING cComponentName, OMX_PTR pAppData, OMX_CALLBACKTYPE* pCallBacks); +OMX_ERRORTYPE OMX_FreeHandle(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE OMX_GetComponentsOfRole (OMX_STRING role, OMX_U32* pNumComps, OMX_U8** compNames); diff --git a/third_party/openmax/il_stub_headers.fragment b/third_party/openmax/il_stub_headers.fragment new file mode 100644 index 0000000..222f4dc --- /dev/null +++ b/third_party/openmax/il_stub_headers.fragment @@ -0,0 +1,8 @@ +// These are some extra includes needed in the generated stub file for defining +// various OpenMAX types. + +extern "C" { + +#include "third_party/openmax/il/OMX_Core.h" + +} diff --git a/third_party/openmax/openmax.gyp b/third_party/openmax/openmax.gyp index ef14e41..16293e4 100644 --- a/third_party/openmax/openmax.gyp +++ b/third_party/openmax/openmax.gyp @@ -1,4 +1,4 @@ -# Copyright (c) 2009 The Chromium Authors. All rights reserved. +# Copyright (c) 2010 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -26,9 +26,12 @@ 'include_dirs': [ 'il', ], + 'defines': [ + '__OMX_EXPORTS', + ], }, 'conditions': [ - ['openmax_type=="stub"', { + ['OS!="linux"', { 'type': '<(library)', 'dependencies': [ '../../base/base.gyp:base', @@ -42,31 +45,64 @@ 'defines': [ '__OMX_EXPORTS', ], + }], + ['OS=="linux"', { + 'variables': { + 'generate_stubs_script': '../../tools/generate_stubs/generate_stubs.py', + 'sig_files': [ + 'il.sigs', + ], + 'extra_header': 'il_stub_headers.fragment', + 'outfile_type': 'posix_stubs', + 'stubs_filename_root': 'il_stubs', + 'project_path': 'third_party/openmax', + 'intermediate_dir': '<(INTERMEDIATE_DIR)', + 'output_root': '<(SHARED_INTERMEDIATE_DIR)/openmax', + }, + 'type': '<(library)', + 'dependencies': [ + '../../base/base.gyp:base', + ], + 'defines': [ + '__OMX_EXPORTS', + ], + 'include_dirs': [ + 'il', + '<(output_root)', + '../..', # The chromium 'src' directory. + ], 'direct_dependent_settings': { - 'defines': [ - '__OMX_EXPORTS', + 'include_dirs': [ + '<(output_root)', + '../..', # The chromium 'src' directory. ], }, - }], - ['openmax_type=="bellagio"', { - 'type': 'none', - 'direct_dependent_settings': { - 'link_settings': { - 'libraries': [ - '-lomxil-bellagio', + 'actions': [ + { + 'action_name': 'generate_stubs', + 'inputs': [ + '<(generate_stubs_script)', + '<(extra_header)', + '<@(sig_files)', ], - }, - }, - }], - ['openmax_type=="omxcore"', { - 'type': 'none', - 'direct_dependent_settings': { - 'link_settings': { - 'libraries': [ - '-lOmxCore', + 'outputs': [ + '<(intermediate_dir)/<(stubs_filename_root).cc', + '<(output_root)/<(project_path)/<(stubs_filename_root).h', + ], + 'action': ['python', + '<(generate_stubs_script)', + '-i', '<(intermediate_dir)', + '-o', '<(output_root)/<(project_path)', + '-t', '<(outfile_type)', + '-e', '<(extra_header)', + '-s', '<(stubs_filename_root)', + '-p', '<(project_path)', + '<@(_inputs)', ], + 'process_outputs_as_sources': 1, + 'message': 'Generating OpenMAX IL stubs for dynamic loading.', }, - }, + ], }], ], }, |