blob: 2bccd1c9beabddfaafa8a0bfd2f4c131fa4fb2da [file] [log] [blame]
// 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;
/**
* 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
}
public static String getCppActionConfigs(
CppPlatform platform,
ImmutableSet<String> existingFeatureNames,
String gccToolPath,
String cppLinkDynamicLibraryToolPath,
String arToolPath,
String stripToolPath,
boolean supportsEmbeddedRuntimes,
boolean supportsInterfaceSharedLibraries) {
String cppDynamicLibraryLinkerTool = "";
if (!existingFeatureNames.contains("dynamic_library_linker_tool")
&& supportsInterfaceSharedLibraries) {
cppDynamicLibraryLinkerTool =
""
+ "feature {"
+ " name: 'dynamic_library_linker_tool'"
+ " flag_set {"
+ " action: 'c++-link-dynamic-library'"
+ " flag_group {"
+ " flag: '"
+ cppLinkDynamicLibraryToolPath
+ "'"
+ " }"
+ " }"
+ "}";
}
return Joiner.on("\n")
.join(
ImmutableList.of(
"action_config {",
" config_name: 'assemble'",
" action_name: 'assemble'",
" tool {",
" tool_path: '" + gccToolPath + "'",
" }",
" implies: 'legacy_compile_flags'",
" implies: 'user_compile_flags'",
" implies: 'sysroot'",
" implies: 'unfiltered_compile_flags'",
"}",
"action_config {",
" 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'",
"}",
"action_config {",
" 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'",
"}",
"action_config {",
" 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'",
"}",
"action_config {",
" 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'",
"}",
"action_config {",
" 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'",
"}",
"action_config {",
" config_name: 'c++-header-preprocessing'",
" action_name: 'c++-header-preprocessing'",
" tool {",
" tool_path: '" + gccToolPath + "'",
" }",
" implies: 'legacy_compile_flags'",
" implies: 'user_compile_flags'",
" implies: 'sysroot'",
" implies: 'unfiltered_compile_flags'",
"}",
"action_config {",
" 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'",
"}",
"action_config {",
" 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'",
"}",
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.LEGACY_COMPILE_FLAGS),
"feature {",
" name: 'legacy_compile_flags'",
" enabled: true",
" flag_set {",
" expand_if_all_available: 'legacy_compile_flags'",
" action: 'assemble'",
" action: 'preprocess-assemble'",
" action: 'linkstamp-compile'",
" action: 'c-compile'",
" action: 'c++-compile'",
" action: 'c++-header-parsing'",
" action: 'c++-header-preprocessing'",
" action: 'c++-module-compile'",
" action: 'c++-module-codegen'",
" action: 'lto-backend'",
" action: 'clif-match'",
" flag_group {",
" 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>
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.DEPENDENCY_FILE),
"feature {",
" name: 'dependency_file'",
" 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-preprocessing'",
" action: 'c++-header-parsing'",
" action: 'clif-match'",
" expand_if_all_available: 'dependency_file'",
" flag_group {",
" 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.
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.RANDOM_SEED),
"feature {",
" name: 'random_seed'",
" flag_set {",
" action: 'c++-compile'",
" action: 'c++-module-codegen'",
" action: 'c++-module-compile'",
" flag_group {",
" flag: '-frandom-seed=%{output_file}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.PIC),
"feature {",
" name: 'pic'",
" flag_set {",
" action: 'assemble'",
" action: 'preprocess-assemble'",
" action: 'linkstamp-compile'",
" action: 'c-compile'",
" action: 'c++-compile'",
" action: 'c++-module-codegen'",
" action: 'c++-module-compile'",
" expand_if_all_available: 'pic'",
" flag_group {",
" flag: '-fPIC'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.PER_OBJECT_DEBUG_INFO),
"feature {",
" name: 'per_object_debug_info'",
" flag_set {",
" action: 'assemble'",
" action: 'preprocess-assemble'",
" action: 'c-compile'",
" action: 'c++-compile'",
" action: 'c++-module-codegen'",
" expand_if_all_available: 'per_object_debug_info_file'",
" flag_group {",
" flag: '-gsplit-dwarf'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.PREPROCESSOR_DEFINES),
"feature {",
" name: 'preprocessor_defines'",
" flag_set {",
" action: 'preprocess-assemble'",
" action: 'linkstamp-compile'",
" action: 'c-compile'",
" action: 'c++-compile'",
" action: 'c++-header-parsing'",
" action: 'c++-header-preprocessing'",
" action: 'c++-module-compile'",
" action: 'clif-match'",
" flag_group {",
" iterate_over: 'preprocessor_defines'",
" flag: '-D%{preprocessor_defines}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("includes"),
"feature {",
" name: 'includes'",
" enabled: true",
" flag_set {",
" action: 'preprocess-assemble'",
" action: 'linkstamp-compile'",
" action: 'c-compile'",
" action: 'c++-compile'",
" action: 'c++-header-parsing'",
" action: 'c++-header-preprocessing'",
" 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}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.INCLUDE_PATHS),
"feature {",
" name: 'include_paths'",
" flag_set {",
" action: 'preprocess-assemble'",
" action: 'linkstamp-compile'",
" action: 'c-compile'",
" action: 'c++-compile'",
" action: 'c++-header-parsing'",
" action: 'c++-header-preprocessing'",
" 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}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.FDO_INSTRUMENT),
"feature {",
" name: 'fdo_instrument'",
" provides: 'profile'",
" flag_set {",
" action: 'c-compile'",
" action: 'c++-compile'",
" action: 'c++-link-interface-dynamic-library'",
" action: 'c++-link-dynamic-library'",
" action: 'c++-link-executable'",
" flag_group {",
" flag: '-fprofile-generate=%{fdo_instrument_path}'",
" flag: '-fno-data-sections'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.FDO_OPTIMIZE),
"feature {",
" name: 'fdo_optimize'",
" provides: 'profile'",
" flag_set {",
" action: 'c-compile'",
" action: 'c++-compile'",
" expand_if_all_available: 'fdo_profile_path'",
" flag_group {",
" 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'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.AUTOFDO),
"feature {",
" name: 'autofdo'",
" provides: 'profile'",
" flag_set {",
" action: 'c-compile'",
" action: 'c++-compile'",
" expand_if_all_available: 'fdo_profile_path'",
" flag_group {",
" flag: '-fauto-profile=%{fdo_profile_path}'",
" flag: '-fprofile-correction'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.LIPO),
"feature {",
" name: 'lipo'",
" requires { feature: 'autofdo' }",
" requires { feature: 'fdo_optimize' }",
" requires { feature: 'fdo_instrument' }",
" flag_set {",
" action: 'c-compile'",
" action: 'c++-compile'",
" flag_group {",
" flag: '-fripa'",
" }",
" }",
"}"),
"action_config {",
" 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: 'legacy_link_flags'",
" implies: 'linker_param_file'",
" implies: 'fission_support'",
" implies: 'sysroot'",
"}",
"action_config {",
" config_name: 'c++-link-dynamic-library'",
" action_name: 'c++-link-dynamic-library'",
" tool {",
" tool_path: '" + gccToolPath + "'",
" }",
ifTrue(
supportsInterfaceSharedLibraries,
"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: 'legacy_link_flags'",
" implies: 'linker_param_file'",
" implies: 'fission_support'",
" implies: 'sysroot'",
"}",
"action_config {",
" config_name: 'c++-link-static-library'",
" action_name: 'c++-link-static-library'",
" tool {",
" tool_path: '" + arToolPath + "'",
" }",
" implies: 'archiver_flags'",
" implies: 'libraries_to_link'",
" implies: 'linker_param_file'",
"}",
"action_config {",
" config_name: 'c++-link-alwayslink-static-library'",
" action_name: 'c++-link-alwayslink-static-library'",
" tool {",
" tool_path: '" + arToolPath + "'",
" }",
" implies: 'archiver_flags'",
" implies: 'libraries_to_link'",
" implies: 'linker_param_file'",
"}",
"action_config {",
" config_name: 'c++-link-pic-static-library'",
" action_name: 'c++-link-pic-static-library'",
" tool {",
" tool_path: '" + arToolPath + "'",
" }",
" implies: 'archiver_flags'",
" implies: 'libraries_to_link'",
" implies: 'linker_param_file'",
"}",
"action_config {",
" config_name: 'c++-link-alwayslink-pic-static-library'",
" action_name: 'c++-link-alwayslink-pic-static-library'",
" tool {",
" tool_path: '" + arToolPath + "'",
" }",
" implies: 'archiver_flags'",
" implies: 'libraries_to_link'",
" implies: 'linker_param_file'",
"}",
ifTrue(
supportsInterfaceSharedLibraries,
"feature {",
" name: 'build_interface_libraries'",
" flag_set {",
" expand_if_all_available: 'generate_interface_library'",
" action: 'c++-link-dynamic-library'",
" flag_group {",
" 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.
cppDynamicLibraryLinkerTool),
ifTrue(
!existingFeatureNames.contains("symbol_counts"),
"feature {",
" name: 'symbol_counts'",
" flag_set {",
" expand_if_all_available: 'symbol_counts_output'",
" action: 'c++-link-executable'",
" action: 'c++-link-dynamic-library'",
" flag_group {",
" flag: '-Wl,--print-symbol-counts=%{symbol_counts_output}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("shared_flag"),
"feature {",
" name: 'shared_flag'",
" flag_set {",
" action: 'c++-link-dynamic-library'",
" flag_group {",
" flag: '-shared'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("linkstamps"),
"feature {",
" name: 'linkstamps'",
" flag_set {",
" action: 'c++-link-executable'",
" action: 'c++-link-dynamic-library'",
" expand_if_all_available: 'linkstamp_paths'",
" flag_group {",
" iterate_over: 'linkstamp_paths'",
" flag: '%{linkstamp_paths}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("output_execpath_flags"),
"feature {",
" name: 'output_execpath_flags'",
" flag_set {",
" expand_if_all_available: 'output_execpath'",
" action: 'c++-link-dynamic-library'",
" action: 'c++-link-executable'",
" flag_group {",
" flag: '-o'",
" flag: '%{output_execpath}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("runtime_library_search_directories"),
"feature {",
" name: 'runtime_library_search_directories',",
" flag_set {",
" expand_if_all_available: 'runtime_library_search_directories'",
" action: 'c++-link-executable'",
" action: 'c++-link-dynamic-library'",
" flag_group {",
" iterate_over: 'runtime_library_search_directories'",
" flag_group {",
// TODO(b/27153401): This should probably be @loader_path on osx.
ifTrue(
supportsEmbeddedRuntimes,
" expand_if_all_available: 'is_cc_test_link_action'",
" flag: ",
" '-Wl,-rpath,$EXEC_ORIGIN/%{runtime_library_search_directories}'",
" }",
" flag_group {",
" expand_if_all_available: 'is_not_cc_test_link_action'"),
" flag: '-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}'",
" }",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("library_search_directories"),
"feature {",
" name: 'library_search_directories'",
" flag_set {",
" expand_if_all_available: 'library_search_directories'",
" action: 'c++-link-executable'",
" action: 'c++-link-dynamic-library'",
" flag_group {",
" iterate_over: 'library_search_directories'",
" flag: '-L%{library_search_directories}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("archiver_flags"),
"feature {",
" name: 'archiver_flags'",
" flag_set {",
" expand_if_all_available: 'output_execpath'",
" action: 'c++-link-static-library'",
" action: 'c++-link-alwayslink-static-library'",
" action: 'c++-link-pic-static-library'",
" action: 'c++-link-alwayslink-pic-static-library'",
" flag_group {",
ifLinux(platform, "flag: 'rcsD'", "flag: '%{output_execpath}'"),
ifMac(
platform,
" flag: '-static'",
" flag: '-s'",
" flag: '-o'",
" flag: '%{output_execpath}'"),
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("libraries_to_link"),
"feature {",
" name: 'libraries_to_link'",
" flag_set {",
" expand_if_all_available: 'libraries_to_link'",
" action: 'c++-link-executable'",
" action: 'c++-link-dynamic-library'",
" action: 'c++-link-static-library'",
" action: 'c++-link-alwayslink-static-library'",
" action: 'c++-link-pic-static-library'",
" action: 'c++-link-alwayslink-pic-static-library'",
" flag_group {",
" 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'",
" }",
" }",
" flag_group {",
" expand_if_true: 'thinlto_param_file'",
" flag: '-Wl,@%{thinlto_param_file}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("force_pic_flags"),
"feature {",
" name: 'force_pic_flags'",
" flag_set {",
" expand_if_all_available: 'force_pic'",
" action: 'c++-link-executable'",
" flag_group {",
" flag: '-pie'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("legacy_link_flags"),
"feature {",
" name: 'legacy_link_flags'",
" flag_set {",
" expand_if_all_available: 'legacy_link_flags'",
" action: 'c++-link-executable'",
" action: 'c++-link-dynamic-library'",
" flag_group {",
" iterate_over: 'legacy_link_flags'",
" flag: '%{legacy_link_flags}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("fission_support"),
"feature {",
" name: 'fission_support'",
" flag_set {",
" action: 'c++-link-executable'",
" action: 'c++-link-dynamic-library'",
" action: 'c++-link-interface-dynamic-library'",
" flag_group {",
" expand_if_all_available: 'is_using_fission'",
" flag: '-Wl,--gdb-index'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("strip_debug_symbols"),
"feature {",
" name: 'strip_debug_symbols'",
" flag_set {",
" action: 'c++-link-executable'",
" action: 'c++-link-dynamic-library'",
" action: 'c++-link-interface-dynamic-library'",
" flag_group {",
" expand_if_all_available: 'strip_debug_symbols'",
" flag: '-Wl,-S'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains(CppRuleClasses.COVERAGE),
"feature {",
" name: 'coverage'",
"}",
"feature {",
" 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-interface-dynamic-library'",
" action: 'c++-link-dynamic-library'",
" action: 'c++-link-executable'",
" action: 'objc-executable'",
" action: 'objc++-executable'",
" flag_group {",
" flag: '-fprofile-instr-generate'",
" }",
" }",
" requires {",
" feature: 'coverage'",
" }",
"}",
"feature {",
" 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-interface-dynamic-library'",
" action: 'c++-link-dynamic-library'",
" action: 'c++-link-executable'",
" flag_group {",
" flag: '-lgcov'",
" }",
" }",
" requires {",
" feature: 'coverage'",
" }",
"}"),
"action_config {",
" 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}'",
" }",
" 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}'",
" }",
" }",
"}"));
}
public static String getFeaturesToAppearLastInToolchain(
ImmutableSet<String> existingFeatureNames) {
return Joiner.on("\n")
.join(
ImmutableList.of(
ifTrue(
!existingFeatureNames.contains("user_compile_flags"),
"feature {",
" name: 'user_compile_flags'",
" enabled: true",
" flag_set {",
" expand_if_all_available: 'user_compile_flags'",
" action: 'assemble'",
" action: 'preprocess-assemble'",
" action: 'linkstamp-compile'",
" action: 'c-compile'",
" action: 'c++-compile'",
" action: 'c++-header-parsing'",
" action: 'c++-header-preprocessing'",
" action: 'c++-module-compile'",
" action: 'c++-module-codegen'",
" action: 'lto-backend'",
" action: 'clif-match'",
" flag_group {",
" iterate_over: 'user_compile_flags'",
" flag: '%{user_compile_flags}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("sysroot"),
"feature {",
" name: 'sysroot'",
" enabled: true",
" flag_set {",
" action: 'preprocess-assemble'",
" action: 'linkstamp-compile'",
" action: 'c-compile'",
" action: 'c++-compile'",
" action: 'c++-header-parsing'",
" action: 'c++-header-preprocessing'",
" action: 'c++-module-compile'",
" action: 'c++-link-executable'",
" action: 'c++-link-dynamic-library'",
" 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.
ifTrue(
!existingFeatureNames.contains("unfiltered_compile_flags"),
"feature {",
" name: 'unfiltered_compile_flags'",
" enabled: true",
" flag_set {",
" expand_if_all_available: 'unfiltered_compile_flags'",
" action: 'assemble'",
" action: 'preprocess-assemble'",
" action: 'linkstamp-compile'",
" action: 'c-compile'",
" action: 'c++-compile'",
" action: 'c++-header-parsing'",
" action: 'c++-header-preprocessing'",
" action: 'c++-module-compile'",
" action: 'c++-module-codegen'",
" action: 'lto-backend'",
" action: 'clif-match'",
" flag_group {",
" iterate_over: 'unfiltered_compile_flags'",
" flag: '%{unfiltered_compile_flags}'",
" }",
" }",
"}"),
ifTrue(
!existingFeatureNames.contains("linker_param_file"),
"feature {",
" name: 'linker_param_file'",
" flag_set {",
" expand_if_all_available: 'linker_param_file'",
" action: 'c++-link-executable'",
" action: 'c++-link-dynamic-library'",
" flag_group {",
" flag: '-Wl,@%{linker_param_file}'",
" }",
" }",
" flag_set {",
" expand_if_all_available: 'linker_param_file'",
" action: 'c++-link-static-library'",
" action: 'c++-link-alwayslink-static-library'",
" action: 'c++-link-pic-static-library'",
" action: 'c++-link-alwayslink-pic-static-library'",
" flag_group {",
" flag: '@%{linker_param_file}'",
" }",
" }",
"}")));
}
private static String ifLinux(CppPlatform platform, String... lines) {
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 "";
}
}
}