From 705c1cec9a816774e00a674ba890297b58b75f33 Mon Sep 17 00:00:00 2001 From: Viktor Sonesten Date: Thu, 10 Apr 2025 11:38:40 +0200 Subject: [PATCH 1/4] maintainers.tmplt: fix email and name --- maintainers/maintainer-list.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index 6588d522f3b6..ee8c86765f3b 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -24392,10 +24392,10 @@ name = "Travis Whitton"; }; tmplt = { - email = "tmplt@dragons.rocks"; + email = "v@tmplt.dev"; github = "tmplt"; githubId = 6118602; - name = "Viktor"; + name = "Viktor Sonesten"; }; tne = { email = "tne@garudalinux.org"; From 65d159f75c82f977eb405b40b3315857db5bb7db Mon Sep 17 00:00:00 2001 From: Vladimir Korolev Date: Thu, 29 Jul 2021 00:53:25 +0300 Subject: [PATCH 2/4] rpclib: init at 2.3.0 --- pkgs/by-name/rp/rpclib/package.nix | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 pkgs/by-name/rp/rpclib/package.nix diff --git a/pkgs/by-name/rp/rpclib/package.nix b/pkgs/by-name/rp/rpclib/package.nix new file mode 100644 index 000000000000..d055c060cce9 --- /dev/null +++ b/pkgs/by-name/rp/rpclib/package.nix @@ -0,0 +1,26 @@ +{ + lib, + stdenv, + fetchFromGitHub, + cmake, +}: +stdenv.mkDerivation (finalAttrs: { + pname = "rpclib"; + version = "2.3.0"; + + src = fetchFromGitHub { + owner = "rpclib"; + repo = "rpclib"; + rev = "v${finalAttrs.version}"; + sha256 = "0dlbkl47zd2fkxwbn93w51wmvfr8ssp4zribn5wi4cpiky44a4g9"; + }; + + nativeBuildInputs = [ cmake ]; + + meta = { + description = "RPC library for C++, providing both a client and server implementation"; + homepage = "https://github.com/rpclib/rpclib/"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ tmplt ]; + }; +}) From f27a434274687b6cb56b3418e2474f37f2be0e8d Mon Sep 17 00:00:00 2001 From: Viktor Sonesten Date: Mon, 5 May 2025 13:58:18 +0200 Subject: [PATCH 3/4] fmi-reference-fmus: init at 0.0.38 --- .../by-name/fm/fmi-reference-fmus/package.nix | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 pkgs/by-name/fm/fmi-reference-fmus/package.nix diff --git a/pkgs/by-name/fm/fmi-reference-fmus/package.nix b/pkgs/by-name/fm/fmi-reference-fmus/package.nix new file mode 100644 index 000000000000..e41e1223d8b9 --- /dev/null +++ b/pkgs/by-name/fm/fmi-reference-fmus/package.nix @@ -0,0 +1,47 @@ +{ + lib, + stdenv, + fetchFromGitHub, + cmake, + + # Build the FMUs following the latest FMI standard + FMIVersion ? 3, +}: + +# C.f. +assert lib.asserts.assertMsg ( + FMIVersion >= 1 && FMIVersion <= 3 +) "FMIVersion must be a valid FMI specification standard: 1, 2, or 3; not ${toString FMIVersion}"; + +# NB: this derivation does not package the fmusim executables, only +# the FMUs. +stdenv.mkDerivation (finalAttrs: { + pname = "reference-fmus"; + version = "0.0.38"; + src = fetchFromGitHub { + owner = "modelica"; + repo = finalAttrs.pname; + rev = "v${finalAttrs.version}"; + hash = "sha256-FeDKYcm9K670q1FGqy41Tp2Ag8p2JidH4z78zpHOngw="; + }; + + nativeBuildInputs = [ cmake ]; + + cmakeFlags = [ + "-DFMI_VERSION=${toString FMIVersion}" + (lib.cmakeBool "WITH_FMUSIM" false) + ]; + CFLAGS = lib.optionalString (FMIVersion == 3) "-Wno-stringop-truncation"; + + meta = { + # CMakeLists.txt explicitly states support for aarch64-darwin, but + # the build fails in a Nix environment. C.f. + # . + broken = with stdenv.hostPlatform; isAarch64 && isDarwin; + description = "Functional Mock-up Units for development, testing and debugging"; + homepage = "https://github.com/modelica/Reference-FMUs"; + license = lib.licenses.bsd2; + maintainers = with lib.maintainers; [ tmplt ]; + platforms = lib.platforms.all; + }; +}) From 795f25b7735363c0e84695ee9989cef4ae6b6ec6 Mon Sep 17 00:00:00 2001 From: Viktor Sonesten Date: Wed, 23 Apr 2025 12:00:39 +0200 Subject: [PATCH 4/4] python312Packages.fmpy: init at 0.3.23 Release notes via https://github.com/CATIA-Systems/FMPy/releases/tag/v0.3.23 Co-authored-by: Vladimir Korolev Co-authored-by: Doron Behar --- .../0001-gui-override-Qt6-libexec-path.patch | 10 + ...undials-override-shared-object-paths.patch | 10 + ...nt-create-lockfile-with-explicit-r-w.patch | 44 ++++ .../python-modules/fmpy/default.nix | 232 ++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 + 5 files changed, 298 insertions(+) create mode 100644 pkgs/development/python-modules/fmpy/0001-gui-override-Qt6-libexec-path.patch create mode 100644 pkgs/development/python-modules/fmpy/0002-sundials-override-shared-object-paths.patch create mode 100644 pkgs/development/python-modules/fmpy/0003-remoting-client-create-lockfile-with-explicit-r-w.patch create mode 100644 pkgs/development/python-modules/fmpy/default.nix diff --git a/pkgs/development/python-modules/fmpy/0001-gui-override-Qt6-libexec-path.patch b/pkgs/development/python-modules/fmpy/0001-gui-override-Qt6-libexec-path.patch new file mode 100644 index 000000000000..80c4933df6ad --- /dev/null +++ b/pkgs/development/python-modules/fmpy/0001-gui-override-Qt6-libexec-path.patch @@ -0,0 +1,10 @@ +--- a/src/fmpy/gui/__init__.py ++++ b/src/fmpy/gui/__init__.py +@@ -15,6 +15,7 @@ def compile_resources(): + + if os.name == 'posix': + pyside_dir = pyside_dir / 'Qt' / 'libexec' ++ pyside_dir = Path("@qt6libexec@") + + gui_dir = Path(__file__).parent + forms_dir = gui_dir / 'forms' diff --git a/pkgs/development/python-modules/fmpy/0002-sundials-override-shared-object-paths.patch b/pkgs/development/python-modules/fmpy/0002-sundials-override-shared-object-paths.patch new file mode 100644 index 000000000000..c4364763d09c --- /dev/null +++ b/pkgs/development/python-modules/fmpy/0002-sundials-override-shared-object-paths.patch @@ -0,0 +1,10 @@ +--- a/src/fmpy/sundials/libraries.py ++++ b/src/fmpy/sundials/libraries.py +@@ -9,6 +9,7 @@ if platform_tuple == 'aarch64_darwin': + library_dir = library_dir / 'x86_64-darwin' + else: + library_dir = library_dir / platform_tuple ++library_dir = Path("@cvode@") / 'lib' + + # load SUNDIALS shared libraries + sundials_nvecserial = cdll.LoadLibrary(str(library_dir / f'sundials_nvecserial{sharedLibraryExtension}')) diff --git a/pkgs/development/python-modules/fmpy/0003-remoting-client-create-lockfile-with-explicit-r-w.patch b/pkgs/development/python-modules/fmpy/0003-remoting-client-create-lockfile-with-explicit-r-w.patch new file mode 100644 index 000000000000..35c96a25a72d --- /dev/null +++ b/pkgs/development/python-modules/fmpy/0003-remoting-client-create-lockfile-with-explicit-r-w.patch @@ -0,0 +1,44 @@ +From bf0f536776d2554a99af3fbcc08fa4c43bba1c7e Mon Sep 17 00:00:00 2001 +From: Viktor Sonesten +Date: Mon, 5 May 2025 17:40:10 +0200 +Subject: [PATCH] remoting/client: create lockfile with explicit r+w +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes the compilation error below, which is triggered in hardened +build environments (e.g. NixOS): + + > In file included from /nix/store/aaaaaaaa-glibc-2.40-66-dev/include/fcntl.h:341, + > from /build/source/native/remoting/client_tcp.cpp:12: + > In function ‘int open(const char*, int, ...)’, + > inlined from ‘void* fmi2Instantiate(fmi2String, fmi2Type, fmi2String, fmi2String, const fmi2CallbackFunctions*, fmi2Boolean, fmi2Boolean)’ at /build/source/native/remoting/client_tcp.cpp:217:28: + > /nix/store/aaaaaaaa-glibc-2.40-66-dev/include/bits/fcntl2.h:52:31: error: call to ‘__open_missing_mode’ declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments + > 52 | __open_missing_mode (); + > | ~~~~~~~~~~~~~~~~~~~~^~ + +In short: O_CREAT without explicit mode params may generate a file +with suid/sgid. Error triggered by _FORTIFY_SOURCE. This commit +explicitly creates the file with read/write permissions for the file +owner. + +Adopted from https://github.com/facebook/hhvm/issues/168 +--- + native/remoting/client_tcp.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/native/remoting/client_tcp.cpp b/native/remoting/client_tcp.cpp +index 708c895..7acbc80 100644 +--- a/native/remoting/client_tcp.cpp ++++ b/native/remoting/client_tcp.cpp +@@ -214,7 +214,7 @@ fmi2Component fmi2Instantiate(fmi2String instanceName, fmi2Type fmuType, fmi2Str + // create lock file + const char *lockFilePath = tempnam(NULL, ""); + +- int lockFile = open(lockFilePath, O_CREAT | O_EXCL); ++ int lockFile = open(lockFilePath, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + + if (lockFile == -1) { + s_logger(s_componentEnvironment, instanceName, fmi2Error, "error", "Failed to create lock file %s.", lockFilePath); +-- +2.47.1 diff --git a/pkgs/development/python-modules/fmpy/default.nix b/pkgs/development/python-modules/fmpy/default.nix new file mode 100644 index 000000000000..fd66b5f34bd2 --- /dev/null +++ b/pkgs/development/python-modules/fmpy/default.nix @@ -0,0 +1,232 @@ +{ + lib, + stdenv, + fetchurl, + buildPythonPackage, + fetchFromGitHub, + pythonOlder, + cmake, + sundials, + lapack, + attrs, + lark, + lxml, + rpclib, + msgpack, + numpy, + scipy, + pytz, + dask, + requests, + matplotlib, + pyqtgraph, + notebook, + plotly, + hatchling, + pyside6, + jinja2, + flask, + dash, + dash-bootstrap-components, + qt6, + fmpy, + runCommand, + enableRemoting ? true, + versionCheckHook, + fmi-reference-fmus, + replaceVars, +}: +buildPythonPackage rec { + pname = "fmpy"; + version = "0.3.23"; + disabled = pythonOlder "3.10"; + pyproject = true; + + # Bumping version? Make sure to look through the commit history for + # bumped native/build_cvode.py pins (see above). + src = fetchFromGitHub { + owner = "CATIA-Systems"; + repo = "FMPy"; + rev = "v${version}"; + fetchSubmodules = true; + hash = "sha256-4jBYOymurGCbjT0WQjIRNsztwOXBYVTGLdc4kNSTOZw="; + }; + + nativeBuildInputs = [ + cmake + ]; + + build-system = [ + hatchling + ]; + + dependencies = [ + pyqtgraph + pyside6 + attrs + lark + lxml + msgpack + numpy + scipy + pytz + dask + requests + matplotlib + pyqtgraph + notebook + plotly + rpclib + fmpy.passthru.cvode + pyside6 + jinja2 + flask + dash + dash-bootstrap-components + ]; + + dontUseCmakeConfigure = true; + dontUseCmakeBuildDir = true; + + patches = [ + (replaceVars ./0001-gui-override-Qt6-libexec-path.patch { + qt6libexec = "${qt6.qtbase}/libexec/"; + }) + (replaceVars ./0002-sundials-override-shared-object-paths.patch { + inherit (fmpy.passthru) cvode; + }) + # Upstream does not accept pull requests for unknown legal + # reasons, see: + # . + # Thus a fix is vendored here until patched by maintainer. C.f. + # + ./0003-remoting-client-create-lockfile-with-explicit-r-w.patch + ]; + + # Make forced includes of other systems' artifacts optional in order + # to pass build (otherwise vendored upstream from CI) + postPatch = '' + sed --in-place 's/force-include/source/g' pyproject.toml + ''; + + # Don't run upstream build scripts as they are too specialized. + # cvode is already built, so we only need to build native binaries. + # We run these cmake builds and then run the standard + # buildPythonPackage phases. + preBuild = + '' + cmakeFlags="-S native/src -B native/src/build -D CVODE_INSTALL_DIR=${passthru.cvode}" + cmakeConfigurePhase + cmake --build native/src/build --config Release + '' + + lib.optionalString (enableRemoting && stdenv.isLinux) '' + # reimplementation of native/build_remoting.py + cmakeFlags="-S native/remoting -B remoting/linux64 -D RPCLIB=${rpclib}" + cmakeConfigurePhase + cmake --build remoting/linux64 --config Release + '' + # C.f. upstream build-wheel CI job + + '' + python native/copy_sources.py + + # reimplementation of native/compile_resources.py + pushd src/ + python -c "from fmpy.gui import compile_resources; compile_resources()" + popd + ''; + + pythonImportsCheck = [ + "fmpy" + "fmpy.cross_check" + "fmpy.cswrapper" + "fmpy.examples" + "fmpy.fmucontainer" + "fmpy.logging" + "fmpy.gui" + "fmpy.gui.generated" + "fmpy.ssp" + "fmpy.sundials" + ]; + + nativeInstallCheckInputs = [ + versionCheckHook + ]; + + passthru = { + # From sundials, build only the CVODE solver. C.f. + # src/native/build_cvode.py + cvode = + (sundials.overrideAttrs (prev: { + # hash copied from native/build_cvode.py + version = "5.3.0"; + src = fetchurl { + url = "https://github.com/LLNL/sundials/releases/download/v5.3.0/sundials-5.3.0.tar.gz"; + sha256 = "88dff7e11a366853d8afd5de05bf197a8129a804d9d4461fb64297f1ef89bca7"; + }; + + cmakeFlags = + prev.cmakeFlags + ++ lib.mapAttrsToList (option: enable: lib.cmakeBool option enable) { + # only build the CVODE solver + BUILD_CVODE = true; + + BUILD_CVODES = false; + BUILD_ARKODE = false; + BUILD_IDA = false; + BUILD_IDAS = false; + BUILD_KINSOL = false; + }; + + # FMPy searches for sundials without the "lib"-prefix; strip it + # and symlink the so-files into existance. + postFixup = '' + pushd $out/lib + for so in *.so; do + ln --verbose --symbolic $so ''${so#lib} + done + popd + ''; + })).override + { + lapackSupport = false; + lapack.isILP64 = stdenv.hostPlatform.is64bit; + blas = lapack; + kluSupport = false; + }; + + # Simulate reference FMUs from + # . + # + # Just check that the execution passes; don't verify any numerical + # results, but save them in case of future or manual check use. + tests.simulate-reference-fmus = runCommand "${pname}-simulate-reference-fmus" { } '' + mkdir $out + # NB(find ! -name): Clocks.fmu is marked TODO upstream and is of a + # FMI type that FMPy doesn't support currently (ModelExchange) + for fmu in $(find ${fmi-reference-fmus}/*.fmu ! -name "Clocks.fmu"); do + name=$(basename $fmu) + echo "--- START $name ---" + ${fmpy}/bin/fmpy simulate $fmu \ + --fmi-logging \ + --output-file $out/$name.csv \ + | tee $out/$name.out + done + ''; + }; + + meta = { + # A logging.dylib is built but is not packaged correctly so as to + # be found. C.f. + # + broken = stdenv.hostPlatform.isDarwin; + description = "Simulate Functional Mockup Units (FMUs) in Python"; + homepage = "https://github.com/CATIA-Systems/FMPy"; + license = lib.licenses.bsd2; + maintainers = with lib.maintainers; [ tmplt ]; + # Supported platforms are not exhaustively and explicitly stated, + # but inferred from the artifacts that are vendored in upstream CI + # builds. C.f. + # + platforms = lib.platforms.x86_64 ++ [ "i686-windows" ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 9bd03dc24f39..b4aa2321c157 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -5124,6 +5124,8 @@ self: super: with self; { flynt = callPackage ../development/python-modules/flynt { }; + fmpy = callPackage ../development/python-modules/fmpy { }; + fnllm = callPackage ../development/python-modules/fnllm { }; fnv-hash-fast = callPackage ../development/python-modules/fnv-hash-fast { };