50 =
"FOAM_CODE_TEMPLATES";
53 =
"codeTemplates/dynamicCode";
56 =
"LIB = $(PWD)/../platforms/$(WM_OPTIONS)/lib";
73 <<
"This code should not be executed by someone" 74 <<
" with administrator rights for security reasons." <<
nl 75 <<
"It generates a shared library which is loaded using dlopen" 83 <<
"Loading shared libraries using case-supplied code may have" 84 <<
" been disabled" <<
nl 85 <<
"by default for security reasons." <<
nl 86 <<
"If you trust the code, you may enable this by adding" 88 <<
" allowSystemOperations 1" <<
nl <<
nl 89 <<
"to the InfoSwitches setting in the system controlDict." <<
nl 90 <<
"The system controlDict is any of" <<
nl <<
nl 92 <<
" ~/.OpenFOAM/controlDict" <<
nl 93 <<
" $WM_PROJECT_DIR/etc/controlDict" <<
nl <<
endl 105 const HashTable<string>& mapping
111 <<
"Failed opening for reading " << is.name()
118 <<
"Failed writing " <<
os.
name()
140 const UList<fileName>& templateNames,
141 DynamicList<fileName>& resolvedFiles,
142 DynamicList<fileName>& badFiles
146 const fileName templateDir(
Foam::getEnv(codeTemplateEnvName));
149 for (
const fileName& templateName : templateNames)
152 if (!templateDir.empty() &&
isDir(templateDir))
154 file = templateDir/templateName;
164 file =
findEtcFile(codeTemplateDirName/templateName);
169 badFiles.append(templateName);
174 resolvedFiles.append(file);
184 const auto fnd = filterVars_.cfind(
"SHA1sum");
191 os <<
"/* dynamicCode:\n * SHA1 = ";
200 if (compileFiles_.empty())
205 const fileName dstFile(this->codePath()/
"Make/files");
208 mkDir(dstFile.path());
210 OFstream
os(dstFile);
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
257 writeCommentSHA1(
os);
291 Foam::dynamicCode::dynamicCode(
const word& codeName,
const word& codeDirName)
293 codeRoot_(
argList::envGlobalPath()/topDirName),
294 libSubDir_(stringOps::
expand(
"platforms/${WM_OPTIONS}/lib")),
296 codeDirName_(codeDirName)
298 if (codeDirName_.empty())
300 codeDirName_ = codeName_;
311 return topDirName/codeDirName_;
329 compileFiles_.clear();
331 createFiles_.clear();
333 filterVars_.set(
"typeName", codeName_);
334 filterVars_.set(
"SHA1sum",
SHA1Digest().str());
349 setFilterContext(context);
355 compileFiles_.append(
name);
361 copyFiles_.append(
name);
368 const string& contents
380 filterVars_.set(
"localCode", context.
localCode());
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());
444 IFstream is(srcFile);
449 <<
"Failed opening " << srcFile
453 OFstream
os(dstFile);
458 <<
"Failed writing " << dstFile
463 copyAndFilter(is,
os, filterVars_);
468 for (
const fileAndContent& content : createFiles_)
472 mkDir(dstFile.path());
473 OFstream
os(dstFile);
478 <<
"Failed writing " << dstFile
489 writeDigest(filterVars_[
"SHA1sum"]);
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)
532 return upToDate(context.sha1());
const string & include() const noexcept
The code includes.
const string & localCode() const noexcept
The local (file-scope) code.
bool writeDigest(const SHA1Digest &) const
Write digest to Make/SHA1Digest.
A class for handling file names.
std::string str(const bool prefixed=false) const
The digest (40-byte) text representation, optionally with '_' prefix.
void reset(const dynamicCodeContext &)
Clear files and reset variables to specified context.
errorManipArg< error, int > exit(error &err, const int errNo=1)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
void setMakeOptions(const std::string &content)
Define contents for Make/options.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Output to file stream, using an OSstream.
int infoDetailLevel
Global for selective suppression of Info output.
constexpr char nl
The newline '\n' character (0x0a)
static bool resolveTemplates(const UList< fileName > &templateNames, DynamicList< fileName > &resolvedFiles, DynamicList< fileName > &badFiles)
Resolve code-templates via the codeTemplateEnvName.
Ostream & endl(Ostream &os)
Add newline and flush stream.
void setFilterContext(const dynamicCodeContext &)
Define filter variables for code, codeInclude, SHA1sum.
static const word codeTemplateEnvName
Name of the code template environment variable.
static const char *const topDirName
Top-level directory name for copy/compiling.
static const char *const targetLibDir
Directory for library targets for Make/files.
static std::string path(const std::string &str)
Return directory path name (part before last /)
void addCompileFile(const fileName &name)
Add a file template name, which will be found and filtered.
string getEnv(const std::string &envName)
Get environment value for given envName.
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
bool writeCommentSHA1(Ostream &) const
Write SHA1 value as C-comment.
virtual Ostream & writeQuoted(const std::string &str, const bool quoted=true)
Write std::string surrounded by quotes.
bool createMakeOptions() const
Copy/create Make/options prior to compilation.
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
fileName codeRelPath() const
Path for specified code name relative to <case>
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
fileName libRelPath() const
Library path for specified code name relative to <case>
A class for handling words, derived from Foam::string.
Functions to search 'etc' directories for configuration files etc.
static const fileName codeTemplateDirName
Name of the code template sub-directory.
Extract command arguments and options from the supplied argc and argv parameters. ...
static int allowSystemOperations
Flag if system operations are allowed.
static void copyAndFilter(ISstream &, OSstream &, const HashTable< string > &mapping)
Copy lines while expanding variables.
void addCreateFile(const fileName &name, const string &contents)
Add a file to create with its contents. Will not be filtered.
static word fullname(word libName)
Library fullname, prefix with 'lib', suffix with '.so'.
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?
bool wmakeLibso() const
Compile a libso.
const int api
OpenFOAM api number (integer) corresponding to the value of OPENFOAM at the time of compilation...
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...
bool upToDate(const dynamicCodeContext &context) const
Verify if the copied code is up-to-date, based on Make/SHA1Digest.
bool copyOrCreateFiles(const bool verbose=false) const
Copy/create files prior to compilation.
OBJstream os(runTime.globalPath()/outputName)
virtual const fileName & name() const
Read/write access to the name of the stream.
const string & code() const noexcept
The code.
bool isAdministrator()
Is the current user the administrator (root)
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
Encapsulation of dynamic code dictionaries.
Ostream & write(Ostream &os, const bool prefixed=false) const
Write (40-byte) text representation, optionally with '_' prefix.
void setFilterVariable(const word &key, const std::string &value)
Define a filter variable.
fileName findEtcFile(const fileName &name, const bool mandatory=false, unsigned short location=0777)
Search for a single FILE within the etc directories.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
bool good() const noexcept
True if next operation might succeed.
void addCopyFile(const fileName &name)
Add a file template name, which will be found and filtered.
OSstream Serr
OSstream wrapped stderr (std::cerr)
fileName libPath() const
Library path for specified code name.
messageStream Info
Information stream (stdout output on master, null elsewhere)
void clear()
Clear files and variables.
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
static void checkSecurity(const char *title, const dictionary &)
Check security for creating dynamic code.
bool createMakeFiles() const
Copy/create Make/files prior to compilation.
const SHA1 & sha1() const noexcept
The SHA1 calculated from options, libs, include, code, etc.
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.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...