NQP::Config
use NQP::Config;
use NQP::Config::Rakudo; # The language we're building
my $cfg = NQP::Config::Rakudo->new;
my $config = $cfg->config( no_ctx => 1 );
$config->{a_variable} = "a value"; # This can be later expanded as @a_variable@ by macros in a template.
$cfg->configure_paths;
$cfg->configure_from_options;
...
$cfg->expand_template;
...
This is a helper module for build a language from NQP/Raku family. It provides basic utility methods,
configure_
-family methods for presetting environment-dependent values, and methods to manipulate this data.
NQP::Config
is a base (abstract) class which has to be inherited and completed by a language-specific class. See
NQP::Config::NQP
and
NQP::Config::Rakudo
classes from nqp
and rakudo
implementations.
A hash of configuration variables as keys with their values.
Usually referred as just context.
A NQP::Config
object manages a collection of configurations stored as a stack-like list. Whenever a configuration
variable is requested its being searched in the list from top to bottom. The bottommost configuration does not belong to
the list and is stored in config
key on the object itself. Each entry in the list is called context because it might
be created by some configuration subsystems for a limited period of time and be destroyed when no long needed. So, we
can say that a configuration variable has a value in a context.
However, contexts are a little more than chunks of configuration. A context is a hash where configuration is defined by
configs
key. Other key names are not reserved by now and can be used for holding any useful information. They're
called properties and can be requested with method prop
. From this point of view attribute keys on the configuration
object itself are the bottom-level properties, similar to config
key been the bottom-level configuration.
Note that configuration keys is using plural form of its name configs
. This is because it is a list too, a list of
configuration hashes in this case. Though it seems somewhat overcomplicated but there is a good explanation for this:
sometimes a context config chunk is being assembled from several pieces; while merging of hashrefs in Perl is
terrible...
Another tricky part is that chunks in the context list are searched for a variable in start-to-end order. This is because the first chunk in the context is considered the base to which other chunks can only append missing variables.
They should be called 'command line options', but a short form is a short form! It's too attractive for lazy ones...
Note that options can only be set from the command line and their alteration is better be avoided at any cost. This is
our initial status which is to be used as the ground for all decisions we make. If an option or its default value is
needed to be reconsidered during configuration process then it's value must be cloned and either stored on the
configuration object itself; or used as a configuration variable. The latter is preferable. If the value is a boolean
and the option of setting a configuration variable is chosen then it is recommended to use some user-readable values.
For example, marking a relocatable build variable relocatable
is set to reloc
; and to nonreloc
otherwise. Though
this might complicate some code a bit it provides a better way to use these variable in templates when necessary:
@template(nqp-m-@relocatable@)@
Nobody would object that having nqp-m-reloc
and nqp-m-nonreloc
template files is preferable over nqp-m-1
and
nqp-m-0
.
An instance of NQP::Config::_Scoping
class which would execute a callback when destroyed. Usually used to auto-delete
a context when code is leaving a scope.
Because NQP::Class
is build using barebones Perl OO implementation, there're no attributes as such. We're listing
here keys on a NQP::Class
instance.
Some irrelevant and internally used keys would miss a description. They're only listed here to avoid being accidentally used by a child class.
-
config
the main (bottommost) hash of configuration variables -
quiet
is a boolean; true if minimal output is requested by a user -
backend_prefix
- mapping of full backend names into short aliases -
abbr_to_backend
– reverse mapping ofbackend_prefix
-
backend_order
- default order (kinda priority) of backends -
active_backends_order
-
options
- a hash of parsed command line options (seeGetopt::Long
). Must be set by aConfigure
script:GetOptions( $cfg->options, ... );
Note that as it was already stated Options section, values in this hash are not to be changed unless absolutely, unavoidably necessary.
-
contexts
- list of contexts -
repo_maps
-
impls
contains data structures related to backend implementations -
backend_errors
-
expand_as_is
- boolean; true if template must be expanded as-is, without adding informational comments -
out_header
-
template
is a file which is being expanded -
out
is a file where expanded output is send to
Use of the keys directly should be avoided as much as possible by external scripts and reduced to reasonable levels by child classes. Methods are always preferable.
Constructor
Initializer. Called by new
. Can be overriden by a child class but must not be called manually.
Outputs a message to the console unless quiet
attribute is true. Usually recommended over say
or print
unless
note
or sorry
methods apply.
Sets quiet
attribute-flag to $on
or to a true value if used without an argument.
For cases where a notice must be output which is not a subject for quiet
ness and requires user attention. $type
is
a short message explaining what type of notice we're printing. It's a free-form, but words like ATTENTION
or 'WARNING'
are recommended. A typical output would look like:
===ATTENTION===
The information we want the user to see
goes here and it is indented for clearer look.
This method outputs a ===SORRY!===
message. For historical reasons it treats it's parameters differently. Where note
considers them a single message, sorry
expects a list of messages. Each will be output on a new lines with on common
===SORRY!===
prefix.
Usually, calling sorry
causes a script to die unless ignore-errors
option is set.
Return current platform's shell. Basically, cmd
for Win* and sh
for others.
Takes a single parameter and forms a valid script name depending on the current platform. I.e. will append .bat
on
Win* if needed.
Determines what command is to be used as make
depending on the current platform. Would mostly result in make
,
nmake
on Win*, and may return gmake
on BSD family.
Return options
hash.
Returns a option $opt
or undef if its doesn't exists.
Returns true if option $opt
exists. It may not necessarily be defined though.
Dies if $backend
is not supported. Error message would inform method name if $method
is defined.
Returns $backend
Return a list of supported backends.
Returns true if $backend
is supported.
Returns a list of short names of supported backends.
Maps short backend name to its full form. Like "j" -> "jvm".
Returns $backend
short name.
If supplied with key => value
pairs (%config
) then this method will store them in a backend-specific configuration
hash. If a key already exists it will be overwritten.
Returns backend-specific configuration hash.
Activates a $backend
for build. This includes:
- appending of the backend to the list of active ones. It means
active_backends_order
content depends in what order the backends were activated. - if no other backends were activated yet, the
default_backend
configuration variable is set to$backend
If the method is called for the second time with the same parameters it returns without any actions taken.
Returns a list of activated backends.
Returns true if $backend
is activate.
Returns a list of short names of active backends.
Takes a relative path and prepends it with base_dir
. If the parameter happens to be an absolute path it is returned as
is then.
The only method of configure_*
family which is used by NQP::Config
itself. It presets configuration values specific
to the current platform.
Methods from this family are to be used by a Configure.pl
script to actually perform configuration tasks. Of those
configure_backends
configure_misc
are abstract and have to be implemented by child classes.
Parses what is passed with --backends
.
Stores error messages related to a $backend
.
Returns a list or arrayref (context dependant) of stored errors for a $backend
.
Expands the default template (see attribute template
). The result of expansion goes into file specified
by out
attribute. If out_header
attribute is defined it's prepended to the expanded text.
See more details in macro expansion docs.
Creates config.status
file in base_dir
using content of @lclang@_config_status
configuration variable.
Generate command line options for subsequent Configure.pl
calls based on the information collected so far; mostly
on based upon user-specified command line options.
Returns list of options or space-concatenated string made of the list depending on the call context.
NOTE: Subsequent calls are the calls made after the main run which creates Makefile
. They're made by the Makefile
receipts and currently their sole purpose is to expand other templates the way they would be expanded by the main run
but at the time of the build process.
Generates a command line option for a subsequent call to a Configure.pl
based on options provided by the user. The
option value is shell-quoted unless no_quote
parameter is true.
Returns a list of options to be ignored when building a command line for subsequent calls to Configure.pl
.
A language-specific child class can override this method.
Shortcuts for checking what our platform is.
Returns true if $file
is an executable.
Builds URL for a github repository based on requested protocol. The protocol could be either "git" or "https".
$user
is github's user account which owns the repository $repo
.
Higher level github URL builder. $repo_alias
is a key from repo_maps
attribute: one of moar, nqp, rakudo, or
roast values. The following keys can be used in %params
:
action
–git
action we're requesting the URL for. For now only push and pull are supported.protocol
–git
protocol. Seegithub_url
Note that for push
action only git
protocol is valid.
Finds a file defined $short_name
in specified subdirectories. Returns file name with path if found or empty string
otherwise.
%params
can have the following keys:
where
- which base directory we're lookin in. Currently it could be either templates or build. But any other word can be used as long as there is a configuration variable${where}_dir
.subdir
– single directory name to look in. Appended to$where
directory.subdirs
- a list of directories.subdirs_only
– boolean. If true then file isn't searched in$where
dir itself, only in subdirectories of it. For example, one can limit the search of aMakefile
template by platform of backend directories avoiding the universalMakefile
template.suffix
- suffix to be appended to$short_name
.suffixes
- list ofsuffix
'es. To look for a file without a suffix too this list must contain an empty string.required
- if its true then the method dies when no file is found.
Implicitly the routine is also using ctx_subdir
configuration variable as a subdir
. It can be set by iterators which
create contexts to look in a context-specific location. For example, an iterator over active backends can set this
variable on a per-context basis and execute a callback where a template is requested. The callback doesn't need to worry
about where to look for its templates as this would be done automatically.
A shortcut to call:
$cfg->find_file_path(
$template,
where => 'templates',
suffixes => [ ".$platform", ".in", "" ],
%params
);
A shortcut to call:
$cfg->find_file_path(
$file_name,
where => 'build',
suffixes => [ qw<.pl .nqp .p6>, "" ],
%params
);
Expand $infile
into $outfile
. $outfile
could be a file name or an opened file handle. $infile
could be a single
template name or an arrayref of templates. If $infile
is a list then all templates are expanded into a single
$outfile
.
For each template being expanded the method creates a context with template_file
property and a configuration variable
of the same name. Both are holding the template file path.
In the output result of each template file expansion is wrapped into a pair of:
# Generated from <template>_
<actual expanded text>
# (end of section generated from <template>)
commetns unless as_is
key in %params
is true.
The actual expansion is done by fill_template_text
method.
Expands $text
by creating an instance of NQP::Macros
class and calling its expand
method on the text. Passes
$self
as the configuration object for the NQP::Macros
instance.
If the expanded text contains "nqp::makefile" string then additionally passes it through fixup_makefile
method.
Returns the expanded text.
This method tries to prepend commands in Makefile
receipts with time
utility if makefile_timing
configuration
variable is true. Must be replaced with a dedicated macro.
Checkouts a repository specified by its short name $repo
(see repo_maps
attribute) into a directory $dir
. By
checkout we mean either clone
or fetch
, depending on the existence of $dir
.
$branch
defined what specific branch is requested if defined.
Method dies if git
command fails.
Returns a list of context hashes. For the simplicity of searching, the list is returned in reverse order so that when searching for a property or a configuration variable iteration could be done in strait direction.
Returns currently active context.
Pushes a context hash to the list. Returns a scoping object which upon destruction will delete the context from the list. So, normally adding a context is:
foreach my $backend ( $self->active_backends ) {
my $scoping = $self->push_ctx(
{
configs => [ { backend => $backend } ],
}
);
... # Do our work
}
As soon as a single loop iteration ends $scoping
will go out of scope and will be destroyed effectively deactivating
the context.
NOTE that strictly saying contexts are not a stack because it is possible for the scoping object to either be preserved and used outside of a scope or be deleted any time, even if other contexts were pushed later. So, the only reason to consider the list as a stack-like structure is the way we look for data in it.
Deletes last pushed context. Usually is not needed.
Shortcut for pushing just a single configuration hash onto the context list. Parameters could be either a hashref or
list of key => value
pairs.
Returns a scoping object.
Returns a configuration hash. Depending on a parameter the hash could be:
- the
config
attribute itself, no contexts added,no_ctx
parameter is true. - otherwise it's a result of summing up the base configuration hash with all currently active contexts.
Fetches a configuration variable. The variable is looked through contexts first then in the config
attribute. If
parameter strict
is true and no variable is found then method dies.
Returns the value of the variable or undef if not found and strict
is not set. In array context if with_ctx
parameter is set will return a list of the value and the context hash where the variable was located.
Set a configuration variable. If in_ctx
parameter is set the variable will be set in the topmost context. Otherwise
the value in the config
attribute is changed.
Looks for a $property
in the contexts. If not found then tries the configuration object itself. If property is not
found but strict
is set then dies.
Locates the context where $property
is defined and has value $value
.
Returns the context hash.
Quotes/escapes $filename
in accordance to the current platform's rules.
The name stands for Normalize File Path. Takes a file path in Unix-like format and converts it to match the current
platform rules. For example, for Windows it means replacing /
directory seprators with \
.
Returns normalized file name.
Escapes a string for use in C
source code.
Escapes a string for use in single quoted delimiters. E.g. a Perl '' string.
Returns platform-specific path separator.
Returns $file
content as a single line.
Maps operation system to a family of platforms. For example, Windows and OS/2 would map into family windows
.
See %os_platforms
hash in the beginning of the module source.
Similar to ExtUtils::Command
rm_*
exports. Deletes symlinks.
Tries to execute @cmd
with system
routine. Dies if exit code is not 0.
Intended as a replacement for qx{command}
. Returns command output or dies if exit code is not 0.
If %params
has an output_timeout
key then the routine attempts to use IPC::Cmd
run_forked
if available and
monitors the subcommand for produced output. If none is produced in more that output_timeout
seconds the process
gets terminated and die
is invoked with an explanation. Additional parameters are used then:
description
– a description for the command invokedheartbeat
– reportdescription
everyhearbeat
seconds to keep the user entertainedverbose
– if true then command output is not hidden;heartbeat
is ignored then
The rest of %params
keys are passed through into run
or run_forked
as is.
Parses standard revisions of MoarVM
, NQP
, Rakudo
.
Returns a list of revision components.
Compares two revisions.
Iterates over @sources
, treats them as executables capable of --show-config
command line option. Reads their output,
parses and combines the result into a configuration hash which is then returned.