DuneInstance¶
This module can be used to generate explicit template instantiations. Suppose you have a template test function that you want to call for a number of template arguments. You want to explicitly instantiate the function for each set of template arguments, and put the instantiation into its own translation unit. (This can be beneficial in that it limits the amount of code that the optimizer sees at once, and thus it can reduce both memory and cpu requirements during compilation.)
A typical workflow is:
dune_instance_begin(FILES mytest.cc mytest.hh)
foreach(TYPE IN ITEMS bool char int double)
dune_instance_add(ID "${TYPE}" FILES mytest_instance.cc)
endforeach()
dune_instance_end()
list(FILTER DUNE_INSTANCE_GENERATED INCLUDE REGEX [[\\.cc$]])
dune_add_test(NAME mytest SOURCES ${DUNE_INSTANCE_GENERATED})
The call to dune_instance_begin() reads mytest.cc.in
and mytest.hh.in and splits them into embedded templates and other
content. It will replace occurrences of @VAR@ now in the other
content and save the result for later.
The call to dune_instance_add() occurs in a loop. Each
call will instantiate the embedded templates extracted earlier to replace
an occurrence of @TYPE@ by the value of the variable TYPE set in
the for loop. Then files containing explicit instantiatons will be
generated as mytest_instance_bool.cc, mytest_instance_bool.cc,
etc, from a template file mytest_instance.cc.in. The name of the
generated files are the base file name from the template definition with
the ID inserted before the extension. The name of the template file
is the same base file name with .in appended.
dune_instance_end() is used to write mytest.cc and
mytest.hh with the collected content from the embedded templates.
The list of generated files will be available in the variable
DUNE_INSTANCE_GENERATED.
The template files then look like this:
mytest.cc.in:
// @GENERATED_SOURCE@
#include <config.h>
#include <mytest.hh>
int main() {
MyTestSuite suite;
#cmake @template@
suite.test<@TYPE@>();
#cmake @endtemplate@
return suite.good() ? EXIT_SUCCESS : EXIT_FAILURE;
}
mytest.hh.in:
// @GENERATED_SOURCE@
#include <mytestsuite.hh>
#cmake @template@
extern template void MyTestSuite::test<@TYPE@>();
#cmake @endtemplate@
mytest_instance.cc.in:
// @GENERATED_SOURCE@
#include <config.h>
#include <mytest.hh>
template void MyTestSuite::test<@TYPE@>();
The @GENERATED_SOURCE@ substitution is good practice, it tells a
human reader that this file was generated and what the template file was,
and it hints editors to go into read-only mode.
The begin of an embedded template is marked by a line containing
@template@ or @template NAME@. Leaving off the name is
equivalent to an empty name. dune_instance_add(TEMPLATE NAME) will
only instantiate embedded templates whose name matches and ignore all
others.
The end of an embedded template is marked by a line containing
@endtemplate@ or @endtemplate NAME@. If a name is given, it must
match the name of the embedded template it closes. If no name is given
(or the name is empty), that check is omitted.
There may be arbitrary characters on the same line before or after the
begin and end markers. These are ignored, so you can use them for
comments or to trick your editor into proper indentation. The one
exception is that the line surrounding the marker may not contain any
@ characters to avoid ambiguities.
The generation is done using the cmake command
configure_file() for template files and
string(CONFIGURE ...) for template strings. These simply substitute
the current variable values, so make sure to set up the variables to
substitute before calling dune_instance_add() or
dune_instance_begin().
Refrain from using substitutions that begin with an underscore
(@_my_local_var@). The generation functions in this module use such
names for their local variables and may hide the variable you are trying
to substitute.
- dune_instance_begin¶
Prepare generation of a family of explicit instantiations.
dune_instance_begin(FILES <file-spec>...)
FILESList of template files with embedded templates.
Read the given template files, and extract embedded templates. Run the generator on the remaining file content with the variables currently in effect.
Note
A matching
dune_instance_end()is required. Since information is communicated through variables in the callers scope,dune_instance_begin()/dune_instance_end()blocks may not be nested inside the same scope. Since a function is a new scope, it may safely contain adune_instance_begin()/dune_instance_end()block, even if it is itself called from one.
- dune_instance_add¶
Instantiate a template with the currently set variable values.
dune_instance_add( FILES <file-spec>... ID <id> [TEMPLATE <template-name>] )
FILESList of template file specifications. These are usually the names of template files with the
.inextension removed. See theIDparameter for details.IDUsed to build the names of generated files. Each file specification together with this id is given to
dune_instance_from_id()to determine the name of a template file and the name of an instance file. To get unique instance file names this ID should usually be a list of variable values joined together by_.Specifically, each file specification may be of the form
template_file_name:base_instance_file_name, or it may be a single token not containing:. In the latter case, if that token contains a trailing.in, that is removed and the result is the base instance file name. The base instance file name has the.inappended again to form the template file name.The template file name is used as-is to generate files from.
The ID is mangled by replacing any runs of non-alphanumeric characters with an underscore
_, and stripping any resulting underscore from the beginning and the end. The result is inserted before any extension into the base instance file name to form the instance file name.TEMPLATEInstantiate embedded templates by this name. Defaults to an empty name, matching embedded templates without name.
Instantiate any embedded templates that match the given template name, substituting the current variables values. Then, generate files according the the file specifications in the template, doing substitutions as well.
- dune_instance_end¶
Close a block started by
dune_instance_begin(), and write the files generated from the templates given there.dune_instance_end()Write the files generated from the template files given in
dune_instance_begin(), including any content generated from embedded templates indune_instance_add().
- dune_instance_parse_file_spec¶
Parse a file specification into a template file name and an instance file name.
dune_instance_parse_file_spec(<spec> <template-var> <instance-var>)
specFile specification to parse.
template-varVariable name receiving the template file name. It may be empty.
instance-varVariable name receiving the instance file name. It may be empty.
The file specification can be the name of a template file if it has
.inat the end, or the name of an instance file if it doesn’t. The name of the other file is obtained by appending or removing.in, as applicable. Both file names can also be given explicitly in the formtemplate_file_name:instance_file_name.Note
This is the function use to parse the file specifications in
dune_instance_begin(). It is also used as a helper indune_instance_from_id()to determine template file name and base instance file name.
- dune_instance_from_id¶
Determine a template file name and an instance file name from a file specification and a unique id.
dune_instance_from_id(<file-spec> <id> <template-var> <instance-var>)
file-specFile specification to interpret.
idThe id specification. This should uniquely identify an instance.
template-varVariable name receiving the template file name. It may be empty.
instance-varVariable name receiving the instance file name. It may be empty.
The file specification is handed to
dune_instance_parse_file_spec()to determine a template file name and a base instance file name.The ID is mangled by replacing any runs of non-alphanumeric characters with an underscore
_, and stripping any resulting underscore from the beginning and the end. The result is inserted before any extension into the base instance file name to form the instance file name.Note
This is the function use to parse the file specifications given in
dune_instance_add(FILES ...).
- dune_instance_apply_bindir¶
Modify a filename to be relative to
CMAKE_CURRENT_BINARY_DIR.dune_instance_apply_bindir(<filename-var>)
filename-varThe name of the variable containing the file name.
This is used to mimic the behaviour of
configure_file(). If the file name given is not absolute, it is modified by prepending${CMAKE_CURRENT_BINARY_DIR}.
- dune_instance_generate_file¶
Convenience replacement for
configure_file(): enable standard substitutions, register files as generated, and flag the same file being generated twice.dune_instance_generate_file(<template> <instance>)
TEMPLATETemplate file name.
INSTANCEGenerated file name, interpreted relative to
${CMAKE_CURRENT_BINARY_DIR}.
When instantiating files we set up a few convenience variables before calling
configure_file()that can be used in substitutions:@TEMPLATE@contains the name of the template file.@INSTANCE@contains the name of the file being generated, not including an implied${CMAKE_CURRENT_BINARY_DIR}. Use@BINDIR_INSTANCE@if you do want the implied${CMAKE_CURRENT_BINARY_DIR}.@GENERATED_SOURCE@contains a one-line message that this file was generated, including the name of the template file.This function checks whether the file to generate has already been generated before. If yes, it reads the existing file and compares it to the content it would generate. If they differ, a fatal error is triggered. This avoids errors due to generating the same file twice with different contents, which would otherwise depend on the order in which generation happens. As a special exception, if the generated content is the same as before, the error is silently skipped.
- dune_instance_quote_element¶
Quote a list element for the internal list-based representation used by the instance generator.
dune_instance_quote_element(<var>)
varVariable whose content is transformed into the internal quoted form.
- dune_instance_unquote_element¶
Undo
dune_instance_quote_element()on a list element in the internal representation.dune_instance_unquote_element(<var>)
varVariable whose content is transformed back from the internal quoted form.
- dune_instance_set_generated¶
Prepare standard substitution variables for generated files.
dune_instance_set_generated()This internal helper prepares variables such as
GENERATED_SOURCEandBINDIR_INSTANCEbefore a file is generated.
- dune_instance_parse_embedded¶
Read a template file and split it into ordinary content parts and embedded templates.
dune_instance_parse_embedded(<name> <content-parts> <template-parts> <template-names>)
nameTemplate file to parse.
content-partsVariable receiving the list of content outside embedded templates.
template-partsVariable receiving the list of embedded template bodies.
template-namesVariable receiving the list of embedded template names.
- dune_instance_generate_parts¶
Instantiate a list of non-template content parts with the current variable values.
dune_instance_generate_parts(<parts-list>)
parts-listVariable naming the internal list of content parts.
- dune_write_changed_file¶
Write a file only if the generated content differs from the existing content.
dune_write_changed_file(<name> <content>)
nameOutput file.
contentFile content to write.
- DUNE_INSTANCE_GENERATED¶
After
dune_instance_end(), this variable contains the list of generated files, including the implied${CMAKE_CURRENT_BINARY_DIR}prefix where applicable.Do not modify this variable inside a
dune_instance_begin()/dune_instance_end()block.
- message_verbose¶
Deprecated since version 2.10: Use
message(VERBOSE "message text")instead. This macro will be removed after Dune 2.10.Deprecated compatibility macro for verbose status output.
message_verbose(<text>)
textMessage text passed through to
message(VERBOSE ...).