Commit c593df03 authored by Tomas Popela's avatar Tomas Popela Committed by Commit Bot

Add a way to specify logging function for stub files

Currently when the stubs code is used outside of the Chromium (i.e. in
WebRTC) the build will fail because of the missing implementation of
VLOG() - it's defined in the //base/logging.h, but WebRTC can't use that as it
uses its own //base_rtc/logging.h with RTC_LOG() functions.

To make it buildable there add a two new options to the
generate_stubs.py. The first one '--logging-function' or '-l' is used
for passing the function call for logging. Its default value is set to
'VLOG(1)' so the current code doesn't need to be updated. The second one
is '--logging-include' or '-n' that is used for passing the header file
where the function from the '--logging-function' is defined.

Change-Id: Iafc898deb818c0a140d177d0190f4db52294df0d
Reviewed-on: https://chromium-review.googlesource.com/c/1317918Reviewed-by: default avatarPatrik Höglund <phoglund@chromium.org>
Reviewed-by: default avatarDirk Pranke <dpranke@chromium.org>
Commit-Queue: Tomáš Popela <tomas.popela@gmail.com>
Cr-Commit-Position: refs/heads/master@{#606405}
parent f50de5ce
...@@ -143,6 +143,7 @@ void %(export)s %(name)s(%(params)s) { ...@@ -143,6 +143,7 @@ void %(export)s %(name)s(%(params)s) {
# following named parameters: # following named parameters:
# guard_name: The macro to use as the header guard. # guard_name: The macro to use as the header guard.
# namespace: The namespace for the stub functions. # namespace: The namespace for the stub functions.
# logging_include: Header file where the logging function is defined.
STUB_HEADER_PREAMBLE = """// This is generated file. Do not modify directly. STUB_HEADER_PREAMBLE = """// This is generated file. Do not modify directly.
#ifndef %(guard_name)s #ifndef %(guard_name)s
...@@ -153,7 +154,7 @@ STUB_HEADER_PREAMBLE = """// This is generated file. Do not modify directly. ...@@ -153,7 +154,7 @@ STUB_HEADER_PREAMBLE = """// This is generated file. Do not modify directly.
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/logging.h" #include "%(logging_include)s"
namespace %(namespace)s { namespace %(namespace)s {
""" """
...@@ -236,11 +237,14 @@ bool %s() { ...@@ -236,11 +237,14 @@ bool %s() {
# name: The name of the function. # name: The name of the function.
# return_type: The return type. # return_type: The return type.
# params: The parameters to the function. # params: The parameters to the function.
# logging_function: Function call for error logging.
STUB_POINTER_INITIALIZER = """ %(name)s_ptr = STUB_POINTER_INITIALIZER = """ %(name)s_ptr =
reinterpret_cast<%(return_type)s (*)(%(parameters)s)>( reinterpret_cast<%(return_type)s (*)(%(parameters)s)>(
dlsym(module, "%(name)s")); dlsym(module, "%(name)s"));
VLOG_IF(1, !%(name)s_ptr) << "Couldn't load %(name)s, dlerror() says:\\n" if (!%(name)s_ptr) {
<< dlerror(); %(logging_function)s << "Couldn't load %(name)s, dlerror() says:\\n"
<< dlerror();
}
""" """
# Template for module initializer function start and end. This template takes # Template for module initializer function start and end. This template takes
...@@ -283,6 +287,7 @@ UMBRELLA_INITIALIZER_CLEANUP_FUNCTION = ( ...@@ -283,6 +287,7 @@ UMBRELLA_INITIALIZER_CLEANUP_FUNCTION = (
""") """)
# Function to initialize each DSO for the given paths. # Function to initialize each DSO for the given paths.
# logging_function: Function call that will be used for error logging.
UMBRELLA_INITIALIZER_INITIALIZE_FUNCTION_START = ( UMBRELLA_INITIALIZER_INITIALIZE_FUNCTION_START = (
"""bool InitializeStubs(const StubPathMap& path_map) { """bool InitializeStubs(const StubPathMap& path_map) {
StubHandleMap opened_libraries; StubHandleMap opened_libraries;
...@@ -306,7 +311,7 @@ UMBRELLA_INITIALIZER_INITIALIZE_FUNCTION_START = ( ...@@ -306,7 +311,7 @@ UMBRELLA_INITIALIZER_INITIALIZE_FUNCTION_START = (
module_opened = true; module_opened = true;
opened_libraries[cur_module] = handle; opened_libraries[cur_module] = handle;
} else { } else {
VLOG(1) << "dlopen(" << dso_path->c_str() << ") failed, " %(logging_function)s << "dlopen(" << dso_path->c_str() << ") failed, "
<< "dlerror() says:\\n" << dlerror(); << "dlerror() says:\\n" << dlerror();
} }
} }
...@@ -521,7 +526,8 @@ class PosixStubWriter(object): ...@@ -521,7 +526,8 @@ class PosixStubWriter(object):
functions plus initialization code for them. functions plus initialization code for them.
""" """
def __init__(self, module_name, export_macro, signatures): def __init__(self, module_name, export_macro, signatures, logging_function,
logging_include):
"""Initializes PosixStubWriter for this set of signatures and module_name. """Initializes PosixStubWriter for this set of signatures and module_name.
Args: Args:
...@@ -530,10 +536,14 @@ class PosixStubWriter(object): ...@@ -530,10 +536,14 @@ class PosixStubWriter(object):
an EXPORT marking, to control visibility. an EXPORT marking, to control visibility.
signatures: The list of signature hashes, as produced by ParseSignatures, signatures: The list of signature hashes, as produced by ParseSignatures,
to create stubs for. to create stubs for.
logging_function: Function call that will be used for error logging.
logging_include: Header file where the logging function is defined.
""" """
self.signatures = signatures self.signatures = signatures
self.module_name = module_name self.module_name = module_name
self.export_macro = export_macro self.export_macro = export_macro
self.logging_function = logging_function
self.logging_include = logging_include
@classmethod @classmethod
def CStyleIdentifier(cls, identifier): def CStyleIdentifier(cls, identifier):
...@@ -697,7 +707,8 @@ class PosixStubWriter(object): ...@@ -697,7 +707,8 @@ class PosixStubWriter(object):
outfile.write(IMPLEMENTATION_PREAMBLE % header_path) outfile.write(IMPLEMENTATION_PREAMBLE % header_path)
@classmethod @classmethod
def WriteUmbrellaInitializer(cls, module_names, namespace, outfile): def WriteUmbrellaInitializer(cls, module_names, namespace, outfile,
logging_function):
"""Writes a single function that will open + initialize each module. """Writes a single function that will open + initialize each module.
This intializer will take in an stl map of that lists the correct This intializer will take in an stl map of that lists the correct
...@@ -719,7 +730,8 @@ class PosixStubWriter(object): ...@@ -719,7 +730,8 @@ class PosixStubWriter(object):
# Create the initialization function that calls all module initializers, # Create the initialization function that calls all module initializers,
# checks if they succeeded, and backs out module loads on an error. # checks if they succeeded, and backs out module loads on an error.
outfile.write(UMBRELLA_INITIALIZER_INITIALIZE_FUNCTION_START) outfile.write(UMBRELLA_INITIALIZER_INITIALIZE_FUNCTION_START % {
'logging_function': logging_function})
outfile.write( outfile.write(
'\n // Initialize each module if we have not already failed.\n') '\n // Initialize each module if we have not already failed.\n')
for module in module_names: for module in module_names:
...@@ -739,7 +751,8 @@ class PosixStubWriter(object): ...@@ -739,7 +751,8 @@ class PosixStubWriter(object):
outfile.write('\n} // namespace %s\n' % namespace) outfile.write('\n} // namespace %s\n' % namespace)
@classmethod @classmethod
def WriteHeaderContents(cls, module_names, namespace, header_guard, outfile): def WriteHeaderContents(cls, module_names, namespace, header_guard, outfile,
logging_include):
"""Writes a header file for the stub file generated for module_names. """Writes a header file for the stub file generated for module_names.
The header file exposes the following: The header file exposes the following:
...@@ -754,9 +767,11 @@ class PosixStubWriter(object): ...@@ -754,9 +767,11 @@ class PosixStubWriter(object):
namespace: The namespace these functions should be in. namespace: The namespace these functions should be in.
header_guard: The macro to use as our header guard. header_guard: The macro to use as our header guard.
outfile: The output handle to populate. outfile: The output handle to populate.
logging_include: Header file where the logging function is defined.
""" """
outfile.write(STUB_HEADER_PREAMBLE % outfile.write(STUB_HEADER_PREAMBLE %
{'guard_name': header_guard, 'namespace': namespace}) {'guard_name': header_guard, 'namespace': namespace,
'logging_include': logging_include})
# Generate the Initializer prototypes for each module. # Generate the Initializer prototypes for each module.
outfile.write('// Individual module initializer functions.\n') outfile.write('// Individual module initializer functions.\n')
...@@ -869,7 +884,8 @@ class PosixStubWriter(object): ...@@ -869,7 +884,8 @@ class PosixStubWriter(object):
outfile.write(STUB_POINTER_INITIALIZER % { outfile.write(STUB_POINTER_INITIALIZER % {
'name': sig['name'], 'name': sig['name'],
'return_type': sig['return_type'], 'return_type': sig['return_type'],
'parameters': ', '.join(sig['params'])}) 'parameters': ', '.join(sig['params']),
'logging_function': self.logging_function})
outfile.write(MODULE_INITIALIZE_END) outfile.write(MODULE_INITIALIZE_END)
# Create function that uninitializes the module (sets all pointers to # Create function that uninitializes the module (sets all pointers to
...@@ -946,6 +962,16 @@ def CreateOptionParser(): ...@@ -946,6 +962,16 @@ def CreateOptionParser():
help=('A macro to place between the return type and ' help=('A macro to place between the return type and '
'function name, e.g. MODULE_EXPORT, to control the ' 'function name, e.g. MODULE_EXPORT, to control the '
'visibility of the stub functions.')) 'visibility of the stub functions.'))
parser.add_option('-l',
'--logging-function',
dest='logging_function',
default='VLOG(1)',
help=('Function call that will be used for error logging.'))
parser.add_option('-n',
'--logging-include',
dest='logging_include',
default='base/logging.h',
help=('Header file where the logging function is defined.'))
return parser return parser
...@@ -1074,7 +1100,8 @@ def CreateWindowsDefForSigFiles(sig_files, out_dir, module_name): ...@@ -1074,7 +1100,8 @@ def CreateWindowsDefForSigFiles(sig_files, out_dir, module_name):
def CreatePosixStubsForSigFiles(sig_files, stub_name, out_dir, def CreatePosixStubsForSigFiles(sig_files, stub_name, out_dir,
intermediate_dir, path_from_source, intermediate_dir, path_from_source,
extra_stub_header, export_macro): extra_stub_header, export_macro,
logging_function, logging_include):
"""Create a POSIX stub library with a module for each signature file. """Create a POSIX stub library with a module for each signature file.
Args: Args:
...@@ -1088,6 +1115,8 @@ def CreatePosixStubsForSigFiles(sig_files, stub_name, out_dir, ...@@ -1088,6 +1115,8 @@ def CreatePosixStubsForSigFiles(sig_files, stub_name, out_dir,
into the generated header for the stub library. into the generated header for the stub library.
export_macro: A preprocessor macro used to annotate stub symbols with export_macro: A preprocessor macro used to annotate stub symbols with
an EXPORT marking, to control visibility. an EXPORT marking, to control visibility.
logging_function: Function call that will be used for error logging.
logging_include: Header file where the logging function is defined.
""" """
header_base_name = stub_name + '.h' header_base_name = stub_name + '.h'
header_path = os.path.join(out_dir, header_base_name) header_path = os.path.join(out_dir, header_base_name)
...@@ -1124,12 +1153,13 @@ def CreatePosixStubsForSigFiles(sig_files, stub_name, out_dir, ...@@ -1124,12 +1153,13 @@ def CreatePosixStubsForSigFiles(sig_files, stub_name, out_dir,
signatures = ParseSignatures(infile) signatures = ParseSignatures(infile)
finally: finally:
infile.close() infile.close()
writer = PosixStubWriter(name, export_macro, signatures) writer = PosixStubWriter(name, export_macro, signatures, logging_function,
logging_include)
writer.WriteImplementationContents(namespace, impl_file) writer.WriteImplementationContents(namespace, impl_file)
# Lastly, output the umbrella function for the file. # Lastly, output the umbrella function for the file.
PosixStubWriter.WriteUmbrellaInitializer(module_names, namespace, PosixStubWriter.WriteUmbrellaInitializer(module_names, namespace,
impl_file) impl_file, logging_function)
finally: finally:
impl_file.close() impl_file.close()
...@@ -1137,7 +1167,8 @@ def CreatePosixStubsForSigFiles(sig_files, stub_name, out_dir, ...@@ -1137,7 +1167,8 @@ def CreatePosixStubsForSigFiles(sig_files, stub_name, out_dir,
header_file = open(header_path, 'w') header_file = open(header_path, 'w')
try: try:
PosixStubWriter.WriteHeaderContents(module_names, namespace, PosixStubWriter.WriteHeaderContents(module_names, namespace,
header_guard, header_file) header_guard, header_file,
logging_include)
finally: finally:
header_file.close() header_file.close()
...@@ -1155,7 +1186,9 @@ def main(): ...@@ -1155,7 +1186,9 @@ def main():
elif options.type == FILE_TYPE_POSIX_STUB: elif options.type == FILE_TYPE_POSIX_STUB:
CreatePosixStubsForSigFiles(args, options.stubfile_name, out_dir, CreatePosixStubsForSigFiles(args, options.stubfile_name, out_dir,
intermediate_dir, options.path_from_source, intermediate_dir, options.path_from_source,
options.extra_stub_header, options.export_macro) options.extra_stub_header, options.export_macro,
options.logging_function,
options.logging_include)
elif options.type == FILE_TYPE_WIN_DEF: elif options.type == FILE_TYPE_WIN_DEF:
CreateWindowsDefForSigFiles(args, out_dir, options.module_name) CreateWindowsDefForSigFiles(args, out_dir, options.module_name)
......
...@@ -167,7 +167,8 @@ class PosixStubWriterUnittest(unittest.TestCase): ...@@ -167,7 +167,8 @@ class PosixStubWriterUnittest(unittest.TestCase):
self.module_name = 'my_module-1' self.module_name = 'my_module-1'
self.signatures = [sig[1] for sig in SIMPLE_SIGNATURES] self.signatures = [sig[1] for sig in SIMPLE_SIGNATURES]
self.out_dir = 'out_dir' self.out_dir = 'out_dir'
self.writer = gs.PosixStubWriter(self.module_name, '', self.signatures) self.writer = gs.PosixStubWriter(self.module_name, '', self.signatures,
'VLOG(1)', 'base/logging.h')
def testEnumName(self): def testEnumName(self):
self.assertEqual('kModuleMy_module1', self.assertEqual('kModuleMy_module1',
...@@ -259,7 +260,7 @@ int ferda(char **argv[]) { ...@@ -259,7 +260,7 @@ int ferda(char **argv[]) {
# Make the header. # Make the header.
outfile = StringIO.StringIO() outfile = StringIO.StringIO()
self.writer.WriteHeaderContents(module_names, 'my_namespace', 'GUARD_', self.writer.WriteHeaderContents(module_names, 'my_namespace', 'GUARD_',
outfile) outfile, 'base/logging.h')
contents = outfile.getvalue() contents = outfile.getvalue()
# Check for namespace and header guard. # Check for namespace and header guard.
...@@ -293,7 +294,8 @@ int ferda(char **argv[]) { ...@@ -293,7 +294,8 @@ int ferda(char **argv[]) {
# Make the header. # Make the header.
outfile = StringIO.StringIO() outfile = StringIO.StringIO()
self.writer.WriteUmbrellaInitializer(module_names, 'my_namespace', outfile) self.writer.WriteUmbrellaInitializer(module_names, 'my_namespace', outfile,
'VLOG(1)')
contents = outfile.getvalue() contents = outfile.getvalue()
# Check for umbrella initializer declaration. # Check for umbrella initializer declaration.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment