mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2024-12-13 10:06:28 +01:00
a76f40eb83
This splits out the API hashes from the cef_version.h file which is generated at build time. Changes to the cef_api_hash.h file are committed to the repo and represent potentially breaking API changes. This commit history will be used to calculate the version number.
216 lines
5.5 KiB
Python
216 lines
5.5 KiB
Python
# Copyright (c) 2018 The Chromium Embedded Framework Authors. All rights
|
|
# reserved. Use of this source code is governed by a BSD-style license that
|
|
# can be found in the LICENSE file.
|
|
|
|
from cef_parser import *
|
|
from file_util import *
|
|
import os
|
|
|
|
# Other headers that export C API functions.
|
|
OTHER_HEADERS = [
|
|
'cef_api_hash.h',
|
|
'cef_version.h',
|
|
'internal/cef_logging_internal.h',
|
|
'internal/cef_string_list.h',
|
|
'internal/cef_string_map.h',
|
|
'internal/cef_string_multimap.h',
|
|
'internal/cef_string_types.h',
|
|
'internal/cef_thread_internal.h',
|
|
'internal/cef_time.h',
|
|
'internal/cef_trace_event_internal.h',
|
|
]
|
|
|
|
|
|
def make_libcef_dll_dylib_impl_parts(name, retval, args):
|
|
# Split arguments into types and names.
|
|
arg_types = ''
|
|
arg_names = ''
|
|
for arg in args:
|
|
if len(arg_types) > 0:
|
|
arg_types += ', '
|
|
arg_names += ', '
|
|
pos = arg.rfind(' ')
|
|
arg_types += arg[0:pos]
|
|
arg_names += arg[pos + 1:]
|
|
|
|
typedef = 'typedef %s (*%s_ptr)(%s);\n' % (retval, name, arg_types)
|
|
|
|
declare = '%s_ptr %s;\n' % (name, name)
|
|
|
|
init = ' INIT_ENTRY(%s);' % name
|
|
|
|
impl = """NO_SANITIZE("cfi-icall") %s %s(%s) {
|
|
%sg_libcef_pointers.%s(%s);
|
|
}
|
|
|
|
""" % (retval, name, ', '.join(args), 'return '
|
|
if retval != 'void' else '', name, arg_names)
|
|
|
|
return (typedef, declare, init, impl)
|
|
|
|
|
|
def make_libcef_dll_dylib_impl_func(func):
|
|
name = func.get_capi_name()
|
|
parts = func.get_capi_parts([])
|
|
retval = parts['retval']
|
|
args = parts['args']
|
|
return make_libcef_dll_dylib_impl_parts(name, retval, args)
|
|
|
|
|
|
def make_libcef_dll_dylib_impl(header):
|
|
filenames = []
|
|
includes = []
|
|
ptr_typedef = ''
|
|
ptr_declare = ''
|
|
ptr_init = ''
|
|
ptr_impl = ''
|
|
|
|
# Include required headers for global functions.
|
|
for func in header.get_funcs():
|
|
typedef, declare, init, impl = make_libcef_dll_dylib_impl_func(func)
|
|
ptr_typedef += typedef
|
|
ptr_declare += declare
|
|
ptr_init += init
|
|
ptr_impl += impl
|
|
|
|
filename = func.get_file_name()
|
|
if not filename in filenames:
|
|
includes.append('#include "include/capi/%s"' % func.get_capi_file_name())
|
|
filenames.append(filename)
|
|
|
|
# Include required headers for static class functions.
|
|
allclasses = header.get_classes()
|
|
for cls in allclasses:
|
|
funcs = cls.get_static_funcs()
|
|
for func in funcs:
|
|
typedef, declare, init, impl = make_libcef_dll_dylib_impl_func(func)
|
|
ptr_typedef += typedef
|
|
ptr_declare += declare
|
|
ptr_init += init
|
|
ptr_impl += impl
|
|
|
|
if len(funcs) > 0:
|
|
filename = cls.get_file_name()
|
|
if not filename in filenames:
|
|
includes.append('#include "include/capi/%s"' % cls.get_capi_file_name())
|
|
filenames.append(filename)
|
|
|
|
# Parse other headers.
|
|
root_directory = header.get_root_directory()
|
|
for other in OTHER_HEADERS:
|
|
path = os.path.join(root_directory, other)
|
|
content = read_file(path)
|
|
funcs = get_function_impls(content, 'CEF_EXPORT', False)
|
|
for func in funcs:
|
|
typedef, declare, init, impl = make_libcef_dll_dylib_impl_parts(
|
|
func['name'], func['retval'], func['args'])
|
|
ptr_typedef += typedef
|
|
ptr_declare += declare
|
|
ptr_init += init
|
|
ptr_impl += impl
|
|
|
|
includes.append('#include "include/%s"' % other)
|
|
|
|
# Build the final output.
|
|
result = get_copyright() + """
|
|
|
|
#include <dlfcn.h>
|
|
#include <stdio.h>
|
|
|
|
""" + "\n".join(sorted(includes)) + """
|
|
#include "include/wrapper/cef_library_loader.h"
|
|
|
|
// GLOBAL WRAPPER FUNCTIONS - Do not edit by hand.
|
|
|
|
namespace {
|
|
|
|
void* g_libcef_handle = NULL;
|
|
|
|
void* libcef_get_ptr(const char* path, const char* name) {
|
|
void* ptr = dlsym(g_libcef_handle, name);
|
|
if (!ptr) {
|
|
fprintf(stderr, "dlsym %s: %s\\n", path, dlerror());
|
|
}
|
|
return ptr;
|
|
}
|
|
|
|
""" + ptr_typedef + """
|
|
|
|
struct libcef_pointers {
|
|
""" + ptr_declare + """
|
|
} g_libcef_pointers = {0};
|
|
|
|
#define INIT_ENTRY(name) \
|
|
g_libcef_pointers.name = (name##_ptr)libcef_get_ptr(path, #name); \
|
|
if (!g_libcef_pointers.name) { \
|
|
return 0; \
|
|
}
|
|
|
|
int libcef_init_pointers(const char* path) {
|
|
""" + ptr_init + """
|
|
return 1;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
int cef_load_library(const char* path) {
|
|
if (g_libcef_handle)
|
|
return 0;
|
|
|
|
g_libcef_handle = dlopen(path, RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST);
|
|
if (!g_libcef_handle) {
|
|
fprintf(stderr, "dlopen %s: %s\\n", path, dlerror());
|
|
return 0;
|
|
}
|
|
|
|
if (!libcef_init_pointers(path)) {
|
|
cef_unload_library();
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int cef_unload_library() {
|
|
int result = 0;
|
|
if (g_libcef_handle) {
|
|
result = !dlclose(g_libcef_handle);
|
|
if (!result) {
|
|
fprintf(stderr, "dlclose: %s\\n", dlerror());
|
|
}
|
|
g_libcef_handle = NULL;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
""" + ptr_impl
|
|
return result
|
|
|
|
|
|
def write_libcef_dll_dylib_impl(header, file):
|
|
newcontents = make_libcef_dll_dylib_impl(header)
|
|
return (file, newcontents)
|
|
|
|
|
|
# Test the module.
|
|
if __name__ == "__main__":
|
|
import sys
|
|
|
|
# Verify that the correct number of command-line arguments are provided.
|
|
if len(sys.argv) < 2:
|
|
sys.stderr.write('Usage: ' + sys.argv[0] + ' <cpp_header_dir>')
|
|
sys.exit()
|
|
|
|
cpp_header_dir = sys.argv[1]
|
|
|
|
# Create the header object. Should match the logic in translator.py.
|
|
header = obj_header()
|
|
header.set_root_directory(cpp_header_dir)
|
|
excluded_files = ['cef_api_hash.h', 'cef_application_mac.h', 'cef_version.h']
|
|
header.add_directory(cpp_header_dir, excluded_files)
|
|
header.add_directory(os.path.join(cpp_header_dir, 'test'))
|
|
header.add_directory(os.path.join(cpp_header_dir, 'views'))
|
|
|
|
# Dump the result to stdout.
|
|
sys.stdout.write(make_libcef_dll_dylib_impl(header))
|