Skip to content

libffi: build on powerpc64/powerpc64le with the CMake build system - #247

Open
pkubaj wants to merge 2 commits into
OpenModelica:masterfrom
pkubaj:ppc64-fbsd-fix
Open

pkubaj wants to merge 2 commits into
OpenModelica:masterfrom
pkubaj:ppc64-fbsd-fix

Conversation

@pkubaj

@pkubaj pkubaj commented Oct 28, 2026

Copy link
Copy Markdown

Related Issues

None filed. Seen while building OpenModelica 1.25.7 on FreeBSD/powerpc64le
(FreeBSD port science/openmodelica):

CMake Error at OMCompiler/3rdParty/libffi/.cmake/configure_platform.cmake:42 (message):
  Unknown host.

Purpose

configure_platform.cmake only knows x86, x86_64, aarch64 and arm, so the
bundled libffi, and with it the whole OpenModelica configure step, fails on
powerpc64 and powerpc64le. libffi itself supports them (configure.host maps
powerpc64*-*-linux* and powerpc64*-*-freebsd* to TARGET=POWERPC); only
the CMake wrapper is missing the mapping.

While testing closures on that platform I also found that FFI_MMAP_EXEC_WRIT
is only set on Darwin and when the platform name contains FREEBSD, which
only the i386 platform on FreeBSD and OpenBSD does. Every other build on those
systems gets the plain malloc closure allocator, and since malloc memory is
not executable there, calling a closure crashes with SIGSEGV. OpenModelica's
ffi_omc.cpp only uses ffi_call, so this is latent for omc, but the bundled
library should not be broken for closures.

Approach

  1. Map powerpc64*/ppc64* hosts to TARGET_PLATFORM POWERPC and build the
    64-bit ELF sources ffi.c, ffi_linux64.c, linux64.S and
    linux64_closure.S with TARGETDIR powerpc. The pattern matches both
    CMAKE_SYSTEM_PROCESSOR (powerpc64le on FreeBSD, ppc64le on Linux) and
    the ppc64le/ppc64 compiler architecture ID that CMake 4.1+ reports. The
    32-bit ffi_sysv.c, sysv.S and ppc_closure.S from configure.host are
    left out: they are entirely under #ifndef POWERPC64, and the two .S
    files include <powerpc/asm.h> relative to src/, which the CMake build
    does not put on the include path.
  2. Set FFI_MMAP_EXEC_WRIT from CMAKE_SYSTEM_NAME for the systems libffi's
    configure.ac sets it for (Darwin, FreeBSD, OpenBSD, Solaris, Android).
    src/tramp.c is already in SOURCES_LIST on master, so the mmap allocator
    links.

Tested on FreeBSD 15.1-RELEASE powerpc64le (POWER9, clang 19.1.7, CMake 3.31)
with a standalone CMake build of libffi/ from OMCompiler-3rdParty master and
a small test program that calls ffi_call with int, double, long double,
struct and pointer arguments and then calls a closure made with
ffi_prep_closure_loc:

Tree Configure ffi_call Closure
master "Unknown host." - -
+ first commit POWERPC correct SIGSEGV
+ second commit POWERPC correct correct

With the first change applied as a FreeBSD port patch, OpenModelica 1.25.7
builds, packages and runs on FreeBSD 15.1 powerpc64le: the HelloWorld example
simulates correctly, and external "C" functions that the frontend evaluates
through libffi (sin(0.5), ldexp(0.75, 3)) return the right values.

configure_platform.cmake only knows x86, x86_64, aarch64 and arm, so
configuring OpenModelica on powerpc64 or powerpc64le stops with
"Unknown host".

Map them to the POWERPC target like libffi's configure.host does for
powerpc64*-*-linux* and powerpc64*-*-freebsd*, and build the 64-bit
ELF sources: ffi.c, ffi_linux64.c, linux64.S and linux64_closure.S.
configure.host also lists ffi_sysv.c, sysv.S and ppc_closure.S, but
they are 32-bit only (everything is under #ifndef POWERPC64) and the
two .S files include <powerpc/asm.h> relative to src/, which the
CMake build does not have on its include path, so they are left out.

The pattern covers both variables the wrapper looks at: before CMake
4.1, CMAKE_C_COMPILER_ARCHITECTURE_ID is empty for GCC and Clang and
CMAKE_SYSTEM_PROCESSOR is "powerpc64le" on FreeBSD and "ppc64le" on
Linux, while CMake 4.1 and later report "ppc64le" or "ppc64" as the
compiler architecture.

Verified on FreeBSD 15.1 powerpc64le (clang 19, CMake 3.31): the
bundled libffi builds, and ffi_call with int, double, long double,
struct and pointer arguments returns the expected values.
FFI_MMAP_EXEC_WRIT was only set on Darwin and when TARGET_PLATFORM
contains FREEBSD, which only the i386 platform on FreeBSD and OpenBSD
does. Every other build on those systems got the malloc based closure
allocator, and since malloc memory is not executable there, calling
a closure made by ffi_prep_closure_loc crashes with SIGSEGV.

Set it from CMAKE_SYSTEM_NAME instead, for the systems libffi's
configure.ac sets it for (Darwin, FreeBSD, OpenBSD, Solaris and
Android), so the mmap based allocator is used on every CPU there.

Found while testing the previous commit on FreeBSD 15.1 powerpc64le:
a small program that calls a closure crashed with SIGSEGV before this
change and passes with it.
@CLAassistant

CLAassistant commented Oct 28, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants