blob: dc96503ed17479391d7f385c7a36947878b0ea9c [file] [log] [blame]
# Copyright 2017 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.
"""Defines abstract build tools."""
import abc
class Tool(object):
"""A base class for all build tools.
Build tools are used to generate Ninja files.
"""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def IsPlatformAgnostic(self):
"""Whether an output of a tool depends on a platform.
Platform-agnostic tools are only processed once, even if they are provided
by both target and host toolchains.
"""
pass
@abc.abstractmethod
def GetRuleName(self):
"""Returns a name of a Ninja rule.
Used as a base name for several Ninja variables, such as path, flags, etc.
Returns:
None if a tool doesn't have a corresponding rule.
"""
pass
# TODO: Inline path in a command and get rid of this method.
@abc.abstractmethod
def GetPath(self):
"""Returns a full path to a tool.
Returns:
None if a tool doesn't have a corresponding rule.
"""
pass
# TODO: Inline extra flags in a command and get rid of this method.
@abc.abstractmethod
def GetExtraFlags(self):
"""Returns tool flags specific to a platform.
These flags are common for all tool invocations.
Returns:
None if a tool doesn't have a corresponding rule.
"""
pass
@abc.abstractmethod
def GetMaxConcurrentProcesses(self):
"""Restricts an amount of concurrently running tool instances.
See 'depth' at https://ninja-build.org/manual.html#ref_pool for details.
Returns:
None if a tool doesn't have a corresponding rule or doesn't restrict an
amount of concurrently running instances.
"""
pass
@abc.abstractmethod
def GetCommand(self, path, extra_flags, flags, shell):
"""Returns a command that invokes a tool.
See 'command' at https://ninja-build.org/manual.html#ref_rule for details.
Args:
path: A variable that contains a path to a tool.
extra_flags: A variable that contains tool flags specific to a platform.
flags: A variable that contains tool flags specific to a target.
shell: The shell that will be used to interpret the command.
Returns:
None if a tool doesn't have a corresponding rule.
"""
pass
@abc.abstractmethod
def GetDescription(self):
"""Returns a human-readable description of an action performed by a tool.
See 'description' at https://ninja-build.org/manual.html#ref_rule for
details.
Returns:
None if a tool doesn't have a corresponding rule.
"""
pass
@abc.abstractmethod
def GetHeaderDependenciesFilePath(self):
"""Returns a path to a Makefile that contains implicit dependencies.
See 'depfile' at https://ninja-build.org/manual.html#ref_rule for details.
Returns:
None if a tool doesn't generate implicit dependencies.
"""
pass
@abc.abstractmethod
def GetHeaderDependenciesFormat(self):
"""Specifies special dependency processing by Ninja.
See 'deps' at https://ninja-build.org/manual.html#ref_rule for details.
Returns:
None if a tool doesn't generate implicit dependencies.
"""
pass
@abc.abstractmethod
def GetRspFilePath(self):
"""Returns a full path to a response file.
See 'rspfile' at https://ninja-build.org/manual.html#ref_rule for details.
Returns:
None if a response file is not used.
"""
pass
@abc.abstractmethod
def GetRspFileContent(self):
"""Returns a content of a response file.
See 'rspfile_content' at https://ninja-build.org/manual.html#ref_rule for
details.
Returns:
None if a response file is not used.
"""
pass
class CCompiler(Tool):
"""Compiles C sources."""
def IsPlatformAgnostic(self):
return False
def GetRuleName(self):
return 'compile_c'
@abc.abstractmethod
def GetFlags(self, defines, include_dirs, cflags):
"""Returns tool flags specific to a target.
This method translates platform-agnostic concepts into a command line
arguments understood by a tool.
Args:
defines: A list of preprocessor defines in "NAME=VALUE" format.
include_dirs: A list of header search directories.
cflags: A list of GCC-style command-line flags. See
https://gcc.gnu.org/onlinedocs/gcc/Invoking-GCC.html#Invoking-GCC for
details.
Returns:
A list of unquoted strings, one for each flag. It is a responsibility of a
caller to quote flags that contain special characters (as determined by a
shell) before passing to a tool.
"""
pass
class CxxCompiler(Tool):
"""Compiles C++ sources."""
def IsPlatformAgnostic(self):
return False
def GetRuleName(self):
return 'compile_cxx'
@abc.abstractmethod
def GetFlags(self, defines, include_dirs, cflags):
"""Returns tool flags specific to a target.
This method translates platform-agnostic concepts into a command line
arguments understood by a tool.
Args:
defines: A list of preprocessor defines in "NAME=VALUE" format.
include_dirs: A list of header search directories.
cflags: A list of GCC-style command-line flags. See
https://gcc.gnu.org/onlinedocs/gcc/Invoking-GCC.html#Invoking-GCC for
details.
Returns:
A list of unquoted strings, one for each flag. It is a responsibility of a
caller to quote flags that contain special characters (as determined by a
shell) before passing to a tool.
"""
pass
class ObjectiveCxxCompiler(Tool):
"""Compiles Objective-C++ sources."""
def IsPlatformAgnostic(self):
return False
def GetRuleName(self):
return 'compile_objective_cxx'
@abc.abstractmethod
def GetFlags(self, defines, include_dirs, cflags):
"""Returns tool flags specific to a target.
This method translates platform-agnostic concepts into a command line
arguments understood by a tool.
Args:
defines: A list of preprocessor defines in "NAME=VALUE" format.
include_dirs: A list of header search directories.
cflags: A list of GCC-style command-line flags. See
https://gcc.gnu.org/onlinedocs/gcc/Invoking-GCC.html#Invoking-GCC for
details.
Returns:
A list of unquoted strings, one for each flag. It is a responsibility of a
caller to quote flags that contain special characters (as determined by a
shell) before passing to a tool.
"""
pass
class AssemblerWithCPreprocessor(Tool):
"""Compiles assembler sources that contain C preprocessor directives."""
def IsPlatformAgnostic(self):
return False
def GetRuleName(self):
return 'assemble'
@abc.abstractmethod
def GetFlags(self, defines, include_dirs, cflags):
"""Returns tool flags specific to a target.
This method translates platform-agnostic concepts into a command line
arguments understood by a tool.
Args:
defines: A list of preprocessor defines in "NAME=VALUE" format.
include_dirs: A list of header search directories.
cflags: A list of GCC-style command-line flags. See
https://gcc.gnu.org/onlinedocs/gcc/Invoking-GCC.html#Invoking-GCC for
details.
Returns:
A list of unquoted strings, one for each flag. It is a responsibility of a
caller to quote flags that contain special characters (as determined by a
shell) before passing to a tool.
"""
pass
class StaticLinker(Tool):
"""Creates self-contained archives."""
def IsPlatformAgnostic(self):
return False
def GetRuleName(self):
return 'link_static'
def GetHeaderDependenciesFilePath(self):
# Only applicable to C family compilers.
return None
def GetHeaderDependenciesFormat(self):
# Only applicable to C family compilers.
return None
class StaticThinLinker(Tool):
"""Creates thin archives using GNU ar."""
def IsPlatformAgnostic(self):
return False
def GetRuleName(self):
return 'link_static_thin'
def GetHeaderDependenciesFilePath(self):
# Only applicable to C family compilers.
return None
def GetHeaderDependenciesFormat(self):
# Only applicable to C family compilers.
return None
class ExecutableLinker(Tool):
"""Links executables."""
def IsPlatformAgnostic(self):
return False
def GetRuleName(self):
return 'link_executable'
def GetHeaderDependenciesFilePath(self):
# Only applicable to C family compilers.
return None
def GetHeaderDependenciesFormat(self):
# Only applicable to C family compilers.
return None
@abc.abstractmethod
def GetFlags(self, ldflags):
"""Returns tool flags specific to a target.
This method translates platform-agnostic concepts into a command line
arguments understood by a tool.
Args:
ldflags: A list of GCC-style command-line flags. See
https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options for
details.
Returns:
A list of unquoted strings, one for each flag. It is a responsibility of a
caller to quote flags that contain special characters (as determined by a
shell) before passing to a tool.
"""
pass
class SharedLibraryLinker(Tool):
"""Links shared libraries."""
def IsPlatformAgnostic(self):
return False
def GetRuleName(self):
return 'link_shared'
def GetHeaderDependenciesFilePath(self):
# Only applicable to C family compilers.
return None
def GetHeaderDependenciesFormat(self):
# Only applicable to C family compilers.
return None
@abc.abstractmethod
def GetFlags(self, ldflags):
"""Returns tool flags specific to a target.
This method translates platform-agnostic concepts into a command line
arguments understood by a tool.
Args:
ldflags: A list of GCC-style command-line flags. See
https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options for
details.
Returns:
A list of unquoted strings, one for each flag. It is a responsibility of a
caller to quote flags that contain special characters (as determined by a
shell) before passing to a tool.
"""
pass
class Stamp(Tool):
"""Updates the access and modification times of a file to the current time."""
def IsPlatformAgnostic(self):
return True
def GetRuleName(self):
return 'stamp'
def GetHeaderDependenciesFilePath(self):
# Only applicable to C family compilers.
return None
def GetHeaderDependenciesFormat(self):
# Only applicable to C family compilers.
return None
class Copy(Tool):
"""Copies individual files."""
def IsPlatformAgnostic(self):
return True
def GetRuleName(self):
return 'copy'
def GetHeaderDependenciesFilePath(self):
# Only applicable to C family compilers.
return None
def GetHeaderDependenciesFormat(self):
# Only applicable to C family compilers.
return None
class Shell(Tool):
"""Constructs command lines."""
def IsPlatformAgnostic(self):
return True
def GetRuleName(self):
# Shell should not be used by Ninja, only by other tools.
return None
def GetPath(self):
# Shell should not be used by Ninja, only by other tools.
return None
def GetExtraFlags(self):
# Shell should not be used by Ninja, only by other tools.
return None
def GetMaxConcurrentProcesses(self):
# Shell should not be used by Ninja, only by other tools.
return None
def GetCommand(self, path, extra_flags, flags, shell):
# Shell should not be used by Ninja, only by other tools.
return None
def GetDescription(self):
# Shell should not be used by Ninja, only by other tools.
return None
def GetHeaderDependenciesFilePath(self):
# Shell should not be used by Ninja, only by other tools.
return None
def GetHeaderDependenciesFormat(self):
# Shell should not be used by Ninja, only by other tools.
return None
def GetRspFilePath(self):
# Shell should not be used by Ninja, only by other tools.
return None
def GetRspFileContent(self):
# Shell should not be used by Ninja, only by other tools.
return None
@abc.abstractmethod
def MaybeQuoteArgument(self, argument):
"""Quotes a string so that shell could interpret it as a single argument.
Args:
argument: A string that can contain arbitrary characters.
Returns:
A quoted and appropriately escaped string. Returns the original string
if no processing is necessary.
"""
pass
@abc.abstractmethod
def Join(self, command):
"""Joins a sequence of unquoted command line terms into a string.
Args:
command: An unquoted, unescaped sequence of command line terms.
Returns:
A quoted and appropriately escaped string for the same command line.
"""
pass
@abc.abstractmethod
def And(self, *commands):
"""Joins a sequence of command lines with the AND shell operator.
Args:
*commands: A sequence of either quoted strings or unquoted sequences of
command line terms that make up the command lines to be ANDed.
Returns:
A quoted and appropriately escaped string for the ANDed command line.
"""
pass
@abc.abstractmethod
def Or(self, *commands):
"""Joins a sequence of command lines with the OR shell operator.
Args:
*commands: A sequence of either quoted strings or unquoted sequences of
command line terms that make up the command lines to be ORed.
Returns:
A quoted and appropriately escaped string for the ORed command line.
"""
pass