51 =
"FOAM_CODE_TEMPLATES";
54 =
"codeTemplates/dynamicCode";
57 =
"LIB = $(PWD)/../platforms/$(WM_OPTIONS)/lib";
74 <<
"This code should not be executed by someone"
75 <<
" with administrator rights for security reasons." <<
nl
76 <<
"It generates a shared library which is loaded using dlopen"
84 <<
"Loading shared libraries using case-supplied code may have"
85 <<
" been disabled" <<
nl
86 <<
"by default for security reasons." <<
nl
87 <<
"If you trust the code, you may enable this by adding"
89 <<
" allowSystemOperations 1" <<
nl <<
nl
90 <<
"to the InfoSwitches setting in the system controlDict." <<
nl
91 <<
"The system controlDict is any of" <<
nl <<
nl
93 <<
" ~/.OpenFOAM/controlDict" <<
nl
94 <<
" $WM_PROJECT_DIR/etc/controlDict" <<
nl <<
endl
106 const HashTable<string>& mapping
112 <<
"Failed opening for reading " << is.name()
119 <<
"Failed writing " <<
os.
name()
141 const UList<fileName>& templateNames,
142 DynamicList<fileName>& resolvedFiles,
143 DynamicList<fileName>& badFiles
147 const fileName templateDir(
Foam::getEnv(codeTemplateEnvName));
150 for (
const fileName& templateName : templateNames)
153 if (!templateDir.empty() &&
isDir(templateDir))
155 file = templateDir/templateName;
165 file =
findEtcFile(codeTemplateDirName/templateName);
170 badFiles.push_back(templateName);
175 resolvedFiles.push_back(file);
185 const auto iter = filterVars_.cfind(
"SHA1sum");
189 os <<
"/* dynamicCode:\n * SHA1 = ";
190 os.writeQuoted(iter.val(),
false) <<
"\n */\n";
200 if (compileFiles_.empty())
205 const fileName dstFile(this->codePath()/
"Make/files");
208 mkDir(dstFile.path());
215 <<
"Failed writing " << dstFile
219 writeCommentSHA1(
os);
222 for (
const fileName& file : compileFiles_)
229 <<
"/lib" << codeName_.c_str() <<
nl;
238 if (compileFiles_.empty() || makeOptions_.empty())
243 const fileName dstFile(this->codePath()/
"Make/options");
246 mkDir(dstFile.path());
248 OFstream
os(dstFile);
253 <<
"Failed writing " << dstFile
258 os.writeQuoted(makeOptions_,
false) <<
nl;
283 os.writeQuoted(sha1,
false) <<
nl;
293 codeRoot_(
argList::envGlobalPath()/topDirName),
294 libSubDir_(
stringOps::expand(
"platforms/${WM_OPTIONS}/lib")),
296 codeDirName_(codeDirName)
298 if (codeDirName_.empty())
300 codeDirName_ = codeName_;
329 compileFiles_.clear();
331 createFiles_.clear();
333 filterVars_.set(
"typeName", codeName_);
334 filterVars_.set(
"SHA1sum",
SHA1Digest().str());
355 compileFiles_.push_back(
name);
361 copyFiles_.push_back(
name);
368 const std::string& fileContents
371 createFiles_.emplace_back(
name, fileContents);
381 filterVars_.set(
"code", context.
code());
382 filterVars_.set(
"codeInclude", context.
include());
383 filterVars_.set(
"SHA1sum", context.
sha1().
str());
390 const std::string& value
393 filterVars_.set(key, value);
399 makeOptions_ = content;
408 <<
"Creating new library in " << this->libRelPath() <<
endl;
411 const label nFiles = compileFiles_.size() + copyFiles_.size();
413 DynamicList<fileName> resolvedFiles(nFiles);
414 DynamicList<fileName> badFiles(nFiles);
417 resolveTemplates(compileFiles_, resolvedFiles, badFiles);
418 resolveTemplates(copyFiles_, resolvedFiles, badFiles);
420 if (!badFiles.empty())
423 <<
"Could not find code template(s): "
425 <<
"Under the $" << codeTemplateEnvName
426 <<
" directory or via the <etc>/"
427 << codeTemplateDirName <<
" expansion"
434 const fileName outputDir = this->codePath();
440 for (
const fileName& srcFile : resolvedFiles)
442 const fileName dstFile(outputDir/srcFile.name());
449 <<
"Failed opening " << srcFile
458 <<
"Failed writing " << dstFile
463 copyAndFilter(is,
os, filterVars_);
468 for (
const auto& content : createFiles_)
472 mkDir(dstFile.path());
478 <<
"Failed writing " << dstFile
497 stringList cmd({
"wmake",
"-s",
"libso", this->codePath()});
506 os <<
"Invoking wmake libso " << this->codePath().c_str() <<
endl;
519 const fileName file = digestFile();
521 if (!
exists(file,
false) || SHA1Digest(IFstream(file)()) != sha1)
559 off_t masterSize = localSize;
574 <<
" masterSize:" << masterSize
575 <<
" localSize:" << localSize <<
endl;
577 if (localSize == masterSize)
581 if (localSize > masterSize)
584 <<
"Excessive size when reading (NFS mounted) library "
587 <<
" detected size " << localSize
588 <<
" whereas master size is " << masterSize
590 <<
"If your case is NFS mounted increase"
591 <<
" fileModificationSkew or maxFileModificationPolls;"
592 <<
nl <<
"If your case is not NFS mounted"
593 <<
" (so distributed) set fileModificationSkew"
600 <<
"Local file " << file
601 <<
" not of same size (" << localSize
603 << masterSize <<
"). Waiting for "
605 <<
" seconds." <<
endl;
615 if (localSize != masterSize)
618 <<
"Cannot read (NFS mounted) library:" <<
nl
621 <<
" detected size " << localSize
622 <<
" whereas master size is " << masterSize
624 <<
"If your case is NFS mounted increase"
625 <<
" fileModificationSkew or maxFileModificationPolls;" <<
nl
626 <<
"If your case is not NFS mounted"
627 <<
" (so distributed) set fileModificationSkew"
634 <<
" masterSize:" << masterSize
635 <<
" localSize:" << localSize
636 <<
" ... after waiting" <<
endl;
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void push_back(const T &val)
Copy append an element to the end of this list.
A HashTable similar to std::unordered_map.
Input from file stream as an ISstream, normally using std::ifstream for the actual input.
static float fileModificationSkew
Time skew (seconds) for file modification checks.
static int maxFileModificationPolls
Max number of times to poll for file modification changes.
bool good() const noexcept
True if next operation might succeed.
Generic input stream using a standard (STL) stream.
virtual const fileName & name() const override
The name of the input serial stream. (eg, the name of the Fstream file name).
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
virtual Ostream & writeQuoted(const char *str, std::streamsize len, const bool quoted=true) override
Write character/string content, with/without surrounding quotes.
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
virtual const fileName & name() const override
Read/write access to the name of the stream.
Generic output stream using a standard (STL) stream.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Ostream & write(Ostream &os, const bool prefixed=false) const
Write (40-byte) text representation, optionally with '_' prefix.
std::string str(const bool prefixed=false) const
The digest (40-byte) text representation, optionally with '_' prefix.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
bool empty() const noexcept
True if List is empty (ie, size() is zero).
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
@ broadcast
broadcast [MPI]
Extract command arguments and options from the supplied argc and argv parameters.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
static word fullname(word libName)
Library fullname, prefix with 'lib', suffix with '.so'.
Encapsulation of dynamic code dictionaries.
const string & code() const noexcept
The code.
const string & include() const noexcept
The code includes.
const SHA1 & sha1() const noexcept
The SHA1 calculated from options, libs, include, code, etc.
const string & localCode() const noexcept
The local (file-scope) code.
static int allowSystemOperations
Flag if system operations are allowed.
static void copyAndFilter(ISstream &, OSstream &, const HashTable< string > &mapping)
Copy lines while expanding variables.
fileName codePath() const
Path for specified code name.
bool copyOrCreateFiles(const bool verbose=false) const
Copy/create files prior to compilation.
dynamicCode(const dynamicCode &)=delete
No copy construct.
void addCopyFile(const fileName &name)
Add a file template name, which will be found and filtered.
void reset(const dynamicCodeContext &)
Clear files and reset variables to specified context.
static const char *const targetLibDir
Directory for library targets for Make/files.
fileName libRelPath() const
Library path for specified code name relative to <case>.
static bool resolveTemplates(const UList< fileName > &templateNames, DynamicList< fileName > &resolvedFiles, DynamicList< fileName > &badFiles)
Resolve code-templates via the codeTemplateEnvName.
static const word codeTemplateEnvName
Name of the code template environment variable.
static const char *const topDirName
Top-level directory name for copy/compiling.
void setFilterVariable(const word &key, const std::string &value)
Define a filter variable.
const word & codeDirName() const noexcept
Return the code-dirname.
static void waitForFile(const fileName &file, const dictionary &contextDict)
Wait for libPath() file to appear on sub-ranks.
void addCreateFile(const fileName &name, const std::string &contents)
Add a file to create with its contents. Will not be filtered.
void setFilterContext(const dynamicCodeContext &)
Define filter variables for code, codeInclude, SHA1sum.
static void checkSecurity(const char *title, const dictionary &)
Check security for creating dynamic code.
bool createMakeFiles() const
Copy/create Make/files prior to compilation.
fileName digestFile() const
Path for SHA1Digest.
bool writeDigest(const SHA1Digest &) const
Write digest to Make/SHA1Digest.
fileName codeRelPath() const
Path for specified code name relative to <case>.
void addCompileFile(const fileName &name)
Add a file template name, which will be found and filtered.
void clear()
Clear files and variables.
bool upToDate(const dynamicCodeContext &context) const
Verify if the copied code is up-to-date, based on Make/SHA1Digest.
fileName libPath() const
Library path for specified code name.
static const fileName codeTemplateDirName
Name of the code template sub-directory.
bool createMakeOptions() const
Copy/create Make/options prior to compilation.
bool wmakeLibso() const
Compile a libso.
bool writeCommentSHA1(Ostream &) const
Write SHA1 value as C-comment.
void setMakeOptions(const std::string &content)
Define contents for Make/options.
const word & codeName() const noexcept
Return the code-name.
A class for handling file names.
static std::string path(const std::string &str)
Return directory path name (part before last /).
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
A class for handling words, derived from Foam::string.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Functions to search 'etc' directories for configuration files etc.
OBJstream os(runTime.globalPath()/outputName)
#define DebugPout
Report an information message using Foam::Pout.
Namespace for handling debugging switches.
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
const int api
OpenFOAM api number (integer) corresponding to the value of OPENFOAM at the time of compilation.
Collection of static functions for various string-related operations.
void inplaceExpand(std::string &s, const HashTable< string > &mapping, const char sigil='$')
Inplace expand occurrences of variables according to the mapping. Does not use environment values.
string expand(const std::string &s, const HashTable< string > &mapping, const char sigil='$')
Expand occurrences of variables according to the mapping and return the expanded string.
string getEnv(const std::string &envName)
Get environment value for given envName.
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
bool isAdministrator()
Is the current user the administrator (root).
messageStream Info
Information stream (stdout output on master, null elsewhere).
unsigned int sleep(const unsigned int sec)
Sleep for the specified number of seconds.
fileName findEtcFile(const fileName &name, const bool mandatory=false, unsigned short location=0777)
Search for a single FILE within the etc directories.
List< string > stringList
List of string.
Ostream & endl(Ostream &os)
Add newline and flush stream.
off_t fileSize(const fileName &name, const bool followLink=true)
Return size of file or -1 on failure (normally follows symbolic links).
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
int infoDetailLevel
Global for selective suppression of Info output.
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
messageStream InfoErr
Information stream (stderr output on master, null elsewhere).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
errorManipArg< error, int > exit(error &err, const int errNo=1)
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
constexpr char nl
The newline '\n' character (0x0a).