Thanks a lot for the advice earlier @ThummeTo & @littlelib , it was really informative!
As suggested, I attempted to place my code within a Julia package. Below is the workflow I followed. Since Iβm a newbie here, I have shared all in detail. While it seems to work better now and does build something, I still run into an error at the end. Iβve included both the workflow and the results.
I would greatly appreciate any help in fixing the error and successfully saving the FMU file!
Step 1: Create a New Julia Package
using Pkg
Pkg.generate("FMUManipulation")
Navigate to the package directory:
cd FMUManipulation
Step 2: Update Project.toml
using Pkg
Pkg.add("FMI")
Pkg.add("FMIExport")
Pkg.add("FMICore")
Pkg.add("FMIZoo")
Pkg.add("FMIBuild")
Step 3: Replace Code in src/FMUManipulation.jl
Open src/FMUManipulation.jl
and replace its contents with your manipulation code. Hereβs what I used:
module FMUManipulation
using FMI
using FMIExport
using FMICore
using FMIZoo
using FMIBuild
originalGetReal = nothing # function pointer to the original fmi2GetReal c-function
function myGetReal!(c::fmi2Component, vr::Union{Array{fmi2ValueReference}, Ptr{fmi2ValueReference}}, nvr::Csize_t, value::Union{Array{fmi2Real}, Ptr{fmi2Real}})
global originalGetReal
status = fmi2GetReal!(originalGetReal, c, vr, nvr, value)
if isa(value, Ptr{fmi2Real})
value = unsafe_wrap(Array{fmi2Real}, value, nvr, own=false)
end
if isa(vr, Ptr{fmi2Real})
vr = unsafe_wrap(Array{fmi2Real}, vr, nvr, own=false)
end
for i in 1:nvr
if vr[i] == 335544320 # value reference for "positionSensor.s"
value[i] *= 2.0
end
end
return status
end
function FMIBUILD_CONSTRUCTOR(resPath)
global originalGetReal
fmu = loadFMU(joinpath(resPath, "SpringDamperPendulum1D.fmu"))
originalGetReal = fmu.cGetReal
fmi2SetFctGetReal(fmu, myGetReal!)
return fmu
end
function save_my_fmu(fmu_save_path)
FMIBuild.saveFMU(fmu, fmu_save_path)
end
end # module FMUManipulation
Step 4: Test Your Package
In the Julia REPL, I activated the new package and tested the FMU manipulation:
using Pkg
Pkg.activate("path/to/FMUManipulation")
using FMUManipulation
using FMIZoo
using FMIBuild
# Get the path to the SpringDamperPendulum1D FMU from FMIZoo
sourceFMU = FMIZoo.get_model_filename("SpringDamperPendulum1D", "Dymola", "2022x")
# Load and manipulate the FMU using the directory containing the FMU file
fmu = FMUManipulation.FMIBUILD_CONSTRUCTOR(dirname(sourceFMU))
# Specify the path where you want to save the modified FMU
fmu_save_path = joinpath(pwd(), "Manipulation.fmu")
# Save the modified FMU
FMUManipulation.save_my_fmu(fmu_save_path)
However, this last line of code throws error. Sorry I know the error log is quite big enough⦠but any how I hope it would help!
julia> FMUManipulation.save_my_fmu(fmu, fmu_save_path)
[ Info: [Build FMU] Automatically determined build file at: `C:\Users\Jisna\FMUManipulation\src\FMUManipulation.jl`.
[ Info: [Build FMU] Generating package ...
[ Info: [Build FMU] Source package is C:\Users\Jisna\FMUManipulation, deployed at C:/Users/Jisna/AppData/Local/Temp/fmibuildjl_HJXV54\merged_SpringDamperPendulum1D
[ Info: [Build FMU] Relative src file path is src\FMUManipulation.jl
[ Info: [Build FMU] ... reading FMU template file at C:\Users\Jisna\.julia\packages\FMIBuild\zfhlh\src/../template/ME/FMU2/src/FMU2_content.jl
[ Info: [Build FMU] ... reading old FMU source file at C:/Users/Jisna/AppData/Local/Temp/fmibuildjl_HJXV54\merged_SpringDamperPendulum1D\src\FMUManipulation.jl
[ Info: [Build FMU] Removing `FMIBUILD_NO_EXPORT_*` blocks ...
[ Info: [Build FMU] ... removed `FMIBUILD_NO_EXPORT_*` blocks.
[ Info: [Build FMU] Adding/removing dependencies ...
[ Info: [Build FMU] > Using active environment `C:\Users\Jisna\FMUManipulation\Project.toml`.
Activating project at `C:\Users\Jisna\FMUManipulation`
Activating project at `C:\Users\Jisna\AppData\Local\Temp\fmibuildjl_HJXV54\merged_SpringDamperPendulum1D`
[ Info: [Build FMU] > Most recent version of `FMIExport` already checked out for FMU, is `C:\Users\Jisna\.julia\packages\FMIExport\DQIzD`.
[ Info: [Build FMU] > Most recent version (as in default environment) of `FMIBase` already checked out, is `C:\Users\Jisna\.julia\packages\FMIBase\kd0aT`.
Updating `C:\Users\Jisna\AppData\Local\Temp\fmibuildjl_HJXV54\merged_SpringDamperPendulum1D\Project.toml`
[226f0e26] - FMIBuild v0.3.2
Updating `C:\Users\Jisna\AppData\Local\Temp\fmibuildjl_HJXV54\merged_SpringDamperPendulum1D\Manifest.toml`
[226f0e26] - FMIBuild v0.3.2
[9b87118b] - PackageCompiler v2.1.19
[ Info: [Build FMU] > Removed FMIBuild
Activating project at `C:\Users\Jisna\FMUManipulation`
[ Info: [Build FMU] ... adding/removing dependencies done.
[ Info: [Build FMU] ... generating new FMU source file at C:/Users/Jisna/AppData/Local/Temp/fmibuildjl_HJXV54\merged_SpringDamperPendulum1D\src\FMUManipulation.jl
[ Info: [Build FMU] ... generating package done.
[ Info: [Build FMU] Compiling FMU ...
PackageCompiler: bundled libraries:
βββ Base:
β βββ libLLVM-14jl.dll - 109.118 MiB
β βββ libatomic-1.dll - 269.943 KiB
β βββ libdSFMT.dll - 117.661 KiB
β βββ libgcc_s_seh-1.dll - 676.965 KiB
β βββ libgfortran-5.dll - 11.193 MiB
β βββ libgmp-10.dll - 1.070 MiB
β βββ libgmp.dll - 1.070 MiB
β βββ libgmpxx-4.dll - 321.332 KiB
β βββ libgmpxx.dll - 321.332 KiB
β βββ libgomp-1.dll - 1.439 MiB
β βββ libjulia-codegen.dll - 90.539 MiB
β βββ libjulia-internal.dll - 12.243 MiB
β βββ libmpfr-6.dll - 2.355 MiB
β βββ libmpfr.dll - 2.355 MiB
β βββ libopenlibm.dll - 369.265 KiB
β βββ libpcre2-16-0.dll - 697.275 KiB
β βββ libpcre2-16.dll - 697.275 KiB
β βββ libpcre2-32-0.dll - 668.666 KiB
β βββ libpcre2-32.dll - 668.666 KiB
β βββ libpcre2-8-0.dll - 759.307 KiB
β βββ libpcre2-8.dll - 759.307 KiB
β βββ libpcre2-posix-3.dll - 112.437 KiB
β βββ libquadmath-0.dll - 1.169 MiB
β βββ libssp-0.dll - 152.373 KiB
β βββ libstdc++-6.dll - 22.621 MiB
β βββ libuv-2.dll - 947.011 KiB
β βββ libwinpthread-1.dll - 330.251 KiB
β βββ libz.dll - 217.723 KiB
β βββ libjulia.dll - 200.572 KiB
βββ Stdlibs:
β βββ OpenBLAS_jll
β β βββ libopenblas64_.dll - 35.020 MiB
β βββ LibCURL_jll
β β βββ libcurl-4.dll - 840.702 KiB
β βββ nghttp2_jll
β β βββ libnghttp2-14.dll - 853.126 KiB
β βββ SuiteSparse_jll
β β βββ libamd.dll - 157.027 KiB
β β βββ libbtf.dll - 113.418 KiB
β β βββ libcamd.dll - 161.690 KiB
β β βββ libccolamd.dll - 161.771 KiB
β β βββ libcholmod.dll - 1.246 MiB
β β βββ libcolamd.dll - 144.054 KiB
β β βββ libklu.dll - 325.667 KiB
β β βββ libldl.dll - 111.612 KiB
β β βββ librbio.dll - 165.083 KiB
β β βββ libspqr.dll - 356.213 KiB
β β βββ libsuitesparseconfig.dll - 116.050 KiB
β β βββ libumfpack.dll - 1.058 MiB
β βββ libblastrampoline_jll
β β βββ libblastrampoline-5.dll - 2.102 MiB
β βββ MbedTLS_jll
β β βββ libmbedcrypto.dll - 690.463 KiB
β β βββ libmbedtls.dll - 365.214 KiB
β β βββ libmbedx509.dll - 262.020 KiB
β βββ LibSSH2_jll
β β βββ libssh2.dll - 408.281 KiB
Total library file size: 307.799 MiB
PackageCompiler: bundled artifacts:
βββ HDF5_jll - 12.833 MiB
βββ Hwloc_jll - 9.198 MiB
βββ LLVMOpenMP_jll - 4.286 MiB
βββ Libiconv_jll - 4.087 MiB
βββ MicrosoftMPI_jll - 11.199 MiB
βββ OpenSSL_jll - 13.134 MiB
βββ OpenSpecFun_jll - 798.680 KiB
βββ XML2_jll - 11.091 MiB
βββ libaec_jll - 530.506 KiB
Total artifact file size: 67.126 MiB
β [03m:05s] PackageCompiler: creating compiler .ji image (incremental=false)
β [06m:38s] PackageCompiler: compiling fresh sysimage (incremental=false)
β [01m:54s] PackageCompiler: compiling nonincremental system image
Precompiling project...
2 dependencies had output during precompilation:
β FilePathsBaseTestExt [36f6b4e4-024d-52bd-a01f-148eb20c09de]
β β Warning: Module FilePathsBaseTestExt with build ID ffffffff-ffff-ffff-0000-fa4cf5a5fe15 is missing from the cache.
β β This may mean FilePathsBaseTestExt [36f6b4e4-024d-52bd-a01f-148eb20c09de] does not support precompilation but is imported by a module that does.
β β @ Base loading.jl:1793
β β Error: Error during loading of extension FilePathsBaseTestExt of FilePathsBase, use `Base.retry_load_extensions()` to retry.
β β exception =
β β 1-element ExceptionStack:
β β Declaring __precompile__(false) is not allowed in files that are being precompiled.
β β Stacktrace:
β β [1] _require(pkg::Base.PkgId, env::Nothing)
β β @ Base .\loading.jl:1797
β β [2] _require_prelocked(uuidkey::Base.PkgId, env::Nothing)
β β @ Base .\loading.jl:1660
β β [3] _require_prelocked(uuidkey::Base.PkgId)
β β @ Base .\loading.jl:1658
β β [4] run_extension_callbacks(extid::Base.ExtensionId)
β β @ Base .\loading.jl:1255
β β [5] run_extension_callbacks(pkgid::Base.PkgId)
β β @ Base .\loading.jl:1290
β β [6] run_package_callbacks(modkey::Base.PkgId)
β β @ Base .\loading.jl:1124
β β [7] _require_prelocked(uuidkey::Base.PkgId, env::String)
β β @ Base .\loading.jl:1667
β β [8] macro expansion
β β @ .\loading.jl:1648 [inlined]
β β [9] macro expansion
β β @ .\lock.jl:267 [inlined]
β β [10] require(into::Module, mod::Symbol)
β β @ Base .\loading.jl:1611
β β [11] include
β β @ .\Base.jl:457 [inlined]
β β [12] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::String)
β β @ Base .\loading.jl:2049
β β [13] top-level scope
β β @ stdin:3
β β [14] eval
β β @ .\boot.jl:370 [inlined]
β β [15] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
β β @ Base .\loading.jl:1903
β β [16] include_string
β β @ .\loading.jl:1913 [inlined]
β β [17] exec_options(opts::Base.JLOptions)
β β @ Base .\client.jl:305
β β [18] _start()
β β @ Base .\client.jl:522
β β @ Base loading.jl:1261
β
β FilePathsBaseMmapExt [968c5e7e-8fc3-5f0f-93d2-8a5e0e125e4f]
β β Warning: Module FilePathsBaseMmapExt with build ID ffffffff-ffff-ffff-0000-fa4b684ca3ad is missing from the cache.
β β This may mean FilePathsBaseMmapExt [968c5e7e-8fc3-5f0f-93d2-8a5e0e125e4f] does not support precompilation but is imported by a module that does.
β β @ Base loading.jl:1793
β β Error: Error during loading of extension FilePathsBaseMmapExt of FilePathsBase, use `Base.retry_load_extensions()` to retry.
β β exception =
β β 1-element ExceptionStack:
β β Declaring __precompile__(false) is not allowed in files that are being precompiled.
β β Stacktrace:
β β [1] _require(pkg::Base.PkgId, env::Nothing)
β β @ Base .\loading.jl:1797
β β [2] _require_prelocked(uuidkey::Base.PkgId, env::Nothing)
β β @ Base .\loading.jl:1660
β β [3] _require_prelocked(uuidkey::Base.PkgId)
β β @ Base .\loading.jl:1658
β β [4] run_extension_callbacks(extid::Base.ExtensionId)
β β @ Base .\loading.jl:1255
β β [5] run_extension_callbacks(pkgid::Base.PkgId)
β β @ Base .\loading.jl:1290
β β [6] run_package_callbacks(modkey::Base.PkgId)
β β @ Base .\loading.jl:1124
β β [7] _require_prelocked(uuidkey::Base.PkgId, env::String)
β β @ Base .\loading.jl:1667
β β [8] macro expansion
β β @ .\loading.jl:1648 [inlined]
β β [9] macro expansion
β β @ .\lock.jl:267 [inlined]
β β [10] require(into::Module, mod::Symbol)
β β @ Base .\loading.jl:1611
β β [11] include
β β @ .\Base.jl:457 [inlined]
β β [12] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::String)
β β @ Base .\loading.jl:2049
β β [13] top-level scope
β β @ stdin:3
β β [14] eval
β β @ .\boot.jl:370 [inlined]
β β [15] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
β β @ Base .\loading.jl:1903
β β [16] include_string
β β @ .\loading.jl:1913 [inlined]
β β [17] exec_options(opts::Base.JLOptions)
β β @ Base .\client.jl:305
β β [18] _start()
β β @ Base .\client.jl:522
β β @ Base loading.jl:1261
β
[ Info: PackageCompiler: Executing C:\Users\Jisna\AppData\Local\Temp\fmibuildjl_HJXV54\merged_SpringDamperPendulum1D\src\FMUManipulation.jl => C:\Users\Jisna\AppData\Local\Temp\jl_packagecompiler_cssUSS\jl_5460.tmp
[ Info: PackageCompiler: Done
β’° [00m:34s] PackageCompiler: compiling incremental system imageArgumentError: Package SpringDamperPendulum1D does not have FMIBase in its dependencies:
Stacktrace:ave a partially installed environment. Try `Pkg.instantiate()`
[1] macro expansionges in the environment are installed.
@ .\loading.jl:1634 [inlined]dulum1D checked out for development and have
[2] macro expansiondependency but haven't updated your primary
@ .\lock.jl:267 [inlined], try `Pkg.resolve()`.
β‘ [00m:34s] PackageCompiler: compiling incremental system imageModule, mod::Symbol)
@ Base .\loading.jl:1611
[4] include
@ .\Base.jl:457 [inlined]
[5] _require(pkg::Base.PkgId, env::Nothing)
@ Base .\loading.jl:1840
[6] _require_prelocked(uuidkey::Base.PkgId, env::Nothing)
@ Base .\loading.jl:1660
[7] _require_prelocked
@ .\loading.jl:1658 [inlined]
[8] macro expansion
@ .\lock.jl:267 [inlined]
[9] require(uuidkey::Base.PkgId)
@ Base .\loading.jl:1655
[10] top-level scope
@ C:\Users\Jisna\AppData\Local\Temp\jl_yzutiPChsf:113
in expression starting at C:\Users\Jisna\AppData\Local\Temp\fmibuildjl_HJXV54\merged_SpringDamperPendulum1D\src\FMUManipulation.jl:1
in expression starting at C:\Users\Jisna\AppData\Local\Temp\jl_yzutiPChsf:113
β [00m:34s] PackageCompiler: compiling incremental system image
ERROR: failed process: Process(`'C:\Users\Jisna\.julia\juliaup\julia-1.9.4+0.x64.w64.mingw32\bin\julia.exe' --color=yes --startup-file=no --pkgimages=no '--cpu-target=generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)' '--sysimage=C:\Users\Jisna\AppData\Local\Temp\jl_R0QMDK\tmp_sys.dll' '--project=C:\Users\Jisna\AppData\Local\Temp\fmibuildjl_HJXV54\merged_SpringDamperPendulum1D' '--output-o=C:\Users\Jisna\AppData\Local\Temp\jl_CDKHsbi9Cn-o.a' 'C:\Users\Jisna\AppData\Local\Temp\jl_yzutiPChsf'`, ProcessExited(1)) [1]
Stacktrace:
[1] pipeline_error
@ .\process.jl:565 [inlined]
[2] run(::Cmd; wait::Bool)
@ Base .\process.jl:480
[3] run
@ .\process.jl:477 [inlined]
[4] #20
@ C:\Users\Jisna\.julia\packages\PackageCompiler\nPK9v\ext\TerminalSpinners.jl:157 [inlined]
[5] spin(f::PackageCompiler.var"#20#22"{Cmd}, s::PackageCompiler.TerminalSpinners.Spinner{Base.TTY})
@ PackageCompiler.TerminalSpinners C:\Users\Jisna\.julia\packages\PackageCompiler\nPK9v\ext\TerminalSpinners.jl:164
[6] macro expansion
@ C:\Users\Jisna\.julia\packages\PackageCompiler\nPK9v\ext\TerminalSpinners.jl:157 [inlined]
[7] create_sysimg_object_file(object_file::String, packages::Vector{String}, packages_sysimg::Set{Base.PkgId}; project::String, base_sysimage::String, precompile_execution_file::Vector{String}, precompile_statements_file::Vector{String}, cpu_target::String, script::Nothing, sysimage_build_args::Cmd, extra_precompiles::String, incremental::Bool, import_into_main::Bool)
@ PackageCompiler C:\Users\Jisna\.julia\packages\PackageCompiler\nPK9v\src\PackageCompiler.jl:134
[8] create_sysimg_object_file
@ C:\Users\Jisna\.julia\packages\PackageCompiler\nPK9v\src\PackageCompiler.jl:315 [inlined]
[9] create_sysimage(packages::Vector{String}; sysimage_path::String, project::String, precompile_execution_file::Vector{String}, precompile_statements_file::Vector{String}, incremental::Bool, filter_stdlibs::Bool, cpu_target::String, script::Nothing, sysimage_build_args::Cmd, include_transitive_dependencies::Bool, base_sysimage::String, julia_init_c_file::String, julia_init_h_file::Vector{String}, version::Nothing, soname::Nothing, compat_level::String, extra_precompiles::String, import_into_main::Bool)
@ PackageCompiler C:\Users\Jisna\.julia\packages\PackageCompiler\nPK9v\src\PackageCompiler.jl:652
[10] create_sysimage_workaround(ctx::Pkg.Types.Context, sysimage_path::String, precompile_execution_file::Vector{String}, precompile_statements_file::Vector{String}, incremental::Bool, filter_stdlibs::Bool, cpu_target::String; sysimage_build_args::Cmd, include_transitive_dependencies::Bool, julia_init_c_file::String, julia_init_h_file::Vector{String}, version::Nothing, soname::Nothing, script::Nothing, base_sysimage::Nothing)
@ PackageCompiler C:\Users\Jisna\.julia\packages\PackageCompiler\nPK9v\src\PackageCompiler.jl:1195
[11] create_sysimage_workaround
@ C:\Users\Jisna\.julia\packages\PackageCompiler\nPK9v\src\PackageCompiler.jl:1161 [inlined]
[12] create_library(package_or_project::String, dest_dir::String; lib_name::String, precompile_execution_file::Vector{String}, precompile_statements_file::Vector{String}, incremental::Bool, filter_stdlibs::Bool, force::Bool, header_files::Vector{String}, julia_init_c_file::String, julia_init_h_file::String, version::Nothing, compat_level::String, cpu_target::String, include_lazy_artifacts::Bool, sysimage_build_args::Cmd, include_transitive_dependencies::Bool, include_preferences::Bool, script::Nothing, base_sysimage::Nothing)
@ PackageCompiler C:\Users\Jisna\.julia\packages\PackageCompiler\nPK9v\src\PackageCompiler.jl:1108
[13] create_library
@ C:\Users\Jisna\.julia\packages\PackageCompiler\nPK9v\src\PackageCompiler.jl:1042 [inlined]
[14] saveFMU(fmu::FMIBase.FMU2, fmu_path::String, fmu_src_file::Nothing; standalone::Bool, compress::Bool, cleanup::Bool, removeLibDependency::Bool, removeNoExportBlocks::Bool, resources::Nothing, debug::Bool, suppressWarnings::Bool, pkg_comp_kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ FMIBuild C:\Users\Jisna\.julia\packages\FMIBuild\zfhlh\src\FMIBuild.jl:304
[15] saveFMU (repeats 2 times)
@ C:\Users\Jisna\.julia\packages\FMIBuild\zfhlh\src\FMIBuild.jl:72 [inlined]
[16] save_my_fmu(fmu::FMIBase.FMU2, fmu_save_path::String)
@ FMUManipulation C:\Users\Jisna\FMUManipulation\src\FMUManipulation.jl:45
[17] top-level scope
@ REPL[26]:1
My guess is that there might be some conflicting dependencies. Could that be the case, or is it something else? Any help would be greatly appreciated!