| # pylint: disable=g-bad-file-header |
| # Copyright 2018 The Bazel Authors. All rights reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| """Library of common crosstool features.""" |
| |
| load( |
| "@bazel_tools//tools/cpp:crosstool_utils.bzl", |
| "ARCHIVE_ACTIONS", |
| "COMPILE_ACTIONS", |
| "LINK_ACTIONS", |
| "feature", |
| "flag_group", |
| "flag_set", |
| "flags", |
| "simple_feature", |
| ) |
| |
| def get_features_to_appear_first(platform): |
| """Returns standard features that should appear in the top of the toolchain. |
| |
| Args: |
| platform: one of [ k8, darwin, msvc ] |
| |
| Returns: |
| a collection of features to be put into crosstool |
| """ |
| return [ |
| simple_feature("no_legacy_features", [], []), |
| simple_feature( |
| "legacy_compile_flags", |
| COMPILE_ACTIONS, |
| ["%{legacy_compile_flags}"], |
| expand_if_all_available = ["legacy_compile_flags"], |
| iterate_over = "legacy_compile_flags", |
| ), |
| simple_feature( |
| "dependency_file", |
| COMPILE_ACTIONS, |
| ["-MD", "-MF", "%{dependency_file}"], |
| expand_if_all_available = ["dependency_file"], |
| ), |
| simple_feature( |
| "random_seed", |
| COMPILE_ACTIONS, |
| ["-frandom-seed=%{output_file}"], |
| ), |
| simple_feature( |
| "pic", |
| COMPILE_ACTIONS, |
| ["-fPIC"], |
| expand_if_all_available = ["pic"], |
| ), |
| simple_feature( |
| "per_object_debug_info", |
| COMPILE_ACTIONS, |
| ["-gsplit-dwarf"], |
| expand_if_all_available = ["per_object_debug_info_file"], |
| ), |
| simple_feature( |
| "preprocessor_defines", |
| COMPILE_ACTIONS, |
| ["-D%{preprocessor_defines}"], |
| iterate_over = "preprocessor_defines", |
| expand_if_all_available = ["preprocessor_defines"], |
| ), |
| simple_feature( |
| "includes", |
| COMPILE_ACTIONS, |
| ["-include", "%{includes}"], |
| iterate_over = "includes", |
| expand_if_all_available = ["includes"], |
| ), |
| simple_feature( |
| "quote_include_paths", |
| COMPILE_ACTIONS, |
| ["-iquote", "%{quote_include_paths}"], |
| iterate_over = "quote_include_paths", |
| expand_if_all_available = ["quote_include_paths"], |
| ), |
| simple_feature( |
| "include_paths", |
| COMPILE_ACTIONS, |
| ["-I%{include_paths}"], |
| iterate_over = "include_paths", |
| expand_if_all_available = ["include_paths"], |
| ), |
| simple_feature( |
| "system_include_paths", |
| COMPILE_ACTIONS, |
| ["-isystem", "%{system_include_paths}"], |
| iterate_over = "system_include_paths", |
| expand_if_all_available = ["system_include_paths"], |
| ), |
| simple_feature( |
| "symbol_counts", |
| LINK_ACTIONS, |
| ["-Wl,--print-symbol-counts=%{symbol_counts_output}"], |
| expand_if_all_available = ["symbol_counts_output"], |
| ), |
| simple_feature( |
| "shared_flag", |
| LINK_ACTIONS, |
| ["-shared"], |
| expand_if_all_available = ["symbol_counts_output"], |
| ), |
| simple_feature( |
| "output_execpath_flags", |
| LINK_ACTIONS, |
| ["-o", "%{output_execpath}"], |
| expand_if_all_available = ["output_execpath"], |
| ), |
| simple_feature( |
| "runtime_library_search_directories", |
| LINK_ACTIONS, |
| [_runtime_library_directory_flag(platform)], |
| iterate_over = "runtime_library_search_directories", |
| expand_if_all_available = ["runtime_library_search_directories"], |
| ), |
| simple_feature( |
| "library_search_directories", |
| LINK_ACTIONS, |
| ["-L%{library_search_directories}"], |
| iterate_over = "library_search_directories", |
| expand_if_all_available = ["library_search_directories"], |
| ), |
| simple_feature("_archiver_flags", ARCHIVE_ACTIONS, _archiver_flags(platform)), |
| feature( |
| "libraries_to_link", |
| [ |
| flag_set(ARCHIVE_ACTIONS, [ |
| flag_group( |
| [ |
| flag_group( |
| flags("%{libraries_to_link.name}"), |
| expand_if_equal = [["libraries_to_link.type", "object_file"]], |
| ), |
| flag_group( |
| flags("%{libraries_to_link.object_files}"), |
| expand_if_equal = [["libraries_to_link.type", "object_file_group"]], |
| iterate_over = "libraries_to_link.object_files", |
| ), |
| ], |
| iterate_over = "libraries_to_link", |
| expand_if_all_available = ["libraries_to_link"], |
| ), |
| ]), |
| flag_set(LINK_ACTIONS, [ |
| flag_group( |
| [ |
| flag_group( |
| flags("-Wl,--start-lib"), |
| expand_if_equal = [["libraries_to_link.type", "object_file_group"]], |
| ), |
| ] + |
| _libraries_to_link_flag_groupss(platform) + [ |
| flag_group( |
| flags("-Wl,--end-lib"), |
| expand_if_equal = [["libraries_to_link.type", "object_file_group"]], |
| ), |
| ], |
| iterate_over = "libraries_to_link", |
| ), |
| flag_group(flags("-Wl,@%{thinlto_param_file}"), expand_if_true = ["thinlto_param_file"]), |
| ]), |
| ], |
| ), |
| simple_feature( |
| "force_pic_flags", |
| ["c++-link-executable"], |
| [_force_pic_flag(platform)], |
| expand_if_all_available = ["force_pic"], |
| ), |
| simple_feature( |
| "user_link_flags", |
| LINK_ACTIONS, |
| ["%{user_link_flags}"], |
| iterate_over = "user_link_flags", |
| expand_if_all_available = ["user_link_flags"], |
| ), |
| simple_feature( |
| "legacy_link_flags", |
| LINK_ACTIONS, |
| ["%{legacy_link_flags}"], |
| iterate_over = "legacy_link_flags", |
| expand_if_all_available = ["legacy_link_flags"], |
| ), |
| simple_feature( |
| "fission_support", |
| LINK_ACTIONS, |
| ["-Wl,--gdb-index"], |
| expand_if_all_available = ["is_using_fission"], |
| ), |
| simple_feature( |
| "strip_debug_symbols", |
| LINK_ACTIONS, |
| ["-Wl,-S"], |
| expand_if_all_available = ["strip_debug_symbols"], |
| ), |
| _coverage_feature(platform), |
| simple_feature("strip_flags", ["strip"], _strip_flags(platform)), |
| ] |
| |
| def get_features_to_appear_last(platform): |
| """Returns standard features that should appear at the end of the toolchain. |
| |
| Args: |
| platform: one of [ k8, darwin, msvc ] |
| |
| Returns: |
| a collection of features to be put into crosstool |
| """ |
| return [ |
| simple_feature( |
| "user_compile_flags", |
| COMPILE_ACTIONS, |
| ["%{user_compile_flags}"], |
| expand_if_all_available = ["user_compile_flags"], |
| iterate_over = "user_compile_flags", |
| ), |
| simple_feature( |
| "sysroot", |
| COMPILE_ACTIONS + LINK_ACTIONS, |
| ["--sysroot=%{sysroot}"], |
| expand_if_all_available = ["sysroot"], |
| ), |
| simple_feature( |
| "unfiltered_compile_flags", |
| COMPILE_ACTIONS, |
| ["%{unfiltered_compile_flags}"], |
| expand_if_all_available = ["unfiltered_compile_flags"], |
| iterate_over = "unfiltered_compile_flags", |
| ), |
| simple_feature( |
| "linker_param_file", |
| LINK_ACTIONS, |
| [_linker_param_file_flag(platform)], |
| expand_if_all_available = ["linker_param_file"], |
| ), |
| simple_feature( |
| "archiver_param_file", |
| ARCHIVE_ACTIONS, |
| [_archiver_param_file_flag(platform)], |
| expand_if_all_available = ["linker_param_file"], |
| ), |
| simple_feature( |
| "compiler_input_flags", |
| COMPILE_ACTIONS, |
| ["-c", "%{source_file}"], |
| expand_if_all_available = ["source_file"], |
| ), |
| feature( |
| "compiler_output_flags", |
| [ |
| flag_set(COMPILE_ACTIONS, [ |
| flag_group( |
| flags("-S"), |
| expand_if_all_available = ["output_assembly_file"], |
| ), |
| flag_group( |
| flags("-E"), |
| expand_if_all_available = ["output_preprocess_file"], |
| ), |
| flag_group( |
| flags("-o", "%{output_file}"), |
| expand_if_all_available = ["output_file"], |
| ), |
| ]), |
| ], |
| ), |
| ] |
| |
| def _is_linux(platform): |
| return platform == "k8" |
| |
| def _is_darwin(platform): |
| return platform == "darwin" |
| |
| def _is_msvc(platform): |
| return platform == "msvc" |
| |
| def _coverage_feature(use_llvm_format): |
| if use_llvm_format: |
| compile_flags = flags("-fprofile-instr-generate", "-fcoverage-mapping") |
| link_flags = flags("-fprofile-instr-generate") |
| else: |
| compile_flags = flags("-fprofile-arcs", "-ftest-coverage") |
| link_flags = flags("--coverage") |
| return feature( |
| "coverage", |
| [ |
| flag_set(COMPILE_ACTIONS, [flag_group(compile_flags)]), |
| flag_set(LINK_ACTIONS, [flag_group(link_flags)]), |
| ], |
| enabled = False, |
| provides = "profile", |
| ) |
| |
| def _runtime_library_directory_flag(platform): |
| if _is_linux(platform): |
| return "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}" |
| elif _is_darwin(platform): |
| return "-Wl,-rpath,@loader_path/%{runtime_library_search_directories}" |
| elif _is_msvc(platform): |
| fail("todo") |
| else: |
| fail("Unsupported platform: " + platform) |
| |
| def _force_pic_flag(platform): |
| if _is_linux(platform): |
| return "-pie" |
| elif _is_darwin(platform): |
| return "-Wl,-pie" |
| elif _is_msvc(platform): |
| fail("todo") |
| else: |
| fail("Unsupported platform: " + platform) |
| |
| def _archiver_flags(platform): |
| if _is_linux(platform): |
| return ["rcsD", "%{output_execpath}"] |
| elif _is_darwin(platform): |
| return ["-static", "-s", "-o", "%{output_execpath}"] |
| elif _is_msvc(platform): |
| fail("todo") |
| else: |
| fail("Unsupported platform: " + platform) |
| |
| def _library_to_link_with_worce_load(variable_type, variable, flag = "", iterate = False): |
| return [ |
| flag_group( |
| [ |
| flag_group( |
| flags( |
| "-Wl,-force_load," + flag + "%{" + variable + "}", |
| expand_if_true = ["libraries_to_link.is_whole_archive"], |
| ), |
| ), |
| flag_group( |
| flags( |
| flag + "%{" + variable + "}", |
| expand_if_false = ["libraries_to_link.is_whole_archive"], |
| ), |
| ), |
| ], |
| iterate_over = variable if iterate else None, |
| expand_if_equal = [["libraries_to_link.type", variable_type]], |
| ), |
| ] |
| |
| def _libraries_to_link_flag_groupss(platform): |
| if _is_linux(platform): |
| return [ |
| flag_group( |
| flags("-Wl,-whole-archive"), |
| expand_if_true = ["libraries_to_link.is_whole_archive"], |
| ), |
| flag_group( |
| flags("-Wl,--start-lib"), |
| expand_if_equal = [["libraries_to_link.type", "object_file_group"]], |
| ), |
| flag_group( |
| flags("%{libraries_to_link.object_files}"), |
| iterate_over = "libraries_to_link.object_files", |
| expand_if_equal = [["libraries_to_link.type", "object_file_group"]], |
| ), |
| flag_group( |
| flags("-Wl,--end-lib"), |
| expand_if_equal = [["libraries_to_link.type", "object_file_group"]], |
| ), |
| flag_group( |
| flags("%{libraries_to_link.name}"), |
| expand_if_equal = [["libraries_to_link.type", "object_file"]], |
| ), |
| flag_group( |
| flags("%{libraries_to_link.name}"), |
| expand_if_equal = [["libraries_to_link.type", "interface_library"]], |
| ), |
| flag_group( |
| flags("%{libraries_to_link.name}"), |
| expand_if_equal = [["libraries_to_link.type", "static_library"]], |
| ), |
| flag_group( |
| flags("-l%{libraries_to_link.name}"), |
| expand_if_equal = [["libraries_to_link.type", "dynamic_library"]], |
| ), |
| flag_group( |
| flags("-l:%{libraries_to_link.name}"), |
| expand_if_equal = [["libraries_to_link.type", "versioned_dynamic_library"]], |
| ), |
| flag_group( |
| flags("-Wl,-no-whole-archive"), |
| expand_if_true = ["libraries_to_link.is_whole_archive"], |
| ), |
| ] |
| if _is_darwin(platform): |
| return [ |
| flag_group( |
| flags("-Wl,--start-lib"), |
| expand_if_equal = [["libraries_to_link.type", "object_file_group"]], |
| ), |
| _library_to_link_with_worce_load( |
| "object_file_group", |
| "libraries_to_link.object_files", |
| iterate = True, |
| ), |
| flag_group( |
| flags("-Wl,--end-lib"), |
| expand_if_equal = [["libraries_to_link.type", "object_file_group"]], |
| ), |
| _library_to_link_with_worce_load("object_file", "libraries_to_link.name"), |
| _library_to_link_with_worce_load("interface_library", "libraries_to_link.name"), |
| _library_to_link_with_worce_load("static_library", "libraries_to_link.name"), |
| _library_to_link_with_worce_load("dynamic_library", "libraries_to_link.name", flag = "-l"), |
| _library_to_link_with_worce_load("versioned_dynamic_library", "libraries_to_link.name", flag = "-l:"), |
| ] |
| elif _is_msvc(platform): |
| fail("todo") |
| else: |
| fail("Unsupported platform: " + platform) |
| |
| def _strip_flags(platform): |
| if _is_linux(platform): |
| return [ |
| "-S", |
| "-p", |
| "-o", |
| "%{output_file}", |
| "-R", |
| ".gnu.switches.text.quote_paths", |
| "-R", |
| ".gnu.switches.text.bracket_paths", |
| "-R", |
| ".gnu.switches.text.system_paths", |
| "-R", |
| ".gnu.switches.text.cpp_defines", |
| "-R", |
| ".gnu.switches.text.cpp_includes", |
| "-R", |
| ".gnu.switches.text.cl_args", |
| "-R", |
| ".gnu.switches.text.lipo_info", |
| "-R", |
| ".gnu.switches.text.annotation", |
| ] |
| elif _is_darwin(platform): |
| return ["-S", "-o", "%{output_file}"] |
| elif _is_msvc(platform): |
| fail("todo") |
| else: |
| fail("Unsupported platform: " + platform) |
| |
| def _linker_param_file_flag(platform): |
| if _is_linux(platform): |
| return "-Wl,@%{linker_param_file}" |
| elif _is_darwin(platform): |
| return "-Wl,@%{linker_param_file}" |
| elif _is_msvc(platform): |
| fail("todo") |
| else: |
| fail("Unsupported platform: " + platform) |
| |
| def _archiver_param_file_flag(platform): |
| if _is_linux(platform): |
| return "@%{linker_param_file}" |
| elif _is_darwin(platform): |
| return "@%{linker_param_file}" |
| elif _is_msvc(platform): |
| fail("todo") |
| else: |
| fail("Unsupported platform: " + platform) |