[PATCH 1/2] Add SWIG bindings files for libcpupower

From: John B. Wyatt IV
Date: Wed Jul 24 2024 - 18:14:08 EST


SWIG is a tool packaged in Fedora and other distros that can generate
bindings from C and C++ code for several languages including Python,
Perl, and Go.

A latter commit will demonstrate taking a SWIG .i file and
the libcpupower object files to generate the bindings.

Note that while SWIG itself is GPL v3+ licensed; the resulting output,
the bindings code, is permissively licensed. Please see
https://swig.org/legal.html for more details.

Signed-off-by: John B. Wyatt IV <jwyatt@xxxxxxxxxx>
Signed-off-by: John B. Wyatt IV <sageofredondo@xxxxxxxxx>
---
.../power/cpupower/bindings/python/.gitignore | 8 ++++
tools/power/cpupower/bindings/python/Makefile | 31 +++++++++++++
tools/power/cpupower/bindings/python/README | 33 ++++++++++++++
.../bindings/python/raw_pylibcpupower.i | 45 +++++++++++++++++++
4 files changed, 117 insertions(+)
create mode 100644 tools/power/cpupower/bindings/python/.gitignore
create mode 100644 tools/power/cpupower/bindings/python/Makefile
create mode 100644 tools/power/cpupower/bindings/python/README
create mode 100644 tools/power/cpupower/bindings/python/raw_pylibcpupower.i

diff --git a/tools/power/cpupower/bindings/python/.gitignore b/tools/power/cpupower/bindings/python/.gitignore
new file mode 100644
index 000000000000..b83e0f5e26a0
--- /dev/null
+++ b/tools/power/cpupower/bindings/python/.gitignore
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-only
+__pycache__/
+*.c
+*.o
+*.so
+*.py
+!test_raw_pylibcpupower.py
+!raw_pylibcpupower.i # git keeps ignoring this file
diff --git a/tools/power/cpupower/bindings/python/Makefile b/tools/power/cpupower/bindings/python/Makefile
new file mode 100644
index 000000000000..a6c779333f8d
--- /dev/null
+++ b/tools/power/cpupower/bindings/python/Makefile
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# Makefile for libcpupower Python bindings
+#
+# This Makefile expects you have already run the makefile for cpupower to build
+# the .o files in the lib directory for the bindings to be created.
+
+CC=gcc
+
+LIB_DIR = ../../lib
+BIND_DIR = .
+PY_INCLUDE := $(firstword $(shell python-config --includes))
+#PY_INCLUDE = $(shell python-config --includes | awk '{ print $1 }')
+
+OBJECTS_LIB = $(wildcard $(LIB_DIR)/*.o)
+OBJECTS_BIND = $(wildcard $(BIND_DIR)/*.o)
+
+all: _raw_pylibcpupower.so
+
+_raw_pylibcpupower.so: raw_pylibcpupower_wrap.o
+ $(CC) -shared $(OBJECTS_LIB) raw_pylibcpupower_wrap.o -o _raw_pylibcpupower.so # raw_pylibcpupower_wrap.o
+# $(CC) -shared $(OBJECTS_BIND) $(OBJECTS_LIB) -o _raw_pylibcpupower.so # raw_pylibcpupower_wrap.o
+
+raw_pylibcpupower_wrap.o: raw_pylibcpupower_wrap.c
+ $(CC) -fPIC -c raw_pylibcpupower_wrap.c $(PY_INCLUDE)
+
+raw_pylibcpupower_wrap.c: raw_pylibcpupower.i
+ swig -python raw_pylibcpupower.i
+
+# Will only clean the bindings folder; will not clean the actual cpupower folder
+clean:
+ rm -f raw_pylibcpupower.py raw_pylibcpupower_wrap.c raw_pylibcpupower_wrap.o _raw_pylibcpupower.so
diff --git a/tools/power/cpupower/bindings/python/README b/tools/power/cpupower/bindings/python/README
new file mode 100644
index 000000000000..a2663a2d23d1
--- /dev/null
+++ b/tools/power/cpupower/bindings/python/README
@@ -0,0 +1,33 @@
+
+This folder contains the necessary files to build Python bindings for libcpupower.
+
+To begin, first build the object files for libcpupower by running make in
+the cpupower directory.
+
+Next you will need to install SWIG. Using Fedora:
+
+sudo dnf install swig
+
+Please check that your version of SWIG is compatible with the version of
+Python installed on your machine by checking the SWIG changelog on their
+website. https://swig.org/
+
+Then return to the directory this README is in to run:
+
+make
+
+To run the test script:
+
+python test_raw_pylibcpupower.py
+
+Note that while SWIG itself is GPL v3+ licensed; the resulting output,
+the bindings code, is permissively licensed. Please see
+https://swig.org/legal.html for more details.
+
+Original Bindings Author:
+John B. Wyatt IV
+jwyatt@xxxxxxxxxx
+sageofredondo@xxxxxxxxx
+
+Copyright (C) 2024 Red Hat
+
diff --git a/tools/power/cpupower/bindings/python/raw_pylibcpupower.i b/tools/power/cpupower/bindings/python/raw_pylibcpupower.i
new file mode 100644
index 000000000000..9a920ecf1f47
--- /dev/null
+++ b/tools/power/cpupower/bindings/python/raw_pylibcpupower.i
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+%module raw_pylibcpupower
+%{
+#include "../../lib/cpupower_intern.h"
+#include "../../lib/acpi_cppc.h"
+#include "../../lib/cpufreq.h"
+#include "../../lib/cpuidle.h"
+#include "../../lib/cpupower.h"
+#include "../../lib/powercap.h"
+%}
+
+/*
+ * cpuidle.h
+ */
+
+unsigned int cpuidle_state_count(unsigned int cpu);
+int cpuidle_state_disable(unsigned int cpu, unsigned int idlestate, unsigned int disable);
+
+/*
+ * cpupower.h
+ */
+
+struct cpupower_topology {
+ /* Amount of CPU cores, packages and threads per core in the system */
+ unsigned int cores;
+ unsigned int pkgs;
+ unsigned int threads; /* per core */
+
+ /* Array gets mallocated with cores entries, holding per core info */
+ struct cpuid_core_info *core_info;
+};
+
+struct cpuid_core_info {
+ int pkg;
+ int core;
+ int cpu;
+
+ /* flags */
+ unsigned int is_online:1;
+};
+
+int get_cpu_topology(struct cpupower_topology *cpu_top);
+void cpu_topology_release(struct cpupower_topology cpu_top);
+int cpupower_is_cpu_online(unsigned int cpu);
--
2.45.2