// 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. package com.google.devtools.build.lib.skylarkbuildapi.cpp; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.skylark.SkylarkRuleContext; import com.google.devtools.build.lib.skylarkbuildapi.ProviderApi; import com.google.devtools.build.lib.skylarkbuildapi.SkylarkRuleContextApi; import com.google.devtools.build.lib.skylarkinterface.Param; import com.google.devtools.build.lib.skylarkinterface.ParamType; import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Runtime.NoneType; import com.google.devtools.build.lib.syntax.SkylarkDict; import com.google.devtools.build.lib.syntax.SkylarkList; import com.google.devtools.build.lib.syntax.SkylarkNestedSet; /** Utilites related to C++ support. */ @SkylarkModule( name = "cc_common", doc = "Utilities for C++ compilation, linking, and command line " + "generation.") public interface CcModuleApi< CcToolchainProviderT extends CcToolchainProviderApi, FeatureConfigurationT extends FeatureConfigurationApi, CcToolchainVariablesT extends CcToolchainVariablesApi, LibraryToLinkT extends LibraryToLinkApi, CcLinkParamsT extends CcLinkParamsApi, CcSkylarkInfoT extends CcSkylarkInfoApi> { @SkylarkCallable( name = "CcToolchainInfo", doc = "The key used to retrieve the provider that contains information about the C++ " + "toolchain being usCced", structField = true) ProviderApi getCcToolchainProvider(); @Deprecated @SkylarkCallable( name = "do_not_use_tools_cpp_compiler_present", doc = "Do not use this field, its only puprose is to help with migration from " + "config_setting.values{'compiler') to " + "config_settings.flag_values{'@bazel_tools//tools/cpp:compiler'}", structField = true) default void compilerFlagExists() {} @SkylarkCallable( name = "configure_features", doc = "Creates a feature_configuration instance.", parameters = { @Param( name = "cc_toolchain", doc = "cc_toolchain for which we configure features.", positional = false, named = true, type = CcToolchainProviderApi.class), @Param( name = "requested_features", doc = "List of features to be enabled.", positional = false, named = true, defaultValue = "[]", type = SkylarkList.class), @Param( name = "unsupported_features", doc = "List of features that are unsupported by the current rule.", positional = false, named = true, defaultValue = "[]", type = SkylarkList.class), }) FeatureConfigurationT configureFeatures( CcToolchainProviderT toolchain, SkylarkList requestedFeatures, SkylarkList unsupportedFeatures) throws EvalException; @SkylarkCallable( name = "get_tool_for_action", doc = "Returns tool path for given action.", parameters = { @Param( name = "feature_configuration", doc = "Feature configuration to be queried.", positional = false, named = true, type = FeatureConfigurationApi.class), @Param( name = "action_name", doc = "Name of the action. Has to be one of the names in " + "@bazel_tools//tools/build_defs/cc:action_names.bzl.", named = true, positional = false), }) String getToolForAction(FeatureConfigurationT featureConfiguration, String actionName); @SkylarkCallable( name = "is_enabled", doc = "Returns True if given feature is enabled in the feature configuration.", parameters = { @Param( name = "feature_configuration", doc = "Feature configuration to be queried.", positional = false, named = true, type = FeatureConfigurationApi.class), @Param( name = "feature_name", doc = "Name of the feature.", named = true, positional = false), }) boolean isEnabled(FeatureConfigurationT featureConfiguration, String featureName); @SkylarkCallable( name = "get_memory_inefficient_command_line", doc = "Returns flattened command line flags for given action, using given variables for " + "expansion. Flattens nested sets and ideally should not be used, or at least " + "should not outlive analysis. Work on memory efficient function returning Args is " + "ongoing.", parameters = { @Param( name = "feature_configuration", doc = "Feature configuration to be queried.", positional = false, named = true, type = FeatureConfigurationApi.class), @Param( name = "action_name", doc = "Name of the action. Has to be one of the names in " + "@bazel_tools//tools/build_defs/cc:action_names.bzl.", named = true, positional = false), @Param( name = "variables", doc = "Build variables to be used for template expansions.", named = true, positional = false, type = CcToolchainVariablesApi.class), }) SkylarkList getCommandLine( FeatureConfigurationT featureConfiguration, String actionName, CcToolchainVariablesT variables); @SkylarkCallable( name = "get_environment_variables", doc = "Returns environment variables to be set for given action.", parameters = { @Param( name = "feature_configuration", doc = "Feature configuration to be queried.", positional = false, named = true, type = FeatureConfigurationApi.class), @Param( name = "action_name", doc = "Name of the action. Has to be one of the names in " + "@bazel_tools//tools/build_defs/cc:action_names.bzl.", named = true, positional = false), @Param( name = "variables", doc = "Build variables to be used for template expansion.", positional = false, named = true, type = CcToolchainVariablesApi.class), }) SkylarkDict getEnvironmentVariable( FeatureConfigurationT featureConfiguration, String actionName, CcToolchainVariablesT variables); @SkylarkCallable( name = "create_compile_variables", doc = "Returns variables used for compilation actions.", parameters = { @Param( name = "cc_toolchain", doc = "cc_toolchain for which we are creating build variables.", positional = false, named = true, type = CcToolchainProviderApi.class), @Param( name = "feature_configuration", doc = "Feature configuration to be queried.", positional = false, named = true, type = FeatureConfigurationApi.class), @Param( name = "source_file", doc = "Optional source file for the compilation. Please prefer passing source_file here " + "over appending it to the end of the command line generated from " + "cc_common.get_memory_inefficient_command_line, as then it's in the power of " + "the toolchain author to properly specify and position compiler flags.", named = true, positional = false, defaultValue = "None", noneable = true), @Param( name = "output_file", doc = "Optional output file of the compilation. Please prefer passing output_file here " + "over appending it to the end of the command line generated from " + "cc_common.get_memory_inefficient_command_line, as then it's in the power of " + "the toolchain author to properly specify and position compiler flags.", named = true, positional = false, defaultValue = "None", noneable = true), @Param( name = "user_compile_flags", doc = "Depset of additional compilation flags (copts).", positional = false, named = true, defaultValue = "None", noneable = true, allowedTypes = { @ParamType(type = NoneType.class), @ParamType(type = SkylarkNestedSet.class) }), @Param( name = "include_directories", doc = "Depset of include directories.", positional = false, named = true, defaultValue = "None", noneable = true, allowedTypes = { @ParamType(type = NoneType.class), @ParamType(type = SkylarkNestedSet.class) }), @Param( name = "quote_include_directories", doc = "Depset of quote include directories.", positional = false, named = true, defaultValue = "None", noneable = true, allowedTypes = { @ParamType(type = NoneType.class), @ParamType(type = SkylarkNestedSet.class) }), @Param( name = "system_include_directories", doc = "Depset of system include directories.", positional = false, named = true, defaultValue = "None", noneable = true, allowedTypes = { @ParamType(type = NoneType.class), @ParamType(type = SkylarkNestedSet.class) }), @Param( name = "preprocessor_defines", doc = "Depset of preprocessor defines.", positional = false, named = true, defaultValue = "None", noneable = true, allowedTypes = { @ParamType(type = NoneType.class), @ParamType(type = SkylarkNestedSet.class) }), @Param( name = "use_pic", doc = "When true the compilation will generate position independent code.", positional = false, named = true, defaultValue = "False"), // TODO(b/65151735): Remove once we migrate crosstools to features @Param( name = "add_legacy_cxx_options", doc = "When true the flags will contain options coming from legacy cxx_flag crosstool " + "fields.", named = true, positional = false, defaultValue = "False") }) CcToolchainVariablesT getCompileBuildVariables( CcToolchainProviderT ccToolchainProvider, FeatureConfigurationT featureConfiguration, Object sourceFile, Object outputFile, Object userCompileFlags, Object includeDirs, Object quoteIncludeDirs, Object systemIncludeDirs, Object defines, boolean usePic, boolean addLegacyCxxOptions) throws EvalException; @SkylarkCallable( name = "create_link_variables", doc = "Returns link variables used for linking actions.", parameters = { @Param( name = "cc_toolchain", doc = "cc_toolchain for which we are creating build variables.", positional = false, named = true, type = CcToolchainProviderApi.class), @Param( name = "feature_configuration", doc = "Feature configuration to be queried.", positional = false, named = true, type = FeatureConfigurationApi.class), @Param( name = "library_search_directories", doc = "Depset of directories where linker will look for libraries at link time.", positional = false, named = true, defaultValue = "None", noneable = true, allowedTypes = { @ParamType(type = NoneType.class), @ParamType(type = SkylarkNestedSet.class) }), @Param( name = "runtime_library_search_directories", doc = "Depset of directories where loader will look for libraries at runtime.", positional = false, named = true, defaultValue = "None", noneable = true, allowedTypes = { @ParamType(type = NoneType.class), @ParamType(type = SkylarkNestedSet.class) }), @Param( name = "user_link_flags", doc = "Depset of additional link flags (linkopts).", positional = false, named = true, defaultValue = "None", noneable = true, allowedTypes = { @ParamType(type = NoneType.class), @ParamType(type = SkylarkNestedSet.class) }), @Param( name = "output_file", doc = "Optional output file path.", named = true, positional = false, defaultValue = "None", noneable = true), @Param( name = "param_file", doc = "Optional param file path.", named = true, positional = false, defaultValue = "None", noneable = true), @Param( name = "def_file", doc = "Optional .def file path.", named = true, positional = false, defaultValue = "None", noneable = true), // TODO(b/65151735): Remove once we migrate crosstools to features @Param( name = "is_using_linker", doc = "True when using linker, False when archiver. Caller is responsible for keeping " + "this in sync with action name used (is_using_linker = True for linking " + "executable or dynamic library, is_using_linker = False for archiving static " + "library).", named = true, positional = false, defaultValue = "True"), // TODO(b/65151735): Remove once we migrate crosstools to features @Param( name = "is_linking_dynamic_library", doc = "True when creating dynamic library, False when executable or static library. " + "Caller is responsible for keeping this in sync with action name used. " + "" + "This field will be removed once b/65151735 is fixed.", named = true, positional = false, defaultValue = "False"), // TODO(b/65151735): Remove once we migrate crosstools to features @Param( name = "must_keep_debug", doc = "When set to True, bazel will expose 'strip_debug_symbols' variable, which is " + "usually used to use the linker to strip debug symbols from the output file.", named = true, positional = false, defaultValue = "True"), // TODO(b/65151735): Remove once we migrate crosstools to features @Param( name = "use_test_only_flags", doc = "When set to True flags coming from test_only_linker_flag crosstool fields will" + " be included." + "" + "This field will be removed once b/65151735 is fixed.", named = true, positional = false, defaultValue = "False"), // TODO(b/65151735): Remove once we migrate crosstools to features @Param( name = "is_static_linking_mode", doc = "True when using static_linking_mode, False when using dynamic_linking_mode. " + "Caller is responsible for keeping this in sync with 'static_linking_mode' " + "and 'dynamic_linking_mode' features enabled on the feature configuration. " + "" + "This field will be removed once b/65151735 is fixed.", named = true, positional = false, defaultValue = "True"), }) CcToolchainVariablesT getLinkBuildVariables( CcToolchainProviderT ccToolchainProvider, FeatureConfigurationT featureConfiguration, Object librarySearchDirectories, Object runtimeLibrarySearchDirectories, Object userLinkFlags, Object outputFile, Object paramFile, Object defFile, boolean isUsingLinkerNotArchiver, boolean isCreatingSharedLibrary, boolean mustKeepDebug, boolean useTestOnlyFlags, boolean isStaticLinkingMode) throws EvalException; @SkylarkCallable(name = "empty_variables", documented = false) CcToolchainVariablesT getVariables(); @SkylarkCallable( name = "create_library_to_link", documented = false, parameters = { @Param( name = "ctx", doc = "Skylark rule context.", positional = false, named = true, type = SkylarkRuleContext.class), @Param( name = "library", doc = "Library to be linked.", positional = false, named = true, type = Artifact.class), @Param( name = "artifact_category", doc = "Artifact category. Can be: static_library, alwayslink_static_library, " + "dynamic_library or interface_library", positional = false, named = true, type = String.class) }) LibraryToLinkT createLibraryLinkerInput( SkylarkRuleContext skylarkRuleContext, Artifact library, String skylarkArtifactCategory) throws EvalException; @SkylarkCallable( name = "create_symlink_library_to_link", documented = false, parameters = { @Param( name = "ctx", doc = "Skylark rule context.", positional = false, named = true, type = SkylarkRuleContext.class), @Param( name = "cc_toolchain", doc = "C++ toolchain provider to be used.", positional = false, named = true, type = CcToolchainProviderApi.class), @Param( name = "library", doc = "Library that should be symlinked.", positional = false, named = true, type = Artifact.class), }) LibraryToLinkT createSymlinkLibraryLinkerInput( SkylarkRuleContext skylarkRuleContext, CcToolchainProviderT ccToolchain, Artifact library); @SkylarkCallable( name = "create_cc_link_params", doc = "Creates cc link parameters", parameters = { @Param( name = "ctx", positional = false, named = true, type = SkylarkRuleContextApi.class, doc = "The rule context."), @Param( name = "libraries_to_link", doc = "List of libraries that should be passed to the linker/archiver. They can be " + "static and/or dynamic libraries.", positional = false, named = true, noneable = true, defaultValue = "None", allowedTypes = { @ParamType(type = SkylarkNestedSet.class), @ParamType(type = NoneType.class) }), @Param( name = "dynamic_libraries_for_runtime", doc = "When 'libraries_to_link' has dynamic libraries, then the runtime library can " + "be specified as well. This is not obligatory though, as we may provide a " + "library for linking and at runtime the actual library will be provided by " + "the system.", positional = false, named = true, noneable = true, defaultValue = "None", allowedTypes = { @ParamType(type = SkylarkNestedSet.class), @ParamType(type = NoneType.class) }), @Param( name = "user_link_flags", doc = "List of user provided linker flags.", positional = false, named = true, noneable = true, defaultValue = "None", allowedTypes = { @ParamType(type = SkylarkNestedSet.class), @ParamType(type = NoneType.class) }) }) CcLinkParamsT createCcLinkParams( SkylarkRuleContext skylarkRuleContext, Object skylarkLibrariesToLink, Object skylarkDynamicLibrariesForRuntime, Object skylarkUserLinkFlags) throws EvalException; @SkylarkCallable( name = "create_cc_skylark_info", documented = false, parameters = { // TODO(plf): Make this parameter mandatory. Change cc_embed_data.bzl first. @Param( name = "ctx", doc = "Skylark rule context.", positional = false, named = true, noneable = true, defaultValue = "None", allowedTypes = { @ParamType(type = SkylarkRuleContextApi.class), @ParamType(type = NoneType.class) }) }) CcSkylarkInfoT createCcSkylarkInfo(Object skylarkRuleContextObject) throws EvalException; }