mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Add initial support for API versioning (see #3836)
- Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
This commit is contained in:
@ -16,7 +16,7 @@ import string
|
||||
import sys
|
||||
|
||||
|
||||
def MakeFileSegment(input, all_names):
|
||||
def _make_pack_header_segment(input, ids):
|
||||
result = """
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -26,8 +26,93 @@ def MakeFileSegment(input, all_names):
|
||||
filename = os.path.split(input)[1]
|
||||
result = result.replace('$FILE$', filename)
|
||||
|
||||
for name, id in ids.items():
|
||||
result += "\n#define %s %s" % (name, id)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def make_pack_header(output, all_files):
|
||||
# header string
|
||||
result = get_copyright(full=True, translator=False) + \
|
||||
"""//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file is generated by the make_pack_header.py tool.
|
||||
//
|
||||
|
||||
#ifndef $GUARD$
|
||||
#define $GUARD$
|
||||
#pragma once"""
|
||||
|
||||
# generate the file segments
|
||||
for file, ids in all_files.items():
|
||||
result += _make_pack_header_segment(file, ids)
|
||||
|
||||
# footer string
|
||||
result += \
|
||||
"""
|
||||
|
||||
#endif // $GUARD$
|
||||
"""
|
||||
|
||||
# add the guard string
|
||||
filename = os.path.split(output)[1]
|
||||
guard = 'CEF_INCLUDE_' + filename.replace('.', '_').upper() + '_'
|
||||
result = result.replace('$GUARD$', guard)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _get_cpp_var_name(output):
|
||||
filename_no_ext = os.path.splitext(os.path.split(output)[1])[0]
|
||||
|
||||
# Convert to CamelCase after removing the 'cef_' prefix.
|
||||
parts = filename_no_ext.split('_')[1:]
|
||||
return "".join([p[0].upper() + p[1:] for p in parts])
|
||||
|
||||
|
||||
def make_pack_inc(output, all_files):
|
||||
var = 'IdNames' + _get_cpp_var_name(output)
|
||||
|
||||
result = get_copyright(full=False, translator=False) + \
|
||||
"""//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the make_pack_header.py tool.
|
||||
//
|
||||
|
||||
namespace {
|
||||
|
||||
struct $var$ {
|
||||
int id;
|
||||
const char* const name;
|
||||
};
|
||||
|
||||
const $var$ k$var$[] = {""".replace('$var$', var)
|
||||
|
||||
for file, ids in all_files.items():
|
||||
result += '\n // From %s:' % file
|
||||
for name, id in ids.items():
|
||||
result += '\n {%s, "%s"},' % (id, name)
|
||||
|
||||
result += \
|
||||
"""
|
||||
};
|
||||
|
||||
const size_t k$var$Size = std::size(k$var$);
|
||||
|
||||
} // namespace
|
||||
""".replace('$var$', var)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _get_defines(input, all_names):
|
||||
contents = read_file(input)
|
||||
|
||||
ids = {}
|
||||
|
||||
# Format for Windows builds with resource whitelisting enabled [1]:
|
||||
# #define IDR_RESOURCE_NAME (::ui::WhitelistedResource<12345>(), 12345)
|
||||
# Format for other builds:
|
||||
@ -50,54 +135,48 @@ def MakeFileSegment(input, all_names):
|
||||
else:
|
||||
all_names[name] = 1
|
||||
|
||||
result += "\n#define %s %s" % (name, id)
|
||||
ids[name] = id
|
||||
|
||||
return result
|
||||
return ids
|
||||
|
||||
|
||||
def MakeFile(output, input):
|
||||
# header string
|
||||
result = get_copyright(full=True, translator=False) + \
|
||||
"""//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file is generated by the make_pack_header.py tool.
|
||||
//
|
||||
|
||||
#ifndef $GUARD$
|
||||
#define $GUARD$
|
||||
#pragma once"""
|
||||
|
||||
def write_pack_header(out_header_file, out_inc_file, inputs):
|
||||
# sort the input files by name
|
||||
input = sorted(input, key=lambda path: os.path.split(path)[1])
|
||||
inputs = sorted(inputs, key=lambda path: os.path.split(path)[1])
|
||||
|
||||
all_names = {}
|
||||
all_files = {}
|
||||
|
||||
# generate the file segments
|
||||
for file in input:
|
||||
result += MakeFileSegment(file, all_names)
|
||||
for file in inputs:
|
||||
filename = os.path.split(file)[1]
|
||||
assert not filename in all_files, filename
|
||||
all_files[filename] = _get_defines(file, all_names)
|
||||
|
||||
# footer string
|
||||
result += \
|
||||
"""
|
||||
out_file = os.path.abspath(out_header_file)
|
||||
result = make_pack_header(out_file, all_files)
|
||||
if not bool(result):
|
||||
sys.stderr.write('Failed to create %s\n' % out_file)
|
||||
sys.exit(1)
|
||||
retval1 = write_file_if_changed(out_file, result)
|
||||
|
||||
#endif // $GUARD$
|
||||
"""
|
||||
out_file = os.path.abspath(out_inc_file)
|
||||
result = make_pack_inc(out_file, all_files)
|
||||
if not bool(result):
|
||||
sys.stderr.write('Failed to create %s\n' % out_file)
|
||||
sys.exit(1)
|
||||
retval2 = write_file_if_changed(out_file, result)
|
||||
|
||||
# add the guard string
|
||||
filename = os.path.split(output)[1]
|
||||
guard = 'CEF_INCLUDE_' + filename.replace('.', '_').upper() + '_'
|
||||
result = result.replace('$GUARD$', guard)
|
||||
|
||||
write_file_if_changed(output, result)
|
||||
return retval1 #or retval2
|
||||
|
||||
|
||||
def main(argv):
|
||||
if len(argv) < 3:
|
||||
print(("Usage:\n %s <output_filename> <input_file1> [input_file2] ... " %
|
||||
argv[0]))
|
||||
if len(argv) < 4:
|
||||
print(
|
||||
"Usage:\n %s <output_header_file> <output_inc_file> <input_file1> [input_file2] ... "
|
||||
% argv[0])
|
||||
sys.exit(-1)
|
||||
MakeFile(argv[1], argv[2:])
|
||||
write_pack_header(argv[1], argv[2], argv[3:])
|
||||
|
||||
|
||||
if '__main__' == __name__:
|
||||
|
Reference in New Issue
Block a user