| // Copyright 2014 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. |
| package com.google.devtools.build.lib.rules.cpp; |
| |
| import com.google.common.base.Joiner; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain; |
| import com.google.protobuf.TextFormat; |
| import com.google.protobuf.TextFormat.ParseException; |
| |
| /** |
| * A helper class for creating action_configs for the c++ actions. |
| * |
| * <p>TODO(b/30109612): Replace this with action_configs in the crosstool instead of putting it in |
| * legacy features. |
| */ |
| public class CppActionConfigs { |
| |
| /** A platform for C++ tool invocations. */ |
| public enum CppPlatform { |
| LINUX, |
| MAC |
| } |
| |
| /** A string constant for the macOS target libc value. */ |
| public static final String MACOS_TARGET_LIBC = "macosx"; |
| |
| // Note: these features won't be added to the crosstools that defines no_legacy_features feature |
| // (e.g. ndk, apple, enclave crosstools). Those need to be modified separately. |
| public static ImmutableList<CToolchain.Feature> getLegacyFeatures( |
| CppPlatform platform, |
| ImmutableSet<String> existingFeatureNames, |
| String cppLinkDynamicLibraryToolPath, |
| boolean supportsEmbeddedRuntimes, |
| boolean supportsInterfaceSharedLibraries, |
| boolean doNotSplitLinkingCmdline) { |
| |
| ImmutableList.Builder<CToolchain.Feature> featureBuilder = ImmutableList.builder(); |
| try { |
| if (!existingFeatureNames.contains(CppRuleClasses.STATIC_LINK_CPP_RUNTIMES) |
| && supportsEmbeddedRuntimes) { |
| featureBuilder.add(getFeature("name: 'static_link_cpp_runtimes' enabled: true")); |
| } |
| if (!existingFeatureNames.contains(CppRuleClasses.SUPPORTS_INTERFACE_SHARED_LIBRARIES) |
| && supportsInterfaceSharedLibraries) { |
| featureBuilder.add(getFeature("name: 'supports_interface_shared_libraries' enabled: true")); |
| } |
| if (!existingFeatureNames.contains(CppRuleClasses.LEGACY_COMPILE_FLAGS)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'legacy_compile_flags'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'assemble'", |
| " action: 'preprocess-assemble'", |
| " action: 'linkstamp-compile'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-header-parsing'", |
| " action: 'c++-module-compile'", |
| " action: 'c++-module-codegen'", |
| " action: 'lto-backend'", |
| " action: 'clif-match'", |
| " flag_group {", |
| " expand_if_all_available: 'legacy_compile_flags'", |
| " iterate_over: 'legacy_compile_flags'", |
| " flag: '%{legacy_compile_flags}'", |
| " }", |
| " }"))); |
| } |
| // Gcc options: |
| // -MD turns on .d file output as a side-effect (doesn't imply -E) |
| // -MM[D] enables user includes only, not system includes |
| // -MF <name> specifies the dotd file name |
| // Issues: |
| // -M[M] alone subverts actual .o output (implies -E) |
| // -M[M]D alone breaks some of the .d naming assumptions |
| // This combination gets user and system includes with specified name: |
| // -MD -MF <name> |
| if (!existingFeatureNames.contains(CppRuleClasses.DEPENDENCY_FILE)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'dependency_file'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'assemble'", |
| " action: 'preprocess-assemble'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-module-compile'", |
| " action: 'objc-compile'", |
| " action: 'objc++-compile'", |
| " action: 'c++-header-parsing'", |
| " action: 'clif-match'", |
| " flag_group {", |
| " expand_if_all_available: 'dependency_file'", |
| " flag: '-MD'", |
| " flag: '-MF'", |
| " flag: '%{dependency_file}'", |
| " }", |
| " }"))); |
| } |
| // GCC and Clang give randomized names to symbols which are defined in |
| // an anonymous namespace but have external linkage. To make |
| // computation of these deterministic, we want to override the |
| // default seed for the random number generator. It's safe to use |
| // any value which differs for all translation units; we use the |
| // path to the object file. |
| if (!existingFeatureNames.contains(CppRuleClasses.RANDOM_SEED)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'random_seed'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-module-codegen'", |
| " action: 'c++-module-compile'", |
| " flag_group {", |
| " expand_if_all_available: 'output_file'", |
| " flag: '-frandom-seed=%{output_file}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains(CppRuleClasses.PIC)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'pic'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'assemble'", |
| " action: 'preprocess-assemble'", |
| " action: 'linkstamp-compile'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-module-codegen'", |
| " action: 'c++-module-compile'", |
| " flag_group {", |
| " expand_if_all_available: 'pic'", |
| " flag: '-fPIC'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains(CppRuleClasses.PER_OBJECT_DEBUG_INFO)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'per_object_debug_info'", |
| " flag_set {", |
| " action: 'assemble'", |
| " action: 'preprocess-assemble'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-module-codegen'", |
| " flag_group {", |
| " expand_if_all_available: 'per_object_debug_info_file'", |
| " flag: '-gsplit-dwarf'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains(CppRuleClasses.PREPROCESSOR_DEFINES)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'preprocessor_defines'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'preprocess-assemble'", |
| " action: 'linkstamp-compile'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-header-parsing'", |
| " action: 'c++-module-compile'", |
| " action: 'clif-match'", |
| " flag_group {", |
| " iterate_over: 'preprocessor_defines'", |
| " flag: '-D%{preprocessor_defines}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("includes")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'includes'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'preprocess-assemble'", |
| " action: 'linkstamp-compile'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-header-parsing'", |
| " action: 'c++-module-compile'", |
| " action: 'clif-match'", |
| " action: 'objc-compile'", |
| " action: 'objc++-compile'", |
| " flag_group {", |
| " expand_if_all_available: 'includes'", |
| " iterate_over: 'includes'", |
| " flag: '-include'", |
| " flag: '%{includes}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains(CppRuleClasses.INCLUDE_PATHS)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'include_paths'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'preprocess-assemble'", |
| " action: 'linkstamp-compile'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-header-parsing'", |
| " action: 'c++-module-compile'", |
| " action: 'clif-match'", |
| " action: 'objc-compile'", |
| " action: 'objc++-compile'", |
| " flag_group {", |
| " iterate_over: 'quote_include_paths'", |
| " flag: '-iquote'", |
| " flag: '%{quote_include_paths}'", |
| " }", |
| " flag_group {", |
| " iterate_over: 'include_paths'", |
| " flag: '-I%{include_paths}'", |
| " }", |
| " flag_group {", |
| " iterate_over: 'system_include_paths'", |
| " flag: '-isystem'", |
| " flag: '%{system_include_paths}'", |
| " }", |
| " flag_group {", |
| " iterate_over: 'framework_include_paths'", |
| " flag: '-F%{framework_include_paths}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains(CppRuleClasses.FDO_INSTRUMENT)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'fdo_instrument'", |
| " provides: 'profile'", |
| " flag_set {", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'c++-link-executable'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'fdo_instrument_path'", |
| " flag: '-fprofile-generate=%{fdo_instrument_path}'", |
| " flag: '-fno-data-sections'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains(CppRuleClasses.FDO_OPTIMIZE)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'fdo_optimize'", |
| " provides: 'profile'", |
| " flag_set {", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " flag_group {", |
| " expand_if_all_available: 'fdo_profile_path'", |
| " flag: '-fprofile-use=%{fdo_profile_path}'", |
| " flag: '-Xclang-only=-Wno-profile-instr-unprofiled'", |
| " flag: '-Xclang-only=-Wno-profile-instr-out-of-date'", |
| " flag: '-fprofile-correction'", |
| " }", |
| " }"))); |
| } |
| |
| if (!existingFeatureNames.contains(CppRuleClasses.CS_FDO_INSTRUMENT)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'cs_fdo_instrument'", |
| " provides: 'csprofile'", |
| " flag_set {", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'lto-backend'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'c++-link-executable'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'cs_fdo_instrument_path'", |
| " flag: '-fcs-profile-generate=%{cs_fdo_instrument_path}'", |
| " }", |
| " }"))); |
| } |
| |
| if (!existingFeatureNames.contains(CppRuleClasses.CS_FDO_OPTIMIZE)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'cs_fdo_optimize'", |
| " provides: 'csprofile'", |
| " flag_set {", |
| " action: 'lto-backend'", |
| " flag_group {", |
| " expand_if_all_available: 'fdo_profile_path'", |
| " flag: '-fprofile-use=%{fdo_profile_path}'", |
| " flag: '-Xclang-only=-Wno-profile-instr-unprofiled'", |
| " flag: '-Xclang-only=-Wno-profile-instr-out-of-date'", |
| " flag: '-fprofile-correction'", |
| " }", |
| " }"))); |
| } |
| |
| if (!existingFeatureNames.contains(CppRuleClasses.FDO_PREFETCH_HINTS)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'fdo_prefetch_hints'", |
| " flag_set {", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'lto-backend'", |
| " flag_group {", |
| " expand_if_all_available: 'fdo_prefetch_hints_path'", |
| " flag: '-Xclang-only=-mllvm'", |
| " flag: '-Xclang-only=-prefetch-hints-file=" |
| + "%{fdo_prefetch_hints_path}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains(CppRuleClasses.AUTOFDO)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'autofdo'", |
| " provides: 'profile'", |
| " flag_set {", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " flag_group {", |
| " expand_if_all_available: 'fdo_profile_path'", |
| " flag: '-fauto-profile=%{fdo_profile_path}'", |
| " flag: '-fprofile-correction'", |
| " }", |
| " }"))); |
| } |
| |
| if (!existingFeatureNames.contains(CppRuleClasses.BUILD_INTERFACE_LIBRARIES)) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'build_interface_libraries'", |
| " flag_set {", |
| " with_feature { feature: 'supports_interface_shared_libraries' }", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " flag_group {", |
| " expand_if_all_available: 'generate_interface_library'", |
| " flag: '%{generate_interface_library}'", |
| " flag: '%{interface_library_builder_path}'", |
| " flag: '%{interface_library_input_path}'", |
| " flag: '%{interface_library_output_path}'", |
| " }", |
| " }"))); |
| } |
| |
| // Order of feature declaration matters, cppDynamicLibraryLinkerTool has to |
| // follow right after build_interface_libraries. |
| if (!existingFeatureNames.contains("dynamic_library_linker_tool")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'dynamic_library_linker_tool'", |
| " flag_set {", |
| " with_feature { feature: 'supports_interface_shared_libraries' }", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " flag_group {", |
| " expand_if_all_available: 'generate_interface_library'", |
| " flag: '" + cppLinkDynamicLibraryToolPath + "'", |
| " }", |
| " }"))); |
| } |
| |
| if (!existingFeatureNames.contains("symbol_counts")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'symbol_counts'", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'symbol_counts_output'", |
| " flag: '-Wl,--print-symbol-counts=%{symbol_counts_output}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("shared_flag")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'shared_flag'", |
| " flag_set {", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " flag_group {", |
| " flag: '-shared'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("linkstamps")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'linkstamps'", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'linkstamp_paths'", |
| " iterate_over: 'linkstamp_paths'", |
| " flag: '%{linkstamp_paths}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("output_execpath_flags")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'output_execpath_flags'", |
| " flag_set {", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'c++-link-executable'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'output_execpath'", |
| " flag: '-o'", |
| " flag: '%{output_execpath}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("runtime_library_search_directories")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'runtime_library_search_directories',", |
| " flag_set {", |
| " with_feature { feature: 'static_link_cpp_runtimes' }", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'runtime_library_search_directories'", |
| " iterate_over: 'runtime_library_search_directories'", |
| " flag_group {", |
| " expand_if_true: 'is_cc_test'", |
| // TODO(b/27153401): This should probably be @loader_path on osx. |
| " flag: ", |
| " '-Wl,-rpath,$EXEC_ORIGIN/%{runtime_library_search_directories}'", |
| " }", |
| " flag_group {", |
| " expand_if_false: 'is_cc_test'", |
| ifLinux( |
| platform, |
| " flag: '-Wl,-rpath,$ORIGIN/" |
| + "%{runtime_library_search_directories}'"), |
| ifMac( |
| platform, |
| " flag: '-Wl,-rpath,@loader_path/" |
| + "%{runtime_library_search_directories}'"), |
| " }", |
| " }", |
| " }", |
| " flag_set {", |
| " with_feature { not_feature: 'static_link_cpp_runtimes' }", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'runtime_library_search_directories'", |
| " iterate_over: 'runtime_library_search_directories'", |
| " flag_group {", |
| ifLinux( |
| platform, |
| " flag: '-Wl,-rpath,$ORIGIN/" |
| + "%{runtime_library_search_directories}'"), |
| ifMac( |
| platform, |
| " flag: '-Wl,-rpath,@loader_path/" |
| + "%{runtime_library_search_directories}'"), |
| " }", |
| " }", |
| "}"))); |
| } |
| if (!existingFeatureNames.contains("library_search_directories")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'library_search_directories'", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'library_search_directories'", |
| " iterate_over: 'library_search_directories'", |
| " flag: '-L%{library_search_directories}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("archiver_flags")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'archiver_flags'", |
| " flag_set {", |
| " action: 'c++-link-static-library'", |
| " flag_group {", |
| ifLinux(platform, "flag: 'rcsD'"), |
| ifMac(platform, "flag: '-static'", "flag: '-s'"), |
| " }", |
| " flag_group {", |
| " expand_if_all_available: 'output_execpath'", |
| ifLinux(platform, "flag: '%{output_execpath}'"), |
| ifMac(platform, "flag: '-o'", "flag: '%{output_execpath}'"), |
| " }", |
| " }", |
| " flag_set { ", |
| " action: 'c++-link-static-library'", |
| " flag_group {", |
| " expand_if_all_available: 'libraries_to_link'", |
| " iterate_over: 'libraries_to_link'", |
| " flag_group {", |
| " expand_if_equal {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'object_file'", |
| " }", |
| " flag: '%{libraries_to_link.name}'", |
| " }", |
| " flag_group {", |
| " expand_if_equal {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'object_file_group'", |
| " }", |
| " iterate_over: 'libraries_to_link.object_files'", |
| " flag: '%{libraries_to_link.object_files}'", |
| " }", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("libraries_to_link")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'libraries_to_link'", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| ifTrue( |
| doNotSplitLinkingCmdline, |
| " flag_group {", |
| " expand_if_true: 'thinlto_param_file'", |
| " flag: '-Wl,@%{thinlto_param_file}'", |
| " }"), |
| " flag_group {", |
| " expand_if_all_available: 'libraries_to_link'", |
| " iterate_over: 'libraries_to_link'", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'object_file_group'", |
| " }", |
| " flag: '-Wl,--start-lib'", |
| " }", |
| ifLinux( |
| platform, |
| " flag_group {", |
| " expand_if_true: 'libraries_to_link.is_whole_archive'", |
| " flag: '-Wl,-whole-archive'", |
| " }", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'object_file_group'", |
| " }", |
| " iterate_over: 'libraries_to_link.object_files'", |
| " flag: '%{libraries_to_link.object_files}'", |
| " }", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'object_file'", |
| " }", |
| " flag: '%{libraries_to_link.name}'", |
| " }", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'interface_library'", |
| " }", |
| " flag: '%{libraries_to_link.name}'", |
| " }", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'static_library'", |
| " }", |
| " flag: '%{libraries_to_link.name}'", |
| " }", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'dynamic_library'", |
| " }", |
| " flag: '-l%{libraries_to_link.name}'", |
| " }", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'versioned_dynamic_library'", |
| " }", |
| " flag: '-l:%{libraries_to_link.name}'", |
| " }", |
| " flag_group {", |
| " expand_if_true: 'libraries_to_link.is_whole_archive'", |
| " flag: '-Wl,-no-whole-archive'", |
| " }"), |
| ifMac( |
| platform, |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'object_file_group'", |
| " }", |
| " iterate_over: 'libraries_to_link.object_files'", |
| " flag_group {", |
| " expand_if_false: 'libraries_to_link.is_whole_archive'", |
| " flag: '%{libraries_to_link.object_files}'", |
| " }", |
| " flag_group {", |
| " expand_if_true: 'libraries_to_link.is_whole_archive'", |
| " flag: '-Wl,-force_load,%{libraries_to_link.object_files}'", |
| " }", |
| " }", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'object_file'", |
| " }", |
| " flag_group {", |
| " expand_if_false: 'libraries_to_link.is_whole_archive'", |
| " flag: '%{libraries_to_link.name}'", |
| " }", |
| " flag_group {", |
| " expand_if_true: 'libraries_to_link.is_whole_archive'", |
| " flag: '-Wl,-force_load,%{libraries_to_link.name}'", |
| " }", |
| " }", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'interface_library'", |
| " }", |
| " flag_group {", |
| " expand_if_false: 'libraries_to_link.is_whole_archive'", |
| " flag: '%{libraries_to_link.name}'", |
| " }", |
| " flag_group {", |
| " expand_if_true: 'libraries_to_link.is_whole_archive'", |
| " flag: '-Wl,-force_load,%{libraries_to_link.name}'", |
| " }", |
| " }", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'static_library'", |
| " }", |
| " flag_group {", |
| " expand_if_false: 'libraries_to_link.is_whole_archive'", |
| " flag: '%{libraries_to_link.name}'", |
| " }", |
| " flag_group {", |
| " expand_if_true: 'libraries_to_link.is_whole_archive'", |
| " flag: '-Wl,-force_load,%{libraries_to_link.name}'", |
| " }", |
| " }", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'dynamic_library'", |
| " }", |
| " flag: '-l%{libraries_to_link.name}'", |
| " }", |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'versioned_dynamic_library'", |
| " }", |
| " flag: '-l:%{libraries_to_link.name}'", |
| " }"), |
| " flag_group {", |
| " expand_if_equal: {", |
| " variable: 'libraries_to_link.type'", |
| " value: 'object_file_group'", |
| " }", |
| " flag: '-Wl,--end-lib'", |
| " }", |
| " }", |
| ifTrue( |
| !doNotSplitLinkingCmdline, |
| " flag_group {", |
| " expand_if_true: 'thinlto_param_file'", |
| " flag: '-Wl,@%{thinlto_param_file}'", |
| " }"), |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("force_pic_flags")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'force_pic_flags'", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'force_pic'", |
| ifLinux(platform, "flag: '-pie'"), |
| ifMac(platform, "flag: '-Wl,-pie'"), |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("user_link_flags")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'user_link_flags'", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'user_link_flags'", |
| " iterate_over: 'user_link_flags'", |
| " flag: '%{user_link_flags}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("legacy_link_flags")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'legacy_link_flags'", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'legacy_link_flags'", |
| " iterate_over: 'legacy_link_flags'", |
| " flag: '%{legacy_link_flags}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("static_libgcc")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'static_libgcc'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " with_feature { feature: 'static_link_cpp_runtimes' }", |
| " flag_group {", |
| " flag: '-static-libgcc'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("fission_support")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'fission_support'", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'is_using_fission'", |
| " flag: '-Wl,--gdb-index'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("strip_debug_symbols")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'strip_debug_symbols'", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'strip_debug_symbols'", |
| " flag: '-Wl,-S'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains(CppRuleClasses.COVERAGE)) { |
| featureBuilder.add( |
| getFeature(" name: 'coverage'"), |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'llvm_coverage_map_format'", |
| " provides: 'profile'", |
| " flag_set {", |
| " action: 'preprocess-assemble'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-module-compile'", |
| " action: 'objc-compile'", |
| " action: 'objc++-compile'", |
| " flag_group {", |
| " flag: '-fprofile-instr-generate'", |
| " flag: '-fcoverage-mapping'", |
| " }", |
| " }", |
| " flag_set {", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'c++-link-executable'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " action: 'objc-executable'", |
| " action: 'objc++-executable'", |
| " flag_group {", |
| " flag: '-fprofile-instr-generate'", |
| " }", |
| " }", |
| " requires {", |
| " feature: 'coverage'", |
| " }")), |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'gcc_coverage_map_format'", |
| " provides: 'profile'", |
| " flag_set {", |
| " action: 'preprocess-assemble'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-module-compile'", |
| " action: 'objc-compile'", |
| " action: 'objc++-compile'", |
| " action: 'objc-executable'", |
| " action: 'objc++-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'gcov_gcno_file'", |
| " flag: '-fprofile-arcs'", |
| " flag: '-ftest-coverage'", |
| " }", |
| " }", |
| " flag_set {", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'c++-link-executable'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " flag: '--coverage'", |
| " }", |
| " }", |
| " requires {", |
| " feature: 'coverage'", |
| " }"))); |
| } |
| } catch (ParseException e) { |
| // Can only happen if we change the proto definition without changing our |
| // configuration above. |
| throw new IllegalStateException(e); |
| } |
| return featureBuilder.build(); |
| } |
| |
| // Note: these configs won't be added to the crosstools that defines no_legacy_features feature |
| // (e.g. ndk, apple, enclave crosstools). Those need to be modified separately. |
| public static ImmutableList<CToolchain.ActionConfig> getLegacyActionConfigs( |
| CppPlatform platform, |
| String gccToolPath, |
| String arToolPath, |
| String stripToolPath, |
| boolean supportsInterfaceSharedLibraries, |
| ImmutableSet<String> existingActionConfigNames) { |
| try { |
| ImmutableList.Builder<CToolchain.ActionConfig> actionConfigBuilder = ImmutableList.builder(); |
| if (!existingActionConfigNames.contains(CppActionNames.ASSEMBLE)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'assemble'", |
| " action_name: 'assemble'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'legacy_compile_flags'", |
| " implies: 'user_compile_flags'", |
| " implies: 'sysroot'", |
| " implies: 'unfiltered_compile_flags'", |
| " implies: 'compiler_input_flags'", |
| " implies: 'compiler_output_flags'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.PREPROCESS_ASSEMBLE)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'preprocess-assemble'", |
| " action_name: 'preprocess-assemble'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'legacy_compile_flags'", |
| " implies: 'user_compile_flags'", |
| " implies: 'sysroot'", |
| " implies: 'unfiltered_compile_flags'", |
| " implies: 'compiler_input_flags'", |
| " implies: 'compiler_output_flags'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.LINKSTAMP_COMPILE)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'linkstamp-compile'", |
| " action_name: 'linkstamp-compile'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'legacy_compile_flags'", |
| " implies: 'user_compile_flags'", |
| " implies: 'sysroot'", |
| " implies: 'unfiltered_compile_flags'", |
| " implies: 'compiler_input_flags'", |
| " implies: 'compiler_output_flags'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.LTO_BACKEND)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'lto-backend'", |
| " action_name: 'lto-backend'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'legacy_compile_flags'", |
| " implies: 'user_compile_flags'", |
| " implies: 'sysroot'", |
| " implies: 'unfiltered_compile_flags'", |
| " implies: 'compiler_input_flags'", |
| " implies: 'compiler_output_flags'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.C_COMPILE)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'c-compile'", |
| " action_name: 'c-compile'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'legacy_compile_flags'", |
| " implies: 'user_compile_flags'", |
| " implies: 'sysroot'", |
| " implies: 'unfiltered_compile_flags'", |
| " implies: 'compiler_input_flags'", |
| " implies: 'compiler_output_flags'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.CPP_COMPILE)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'c++-compile'", |
| " action_name: 'c++-compile'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'legacy_compile_flags'", |
| " implies: 'user_compile_flags'", |
| " implies: 'sysroot'", |
| " implies: 'unfiltered_compile_flags'", |
| " implies: 'compiler_input_flags'", |
| " implies: 'compiler_output_flags'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.CPP_HEADER_PARSING)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'c++-header-parsing'", |
| " action_name: 'c++-header-parsing'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'legacy_compile_flags'", |
| " implies: 'user_compile_flags'", |
| " implies: 'sysroot'", |
| " implies: 'unfiltered_compile_flags'", |
| " implies: 'compiler_input_flags'", |
| " implies: 'compiler_output_flags'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.CPP_MODULE_COMPILE)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'c++-module-compile'", |
| " action_name: 'c++-module-compile'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'legacy_compile_flags'", |
| " implies: 'user_compile_flags'", |
| " implies: 'sysroot'", |
| " implies: 'unfiltered_compile_flags'", |
| " implies: 'compiler_input_flags'", |
| " implies: 'compiler_output_flags'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.CPP_MODULE_CODEGEN)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'c++-module-codegen'", |
| " action_name: 'c++-module-codegen'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'legacy_compile_flags'", |
| " implies: 'user_compile_flags'", |
| " implies: 'sysroot'", |
| " implies: 'unfiltered_compile_flags'", |
| " implies: 'compiler_input_flags'", |
| " implies: 'compiler_output_flags'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.CPP_LINK_EXECUTABLE)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'c++-link-executable'", |
| " action_name: 'c++-link-executable'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'symbol_counts'", |
| " implies: 'strip_debug_symbols'", |
| " implies: 'linkstamps'", |
| " implies: 'output_execpath_flags'", |
| " implies: 'runtime_library_search_directories'", |
| " implies: 'library_search_directories'", |
| " implies: 'libraries_to_link'", |
| " implies: 'force_pic_flags'", |
| " implies: 'user_link_flags'", |
| " implies: 'legacy_link_flags'", |
| " implies: 'linker_param_file'", |
| " implies: 'fission_support'", |
| " implies: 'sysroot'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.LTO_INDEX_EXECUTABLE)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'lto-index-for-executable'", |
| " action_name: 'lto-index-for-executable'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'symbol_counts'", |
| " implies: 'strip_debug_symbols'", |
| " implies: 'linkstamps'", |
| " implies: 'output_execpath_flags'", |
| " implies: 'runtime_library_search_directories'", |
| " implies: 'library_search_directories'", |
| " implies: 'libraries_to_link'", |
| " implies: 'force_pic_flags'", |
| " implies: 'user_link_flags'", |
| " implies: 'legacy_link_flags'", |
| " implies: 'linker_param_file'", |
| " implies: 'fission_support'", |
| " implies: 'sysroot'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.CPP_LINK_NODEPS_DYNAMIC_LIBRARY)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'c++-link-nodeps-dynamic-library'", |
| " action_name: 'c++-link-nodeps-dynamic-library'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'build_interface_libraries'", |
| " implies: 'dynamic_library_linker_tool'", |
| " implies: 'symbol_counts'", |
| " implies: 'strip_debug_symbols'", |
| " implies: 'shared_flag'", |
| " implies: 'linkstamps'", |
| " implies: 'output_execpath_flags'", |
| " implies: 'runtime_library_search_directories'", |
| " implies: 'library_search_directories'", |
| " implies: 'libraries_to_link'", |
| " implies: 'user_link_flags'", |
| " implies: 'legacy_link_flags'", |
| " implies: 'linker_param_file'", |
| " implies: 'fission_support'", |
| " implies: 'sysroot'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.LTO_INDEX_NODEPS_DYNAMIC_LIBRARY)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'lto-index-for-nodeps-dynamic-library'", |
| " action_name: 'lto-index-for-nodeps-dynamic-library'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'build_interface_libraries'", |
| " implies: 'dynamic_library_linker_tool'", |
| " implies: 'symbol_counts'", |
| " implies: 'strip_debug_symbols'", |
| " implies: 'shared_flag'", |
| " implies: 'linkstamps'", |
| " implies: 'output_execpath_flags'", |
| " implies: 'runtime_library_search_directories'", |
| " implies: 'library_search_directories'", |
| " implies: 'libraries_to_link'", |
| " implies: 'user_link_flags'", |
| " implies: 'legacy_link_flags'", |
| " implies: 'linker_param_file'", |
| " implies: 'fission_support'", |
| " implies: 'sysroot'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.CPP_LINK_DYNAMIC_LIBRARY)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'c++-link-dynamic-library'", |
| " action_name: 'c++-link-dynamic-library'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'build_interface_libraries'", |
| " implies: 'dynamic_library_linker_tool'", |
| " implies: 'symbol_counts'", |
| " implies: 'strip_debug_symbols'", |
| " implies: 'shared_flag'", |
| " implies: 'linkstamps'", |
| " implies: 'output_execpath_flags'", |
| " implies: 'runtime_library_search_directories'", |
| " implies: 'library_search_directories'", |
| " implies: 'libraries_to_link'", |
| " implies: 'user_link_flags'", |
| " implies: 'legacy_link_flags'", |
| " implies: 'linker_param_file'", |
| " implies: 'fission_support'", |
| " implies: 'sysroot'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.LTO_INDEX_DYNAMIC_LIBRARY)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'lto-index-for-dynamic-library'", |
| " action_name: 'lto-index-for-dynamic-library'", |
| " tool {", |
| " tool_path: '" + gccToolPath + "'", |
| " }", |
| " implies: 'build_interface_libraries'", |
| " implies: 'dynamic_library_linker_tool'", |
| " implies: 'symbol_counts'", |
| " implies: 'strip_debug_symbols'", |
| " implies: 'shared_flag'", |
| " implies: 'linkstamps'", |
| " implies: 'output_execpath_flags'", |
| " implies: 'runtime_library_search_directories'", |
| " implies: 'library_search_directories'", |
| " implies: 'libraries_to_link'", |
| " implies: 'user_link_flags'", |
| " implies: 'legacy_link_flags'", |
| " implies: 'linker_param_file'", |
| " implies: 'fission_support'", |
| " implies: 'sysroot'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.CPP_LINK_STATIC_LIBRARY)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'c++-link-static-library'", |
| " action_name: 'c++-link-static-library'", |
| " tool {", |
| " tool_path: '" + arToolPath + "'", |
| " }", |
| " implies: 'archiver_flags'", |
| " implies: 'linker_param_file'"))); |
| } |
| if (!existingActionConfigNames.contains(CppActionNames.STRIP)) { |
| actionConfigBuilder.add( |
| getActionConfig( |
| Joiner.on("\n") |
| .join( |
| " config_name: 'strip'", |
| " action_name: 'strip'", |
| " tool {", |
| " tool_path: '" + stripToolPath + "'", |
| " }", |
| " flag_set {", |
| " flag_group {", |
| " flag: '-S'", |
| ifLinux(platform, "flag: '-p'"), |
| " flag: '-o'", |
| " flag: '%{output_file}'", |
| " }", |
| ifLinux( |
| platform, |
| " flag_group {", |
| " flag: '-R'", |
| " flag: '.gnu.switches.text.quote_paths'", |
| " flag: '-R'", |
| " flag: '.gnu.switches.text.bracket_paths'", |
| " flag: '-R'", |
| " flag: '.gnu.switches.text.system_paths'", |
| " flag: '-R'", |
| " flag: '.gnu.switches.text.cpp_defines'", |
| " flag: '-R'", |
| " flag: '.gnu.switches.text.cpp_includes'", |
| " flag: '-R'", |
| " flag: '.gnu.switches.text.cl_args'", |
| " flag: '-R'", |
| " flag: '.gnu.switches.text.lipo_info'", |
| " flag: '-R'", |
| " flag: '.gnu.switches.text.annotation'", |
| " }"), |
| " flag_group {", |
| " iterate_over: 'stripopts'", |
| " flag: '%{stripopts}'", |
| " }", |
| " flag_group {", |
| " flag: '%{input_file}'", |
| " }", |
| " }"))); |
| } |
| return actionConfigBuilder.build(); |
| } catch (ParseException e) { |
| // Can only happen if we change the proto definition without changing our |
| // configuration above. |
| throw new IllegalStateException(e); |
| } |
| } |
| |
| // Note: these feaures won't be added to the crosstools that defines no_legacy_features feature |
| // (e.g. ndk, apple, enclave crosstools). Those need to be modified separately. |
| public static ImmutableList<CToolchain.Feature> getFeaturesToAppearLastInFeaturesList( |
| ImmutableSet<String> existingFeatureNames, boolean doNotSplitLinkingCmdline) { |
| ImmutableList.Builder<CToolchain.Feature> featureBuilder = ImmutableList.builder(); |
| try { |
| if (!existingFeatureNames.contains("fully_static_link")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'fully_static_link'", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " flag: '-static'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("user_compile_flags")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'user_compile_flags'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'assemble'", |
| " action: 'preprocess-assemble'", |
| " action: 'linkstamp-compile'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-header-parsing'", |
| " action: 'c++-module-compile'", |
| " action: 'c++-module-codegen'", |
| " action: 'lto-backend'", |
| " action: 'clif-match'", |
| " flag_group {", |
| " expand_if_all_available: 'user_compile_flags'", |
| " iterate_over: 'user_compile_flags'", |
| " flag: '%{user_compile_flags}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("sysroot")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'sysroot'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'preprocess-assemble'", |
| " action: 'linkstamp-compile'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-header-parsing'", |
| " action: 'c++-module-compile'", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " action: 'clif-match'", |
| " action: 'lto-backend'", |
| " flag_group {", |
| " expand_if_all_available: 'sysroot'", |
| " flag: '--sysroot=%{sysroot}'", |
| " }", |
| " }"))); |
| } |
| // unfiltered_compile_flags contain system include paths. These must be added |
| // after the user provided options (present in legacy_compile_flags build |
| // variable above), otherwise users adding include paths will not pick up their own |
| // include paths first. |
| if (!existingFeatureNames.contains("unfiltered_compile_flags")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'unfiltered_compile_flags'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'assemble'", |
| " action: 'preprocess-assemble'", |
| " action: 'linkstamp-compile'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'c++-header-parsing'", |
| " action: 'c++-module-compile'", |
| " action: 'c++-module-codegen'", |
| " action: 'lto-backend'", |
| " action: 'clif-match'", |
| " flag_group {", |
| " expand_if_all_available: 'unfiltered_compile_flags'", |
| " iterate_over: 'unfiltered_compile_flags'", |
| " flag: '%{unfiltered_compile_flags}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("linker_param_file")) { |
| String dynamicLibraryParamFile = " flag: '-Wl,@%{linker_param_file}'"; |
| if (doNotSplitLinkingCmdline |
| || existingFeatureNames.contains(CppRuleClasses.DO_NOT_SPLIT_LINKING_CMDLINE)) { |
| dynamicLibraryParamFile = " flag: '@%{linker_param_file}'"; |
| } |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'linker_param_file'", |
| " flag_set {", |
| " action: 'c++-link-executable'", |
| " action: 'c++-link-dynamic-library'", |
| " action: 'c++-link-nodeps-dynamic-library'", |
| " action: 'lto-index-for-dynamic-library'", |
| " action: 'lto-index-for-nodeps-dynamic-library'", |
| " action: 'lto-index-for-executable'", |
| " flag_group {", |
| " expand_if_all_available: 'linker_param_file'", |
| dynamicLibraryParamFile, |
| " }", |
| " }", |
| " flag_set {", |
| " action: 'c++-link-static-library'", |
| " flag_group {", |
| " expand_if_all_available: 'linker_param_file'", |
| " flag: '@%{linker_param_file}'", |
| " }", |
| " }"))); |
| } |
| if (!existingFeatureNames.contains("compiler_input_flags")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'compiler_input_flags'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'assemble'", |
| " action: 'preprocess-assemble'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'linkstamp-compile'", |
| " action: 'c++-module-compile'", |
| " action: 'c++-module-codegen'", |
| " action: 'objc-compile'", |
| " action: 'objc++-compile'", |
| " action: 'c++-header-parsing'", |
| " action: 'lto-backend'", |
| " flag_group {", |
| " expand_if_all_available: 'source_file'", |
| " flag: '-c'", |
| " flag: '%{source_file}'", |
| " }", |
| " }"))); |
| } |
| |
| if (!existingFeatureNames.contains("compiler_output_flags")) { |
| featureBuilder.add( |
| getFeature( |
| Joiner.on("\n") |
| .join( |
| " name: 'compiler_output_flags'", |
| " enabled: true", |
| " flag_set {", |
| " action: 'assemble'", |
| " action: 'preprocess-assemble'", |
| " action: 'c-compile'", |
| " action: 'c++-compile'", |
| " action: 'linkstamp-compile'", |
| " action: 'c++-module-compile'", |
| " action: 'c++-module-codegen'", |
| " action: 'objc-compile'", |
| " action: 'objc++-compile'", |
| " action: 'c++-header-parsing'", |
| " action: 'lto-backend'", |
| " flag_group {", |
| " expand_if_all_available: 'output_assembly_file'", |
| " flag: '-S'", |
| " }", |
| " flag_group {", |
| " expand_if_all_available: 'output_preprocess_file'", |
| " flag: '-E'", |
| " }", |
| " flag_group {", |
| " expand_if_all_available: 'output_file'", |
| " flag: '-o'", |
| " flag: '%{output_file}'", |
| " }", |
| " }"))); |
| } |
| } catch (ParseException e) { |
| // Can only happen if we change the proto definition without changing our |
| // configuration above. |
| throw new IllegalStateException(e); |
| } |
| return featureBuilder.build(); |
| } |
| |
| private static String ifLinux(CppPlatform platform, String... lines) { |
| // Platform `LINUX` also includes FreeBSD and OpenBSD. |
| return ifTrue(platform == CppPlatform.LINUX, lines); |
| } |
| |
| private static String ifMac(CppPlatform platform, String... lines) { |
| return ifTrue(platform == CppPlatform.MAC, lines); |
| } |
| |
| private static String ifTrue(boolean condition, String... lines) { |
| if (condition) { |
| return Joiner.on("\n").join(lines); |
| } else { |
| return ""; |
| } |
| } |
| |
| private static CToolchain.Feature getFeature(String protoText) throws ParseException { |
| CToolchain.Feature.Builder feature = CToolchain.Feature.newBuilder(); |
| TextFormat.merge(protoText, feature); |
| return feature.build(); |
| } |
| |
| private static CToolchain.ActionConfig getActionConfig(String protoText) throws ParseException { |
| CToolchain.ActionConfig.Builder actionConfig = CToolchain.ActionConfig.newBuilder(); |
| TextFormat.merge(protoText, actionConfig); |
| return actionConfig.build(); |
| } |
| } |