blob: a30d919eafd7620d9c904ac3b08bd065f729a2ab [file] [log] [blame]
// Copyright (C) 2015 The Android Open Source Project
//
// 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 cpp
import (
"strings"
"android.googlesource.com/platform/tools/gpu/build"
)
type misotool func(inputs build.FileSet, output build.File, cfg Config, env build.Environment) error
type sisotool func(input build.File, output build.File, cfg Config, env build.Environment) error
type depsFor func(output build.File, cfg Config, env build.Environment) (deps build.FileSet, valid bool)
type depFileFor func(output build.File, cfg Config, env build.Environment) build.File
// OptimisationLevel is an enumerator of optimisation levels to use by a toolchain.
type OptimizationLevel int
const (
NoOptimization = iota // Use to disable optimization. Useful for debugging.
FullOptimization // Full optimizations enabled. Fastest option.
)
// Toolchain is a collection of tools used to build objects, libraries and programs.
type Toolchain struct {
Compiler sisotool // Tool used to compile source to object files.
Archiver misotool // Tool used to package object files into archives.
DllLinker misotool // Tool used to link objects and packages into dynamic libraries.
ExeLinker misotool // Tool used to link objects and packages into executables.
DepFileFor depFileFor // Returns the name of the dependency file
DepsFor depsFor // Returns the list of dependencies for the given file.
LibName func(Config) string // Returns the name of the emitted static library file.
DllName func(Config) string // Returns the name of the emitted dynamic library file.
ExeName func(Config) string // Returns the name of the emitted executable.
ObjExt func(Config) string // Extension used for object files.
}
func (t Toolchain) LibExt(cfg Config) string {
return build.File(t.LibName(cfg)).Ext()
}
// Config is the configuration for a C++, C or Objective-C++ build.
type Config struct {
Name string // The name that may be mangled to produce the output file.
OutputExt *string // The output file extension. If nil, a toolchain default is used.
OutputDir build.File // The output directory
Toolchain *Toolchain // The toolchain used to build.
OptimizationLevel OptimizationLevel // The optimization level to use.
OS string // The target operating system, e.g. "windows".
Architecture string // The target architecture, e.g. "x64".
Flavor string // Flavor is used to separate different build configurations, e.g. "release".
Defines map[string]string // The list of defines used for compilation.
CompilerArgs []string // Custom complier flags.
ArchiverArgs []string // Custom archiver flags.
LinkerArgs []string // Custom linker flags.
Libraries build.FileSet // The list of libraries used by the linker.
LibrarySearchPaths build.FileSet // The list of library search paths.
IncludeSearchPaths build.FileSet // The list of include search paths.
AdditionalSources build.FileSet // Additional list of source files to compile.
Permissions []string // APK required permissions (NDK only).
ModuleDefinition build.File // An optional module definition file for dlls.
}
// Extend returns a new Config based on this Config, but with field added or
// replaced by any non-default fields of n.
func (c Config) Extend(n Config) Config {
if n.Name != "" {
c.Name = n.Name
}
if n.OutputExt != nil {
c.OutputExt = n.OutputExt
}
if n.OutputDir != "" {
c.OutputDir = n.OutputDir
}
if n.Toolchain != nil {
c.Toolchain = n.Toolchain
}
if n.OS != "" {
c.OS = n.OS
}
if n.Architecture != "" {
c.Architecture = n.Architecture
}
if n.Flavor != "" {
c.Flavor = n.Flavor
}
for n, v := range n.Defines {
c.Defines[n] = v
}
c.CompilerArgs = append(append([]string{}, c.CompilerArgs...), n.CompilerArgs...)
c.ArchiverArgs = append(append([]string{}, c.ArchiverArgs...), n.ArchiverArgs...)
c.LinkerArgs = append(append([]string{}, c.LinkerArgs...), n.LinkerArgs...)
c.Libraries = c.Libraries.Append(n.Libraries...)
c.LibrarySearchPaths = c.LibrarySearchPaths.Append(n.LibrarySearchPaths...)
c.IncludeSearchPaths = c.IncludeSearchPaths.Append(n.IncludeSearchPaths...)
c.AdditionalSources = c.AdditionalSources.Append(n.AdditionalSources...)
c.Permissions = append(append([]string{}, c.Permissions...), n.Permissions...)
if n.ModuleDefinition != "" {
c.ModuleDefinition = n.ModuleDefinition
}
return c
}
// Triplet returns a string combining the os, architecture and flavour of cfg.
func Triplet(cfg Config) string {
return strings.Join([]string{cfg.OS, cfg.Architecture, cfg.Flavor}, "-")
}
// IntermediatePath returns a File in the intermediate directory for generating
// a file built from source using cfg and env.
func IntermediatePath(source build.File, ext string, cfg Config, env build.Environment) build.File {
root := env.Roots.Find(source)
if root == nil {
root = &build.RepoRoot
}
rel := source.RelativeTo(root.Path)
rel = strings.Replace(rel, "..", "__", -1) // prevent leaking outside of the Intermediates directory
out := env.Intermediates.Join(Triplet(cfg), root.Name, rel).ChangeExt(ext)
return out
}