diff options
Diffstat (limited to 'cmake/bazel_to_cmake.py')
-rwxr-xr-x | cmake/bazel_to_cmake.py | 297 |
1 files changed, 151 insertions, 146 deletions
diff --git a/cmake/bazel_to_cmake.py b/cmake/bazel_to_cmake.py index ba1a38b..8f972ba 100755 --- a/cmake/bazel_to_cmake.py +++ b/cmake/bazel_to_cmake.py @@ -49,88 +49,92 @@ replacements = [ ['selects.config_setting_group', 'config_setting_group'], ['@com_google_googletest//:gtest', 'gtest'], ['@com_google_googletest//:gtest_main', 'gtest_main'], - ['@cpuinfo//:cpuinfo_with_unstripped_include_path', 'cpuinfo'], + ['@cpuinfo', 'cpuinfo'], ] def preprocess_input_text(text): - result = text - for replacement in replacements: - result = result.replace(replacement[0], replacement[1]) - return result + result = text + for replacement in replacements: + result = result.replace(replacement[0], replacement[1]) + return result def set_cmake_list(list_name, values, indent): - semicolon_separated = ";".join(values) - print(f'{indent}set({list_name} "{semicolon_separated}")') + semicolon_separated = ';'.join(values) + print(f'{indent}set({list_name} "{semicolon_separated}")') def generate_cmake_select(select_name, dict): - new_if_branch_keyword = 'if' - default_value = [] - for key in dict: - condition = '' - if key == '//conditions:default': - default_value = dict[key] - continue - elif re.search(r':windows$', key): - condition = 'CMAKE_SYSTEM_NAME STREQUAL Windows' - elif re.search(r':ppc$', key): - condition = 'CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64le' - elif re.search(r':s390x$', key): - condition = 'CMAKE_SYSTEM_PROCESSOR STREQUAL s390 OR CMAKE_SYSTEM_PROCESSOR STREQUAL s390x' - elif re.search(r':fuchsia$', key): - condition = 'CMAKE_SYSTEM_NAME STREQUAL Fuchsia' - elif re.search(r':arm32_assuming_neon$', key): - condition = 'CMAKE_SYSTEM_PROCESSOR STREQUAL arm' - elif re.search(r':do_not_want_O3$', key): - # Ruy is a specialist library: we always want code to be compiled - # with -O3 unless the build type is Debug or the compiler does not - # support that flag syntax. - condition = '(CMAKE_BUILD_TYPE STREQUAL Debug) OR MSVC' - elif re.search(r':x86_64_and_not_msvc$', key): - condition = '(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64) AND NOT MSVC' - elif re.search(r':windows_msvc$', key): - condition = 'MSVC' - elif re.search(r':ruy_profiler$', key): - condition = '${RUY_PROFILER}' - else: - raise ValueError(f'Unhandled key in select: {key}') + new_if_branch_keyword = 'if' + default_value = [] + for key in dict: + condition = '' + if key == '//conditions:default': + default_value = dict[key] + continue + elif re.search(r':windows$', key): + condition = 'CMAKE_SYSTEM_NAME STREQUAL Windows' + elif re.search(r':ppc$', key): + condition = ('CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64 OR ' + 'CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64le') + elif re.search(r':s390x$', key): + condition = ('CMAKE_SYSTEM_PROCESSOR STREQUAL s390 OR ' + 'CMAKE_SYSTEM_PROCESSOR STREQUAL s390x') + elif re.search(r':fuchsia$', key): + condition = 'CMAKE_SYSTEM_NAME STREQUAL Fuchsia' + elif re.search(r':arm32_assuming_neon$', key): + condition = 'CMAKE_SYSTEM_PROCESSOR STREQUAL arm' + elif re.search(r':do_not_want_O3$', key): + # Ruy is a specialist library: we always want code to be compiled + # with -O3 unless the build type is Debug or the compiler does not + # support that flag syntax. + condition = '(CMAKE_BUILD_TYPE STREQUAL Debug) OR MSVC' + elif re.search(r':x86_64_and_not_msvc$', key): + condition = ('(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR ' + 'CMAKE_SYSTEM_PROCESSOR STREQUAL amd64) AND NOT MSVC') + elif re.search(r':windows_msvc$', key): + condition = 'MSVC' + elif re.search(r':ruy_profiler$', key): + condition = '${RUY_PROFILER}' + else: + raise ValueError(f'Unhandled key in select: {key}') - print(f'{new_if_branch_keyword}({condition})') - set_cmake_list(select_name, dict[key], ' ') - new_if_branch_keyword = 'elseif' + print(f'{new_if_branch_keyword}({condition})') + set_cmake_list(select_name, dict[key], ' ') + new_if_branch_keyword = 'elseif' - print('else()') - set_cmake_list(select_name, default_value, ' ') + print('else()') + set_cmake_list(select_name, default_value, ' ') - print('endif()\n') + print('endif()\n') def trim_multiple_ruy_prefixes(name): - return re.sub(r'(ruy_)+ruy', 'ruy', name) + return re.sub(r'(ruy_)+ruy', 'ruy', name) + def get_cmake_local_target_name(name): - global package_prefix - return trim_multiple_ruy_prefixes(f'ruy_{package_prefix}_{name}') + global package_prefix + return trim_multiple_ruy_prefixes(f'ruy_{package_prefix}_{name}') def get_cmake_dep_target_name(name): - if name in external_targets: - return name - if name.startswith('$'): - # Happens for deps that are the result of expanding a select() that we - # have compiled to expanding a variable. - return name - if name.startswith('//'): - after_last_slash = name.split('/')[-1] - if not ':' in after_last_slash: - name = f'{name}:{after_last_slash}' - raw=name[2:].replace('/', '_').replace(':', '_') - return trim_multiple_ruy_prefixes(raw) - if name.startswith(':'): - name = name[1:] - return get_cmake_local_target_name(name) + if name in external_targets: + return name + if name.startswith('$'): + # Happens for deps that are the result of expanding a select() that we + # have compiled to expanding a variable. + return name + if name.startswith('//'): + after_last_slash = name.split('/')[-1] + if ':' not in after_last_slash: + name = f'{name}:{after_last_slash}' + raw = name[2:].replace('/', '_').replace(':', '_') + return trim_multiple_ruy_prefixes(raw) + if name.startswith(':'): + name = name[1:] + return get_cmake_local_target_name(name) # @@ -139,45 +143,45 @@ def get_cmake_dep_target_name(name): def package(**kwargs): - pass + pass def exports_files(*args): - pass + pass def load(filename, *args): - if filename.startswith('@'): - return - elif filename.startswith(':'): - filename = os.path.join(bazel_package_dir, filename[1:]) - elif filename.startswith('//'): - split = filename[2:].split(':') - filename = os.path.join(bazel_workspace_dir, split[0], split[1]) + if filename.startswith('@'): + return + elif filename.startswith(':'): + filename = os.path.join(bazel_package_dir, filename[1:]) + elif filename.startswith('//'): + split = filename[2:].split(':') + filename = os.path.join(bazel_workspace_dir, split[0], split[1]) - src_file_content = open(filename).read() - processed_file_content = preprocess_input_text(src_file_content) - exec(processed_file_content, globals(), globals()) + src_file_content = open(filename).read() + processed_file_content = preprocess_input_text(src_file_content) + exec(processed_file_content, globals(), globals()) def config_setting(**kwargs): - # Nothing to do since our implementation of select() is based on parsing - # the names of config_settings, not looking deep into their actual - # implementation. - pass + # Nothing to do since our implementation of select() is based on parsing + # the names of config_settings, not looking deep into their actual + # implementation. + pass def filegroup(**kwargs): - pass + pass def config_setting_group(**kwargs): - # See config_setting. - pass + # See config_setting. + pass def bzl_library(**kwargs): - pass + pass select_index = 0 @@ -185,95 +189,96 @@ select_cache = {} def select(select_dict): - global select_index - global select_cache - global package_prefix - key = pickle.dumps(sorted(select_dict.items())) - if key in select_cache: - select_name = select_cache[key] - else: - unique_values = sorted(set(itertools.chain.from_iterable(select_dict.values()))) # sorting ensures determinism, no spurious diffs - description = '_'.join(unique_values) - select_name = f'{package_prefix}_{select_index}_{description}' - select_name = select_name.replace('c++', 'cxx') - select_name = re.sub(r'[^a-zA-Z0-9]+', '_', select_name) - select_index = select_index + 1 - select_cache[key] = select_name - generate_cmake_select(select_name, select_dict) - - return [f'${{{select_name}}}'] + global select_index + global select_cache + global package_prefix + key = pickle.dumps(sorted(select_dict.items())) + if key in select_cache: + select_name = select_cache[key] + else: + unique_values = sorted( + set(itertools.chain.from_iterable(select_dict.values())) + ) # sorting ensures determinism, no spurious diffs + description = '_'.join(unique_values) + select_name = f'{package_prefix}_{select_index}_{description}' + select_name = select_name.replace('c++', 'cxx') + select_name = re.sub(r'[^a-zA-Z0-9]+', '_', select_name) + select_index = select_index + 1 + select_cache[key] = select_name + generate_cmake_select(select_name, select_dict) + + return [f'${{{select_name}}}'] def generic_rule(rule_name, **kwargs): - print(f'{rule_name}(') - for key in kwargs.keys(): - values = kwargs[key] - if type(values) is bool: - if values: - print(f' {key.upper()}') - continue - else: - raise ValueError( - 'Cannot specify FALSE boolean args in CMake') - if key == 'visibility': - if values == ['//visibility:public']: - print(f' PUBLIC') - continue - if key == 'tags': - values = list(filter(lambda x : not x.startswith('req_dep'), values)) - if not values: - continue + print(f'{rule_name}(') + for key in kwargs.keys(): + values = kwargs[key] + if type(values) is bool: + if values: print(f' {key.upper()}') - if type(values) is list: - for value in values: - if key == 'deps': - target_name = get_cmake_dep_target_name(value) - print(f' {target_name}') - else: - print(f' {value}') + continue + else: + raise ValueError('Cannot specify FALSE boolean args in CMake') + if key == 'visibility': + if values == ['//visibility:public']: + print(f' PUBLIC') + continue + if key == 'tags': + values = list(filter(lambda x: not x.startswith('req_dep'), values)) + if not values: + continue + print(f' {key.upper()}') + if type(values) is list: + for value in values: + if key == 'deps': + target_name = get_cmake_dep_target_name(value) + print(f' {target_name}') else: - if key == 'name': - target_name = get_cmake_local_target_name(values) - print(f' {target_name}') - else: - print(f' {values}') - print(')\n') + print(f' {value}') + else: + if key == 'name': + target_name = get_cmake_local_target_name(values) + print(f' {target_name}') + else: + print(f' {values}') + print(')\n') def cc_library(**kwargs): - generic_rule('ruy_cc_library', **kwargs) + generic_rule('ruy_cc_library', **kwargs) def cc_test(**kwargs): - generic_rule('ruy_cc_test', **kwargs) + generic_rule('ruy_cc_test', **kwargs) def cc_binary(**kwargs): - generic_rule('ruy_cc_binary', **kwargs) + generic_rule('ruy_cc_binary', **kwargs) # # Program entry point. # if __name__ == "__main__": - if len(sys.argv) != 3: - print("Usage: bazel_to_cmake.py bazel_workspace_dir bazel_package_dir") - sys.exit(1) + if len(sys.argv) != 3: + print('Usage: bazel_to_cmake.py bazel_workspace_dir bazel_package_dir') + sys.exit(1) - bazel_workspace_dir = sys.argv[1] - bazel_package_dir = sys.argv[2] - bazel_package_relative_dir = os.path.relpath( - bazel_package_dir, bazel_workspace_dir) - package_prefix = bazel_package_relative_dir.replace(os.path.sep, '_') + bazel_workspace_dir = sys.argv[1] + bazel_package_dir = sys.argv[2] + bazel_package_relative_dir = os.path.relpath(bazel_package_dir, + bazel_workspace_dir) + package_prefix = bazel_package_relative_dir.replace(os.path.sep, '_') - print("""# This file is generated (whence no license header). Do not edit! + print("""# This file is generated (whence no license header). Do not edit! # To regenerate, run: # cmake/bazel_to_cmake.sh """) - src_build_file = os.path.join(bazel_package_dir, "BUILD") - src_build_content = open(src_build_file).read() - processed_build_content = preprocess_input_text(src_build_content) - exec(processed_build_content) + src_build_file = os.path.join(bazel_package_dir, 'BUILD') + src_build_content = open(src_build_file).read() + processed_build_content = preprocess_input_text(src_build_content) + exec(processed_build_content) - print("ruy_add_all_subdirs()") + print('ruy_add_all_subdirs()') |