Skip to content

Commit

Permalink
Make CMake FMUs default (#10542)
Browse files Browse the repository at this point in the history
* Added deprecation warning to Makefile FMU build
* fmuRuntimeDepends depends on CMake version on generating system
* Adding documentation for CMake FMUs to User's Guide
  - Updating FMU Export documentation
  - Explaining (re-)compilation of source-code FMUs
  - Explain platforms keyword
* Updating User's Guide build
  - Compatibility with CMake build
  - Fixing some errors and warnings form sphinx-build
  • Loading branch information
AnHeuermann committed Apr 27, 2023
1 parent 26b9177 commit 86483b1
Show file tree
Hide file tree
Showing 42 changed files with 1,003 additions and 586 deletions.
2 changes: 1 addition & 1 deletion OMCompiler/CMakeLists.txt
Expand Up @@ -61,4 +61,4 @@ endif()
omc_add_subdirectory(SimulationRuntime)
omc_add_subdirectory(Parser)
omc_add_subdirectory(Compiler)

omc_add_subdirectory(Examples)
6 changes: 5 additions & 1 deletion OMCompiler/Compiler/FrontEnd/ModelicaBuiltin.mo
Expand Up @@ -2501,7 +2501,11 @@ The only required argument is the className, while all others have some default
input String version = "2.0" "FMU version, 1.0 or 2.0.";
input String fmuType = "me" "FMU type, me (model exchange), cs (co-simulation), me_cs (both model exchange and co-simulation)";
input String fileNamePrefix = "<default>" "fileNamePrefix. <default> = \"className\"";
input String platforms[:] = {"static"} "The list of platforms to generate code for. \"dynamic\"=current platform, dynamically link the runtime. \"static\"=current platform, statically link everything. Else, use a host triple, e.g. \"x86_64-linux-gnu\" or \"x86_64-w64-mingw32\"";
input String platforms[:] = {"static"} "The list of platforms to generate code for.
\"dynamic\"=current platform, dynamically link the runtime.
\"static\"=current platform, statically link everything.
\"<cpu>-<vendor>-<os>\", host tripple, e.g. \"x86_64-linux-gnu\" or \"x86_64-w64-mingw32\".
\"<cpu>-<vendor>-<os> docker run <image>\" host tripple with Docker image, e.g. \"x86_64-linux-gnu docker run --pull=never multiarch/crossbuild\"";
input Boolean includeResources = false "include Modelica based resources via loadResource or not";
output String generatedFileName "Returns the full path of the generated FMU.";
external "builtin";
Expand Down
6 changes: 5 additions & 1 deletion OMCompiler/Compiler/NFFrontEnd/NFModelicaBuiltin.mo
Expand Up @@ -2754,7 +2754,11 @@ The only required argument is the className, while all others have some default
input String version = "2.0" "FMU version, 1.0 or 2.0.";
input String fmuType = "me" "FMU type, me (model exchange), cs (co-simulation), me_cs (both model exchange and co-simulation)";
input String fileNamePrefix = "<default>" "fileNamePrefix. <default> = \"className\"";
input String platforms[:] = {"static"} "The list of platforms to generate code for. \"dynamic\"=current platform, dynamically link the runtime. \"static\"=current platform, statically link everything. Else, use a host triple, e.g. \"x86_64-linux-gnu\" or \"x86_64-w64-mingw32\"";
input String platforms[:] = {"static"} "The list of platforms to generate code for.
\"dynamic\"=current platform, dynamically link the runtime.
\"static\"=current platform, statically link everything.
\"<cpu>-<vendor>-<os>\", host tripple, e.g. \"x86_64-linux-gnu\" or \"x86_64-w64-mingw32\".
\"<cpu>-<vendor>-<os> docker run <image>\" host tripple with Docker image, e.g. \"x86_64-linux-gnu docker run --pull=never multiarch/crossbuild\"";
input Boolean includeResources = false "include Modelica based resources via loadResource or not";
output String generatedFileName "Returns the full path of the generated FMU.";
external "builtin";
Expand Down
35 changes: 6 additions & 29 deletions OMCompiler/Compiler/Script/CevalScriptBackend.mo
Expand Up @@ -3972,7 +3972,6 @@ protected
SimCode.SimulationSettings simSettings;
list<String> libs;
Boolean isWindows;
Boolean useCrossCompileCmake = false;
list<String> fmiFlagsList;
Boolean needs3rdPartyLibs;
String FMUType = inFMUType;
Expand Down Expand Up @@ -4060,38 +4059,16 @@ algorithm
// Check flag fmiFlags if we need additional 3rdParty runtime libs and files
needs3rdPartyLibs := SimCodeUtil.cvodeFmiFlagIsSet(SimCodeUtil.createFMISimulationFlags(false));

// Use CMake on Windows when cross-compiling with docker
_ := match (Flags.getConfigString(Flags.FMU_CMAKE_BUILD), needs3rdPartyLibs)
case ("true", _) algorithm
useCrossCompileCmake := true;
then();
case ("false", _) algorithm
useCrossCompileCmake := false;
then();
case ("default", false) algorithm
if (listLength(platforms) > 1 and isWindows) then
Error.addCompilerNotification("OS is Windows and multiple platform detected. Using CMake to build FMU.");
useCrossCompileCmake := true;
else
for platform in platforms loop
if isWindows and 1 == System.regex(platform, " docker run ", 0, true, false) then
Error.addCompilerNotification("OS is Windows and docker platform detected. Using CMake to build FMU.");
useCrossCompileCmake := true;
end if;
end for;
end if;
then();
else
algorithm
useCrossCompileCmake := false;
then();
end match;

// Warn about deprecated Makefile build
if not Flags.getConfigBool(Flags.FMU_CMAKE_BUILD) then
Error.addCompilerNotification("The Makefile build for FMUs is deprecated and will be removed in a future version of OpenModelica."
+ " Use \"--" + Flags.getConfigName(Flags.FMU_CMAKE_BUILD) + "=true\".");
end if;

// Configure the FMU Makefile
for platform in platforms loop
configureLogFile := System.realpath(fmutmp)+"/resources/"+System.stringReplace(listGet(Util.stringSplitAtChar(platform," "),1),"/","-")+".log";
if useCrossCompileCmake then
if Flags.getConfigBool(Flags.FMU_CMAKE_BUILD) then
configureFMU_cmake(platform, fmutmp, filenameprefix, configureLogFile, libs, isWindows);
else
configureFMU(platform, fmutmp, configureLogFile, isWindows, needs3rdPartyLibs);
Expand Down
15 changes: 15 additions & 0 deletions OMCompiler/Compiler/SimCode/SimCodeMain.mo
Expand Up @@ -93,6 +93,7 @@ import HpcOmSimCodeMain;
import HpcOmTaskGraph;
import NFConvertDAE;
import RuntimeSources;
import SemanticVersion;
import SerializeInitXML;
import SerializeModelInfo;
import SerializeSparsityPattern;
Expand Down Expand Up @@ -926,7 +927,21 @@ algorithm
destination = fmu_tmp_sources_dir + "CMakeLists.txt");
cmakelistsStr := System.readFile(fmu_tmp_sources_dir + "CMakeLists.txt");
cmakelistsStr := System.stringReplace(cmakelistsStr, "@FMU_NAME_IN@", simCode.fileNamePrefix);

// Set CMake runtime dependencies level
_ := match (Flags.getConfigString(Flags.FMU_RUNTIME_DEPENDS))
local
SemanticVersion.Version cmakeVersion;
SemanticVersion.Version minimumVersion;
case("default") algorithm
cmakeVersion := SimCodeUtil.getCMakeVersion();
minimumVersion := SemanticVersion.SEMVER(3, 21, 0, {}, {}); // v3.21.0
if SemanticVersion.compare(minimumVersion, cmakeVersion) <= 0 /* minimumVersion <= cmakeVersion */ then
cmakelistsStr := System.stringReplace(cmakelistsStr, "@RUNTIME_DEPENDENCIES_LEVEL@", "\"modelica\"");
else
cmakelistsStr := System.stringReplace(cmakelistsStr, "@RUNTIME_DEPENDENCIES_LEVEL@", "\"none\"");
end if;
then();
case("none") algorithm
cmakelistsStr := System.stringReplace(cmakelistsStr, "@RUNTIME_DEPENDENCIES_LEVEL@", "\"none\"");
then();
Expand Down
24 changes: 23 additions & 1 deletion OMCompiler/Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -59,8 +59,9 @@ import HashSetString;

// protected imports
protected
import Array;
import AbsynUtil;
import Array;
import Autoconf;
import AvlSetString;
import BackendDAEOptimize;
import BackendDAETransform;
Expand Down Expand Up @@ -105,6 +106,7 @@ import Matching;
import MetaModelica.Dangerous;
import Mutable;
import PriorityQueue;
import SemanticVersion;
import SimCodeDump;
import SimCodeFunctionUtil;
import SimCodeFunctionUtil.varName;
Expand Down Expand Up @@ -15763,6 +15765,26 @@ algorithm
end for;
end make2CMakeInclude;

public function getCMakeVersion
"Get CMake version"
input String pathToCMake = Autoconf.cmake;
output SemanticVersion.Version cmakeVersion;
protected
Integer retVal;
String cmakeVersionLogFile = "systemCall_cmakeVersion.log";
String cmakeVersionString;
algorithm
// Regex magic to read major.minor.patch version from cmake --version
retVal := System.systemCall(pathToCMake + " --version 2>&1 | grep \"^.*cmake version\" | sed -e 's/^.*cmake version *//' | sed -e 's/-.*//'", cmakeVersionLogFile);
if 0 <> retVal then
System.removeFile(cmakeVersionLogFile);
Error.addInternalError("Failed to get version from " + pathToCMake, sourceInfo());
end if;
cmakeVersionString := System.trimWhitespace(System.readFile(cmakeVersionLogFile));
cmakeVersion := SemanticVersion.parse(cmakeVersionString);
System.removeFile(cmakeVersionLogFile);
end getCMakeVersion;

function getSimIteratorSize
input list<BackendDAE.SimIterator> iters;
output Integer size = 1;
Expand Down
20 changes: 12 additions & 8 deletions OMCompiler/Compiler/Util/Flags.mo
Expand Up @@ -1363,13 +1363,8 @@ constant ConfigFlag FMI_FLAGS = CONFIG_FLAG(141, "fmiFlags", NONE(), EXTERNAL(),
Gettext.gettext("Add simulation flags to FMU. Will create <fmiPrefix>_flags.json in resources folder with given flags. Use --fmiFlags or --fmiFlags=none to disable [default]. Use --fmiFlags=default for the default simulation flags. To pass flags use e.g. --fmiFlags=s:cvode,nls:homotopy or --fmiFlags=path/to/yourFlags.json."));

constant ConfigFlag FMU_CMAKE_BUILD = CONFIG_FLAG(142, "fmuCMakeBuild",
NONE(), EXTERNAL(), STRING_FLAG("default"),
SOME(STRING_DESC_OPTION({
("default", Gettext.notrans("Let omc decide if CMake should be used.")),
("true", Gettext.notrans("Use CMake to compile FMU binaries.")),
("false", Gettext.notrans("Use default GNU Autoconf toolchain to compile FMU binaries."))
})),
Gettext.gettext("Defines if FMUs will be configured and build with CMake."));
NONE(), EXTERNAL(), BOOL_FLAG(true), NONE(),
Gettext.gettext("Configured and build FMU with CMake if true."));

constant ConfigFlag NEW_BACKEND = CONFIG_FLAG(143, "newBackend",
NONE(), EXTERNAL(), BOOL_FLAG(false), NONE(),
Expand Down Expand Up @@ -1437,8 +1432,9 @@ constant ConfigFlag OBFUSCATE = CONFIG_FLAG(152, "obfuscate",
Gettext.gettext("Obfuscates identifiers in the simulation model"));

constant ConfigFlag FMU_RUNTIME_DEPENDS = CONFIG_FLAG(153, "fmuRuntimeDepends",
NONE(), EXTERNAL(), STRING_FLAG("modelica"),
NONE(), EXTERNAL(), STRING_FLAG("default"),
SOME(STRING_DESC_OPTION({
("default", Gettext.notrans("Depending on CMake version. If CMake version >= 3.21 use \"modelica\", otherwise use \"none\"")),
("none", Gettext.notrans("No runtime library dependencies are copied into the FMU.")),
("modelica", Gettext.notrans("All modelica runtime library dependencies are copied into the FMU." +
"System librarys located in '/lib*', '/usr/lib*' and '/usr/local/lib*' are excluded." +
Expand Down Expand Up @@ -1490,6 +1486,14 @@ algorithm
isMember := listMember(hasMember, Flags.getConfigStringList(inFlag));
end isConfigFlagSet;

public function getConfigName
"Returns name of configuration flag"
input ConfigFlag inFlag;
output String name;
algorithm
CONFIG_FLAG(name = name) := inFlag;
end getConfigName;

public function getConfigValue
"Returns the value of a configuration flag."
input ConfigFlag inFlag;
Expand Down
31 changes: 22 additions & 9 deletions OMCompiler/Compiler/Util/SemanticVersion.mo
Expand Up @@ -39,16 +39,19 @@ import System;
public

uniontype Version
record SEMVER
Integer major, minor, patch;
list<String> prerelease, meta;
end SEMVER;
record NONSEMVER
String version;
end NONSEMVER;
record SEMVER
"Semantic version number MAJOR.MINOR.PATCH, see https://semver.org/."
Integer major, minor, patch;
list<String> prerelease, meta;
end SEMVER;
record NONSEMVER
"Non-semantic version number"
String version;
end NONSEMVER;
end Version;

function parse
"Parse version string into SemanticVersion.Version."
input String s;
input Boolean nonsemverAsZeroZeroZero = false;
output Version v;
Expand Down Expand Up @@ -93,6 +96,13 @@ algorithm
end parse;

function compare
"Compare two versions v1 and v2.
If v1 and v2 both non-semver or both semver:
Return -1 if the first is smallest,
1 if the second is smallest,
or 0 if they are equal.
If v1 non-semver and v2 semver: return -1.
If v1 semver and v2 non-semver: return 1."
input Version v1, v2;
input Boolean comparePrerelease = true;
input Boolean compareBuildInformation = false;
Expand Down Expand Up @@ -151,6 +161,7 @@ algorithm
end toString;

function isPrerelease
"Return true if semver version has pre-release information."
input Version v;
output Boolean b;
algorithm
Expand All @@ -161,6 +172,7 @@ algorithm
end isPrerelease;

function hasMetaInformation
"Return true if semver version has meta information."
input Version v;
output Boolean b;
algorithm
Expand All @@ -172,12 +184,13 @@ algorithm
end hasMetaInformation;

function isSemVer
"Return true if version is of semantic versioning type."
input Version v;
output Boolean b;
algorithm
b := match v
case NONSEMVER() then false;
else true;
case SEMVER() then true;
else false;
end match;
end isSemVer;

Expand Down
3 changes: 2 additions & 1 deletion OMCompiler/Examples/CMakeLists.txt
Expand Up @@ -7,4 +7,5 @@ FILE(GLOB ALL_C *.c)
FILE(GLOB ALL_H *.h)

SET(DOCS ${ALL_MO} ${ALL_MOS} ${ALL_ONB} ${ALL_C} ${ALL_H})
INSTALL(FILES ${DOCS} DESTINATION testmodels)
# TODO: Add this install to some User's Guide target
INSTALL(FILES ${DOCS} DESTINATION "share/doc/omc/testmodels")
Expand Up @@ -973,7 +973,7 @@ int initRuntimeAndSimulation(int argc, char**argv, DATA *data, threadData_t *thr
setGlobalLoggingTime(data->simulationInfo);
if(omc_flag[FLAG_LV_MAX_WARN]) {
data->simulationInfo->maxWarnDisplays = atoi(omc_flagValue[FLAG_LV_MAX_WARN]);
infoStreamPrint(LOG_STDOUT, 0, "Display limit for repeating warnings changed to %u.", data->simulationInfo->maxWarnDisplays);
infoStreamPrint(LOG_STDOUT, 0, "Display limit for repeating warnings changed to %lu.", data->simulationInfo->maxWarnDisplays);
} else {
data->simulationInfo->maxWarnDisplays = DEFAULT_FLAG_LV_MAX_WARN;
}
Expand Down
17 changes: 11 additions & 6 deletions doc/UsersGuide/Makefile
@@ -1,9 +1,15 @@
# Makefile for Sphinx documentation
#

OPENMODELICA_ROOT = $(CURDIR)/../../
OPENMODELICA_ROOT = $(CURDIR)/../..
# OMPython needs this
OPENMODELICAHOME := $(OPENMODELICA_ROOT)/build/
OPENMODELICAHOME := $(shell \
if [ -d $(OPENMODELICA_ROOT)/build_cmake/install ]; \
then echo '$(OPENMODELICA_ROOT)/build_cmake/install'; \
elif [ -d $(OPENMODELICA_ROOT)/install_cmake ]; \
then echo '$(OPENMODELICA_ROOT)/install_cmake'; \
else \
echo '$(OPENMODELICA_ROOT)/build/'; fi)

OMSUSERSGUIDE = $(OPENMODELICA_ROOT)/OMSimulator/doc/UsersGuide

Expand Down Expand Up @@ -233,7 +239,7 @@ source/openmodelica.bib: resolve-crossref.py ../bibliography/openmodelica.bib
./resolve-crossref.py "../bibliography/openmodelica.bib" source/openmodelica.bib
source/interface.inc: interface.mos
@mkdir -p tmp
$(OPENMODELICA_ROOT)/build/bin/omc -g=MetaModelica -d=nogen interface.mos
$(OPENMODELICAHOME)/bin/omc -g=MetaModelica -d=nogen interface.mos
mv interface.inc $@

OMEDIT_ICONS_BASE=connect-mode.svg transition-mode.svg parametric-plot-window.svg plot-window.svg array-parametric-plot-window.svg array-plot-window.svg re-simulate.svg tlm-simulate.svg interface-data.svg simulation-parameters.svg
Expand All @@ -255,7 +261,6 @@ source/media/omedit-icons/%.png: source/media/omedit-icons/%.svg
inkscape "$<" --export-png="$@"
source/media/omedit-icons/%.pdf: source/media/omedit-icons/%.svg
inkscape "$<" --export-pdf="$@"

source/media/omoptim-icons/%.png: $(OPENMODELICA_ROOT)/OMOptim/OMOptim/GUI/Resources/icons/%.png
@mkdir -p source/media/omoptim-icons
cp -a "$<" "$@"
Expand All @@ -266,10 +271,10 @@ readme: readme/sphinxcontribopenmodelica.py
ln -sf ../source/aplot.svg readme
sphinx-build -b html -t nomathjax -d build/readme/doctrees readme build/readme/html
source/simoptions.inc:
$(OPENMODELICA_ROOT)/build/bin/omc +help=simulation-sphinxoutput > "$@.tmp"
$(OPENMODELICAHOME)/bin/omc +help=simulation-sphinxoutput > "$@.tmp"
mv "$@.tmp" "$@"
source/omchelptext.rst:
$(OPENMODELICA_ROOT)/build/bin/omc +help=omcall-sphinxoutput > "$@.tmp"
$(OPENMODELICAHOME)/bin/omc +help=omcall-sphinxoutput > "$@.tmp"
mv "$@.tmp" "$@"
source/omsimulator-help.inc:
$(OPENMODELICAHOME)/bin/OMSimulator --help > "$@.tmp"
Expand Down
14 changes: 12 additions & 2 deletions doc/UsersGuide/README.md
Expand Up @@ -10,8 +10,11 @@ set `GITHUB_AUTH`.

- omc, omc-diff and omsimulator
- Inkscape
- Sphinx
- Python3 and packages from [requirements.txt](https://raw.githubusercontent.com/OpenModelica/OpenModelica-doc/master/UsersGuide/source/requirements.txt)
- [Sphinx](http://sphinx-doc.org/)
- Python3 and packages from [source/requirements.txt](./source/requirements.txt)
```bash
pip3 install --upgrade -r source/requirements.txt
```
- Python PyGithub package

### GITHUB_AUTH
Expand Down Expand Up @@ -43,6 +46,13 @@ https://github.com/OpenModelica/OpenModelica with the PyGithub package.
- Install `inkscape` and make sure it's in PATH.

## Build instructions

```bash
make html
```

## Preview build

```bash
python3 -m http.server --directory build/html
```
2 changes: 1 addition & 1 deletion doc/UsersGuide/source/.gitignore
Expand Up @@ -74,4 +74,4 @@ tmp.rst
tmp.wiki
VanDerPol.pdf
VanDerPol.png
VanDerPol.svg
VanDerPol.svg

0 comments on commit 86483b1

Please sign in to comment.