Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 34 additions & 9 deletions pythonfmu3/osutil.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,40 @@
import platform
import sys

import platform
# FMI 3.0 platform tuples are "<arch>-<sys>" (FMI 3.0 standard, section 2.5.1.4),
# e.g. x86_64-linux, aarch64-darwin, x86-windows.
_SYSTEMS = {"Windows": "windows", "Linux": "linux", "Darwin": "darwin"}

_ARCHITECTURES_64 = {
"x86_64": "x86_64", "amd64": "x86_64", "x64": "x86_64",
"i386": "x86_64", "i686": "x86_64", "x86": "x86_64", # 64-bit Python on x86 hardware
"aarch64": "aarch64", "arm64": "aarch64", "armv8l": "aarch64",
"ppc64": "ppc64", "ppc64le": "ppc64",
"riscv64": "riscv64",
}

_ARCHITECTURES_32 = {
"x86_64": "x86", "amd64": "x86", "x64": "x86", "i386": "x86", "i686": "x86", "x86": "x86",
"aarch64": "aarch32", "arm64": "aarch32", "armv7l": "aarch32", "armv8l": "aarch32", "arm": "aarch32",
"ppc": "ppc32",
"riscv32": "riscv32",
}


def _is_64bit() -> bool:
# Bitness of the running interpreter, which is what the FMU binary must match
# (e.g. a 32-bit Python on 64-bit Windows needs x86-windows).
return sys.maxsize > 2 ** 32


def get_fmu_arch() -> str:
"""FMI 3.0 platform tuple of the running interpreter, e.g. 'aarch64-darwin'."""
machine = platform.machine().lower()
table = _ARCHITECTURES_64 if _is_64bit() else _ARCHITECTURES_32
arch = table.get(machine, machine or "unknown")
system = _SYSTEMS.get(platform.system(), platform.system().lower() or "unknown")
return f"{arch}-{system}"

def get_fmu_arch():
#is_64bits = sys.maxsize > 2 ** 32
system = platform.system()
is_x86 = platform.machine() in ["i386", "AMD64", "x86_64"]
platforms = {"Windows": "windows", "Linux": "linux", "Darwin": "darwin"}
arch = "x86_64" if is_x86 else "x86"
return arch + "-" + platforms.get(system, "unknown")

def get_platform() -> str:
"""Get FMU binary platform folder name."""
Expand All @@ -19,4 +45,3 @@ def get_lib_extension() -> str:
"""Get FMU library platform extension."""
platforms = {"Darwin": "dylib", "Linux": "so", "Windows": "dll"}
return platforms.get(platform.system(), "")

38 changes: 35 additions & 3 deletions pythonfmu3/pythonfmu-export/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,44 @@ else ()
set(TARGET_PLATFORM linux)
endif ()

if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set(TARGET_PLATFORM x86_64-${TARGET_PLATFORM})
# FMI 3.0 platform tuple <arch>-<sys>; must match pythonfmu3/osutil.py:get_fmu_arch().
# The architecture is the one being *built for*: the Visual Studio -A option, or a single
# CMAKE_OSX_ARCHITECTURES entry on macOS, take precedence over the host processor.
if (CMAKE_GENERATOR_PLATFORM)
set(_arch "${CMAKE_GENERATOR_PLATFORM}")
elseif (APPLE AND CMAKE_OSX_ARCHITECTURES)
list(LENGTH CMAKE_OSX_ARCHITECTURES _n_arch)
if (NOT _n_arch EQUAL 1)
message(FATAL_ERROR "Universal builds are not supported: set CMAKE_OSX_ARCHITECTURES to a single architecture")
endif ()
set(_arch "${CMAKE_OSX_ARCHITECTURES}")
else ()
set(_arch "${CMAKE_SYSTEM_PROCESSOR}")
endif ()
string(TOLOWER "${_arch}" _arch)

if (_arch MATCHES "^(aarch64|arm64|armv8)")
set(_fmi_arch aarch64)
elseif (_arch MATCHES "^arm")
set(_fmi_arch aarch32)
elseif (_arch MATCHES "^(x86_64|amd64|x64|i[3-6]86|x86|win32)$")
set(_fmi_arch x86)
else ()
set(TARGET_PLATFORM x86-${TARGET_PLATFORM})
set(_fmi_arch "${_arch}")
endif ()

if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
if (_fmi_arch STREQUAL "x86")
set(_fmi_arch x86_64)
elseif (_fmi_arch STREQUAL "aarch32")
set(_fmi_arch aarch64)
endif ()
elseif (_fmi_arch STREQUAL "aarch64")
set(_fmi_arch aarch32)
endif ()

set(TARGET_PLATFORM ${_fmi_arch}-${TARGET_PLATFORM})

message("Building pythonfmu-export for platform ${TARGET_PLATFORM}")

add_subdirectory(src)
23 changes: 23 additions & 0 deletions pythonfmu3/tests/test_osutil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import pytest

from pythonfmu3 import osutil


@pytest.mark.parametrize(
"system, machine, is_64bit, expected",
[
("Darwin", "arm64", True, "aarch64-darwin"), # Apple Silicon
("Darwin", "x86_64", True, "x86_64-darwin"), # Intel Mac (or Rosetta)
("Linux", "x86_64", True, "x86_64-linux"),
("Linux", "aarch64", True, "aarch64-linux"), # Raspberry Pi 4/5, Graviton
("Linux", "armv7l", False, "aarch32-linux"),
("Windows", "AMD64", True, "x86_64-windows"),
("Windows", "AMD64", False, "x86-windows"), # 32-bit Python on 64-bit Windows
("Windows", "ARM64", True, "aarch64-windows"),
],
)
def test_fmi3_platform_tuple(monkeypatch, system, machine, is_64bit, expected):
monkeypatch.setattr(osutil.platform, "system", lambda: system)
monkeypatch.setattr(osutil.platform, "machine", lambda: machine)
monkeypatch.setattr(osutil, "_is_64bit", lambda: is_64bit)
assert osutil.get_platform() == expected
Loading