diff --git a/Project.toml b/Project.toml index c4c1c50..7af0806 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "FMIBuild" uuid = "226f0e26-6dd6-4589-ada7-1d32f6e1d800" authors = ["TT ", "LM "] -version = "0.3.0" +version = "0.3.1" [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" diff --git a/src/FMIBuild.jl b/src/FMIBuild.jl index 479103f..9349f43 100644 --- a/src/FMIBuild.jl +++ b/src/FMIBuild.jl @@ -14,7 +14,6 @@ using FMIBase #using FMICore: fmi2CausalityToString, fmi2VariabilityToString, fmi2InitialToString, fmi2DependencyKindToString #using FMICore: fmi2RealAttributes, fmi2IntegerAttributes, fmi2BooleanAttributes, fmi2StringAttributes, fmi2EnumerationAttributes #using FMICore: fmi2RealAttributesExt, fmi2IntegerAttributesExt, fmi2BooleanAttributesExt, fmi2StringAttributesExt, fmi2EnumerationAttributesExt -#using FMIExport: fmi2SaveModelDescription import PackageCompiler import Pkg @@ -39,7 +38,7 @@ function packagePath(pkg; ) end """ - fmi2Save(fmu::FMU2, + saveFMU(fmu::FMU2, fmu_path::String, fmu_src_file::Union{Nothing, String}=nothing; standalone=true, @@ -203,7 +202,7 @@ function saveFMU(fmu::FMU2, fmu_path::String, fmu_src_file::Union{Nothing, Strin cdata = read(f, String); close(f) - # ToDo: This will fail badly on `fmi2Save(a, (b, c), d)` -> use Julia code parser + # ToDo: This will fail badly on `saveFMU(a, (b, c), d)` -> use Julia code parser if removeNoExportBlocks @info "[Build FMU] Removing `FMIBUILD_NO_EXPORT_*` blocks ..." @@ -235,27 +234,11 @@ function saveFMU(fmu::FMU2, fmu_path::String, fmu_src_file::Union{Nothing, Strin end Pkg.activate(defaultEnv) default_fmiexportPath = packagePath("FMIExport") - default_fmicorePath = packagePath("FMICore") + default_fmibasePath = packagePath("FMIBase") # adding Pkgs Pkg.activate(merge_dir) - if isnothing(default_fmicorePath) - @info "[Build FMU] > Default environment `$(defaultEnv)` has no dependency on `FMICore`, adding `FMICore` from registry." - Pkg.add("FMICore") - else - old_fmicorePath = packagePath("FMICore") - if isnothing(old_fmicorePath) - @info "[Build FMU] > `FMICore` not installed, adding at `$(default_fmicorePath)`, adding `FMICore` from default environment." - Pkg.add(path=default_fmicorePath) - elseif lowercase(old_fmicorePath) == lowercase(default_fmicorePath) - @info "[Build FMU] > Most recent version (as in default environment) of `FMICore` already checked out, is `$(default_fmicorePath)`." - else - @info "[Build FMU] > Replacing `FMICore` at `$(old_fmicorePath)` with the default environment installation at `$(default_fmicorePath)`." - Pkg.add(path=default_fmicorePath) - end - end - # [note] redirect FMIExport.jl package in case the active environment (the env the installer is called from) # has a *more recent* version of FMIExport.jl than the registry (necessary for Github-CI to use the current version from a PR) if isnothing(default_fmiexportPath) # the environemnt the exporter is called from *has no* FMIExport.jl installed @@ -273,6 +256,23 @@ function saveFMU(fmu::FMU2, fmu_path::String, fmu_src_file::Union{Nothing, Strin end end + # FMIBase.jl + if isnothing(default_fmibasePath) + @info "[Build FMU] > Default environment `$(defaultEnv)` has no dependency on `FMIBase`, adding `FMIBase` from registry." + Pkg.add("FMIBase") + else + old_fmibasePath = packagePath("FMIBase") + if isnothing(old_fmibasePath) + @info "[Build FMU] > `FMIBase` not installed, adding at `$(default_fmibasePath)`, adding `FMIBase` from default environment." + Pkg.add(path=default_fmibasePath) + elseif lowercase(old_fmibasePath) == lowercase(default_fmibasePath) + @info "[Build FMU] > Most recent version (as in default environment) of `FMIBase` already checked out, is `$(default_fmibasePath)`." + else + @info "[Build FMU] > Replacing `FMIBase` at `$(old_fmibasePath)` with the default environment installation at `$(default_fmibasePath)`." + Pkg.add(path=default_fmibasePath) + end + end + if removeLibDependency cdata = replace(cdata, r"(using|import) FMIBuild" => "") try @@ -336,7 +336,7 @@ function saveFMU(fmu::FMU2, fmu_path::String, fmu_src_file::Union{Nothing, Strin startPacking = time() @info "[Build FMU] Building model description ..." - fmi2SaveModelDescription(fmu.modelDescription, md_path) + saveModelDescription(fmu.modelDescription, md_path) @info "[Build FMU] ... building model description done." # parse and zip directories @@ -467,15 +467,15 @@ function dependencyKindString(dependencies::AbstractArray) return "" end - depStr = "$(fmi2DependencyKindToString(dependencies[1]))" + depStr = "$(dependencyKindToString(md, dependencies[1]))" for d in 2:length(dependencies) - depStr *= " $(fmi2DependencyKindToString(dependencies[d]))" + depStr *= " $(dependencyKindToString(md, dependencies[d]))" end return depStr end -function addFieldsAsAttributes(node, _struct, skiplist=()) +function addFieldsAsAttributes(md, node, _struct, skiplist=()) for field in fieldnames(typeof(_struct)) if field ∉ skiplist @@ -495,13 +495,13 @@ function addFieldsAsAttributes(node, _struct, skiplist=()) value = (value ? "true" : "false") elseif field == :causality - value = fmi2CausalityToString(value) + value = causalityToString(md, value) elseif field == :variability - value = fmi2VariabilityToString(value) + value = variabilityToString(md, value) elseif field == :initial - value = fmi2InitialToString(value) + value = initialToString(md, value) elseif field == :dependencies if length(value) <= 0 @@ -517,9 +517,9 @@ function addFieldsAsAttributes(node, _struct, skiplist=()) if length(value) <= 0 return "" end - depStr = "$(fmi2DependencyKindToString(value[1]))" + depStr = "$(dependencyKindToString(md, value[1]))" for d in 2:length(value) - depStr *= " $(fmi2DependencyKindToString(value[d]))" + depStr *= " $(dependencyKindToString(md, value[d]))" end value = depStr end @@ -529,7 +529,7 @@ function addFieldsAsAttributes(node, _struct, skiplist=()) end end -function fmi2SaveModelDescription(md::fmi2ModelDescription, file_path::String) +function saveModelDescription(md::fmi2ModelDescription, file_path::String) doc = XMLDocument() doc_root = ElementNode("fmiModelDescription") @@ -550,7 +550,7 @@ function fmi2SaveModelDescription(md::fmi2ModelDescription, file_path::String) elseif isa(md.generationDateAndTime, String) dateTimeString = md.generationDateAndTime else - @warn "fmi2SaveModelDescription(...): Unkown data type for field `generationDateAndTime`. Supported is `DateTime` and `String`, but given `$(md.generationDateAndTime)` (typeof `$(typeof(md.generationDateAndTime))`)." + @warn "saveModelDescription(...): Unkown data type for field `generationDateAndTime`. Supported is `DateTime` and `String`, but given `$(md.generationDateAndTime)` (typeof `$(typeof(md.generationDateAndTime))`)." end link!(doc_root, AttributeNode("generationDateAndTime", dateTimeString)) end @@ -564,13 +564,13 @@ function fmi2SaveModelDescription(md::fmi2ModelDescription, file_path::String) if !isnothing(md.modelExchange) me = ElementNode("ModelExchange") link!(doc_root, me) - addFieldsAsAttributes(me, md.modelExchange) + addFieldsAsAttributes(md, me, md.modelExchange) end if !isnothing(md.coSimulation) cs = ElementNode("CoSimulation") link!(doc_root, cs) - addFieldsAsAttributes(cs, md.coSimulation) + addFieldsAsAttributes(md, cs, md.coSimulation) end if !isnothing(md.typeDefinitions) @@ -581,32 +581,32 @@ function fmi2SaveModelDescription(md::fmi2ModelDescription, file_path::String) st = ElementNode("SimpleType") link!(td, st) - addFieldsAsAttributes(st, typdef, (:attribute,)) + addFieldsAsAttributes(md, st, typdef, (:attribute,)) if isa(typdef.attribute, fmi2RealAttributes) tn = ElementNode("Real") - addFieldsAsAttributes(tn, typdef.attribute) + addFieldsAsAttributes(md, tn, typdef.attribute) link!(st, tn) elseif isa(typdef.attribute, fmi2IntegerAttributes) tn = ElementNode("Integer") - addFieldsAsAttributes(tn, typdef.attribute) + addFieldsAsAttributes(md, tn, typdef.attribute) link!(st, tn) elseif isa(typdef.attribute, fmi2BooleanAttributes) tn = ElementNode("Boolean") - addFieldsAsAttributes(tn, typdef.attribute) + addFieldsAsAttributes(md, tn, typdef.attribute) link!(st, tn) elseif isa(typdef.attribute, fmi2StringAttributes) tn = ElementNode("String") - addFieldsAsAttributes(tn, typdef.attribute) + addFieldsAsAttributes(md, tn, typdef.attribute) link!(st, tn) elseif isa(typdef.attribute, fmi2EnumerationAttributes) tn = ElementNode("Enumeration") - addFieldsAsAttributes(tn, typdef.attribute, (:items,)) + addFieldsAsAttributes(md, tn, typdef.attribute, (:items,)) link!(st, tn) for j in 1:length(typdef.attribute) itemNode = ElementNode("Item") - addFieldsAsAttributes(itemNode, typdef.attribute[j]) + addFieldsAsAttributes(md, itemNode, typdef.attribute[j]) link!(tn, itemNode) end else @@ -625,42 +625,42 @@ function fmi2SaveModelDescription(md::fmi2ModelDescription, file_path::String) sv_node = ElementNode("ScalarVariable") link!(mv, sv_node) - addFieldsAsAttributes(sv_node, sv, (:attribute,)) + addFieldsAsAttributes(md, sv_node, sv, (:attribute,)) # Real if sv.Real != nothing r_node = ElementNode("Real") - addFieldsAsAttributes(r_node, sv.Real, (:attributes,)) - addFieldsAsAttributes(r_node, sv.attribute.attributes) + addFieldsAsAttributes(md, r_node, sv.Real, (:attributes,)) + addFieldsAsAttributes(md, r_node, sv.attribute.attributes) link!(sv_node, r_node) end # Integer if sv.Integer != nothing i_node = ElementNode("Integer") - addFieldsAsAttributes(i_node, sv.Integer, (:attributes,)) - addFieldsAsAttributes(i_node, sv.attribute.attributes) + addFieldsAsAttributes(md, i_node, sv.Integer, (:attributes,)) + addFieldsAsAttributes(md, i_node, sv.attribute.attributes) link!(sv_node, i_node) end # Boolean if sv.Boolean != nothing b_node = ElementNode("Boolean") - addFieldsAsAttributes(b_node, sv.Boolean) + addFieldsAsAttributes(md, b_node, sv.Boolean) link!(sv_node, b_node) end # String if sv.String != nothing s_node = ElementNode("String") - addFieldsAsAttributes(s_node, sv.String) + addFieldsAsAttributes(md, s_node, sv.String) link!(sv_node, s_node) end # Enumeration if sv.Enumeration != nothing e_node = ElementNode("Enumeration") - addFieldsAsAttributes(e_node, sv.Enumeration) + addFieldsAsAttributes(md, e_node, sv.Enumeration) link!(sv_node, e_node) end end @@ -676,7 +676,7 @@ function fmi2SaveModelDescription(md::fmi2ModelDescription, file_path::String) uk = md.modelStructure.outputs[i] uk_node = ElementNode("Unknown") - addFieldsAsAttributes(uk_node, uk) + addFieldsAsAttributes(md, uk_node, uk) link!(outs, uk_node) end end @@ -689,7 +689,7 @@ function fmi2SaveModelDescription(md::fmi2ModelDescription, file_path::String) uk = md.modelStructure.derivatives[i] uk_node = ElementNode("Unknown") - addFieldsAsAttributes(uk_node, uk) + addFieldsAsAttributes(md, uk_node, uk) link!(ders, uk_node) end end @@ -702,7 +702,7 @@ function fmi2SaveModelDescription(md::fmi2ModelDescription, file_path::String) uk = md.modelStructure.initialUnknowns[i] uk_node = ElementNode("Unknown") - addFieldsAsAttributes(uk_node, uk) + addFieldsAsAttributes(md, uk_node, uk) link!(inis, uk_node) end end diff --git a/template/ME/FMU2/src/FMU2_content.jl b/template/ME/FMU2/src/FMU2_content.jl index 6fbbaab..bdaef16 100644 --- a/template/ME/FMU2/src/FMU2_content.jl +++ b/template/ME/FMU2/src/FMU2_content.jl @@ -3,12 +3,11 @@ # Licensed under the MIT license. See LICENSE file in the project root for details. # -using FMICore -using FMICore: fmi2CallbackFunctions, fmi2Component, fmi2ComponentEnvironment, fmi2EventInfo, fmi2ValueReference -using FMICore: fmi2Real, fmi2Integer, fmi2Boolean, fmi2String, fmi2True, fmi2False, fmi2StatusOK, fmi2StatusWarning, fmi2StatusError, fmi2StatusFatal -using FMICore: fmi2Status, fmi2Type -using FMICore: FMU2Component -import FMICore: logInfo, logWarning, logError +using FMIBase.FMICore +using FMIBase.FMICore: fmi2CallbackFunctions, fmi2Component, fmi2ComponentEnvironment, fmi2EventInfo, fmi2ValueReference +using FMIBase.FMICore: fmi2Real, fmi2Integer, fmi2Boolean, fmi2String, fmi2True, fmi2False, fmi2StatusOK, fmi2StatusWarning, fmi2StatusError, fmi2StatusFatal +using FMIBase.FMICore: fmi2Status, fmi2Type +import FMIBase: logInfo, logWarning, logError, FMU2Component ############## @@ -22,7 +21,7 @@ global FMIBUILD_INSTANCES = [] function dereferenceInstance(address::fmi2Component) global FMIBUILD_FMU for component in FMIBUILD_FMU.components - if component.compAddr == address + if component.addr == address return component end end @@ -89,7 +88,7 @@ Base.@ccallable function fmi2Instantiate(_instanceName::fmi2String, end Base.@ccallable function fmi2FreeInstance(_component::fmi2Component)::Cvoid - return FMICore.fmi2FreeInstance!(FMIBUILD_FMU.cFreeInstance, _component) + return FMICore.fmi2FreeInstance(FMIBUILD_FMU.cFreeInstance, _component) end Base.@ccallable function fmi2SetDebugLogging(_component::fmi2Component, loggingOn::fmi2Boolean, nCategories::Csize_t, categories::Ptr{fmi2String})::fmi2Status diff --git a/template/ME/FMU2/src/FMU2_content_debug.jl b/template/ME/FMU2/src/FMU2_content_debug.jl index a5421d1..342389e 100644 --- a/template/ME/FMU2/src/FMU2_content_debug.jl +++ b/template/ME/FMU2/src/FMU2_content_debug.jl @@ -3,12 +3,11 @@ # Licensed under the MIT license. See LICENSE file in the project root for details. # -using FMICore -using FMICore: fmi2CallbackFunctions, fmi2Component, fmi2ComponentEnvironment, fmi2EventInfo, fmi2ValueReference -using FMICore: fmi2Real, fmi2Integer, fmi2Boolean, fmi2String, fmi2True, fmi2False, fmi2StatusOK, fmi2StatusWarning, fmi2StatusError, fmi2StatusFatal -using FMICore: fmi2Status, fmi2Type -using FMICore: FMU2Component -import FMICore: logInfo, logWarning, logError +using FMIBase.FMICore +using FMIBase.FMICore: fmi2CallbackFunctions, fmi2Component, fmi2ComponentEnvironment, fmi2EventInfo, fmi2ValueReference +using FMIBase.FMICore: fmi2Real, fmi2Integer, fmi2Boolean, fmi2String, fmi2True, fmi2False, fmi2StatusOK, fmi2StatusWarning, fmi2StatusError, fmi2StatusFatal +using FMIBase.FMICore: fmi2Status, fmi2Type +import FMIBase: logInfo, logWarning, logError, FMU2Component, statusToString ############## @@ -22,7 +21,7 @@ global FMIBUILD_INSTANCES = [] function dereferenceInstance(address::fmi2Component) global FMIBUILD_FMU for component in FMIBUILD_FMU.components - if component.compAddr == address + if component.addr == address return component end end @@ -106,7 +105,7 @@ Base.@ccallable function fmi2FreeInstance(_component::fmi2Component)::Cvoid if FMIBUILD_LOGGING logInfo(_component, "fmi2FreeInstance($(_component))") end - FMICore.fmi2FreeInstance!(FMIBUILD_FMU.cFreeInstance, _component) + FMICore.fmi2FreeInstance(FMIBUILD_FMU.cFreeInstance, _component) if FMIBUILD_LOGGING logInfo(_component, "\t-> [NOTHING]") end