// Copyright 2016 Google Inc. 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 cc

import (
	"path/filepath"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"

	"android/soong/android"
	"android/soong/bazel"
)

type BinaryLinkerProperties struct {
	// compile executable with -static
	Static_executable *bool `android:"arch_variant"`

	// set the name of the output
	Stem *string `android:"arch_variant"`

	// append to the name of the output
	Suffix *string `android:"arch_variant"`

	// if set, add an extra objcopy --prefix-symbols= step
	Prefix_symbols *string

	// if set, install a symlink to the preferred architecture
	Symlink_preferred_arch *bool `android:"arch_variant"`

	// install symlinks to the binary.  Symlink names will have the suffix and the binary
	// extension (if any) appended
	Symlinks []string `android:"arch_variant"`

	// override the dynamic linker
	DynamicLinker string `blueprint:"mutated"`

	// Names of modules to be overridden. Listed modules can only be other binaries
	// (in Make or Soong).
	// This does not completely prevent installation of the overridden binaries, but if both
	// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
	// from PRODUCT_PACKAGES.
	Overrides []string

	// Inject boringssl hash into the shared library.  This is only intended for use by external/boringssl.
	Inject_bssl_hash *bool `android:"arch_variant"`
}

func init() {
	RegisterBinaryBuildComponents(android.InitRegistrationContext)
}

func RegisterBinaryBuildComponents(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("cc_binary", BinaryFactory)
	ctx.RegisterModuleType("cc_binary_host", BinaryHostFactory)
}

// cc_binary produces a binary that is runnable on a device.
func BinaryFactory() android.Module {
	module, _ := newBinary(android.HostAndDeviceSupported, true)
	return module.Init()
}

// cc_binary_host produces a binary that is runnable on a host.
func BinaryHostFactory() android.Module {
	module, _ := newBinary(android.HostSupported, true)
	module.bazelable = true
	return module.Init()
}

//
// Executables
//

// binaryDecorator is a decorator containing information for C++ binary modules.
type binaryDecorator struct {
	*baseLinker
	*baseInstaller
	stripper Stripper

	Properties BinaryLinkerProperties

	toolPath android.OptionalPath

	// Location of the linked, unstripped binary
	unstrippedOutputFile android.Path

	// Names of symlinks to be installed for use in LOCAL_MODULE_SYMLINKS
	symlinks []string

	// If the module has symlink_preferred_arch set, the name of the symlink to the
	// binary for the preferred arch.
	preferredArchSymlink string

	// Output archive of gcno coverage information
	coverageOutputFile android.OptionalPath

	// Location of the files that should be copied to dist dir when requested
	distFiles android.TaggedDistFiles

	// Action command lines to run directly after the binary is installed. For example,
	// may be used to symlink runtime dependencies (such as bionic) alongside installation.
	postInstallCmds []string
}

var _ linker = (*binaryDecorator)(nil)

// linkerProps returns the list of individual properties objects relevant
// for this binary.
func (binary *binaryDecorator) linkerProps() []interface{} {
	return append(binary.baseLinker.linkerProps(),
		&binary.Properties,
		&binary.stripper.StripProperties)

}

// getStemWithoutSuffix returns the main section of the name to use for the symlink of
// the main output file of this binary module. This may be derived from the module name
// or other property overrides.
// For the full symlink name, the `Suffix` property of a binary module must be appended.
func (binary *binaryDecorator) getStemWithoutSuffix(ctx BaseModuleContext) string {
	stem := ctx.baseModuleName()
	if String(binary.Properties.Stem) != "" {
		stem = String(binary.Properties.Stem)
	}

	return stem
}

// getStem returns the full name to use for the symlink of the main output file of this binary
// module. This may be derived from the module name and/or other property overrides.
func (binary *binaryDecorator) getStem(ctx BaseModuleContext) string {
	return binary.getStemWithoutSuffix(ctx) + String(binary.Properties.Suffix)
}

// linkerDeps augments and returns the given `deps` to contain dependencies on
// modules common to most binaries, such as bionic libraries.
func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
	deps = binary.baseLinker.linkerDeps(ctx, deps)
	if !Bool(binary.baseLinker.Properties.Nocrt) {
		if binary.static() {
			deps.CrtBegin = ctx.toolchain().CrtBeginStaticBinary()
			deps.CrtEnd = ctx.toolchain().CrtEndStaticBinary()
		} else {
			deps.CrtBegin = ctx.toolchain().CrtBeginSharedBinary()
			deps.CrtEnd = ctx.toolchain().CrtEndSharedBinary()
		}
	}

	if binary.static() {
		deps.StaticLibs = append(deps.StaticLibs, deps.SystemSharedLibs...)
	}

	if ctx.toolchain().Bionic() {
		if binary.static() {
			if ctx.selectedStl() == "libc++_static" {
				deps.StaticLibs = append(deps.StaticLibs, "libm", "libc")
			}
			// static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
			// --start-group/--end-group along with libgcc.  If they are in deps.StaticLibs,
			// move them to the beginning of deps.LateStaticLibs
			var groupLibs []string
			deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
				[]string{"libc", "libc_nomalloc", "libcompiler_rt"})
			deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
		}

		if ctx.Os() == android.LinuxBionic && !binary.static() {
			deps.DynamicLinker = "linker"
		}
	}

	if !binary.static() && inList("libc", deps.StaticLibs) && !ctx.BazelConversionMode() {
		ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
			"from static libs or set static_executable: true")
	}

	return deps
}

// NewBinary builds and returns a new Module corresponding to a C++ binary.
// Individual module implementations which comprise a C++ binary should call this function,
// set some fields on the result, and then call the Init function.
func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
	return newBinary(hod, true)
}

func newBinary(hod android.HostOrDeviceSupported, bazelable bool) (*Module, *binaryDecorator) {
	module := newModule(hod, android.MultilibFirst)
	binary := &binaryDecorator{
		baseLinker:    NewBaseLinker(module.sanitize),
		baseInstaller: NewBaseInstaller("bin", "", InstallInSystem),
	}
	module.compiler = NewBaseCompiler()
	module.linker = binary
	module.installer = binary
	module.bazelable = bazelable

	// Allow module to be added as member of an sdk/module_exports.
	module.sdkMemberTypes = []android.SdkMemberType{
		ccBinarySdkMemberType,
	}
	return module, binary
}

// linkerInit initializes dynamic properties of the linker (such as runpath) based
// on properties of this binary.
func (binary *binaryDecorator) linkerInit(ctx BaseModuleContext) {
	binary.baseLinker.linkerInit(ctx)

	if !ctx.toolchain().Bionic() && !ctx.toolchain().Musl() {
		if ctx.Os() == android.Linux {
			// Unless explicitly specified otherwise, host static binaries are built with -static
			// if HostStaticBinaries is true for the product configuration.
			if binary.Properties.Static_executable == nil && ctx.Config().HostStaticBinaries() {
				binary.Properties.Static_executable = BoolPtr(true)
			}
		} else {
			// Static executables are not supported on Darwin or Windows
			binary.Properties.Static_executable = nil
		}
	}
}

func (binary *binaryDecorator) static() bool {
	return Bool(binary.Properties.Static_executable)
}

func (binary *binaryDecorator) staticBinary() bool {
	return binary.static()
}

func (binary *binaryDecorator) binary() bool {
	return true
}

// linkerFlags returns a Flags object containing linker flags that are defined
// by this binary, or that are implied by attributes of this binary. These flags are
// combined with the given flags.
func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
	flags = binary.baseLinker.linkerFlags(ctx, flags)

	// Passing -pie to clang for Windows binaries causes a warning that -pie is unused.
	if ctx.Host() && !ctx.Windows() && !binary.static() {
		if !ctx.Config().IsEnvTrue("DISABLE_HOST_PIE") {
			flags.Global.LdFlags = append(flags.Global.LdFlags, "-pie")
		}
	}

	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
	// all code is position independent, and then those warnings get promoted to
	// errors.
	if !ctx.Windows() {
		flags.Global.CFlags = append(flags.Global.CFlags, "-fPIE")
	}

	if ctx.toolchain().Bionic() {
		if binary.static() {
			// Clang driver needs -static to create static executable.
			// However, bionic/linker uses -shared to overwrite.
			// Linker for x86 targets does not allow coexistance of -static and -shared,
			// so we add -static only if -shared is not used.
			if !inList("-shared", flags.Local.LdFlags) {
				flags.Global.LdFlags = append(flags.Global.LdFlags, "-static")
			}

			flags.Global.LdFlags = append(flags.Global.LdFlags,
				"-nostdlib",
				"-Bstatic",
				"-Wl,--gc-sections",
			)
		} else { // not static
			if flags.DynamicLinker == "" {
				if binary.Properties.DynamicLinker != "" {
					flags.DynamicLinker = binary.Properties.DynamicLinker
				} else {
					switch ctx.Os() {
					case android.Android:
						if ctx.bootstrap() && !ctx.inRecovery() && !ctx.inRamdisk() && !ctx.inVendorRamdisk() {
							flags.DynamicLinker = "/system/bin/bootstrap/linker"
						} else {
							flags.DynamicLinker = "/system/bin/linker"
						}
						if flags.Toolchain.Is64Bit() {
							flags.DynamicLinker += "64"
						}
					case android.LinuxBionic:
						flags.DynamicLinker = ""
					default:
						ctx.ModuleErrorf("unknown dynamic linker")
					}
				}

				if ctx.Os() == android.LinuxBionic {
					// Use the dlwrap entry point, but keep _start around so
					// that it can be used by host_bionic_inject
					flags.Global.LdFlags = append(flags.Global.LdFlags,
						"-Wl,--entry=__dlwrap__start",
						"-Wl,--undefined=_start",
					)
				}
			}

			flags.Global.LdFlags = append(flags.Global.LdFlags,
				"-pie",
				"-nostdlib",
				"-Bdynamic",
				"-Wl,--gc-sections",
				"-Wl,-z,nocopyreloc",
			)
		}
	} else { // not bionic
		if binary.static() {
			flags.Global.LdFlags = append(flags.Global.LdFlags, "-static")
		}
		if ctx.Darwin() {
			flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-headerpad_max_install_names")
		}
	}

	return flags
}

// link registers actions to link this binary, and sets various fields
// on this binary to reflect information that should be exported up the build
// tree (for example, exported flags and include paths).
func (binary *binaryDecorator) link(ctx ModuleContext,
	flags Flags, deps PathDeps, objs Objects) android.Path {

	fileName := binary.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
	outputFile := android.PathForModuleOut(ctx, fileName)
	ret := outputFile

	var linkerDeps android.Paths

	if flags.DynamicLinker != "" {
		flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-dynamic-linker,"+flags.DynamicLinker)
	} else if (ctx.toolchain().Bionic() || ctx.toolchain().Musl()) && !binary.static() {
		flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-dynamic-linker")
	}

	if ctx.Darwin() && deps.DarwinSecondArchOutput.Valid() {
		fatOutputFile := outputFile
		outputFile = android.PathForModuleOut(ctx, "pre-fat", fileName)
		transformDarwinUniversalBinary(ctx, fatOutputFile, outputFile, deps.DarwinSecondArchOutput.Path())
	}

	builderFlags := flagsToBuilderFlags(flags)
	stripFlags := flagsToStripFlags(flags)
	if binary.stripper.NeedsStrip(ctx) {
		if ctx.Darwin() {
			stripFlags.StripUseGnuStrip = true
		}
		strippedOutputFile := outputFile
		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
		binary.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, stripFlags)
	}

	binary.unstrippedOutputFile = outputFile

	if String(binary.Properties.Prefix_symbols) != "" {
		afterPrefixSymbols := outputFile
		outputFile = android.PathForModuleOut(ctx, "unprefixed", fileName)
		transformBinaryPrefixSymbols(ctx, String(binary.Properties.Prefix_symbols), outputFile,
			builderFlags, afterPrefixSymbols)
	}

	outputFile = maybeInjectBoringSSLHash(ctx, outputFile, binary.Properties.Inject_bssl_hash, fileName)

	// If use_version_lib is true, make an android::build::GetBuildNumber() function available.
	if Bool(binary.baseLinker.Properties.Use_version_lib) {
		if ctx.Host() {
			versionedOutputFile := outputFile
			outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
			binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
		} else {
			// When dist'ing a library or binary that has use_version_lib set, always
			// distribute the stamped version, even for the device.
			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
			binary.distFiles = android.MakeDefaultDistFiles(versionedOutputFile)

			if binary.stripper.NeedsStrip(ctx) {
				out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
				binary.distFiles = android.MakeDefaultDistFiles(out)
				binary.stripper.StripExecutableOrSharedLib(ctx, versionedOutputFile, out, stripFlags)
			}

			binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
		}
	}

	var validations android.Paths

	// Handle host bionic linker symbols.
	if ctx.Os() == android.LinuxBionic && !binary.static() {
		verifyFile := android.PathForModuleOut(ctx, "host_bionic_verify.stamp")

		if !deps.DynamicLinker.Valid() {
			panic("Non-static host bionic modules must have a dynamic linker")
		}

		binary.verifyHostBionicLinker(ctx, outputFile, deps.DynamicLinker.Path(), verifyFile)
		validations = append(validations, verifyFile)
	}

	var sharedLibs android.Paths
	// Ignore shared libs for static executables.
	if !binary.static() {
		sharedLibs = deps.EarlySharedLibs
		sharedLibs = append(sharedLibs, deps.SharedLibs...)
		sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
		linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
		linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
		linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
		linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...)
	}

	validations = append(validations, objs.tidyDepFiles...)
	linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)

	// Register link action.
	transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs,
		deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
		builderFlags, outputFile, nil, validations)

	objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
	objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
	binary.coverageOutputFile = transformCoverageFilesToZip(ctx, objs, binary.getStem(ctx))

	// Need to determine symlinks early since some targets (ie APEX) need this
	// information but will not call 'install'
	for _, symlink := range binary.Properties.Symlinks {
		binary.symlinks = append(binary.symlinks,
			symlink+String(binary.Properties.Suffix)+ctx.toolchain().ExecutableSuffix())
	}

	if Bool(binary.Properties.Symlink_preferred_arch) {
		if String(binary.Properties.Suffix) == "" {
			ctx.PropertyErrorf("symlink_preferred_arch", "must also specify suffix")
		}
		if ctx.TargetPrimary() {
			// Install a symlink to the preferred architecture
			symlinkName := binary.getStemWithoutSuffix(ctx)
			binary.symlinks = append(binary.symlinks, symlinkName)
			binary.preferredArchSymlink = symlinkName
		}
	}

	return ret
}

func (binary *binaryDecorator) unstrippedOutputFilePath() android.Path {
	return binary.unstrippedOutputFile
}

func (binary *binaryDecorator) symlinkList() []string {
	return binary.symlinks
}

func (binary *binaryDecorator) nativeCoverage() bool {
	return true
}

func (binary *binaryDecorator) coverageOutputFilePath() android.OptionalPath {
	return binary.coverageOutputFile
}

// /system/bin/linker -> /apex/com.android.runtime/bin/linker
func (binary *binaryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) {
	dir := binary.baseInstaller.installDir(ctx)
	dirOnDevice := android.InstallPathToOnDevicePath(ctx, dir)
	target := "/" + filepath.Join("apex", "com.android.runtime", dir.Base(), file.Base())

	ctx.InstallAbsoluteSymlink(dir, file.Base(), target)
	binary.postInstallCmds = append(binary.postInstallCmds, makeSymlinkCmd(dirOnDevice, file.Base(), target))

	for _, symlink := range binary.symlinks {
		ctx.InstallAbsoluteSymlink(dir, symlink, target)
		binary.postInstallCmds = append(binary.postInstallCmds, makeSymlinkCmd(dirOnDevice, symlink, target))
	}
}

func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) {
	// Bionic binaries (e.g. linker) is installed to the bootstrap subdirectory.
	// The original path becomes a symlink to the corresponding file in the
	// runtime APEX.
	translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled
	if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !ctx.Host() && ctx.directlyInAnyApex() &&
		!translatedArch && ctx.apexVariationName() == "" && !ctx.inRamdisk() && !ctx.inRecovery() &&
		!ctx.inVendorRamdisk() {

		if ctx.Device() && isBionic(ctx.baseModuleName()) {
			binary.installSymlinkToRuntimeApex(ctx, file)
		}
		binary.baseInstaller.subDir = "bootstrap"
	}
	binary.baseInstaller.install(ctx, file)

	var preferredArchSymlinkPath android.OptionalPath
	for _, symlink := range binary.symlinks {
		installedSymlink := ctx.InstallSymlink(binary.baseInstaller.installDir(ctx), symlink,
			binary.baseInstaller.path)
		if symlink == binary.preferredArchSymlink {
			// If this is the preferred arch symlink, save the installed path for use as the
			// tool path.
			preferredArchSymlinkPath = android.OptionalPathForPath(installedSymlink)
		}
	}

	if ctx.Os().Class == android.Host {
		// If the binary is multilib with a symlink to the preferred architecture, use the
		// symlink instead of the binary because that's the more "canonical" name.
		if preferredArchSymlinkPath.Valid() {
			binary.toolPath = preferredArchSymlinkPath
		} else {
			binary.toolPath = android.OptionalPathForPath(binary.baseInstaller.path)
		}
	}
}

func (binary *binaryDecorator) hostToolPath() android.OptionalPath {
	return binary.toolPath
}

func init() {
	pctx.HostBinToolVariable("verifyHostBionicCmd", "host_bionic_verify")
}

var verifyHostBionic = pctx.AndroidStaticRule("verifyHostBionic",
	blueprint.RuleParams{
		Command:     "$verifyHostBionicCmd -i $in -l $linker && touch $out",
		CommandDeps: []string{"$verifyHostBionicCmd"},
	}, "linker")

func (binary *binaryDecorator) verifyHostBionicLinker(ctx ModuleContext, in, linker android.Path, out android.WritablePath) {
	ctx.Build(pctx, android.BuildParams{
		Rule:        verifyHostBionic,
		Description: "verify host bionic",
		Input:       in,
		Implicit:    linker,
		Output:      out,
		Args: map[string]string{
			"linker": linker.String(),
		},
	})
}

func binaryBp2build(ctx android.TopDownMutatorContext, m *Module, typ string) {
	baseAttrs := bp2BuildParseBaseProps(ctx, m)
	binaryLinkerAttrs := bp2buildBinaryLinkerProps(ctx, m)

	if proptools.BoolDefault(binaryLinkerAttrs.Linkshared, true) {
		baseAttrs.implementationDynamicDeps.Add(baseAttrs.protoDependency)
	} else {
		baseAttrs.implementationDeps.Add(baseAttrs.protoDependency)
	}

	attrs := &binaryAttributes{
		binaryLinkerAttrs: binaryLinkerAttrs,

		Srcs:    baseAttrs.srcs,
		Srcs_c:  baseAttrs.cSrcs,
		Srcs_as: baseAttrs.asSrcs,

		Copts:      baseAttrs.copts,
		Cppflags:   baseAttrs.cppFlags,
		Conlyflags: baseAttrs.conlyFlags,
		Asflags:    baseAttrs.asFlags,

		Deps:               baseAttrs.implementationDeps,
		Dynamic_deps:       baseAttrs.implementationDynamicDeps,
		Whole_archive_deps: baseAttrs.wholeArchiveDeps,
		System_deps:        baseAttrs.systemDynamicDeps,

		Local_includes:    baseAttrs.localIncludes,
		Absolute_includes: baseAttrs.absoluteIncludes,
		Linkopts:          baseAttrs.linkopts,
		Link_crt:          baseAttrs.linkCrt,
		Use_libcrt:        baseAttrs.useLibcrt,
		Rtti:              baseAttrs.rtti,
		Stl:               baseAttrs.stl,
		Cpp_std:           baseAttrs.cppStd,

		Additional_linker_inputs: baseAttrs.additionalLinkerInputs,

		Strip: stripAttributes{
			Keep_symbols:                 baseAttrs.stripKeepSymbols,
			Keep_symbols_and_debug_frame: baseAttrs.stripKeepSymbolsAndDebugFrame,
			Keep_symbols_list:            baseAttrs.stripKeepSymbolsList,
			All:                          baseAttrs.stripAll,
			None:                         baseAttrs.stripNone,
		},

		Features: baseAttrs.features,
	}

	var enabledProperty bazel.BoolAttribute
	if typ == "cc_binary_host" {
		falseVal := false
		enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, android.Android.Name, &falseVal)
	}

	ctx.CreateBazelTargetModuleWithRestrictions(bazel.BazelTargetModuleProperties{
		Rule_class:        "cc_binary",
		Bzl_load_location: "//build/bazel/rules:cc_binary.bzl",
	},
		android.CommonAttributes{Name: m.Name()},
		attrs,
		enabledProperty)
}

// binaryAttributes contains Bazel attributes corresponding to a cc binary
type binaryAttributes struct {
	binaryLinkerAttrs
	Srcs    bazel.LabelListAttribute
	Srcs_c  bazel.LabelListAttribute
	Srcs_as bazel.LabelListAttribute

	Copts      bazel.StringListAttribute
	Cppflags   bazel.StringListAttribute
	Conlyflags bazel.StringListAttribute
	Asflags    bazel.StringListAttribute

	Deps               bazel.LabelListAttribute
	Dynamic_deps       bazel.LabelListAttribute
	Whole_archive_deps bazel.LabelListAttribute
	System_deps        bazel.LabelListAttribute

	Local_includes    bazel.StringListAttribute
	Absolute_includes bazel.StringListAttribute

	Linkopts                 bazel.StringListAttribute
	Additional_linker_inputs bazel.LabelListAttribute

	Link_crt   bazel.BoolAttribute
	Use_libcrt bazel.BoolAttribute

	Rtti    bazel.BoolAttribute
	Stl     *string
	Cpp_std *string

	Strip stripAttributes

	Features bazel.StringListAttribute
}
