git: 9cc495302643 - main - science/py-tensorflow: fix and enable the build on powerpc64le

From: Piotr Kubaj <pkubaj_at_FreeBSD.org>
Date: Fri, 11 Sep 2026 12:50:06 UTC
The branch main has been updated by pkubaj:

URL: https://cgit.FreeBSD.org/ports/commit/?id=9cc495302643f923e5fcbe170e84e6dcd837d0d5

commit 9cc495302643f923e5fcbe170e84e6dcd837d0d5
Author:     Piotr Kubaj <pkubaj@FreeBSD.org>
AuthorDate: 2026-09-02 10:02:06 +0000
Commit:     Piotr Kubaj <pkubaj@FreeBSD.org>
CommitDate: 2026-09-11 12:49:10 +0000

    science/py-tensorflow: fix and enable the build on powerpc64le
    
    Most of the architecture gates that had to be fixed failed the same way:
    the port's cc_toolchain_config hardcodes cpu = "freebsd", which names the
    OS and not the CPU, so bazel config_settings written as
    values = {"cpu": ...} cannot tell FreeBSD architectures apart.  The C
    preprocessor still takes the correct powerpc path (it sees __PPC64__), so
    bazel selected x86 sources while the compiler compiled powerpc ones.
    
    - files/freebsd/BUILD: the FreeBSD cc toolchain was declared
      exec/target_compatible_with @platforms//cpu:x86_64, so on powerpc64le it
      never resolved and bazel fell back to the auto-detected toolchain, whose
      empty cxx_builtin_include_directories made it reject the numpy -isystem
      copt for every compile.  Constrain on @platforms//os:freebsd only, as
      the python_cc_toolchain in the same file already does.
    
    - Makefile: clang rejects -march= on powerpc, and -mcpu=native is silently
      ignored there, so use -mcpu with a power8 baseline that CPUTYPE can
      override.  Do not auto-detect the builder's CPU: the package builder may
      be newer than the target baseline.
    
    - cpuinfo, XNNPACK and highwayhash: key the architecture config_settings
      on @platforms//cpu:* constraint_values instead of the cpu string.
      Without this XNNPACK compiled amd64 AVX-512 assembly and microkernels,
      and highwayhash included hh_vsx.h while bazel had selected
      hh_avx2/hh_sse41.
    
    - XNNPACK: disable assembly on powerpc64le, and detect VSX using FreeBSD's
      elf_aux_info() with the PPC_FEATURE_* constants from <machine/cpu.h>.
      FreeBSD has no getauxval(); its absence was only an implicit-declaration
      warning that would have become a link error.
    
    - XLA: builtin_fp16.h uses uint16_t in its fallback without including
      <cstdint>, and vector_ops.h/eigen_unary.cc use _Float16 behind a guard
      that only tests ext_vector_type.  clang provides those attributes on
      powerpc but not _Float16, so also require __FLT16_MANT_DIG__.
    
    - Makefile: link with -Wl,-z,undefs on powerpc64le.  libtensorflow_framework
      is linked with -z defs, but LLVM's Program.cpp and tsl's subprocess.cc
      reference environ, which on FreeBSD lives in crt1.o rather than in
      libc.so.  On powerpc64 its address is taken through a TOC entry that
      survives --gc-sections, so the link fails where it does not on amd64.
    
    The XNNPACK and XLA changes are carried here only until TensorFlow picks
    up revisions containing them; both have since been merged upstream:
    
            https://github.com/google/XNNPACK/pull/11114 (merged 2026-09-03)
            https://github.com/openxla/xla/pull/48240 (merged
            2026-09-02 as openxla/xla commit 927b467078fd)
    
    The cpuinfo and highwayhash problems are already fixed in newer upstream
    revisions than the ones TensorFlow 2.21.0 pins, so those two hunks can be
    dropped when the vendored copies are updated.
    
    Tested on powerpc64le: py312-tensorflow-2.21.0_3 builds in 4h11m with a
    clean pkg-plist.  Also tested on amd64, which is unaffected: every hunk is
    either ARCH-gated, inside #if XNN_ARCH_PPC64, or a constraint_values
    addition that still matches on x86_64.
---
 science/py-tensorflow/Makefile                     | 27 +++++++++++++++----
 .../files/cpuinfo-freebsd-alwayslink.patch         | 27 ++++++++++++++++++-
 science/py-tensorflow/files/freebsd/BUILD          |  2 --
 .../files/patch-tensorflow_workspace2.bzl          |  2 +-
 ..._xla_third__party_highwayhash_highwayhash.BUILD | 11 ++++++++
 ...ty_xla_xla_backends_cpu_codegen_builtin__fp16.h | 11 ++++++++
 ...y_xla_xla_codegen_intrinsic_cpp_eigen__unary.cc | 12 +++++++++
 ...rty_xla_xla_codegen_intrinsic_cpp_vector__ops.h | 12 +++++++++
 .../py-tensorflow/files/xnnpack-freebsd-mmap.patch |  3 ++-
 .../files/xnnpack-freebsd-ppc-hwcap.patch          | 30 ++++++++++++++++++++++
 10 files changed, 127 insertions(+), 10 deletions(-)

diff --git a/science/py-tensorflow/Makefile b/science/py-tensorflow/Makefile
index bf145dab1426..de96a9bf5e95 100644
--- a/science/py-tensorflow/Makefile
+++ b/science/py-tensorflow/Makefile
@@ -15,7 +15,7 @@ WWW=		https://www.tensorflow.org \
 LICENSE=	APACHE20
 LICENSE_FILE=	${WRKSRC}/LICENSE
 
-ONLY_FOR_ARCHS=	amd64
+ONLY_FOR_ARCHS=	amd64 powerpc64le
 
 BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}grpcio-tools>=1.22.0:devel/py-grpcio-tools@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}numpy>=1.22.0:math/py-numpy@${PY_FLAVOR} \
@@ -83,13 +83,28 @@ JOBS_ALL_DESC=			Run all jobs
 JOBS_ALL_VARS=			TF_JOBS_NUMBER=${MAKE_JOBS_NUMBER}
 
 CPU_OPTS_DESC=			Enable optimisations using features available on your CPU
-CPU_OPTS_VARS=			CPU_TARGET=native BAZEL_COPT="-c opt --copt=-march=native --copt=-mfpmath=sse"
-CPU_OPTS_VARS_OFF=		CPU_TARGET=x86-64
+CPU_OPTS_VARS=			CPU_TARGET=${CPU_NATIVE} BAZEL_COPT="-c opt --copt=${CPU_FLAG}=${CPU_NATIVE} ${CPU_COPT_EXTRA}"
+CPU_OPTS_VARS_OFF=		CPU_TARGET=${CPU_BASELINE}
 
 XLA_DESC=			Accelerated Linear Algebra
 XLA_VARS=			XLA_OPT="1"
 XLA_VARS_OFF=			XLA_OPT="0"
 
+.include <bsd.port.options.mk>
+
+.if ${ARCH} == powerpc64le
+CPU_FLAG=			-mcpu
+CPU_BASELINE=			${CPUTYPE:Upower8}
+CPU_NATIVE=			${CPU_BASELINE}
+BAZEL_ARCH_DEFINES=		--define=xnn_enable_assembly=false \
+				--linkopt=-Wl,-z,undefs
+.else
+CPU_FLAG=			-march
+CPU_BASELINE=			x86-64
+CPU_NATIVE=			native
+CPU_COPT_EXTRA=			--copt=-mfpmath=sse
+.endif
+
 .include "Makefile.MASTER_SITES"
 
 BAZEL_BOOT=	--output_user_root=${WRKDIR}/bazel_out
@@ -166,6 +181,8 @@ post-patch:
 		${WRKSRC}/third_party/xla/third_party/pthreadpool/freebsd_alloca.patch
 	@${CP} ${PATCHDIR}/xnnpack-freebsd-mmap.patch \
 		${WRKSRC}/third_party/xla/third_party/xnnpack/freebsd_mmap.patch
+	@${CP} ${PATCHDIR}/xnnpack-freebsd-ppc-hwcap.patch \
+		${WRKSRC}/third_party/xla/third_party/xnnpack/freebsd_ppc_hwcap.patch
 	@${CP} ${PATCHDIR}/protobuf-freebsd-upb.patch \
 		${WRKSRC}/third_party/xla/third_party/protobuf/freebsd_upb.patch
 	@${CP} ${PATCHDIR}/cpuinfo-freebsd-alwayslink.patch \
@@ -222,7 +239,7 @@ do-configure:
 		TF_DOWNLOAD_CLANG=0 \
 		TF_NEED_NCCL=0 \
 		TF_IGNORE_MAX_BAZEL_VERSION=1 \
-		CC_OPT_FLAGS="-march=${CPU_TARGET} -I${LOCALBASE}/include" \
+		CC_OPT_FLAGS="${CPU_FLAG}=${CPU_TARGET} -I${LOCALBASE}/include" \
 		PREFIX="${LOCALBASE}" \
 		TF_SYSTEM_LIBS="astor_archive astunparse_archive boringssl com_github_googlecloudplatform_google_cloud_cpp \
 				com_googlesource_code_re2 curl cython dill_archive functools32_archive gast_archive \
@@ -270,7 +287,7 @@ do-build:
 			${ECHO_MSG} "WARNING: llvm config.bzl not found at $${LLVMCONF}; build may fail"; \
 		fi
 	@cd ${WRKSRC} && \
-		bazel --bazelrc="${WRKDIR}/bazelrc" ${BAZEL_BOOT} build --jobs ${TF_JOBS_NUMBER} ${BAZEL_COPT} --host_copt="-I${LOCALBASE}/include" \
+		bazel --bazelrc="${WRKDIR}/bazelrc" ${BAZEL_BOOT} build --jobs ${TF_JOBS_NUMBER} ${BAZEL_COPT} ${BAZEL_ARCH_DEFINES} --host_copt="-I${LOCALBASE}/include" \
 		--host_linkopt="-L${LOCALBASE}/lib -lexecinfo" ${BAZEL_LINKOPT} --copt="-I${LOCALBASE}/include" \
 		--verbose_failures -s \
 		--distdir=${WRKDIR}/bazel-dist \
diff --git a/science/py-tensorflow/files/cpuinfo-freebsd-alwayslink.patch b/science/py-tensorflow/files/cpuinfo-freebsd-alwayslink.patch
index 7423f274a523..96fc57e4f1df 100644
--- a/science/py-tensorflow/files/cpuinfo-freebsd-alwayslink.patch
+++ b/science/py-tensorflow/files/cpuinfo-freebsd-alwayslink.patch
@@ -1,7 +1,15 @@
 diff --git a/BUILD.bazel b/BUILD.bazel
 --- a/BUILD.bazel
 +++ b/BUILD.bazel
-@@ -182,6 +182,7 @@
+@@ -142,6 +142,7 @@
+         ":macos_x86_64_legacy": COMMON_SRCS + X86_SRCS + MACH_SRCS + MACH_X86_SRCS,
+         ":macos_arm64": COMMON_SRCS + MACH_SRCS + MACH_ARM_SRCS,
+         ":freebsd_x86_64": COMMON_SRCS + X86_SRCS + FREEBSD_SRCS + FREEBSD_X86_SRCS,
++        ":freebsd_ppc64le": COMMON_SRCS + FREEBSD_SRCS,
+         ":windows_x86_64": COMMON_SRCS + X86_SRCS + WINDOWS_X86_SRCS,
+         ":windows_arm64": COMMON_SRCS + ARM_SRCS + WINDOWS_ARM_SRCS,
+         ":android_armv7": COMMON_SRCS + ARM_SRCS + LINUX_SRCS + LINUX_ARM32_SRCS + ANDROID_ARM_SRCS,
+@@ -182,6 +183,7 @@
          ":macos_x86_64_legacy": False,
          "//conditions:default": True,
      }),
@@ -9,3 +17,20 @@ diff --git a/BUILD.bazel b/BUILD.bazel
      # Headers must be in textual_hdrs to allow us to set the standard to C99
      textual_hdrs = [
          "include/cpuinfo.h",
+@@ -482,7 +484,16 @@
+ 
+ config_setting(
+     name = "freebsd_x86_64",
++    constraint_values = ["@platforms//cpu:x86_64"],
+     values = {
+         "cpu": "freebsd",
+     },
+ )
++
++config_setting(
++    name = "freebsd_ppc64le",
++    constraint_values = ["@platforms//cpu:ppc"],
++    values = {
++        "cpu": "freebsd",
++    },
++)
diff --git a/science/py-tensorflow/files/freebsd/BUILD b/science/py-tensorflow/files/freebsd/BUILD
index 04a5fda857fd..98aa98aa0100 100644
--- a/science/py-tensorflow/files/freebsd/BUILD
+++ b/science/py-tensorflow/files/freebsd/BUILD
@@ -56,11 +56,9 @@ cc_toolchain_config(
 toolchain(
     name = "cc-toolchain-freebsd",
     exec_compatible_with = [
-        "@platforms//cpu:x86_64",
         "@platforms//os:freebsd",
     ],
     target_compatible_with = [
-        "@platforms//cpu:x86_64",
         "@platforms//os:freebsd",
     ],
     toolchain = ":cc-compiler-freebsd",
diff --git a/science/py-tensorflow/files/patch-tensorflow_workspace2.bzl b/science/py-tensorflow/files/patch-tensorflow_workspace2.bzl
index a9ba0a253e9f..32124132b727 100644
--- a/science/py-tensorflow/files/patch-tensorflow_workspace2.bzl
+++ b/science/py-tensorflow/files/patch-tensorflow_workspace2.bzl
@@ -4,7 +4,7 @@
          sha256 = "44bf8a258cfd0d7b500b6058a2bb5c7387c8cebba295cfca985a68d16513f7c8",
          strip_prefix = "XNNPACK-25b42dfddb0ee22170d73ff0d4b333ea1e6edfeb",
          urls = tf_mirror_urls("https://github.com/google/XNNPACK/archive/25b42dfddb0ee22170d73ff0d4b333ea1e6edfeb.zip"),
-+        patch_file = ["@xla//third_party/xnnpack:freebsd_mmap.patch"],
++        patch_file = ["@xla//third_party/xnnpack:freebsd_mmap.patch", "@xla//third_party/xnnpack:freebsd_ppc_hwcap.patch"],
      )
      # LINT.ThenChange(//tensorflow/lite/tools/cmake/modules/xnnpack.cmake)
  
diff --git a/science/py-tensorflow/files/patch-third__party_xla_third__party_highwayhash_highwayhash.BUILD b/science/py-tensorflow/files/patch-third__party_xla_third__party_highwayhash_highwayhash.BUILD
new file mode 100644
index 000000000000..0131b1d6db1b
--- /dev/null
+++ b/science/py-tensorflow/files/patch-third__party_xla_third__party_highwayhash_highwayhash.BUILD
@@ -0,0 +1,11 @@
+--- third_party/xla/third_party/highwayhash/highwayhash.BUILD.orig	2026-03-04 22:33:50 UTC
++++ third_party/xla/third_party/highwayhash/highwayhash.BUILD
+@@ -21,7 +21,7 @@
+ 
+ config_setting(
+     name = "cpu_ppc",
+-    values = {"cpu": "ppc"},
++    constraint_values = ["@platforms//cpu:ppc"],
+ )
+ 
+ config_setting(
diff --git a/science/py-tensorflow/files/patch-third__party_xla_xla_backends_cpu_codegen_builtin__fp16.h b/science/py-tensorflow/files/patch-third__party_xla_xla_backends_cpu_codegen_builtin__fp16.h
new file mode 100644
index 000000000000..8c9d2e1a74a0
--- /dev/null
+++ b/science/py-tensorflow/files/patch-third__party_xla_xla_backends_cpu_codegen_builtin__fp16.h
@@ -0,0 +1,11 @@
+--- third_party/xla/xla/backends/cpu/codegen/builtin_fp16.h.orig	2026-03-04 22:33:50 UTC
++++ third_party/xla/xla/backends/cpu/codegen/builtin_fp16.h
+@@ -16,6 +16,8 @@
+ #ifndef XLA_BACKENDS_CPU_CODEGEN_BUILTIN_FP16_H_
+ #define XLA_BACKENDS_CPU_CODEGEN_BUILTIN_FP16_H_
+ 
++#include <cstdint>
++
+ // _Float16 always gets us the correct ABI type, so use that if available.
+ // AArch64 GCC defines __FLT16_MANT_DIG__ even when _Float16 is not available.
+ #if defined(__FLT16_MANT_DIG__) && \
diff --git a/science/py-tensorflow/files/patch-third__party_xla_xla_codegen_intrinsic_cpp_eigen__unary.cc b/science/py-tensorflow/files/patch-third__party_xla_xla_codegen_intrinsic_cpp_eigen__unary.cc
new file mode 100644
index 000000000000..525dd6c717b9
--- /dev/null
+++ b/science/py-tensorflow/files/patch-third__party_xla_xla_codegen_intrinsic_cpp_eigen__unary.cc
@@ -0,0 +1,12 @@
+--- third_party/xla/xla/codegen/intrinsic/cpp/eigen_unary.cc.orig	2026-03-04 22:33:50 UTC
++++ third_party/xla/xla/codegen/intrinsic/cpp/eigen_unary.cc
+@@ -13,7 +13,8 @@
+ limitations under the License.
+ ==============================================================================*/
+ 
+-#if defined(__has_attribute) && __has_attribute(ext_vector_type) && \
++#if defined(__FLT16_MANT_DIG__) && \
++    defined(__has_attribute) && __has_attribute(ext_vector_type) && \
+     defined(__has_builtin) && __has_builtin(__builtin_vectorelements)
+ 
+ #include "xla/codegen/intrinsic/cpp/eigen_unary.h"
diff --git a/science/py-tensorflow/files/patch-third__party_xla_xla_codegen_intrinsic_cpp_vector__ops.h b/science/py-tensorflow/files/patch-third__party_xla_xla_codegen_intrinsic_cpp_vector__ops.h
new file mode 100644
index 000000000000..adc9dda6f212
--- /dev/null
+++ b/science/py-tensorflow/files/patch-third__party_xla_xla_codegen_intrinsic_cpp_vector__ops.h
@@ -0,0 +1,12 @@
+--- third_party/xla/xla/codegen/intrinsic/cpp/vector_ops.h.orig	2026-03-04 22:33:50 UTC
++++ third_party/xla/xla/codegen/intrinsic/cpp/vector_ops.h
+@@ -16,7 +16,8 @@
+ #ifndef XLA_CODEGEN_INTRINSIC_CPP_VECTOR_OPS_H_
+ #define XLA_CODEGEN_INTRINSIC_CPP_VECTOR_OPS_H_
+ 
+-#if defined(__has_attribute) && __has_attribute(ext_vector_type) && \
++#if defined(__FLT16_MANT_DIG__) && \
++    defined(__has_attribute) && __has_attribute(ext_vector_type) && \
+     defined(__has_builtin) && __has_builtin(__builtin_vectorelements)
+ 
+ #include <cstddef>
diff --git a/science/py-tensorflow/files/xnnpack-freebsd-mmap.patch b/science/py-tensorflow/files/xnnpack-freebsd-mmap.patch
index 53e6a43e21a5..8fea9541fe0d 100644
--- a/science/py-tensorflow/files/xnnpack-freebsd-mmap.patch
+++ b/science/py-tensorflow/files/xnnpack-freebsd-mmap.patch
@@ -38,12 +38,13 @@ diff --git a/src/memory.c b/src/memory.c
 diff --git a/build_config/BUILD.bazel b/build_config/BUILD.bazel
 --- a/build_config/BUILD.bazel
 +++ b/build_config/BUILD.bazel
-@@ -351,6 +351,11 @@
+@@ -351,6 +351,12 @@
      ],
  )
  
 +config_setting(
 +    name = "freebsd_x86_64",
++    constraint_values = ["@platforms//cpu:x86_64"],
 +    values = {"cpu": "freebsd"},
 +)
 +
diff --git a/science/py-tensorflow/files/xnnpack-freebsd-ppc-hwcap.patch b/science/py-tensorflow/files/xnnpack-freebsd-ppc-hwcap.patch
new file mode 100644
index 000000000000..09f380362e1e
--- /dev/null
+++ b/science/py-tensorflow/files/xnnpack-freebsd-ppc-hwcap.patch
@@ -0,0 +1,30 @@
+diff --git a/src/configs/hardware-config.c b/src/configs/hardware-config.c
+--- a/src/configs/hardware-config.c
++++ b/src/configs/hardware-config.c
+@@ -46,6 +46,9 @@
+ 
+ #if XNN_ARCH_PPC64
+   #include <sys/auxv.h>
++  #if defined(__FreeBSD__)
++    #include <machine/cpu.h>
++  #endif
+ #endif
+ 
+ #if XNN_ARCH_WASM || XNN_ARCH_WASMSIMD || XNN_ARCH_WASMRELAXEDSIMD
+@@ -304,8 +307,14 @@
+   #endif
+ 
+   #if XNN_ARCH_PPC64
+-    const unsigned long HWCAPs = getauxval(AT_HWCAP);
+-    const unsigned long HWCAPs_2 = getauxval(AT_HWCAP2);
++    #if defined(__FreeBSD__)
++      unsigned long HWCAPs = 0, HWCAPs_2 = 0;
++      elf_aux_info(AT_HWCAP, &HWCAPs, sizeof(HWCAPs));
++      elf_aux_info(AT_HWCAP2, &HWCAPs_2, sizeof(HWCAPs_2));
++    #else
++      const unsigned long HWCAPs = getauxval(AT_HWCAP);
++      const unsigned long HWCAPs_2 = getauxval(AT_HWCAP2);
++    #endif
+     if (HWCAPs & PPC_FEATURE_HAS_VSX) {
+       set_arch_flag(xnn_arch_vsx, 1);
+     }