From ec938b5d42cef7b4de3418e918d9fd3896af2648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavol=20=C5=BD=C3=A1=C4=8Dik?= Date: Tue, 23 Jul 2024 18:04:47 +0200 Subject: [PATCH] Document the Python bindings using Sphinx Additionally, setup the documentation for deployment to Read The Docs. --- .gitignore | 5 +++- .readthedocs.yml | 29 ++++++++++++++++++++ Readme.md | 7 +++++ python/README.md | 8 ++++++ python/docs/api/clock.rst | 6 +++++ python/docs/api/enums.rst | 6 +++++ python/docs/api/errors.rst | 5 ++++ python/docs/api/info.rst | 22 ++++++++++++++++ python/docs/api/libcpuid.rst | 5 ++++ python/docs/api/msr.rst | 6 +++++ python/docs/api/raw.rst | 10 +++++++ python/docs/conf.py | 35 +++++++++++++++++++++++++ python/docs/index.rst | 51 ++++++++++++++++++++++++++++++++++++ python/docs/requirements.txt | 1 + python/ffi_build_rtd.py | 31 ++++++++++++++++++++++ 15 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 .readthedocs.yml create mode 100644 python/README.md create mode 100644 python/docs/api/clock.rst create mode 100644 python/docs/api/enums.rst create mode 100644 python/docs/api/errors.rst create mode 100644 python/docs/api/info.rst create mode 100644 python/docs/api/libcpuid.rst create mode 100644 python/docs/api/msr.rst create mode 100644 python/docs/api/raw.rst create mode 100644 python/docs/conf.py create mode 100644 python/docs/index.rst create mode 100644 python/docs/requirements.txt create mode 100644 python/ffi_build_rtd.py diff --git a/.gitignore b/.gitignore index d12bc21..5f34a4c 100644 --- a/.gitignore +++ b/.gitignore @@ -40,11 +40,14 @@ cpuid_tool/x32 cpuid_tool/x64 *.vcxproj.user build -docs +/docs .vscode raw.txt report.txt *__pycache__ +python/docs/_build +python/docs/doctrees +python/docs/html python/dist python/src/libcpuid/_libcpuid_cffi.* python/src/libcpuid/libcpuid.h diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..61e9458 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,29 @@ +# Read the Docs configuration file + +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: latest + apt_packages: + - autoconf + - libtool + - automake + jobs: + pre_install: + - libtoolize + - autoreconf --install + - mkdir ./install + - ./configure --prefix=`pwd`/install + - make + - make install + - pip install cffi + - python ./python/ffi_build_rtd.py ./libcpuid/libcpuid.h ./install + +sphinx: + configuration: python/docs/conf.py + +python: + install: + - requirements: python/docs/requirements.txt diff --git a/Readme.md b/Readme.md index 33b163e..db67714 100644 --- a/Readme.md +++ b/Readme.md @@ -171,6 +171,13 @@ When no options are present, the program behaves as if it was invoked with cpuid_tool "--save=raw.txt --outfile=report.txt --report --verbose" ``` +### Python bindings + +The libcpuid library features Python bindings, which can be installed as a library +using `python -m pip install libcpuid`. Visit the +[documentation at Read the Docs](https://libcpuid.readthedocs.io/en/latest/index.html#) +to see how the library is used. + ## Contributing Refer to the [dedicated page](CONTRIBUTING.md). diff --git a/python/README.md b/python/README.md new file mode 100644 index 0000000..779d418 --- /dev/null +++ b/python/README.md @@ -0,0 +1,8 @@ +# libcpuid + +libcpuid is a package that provides Python bindings to +the C library of the same name. Its main feature is +CPU identification for the x86 and ARM architectures. + +Visit the [documentation at Read the Docs](https://libcpuid.readthedocs.io/en/latest/index.html#) +to see how the library is used. diff --git a/python/docs/api/clock.rst b/python/docs/api/clock.rst new file mode 100644 index 0000000..939c148 --- /dev/null +++ b/python/docs/api/clock.rst @@ -0,0 +1,6 @@ +Clock and frequency computation +=============================== + +.. automodule:: libcpuid.clock + :members: + :undoc-members: diff --git a/python/docs/api/enums.rst b/python/docs/api/enums.rst new file mode 100644 index 0000000..bb74eba --- /dev/null +++ b/python/docs/api/enums.rst @@ -0,0 +1,6 @@ +Enumeration classes +=================== + +.. automodule:: libcpuid.enums + :members: + :undoc-members: diff --git a/python/docs/api/errors.rst b/python/docs/api/errors.rst new file mode 100644 index 0000000..c16d059 --- /dev/null +++ b/python/docs/api/errors.rst @@ -0,0 +1,5 @@ +Library exceptions +================== + +.. automodule:: libcpuid.errors + :members: diff --git a/python/docs/api/info.rst b/python/docs/api/info.rst new file mode 100644 index 0000000..65ca634 --- /dev/null +++ b/python/docs/api/info.rst @@ -0,0 +1,22 @@ +Basic CPU information +===================== + +.. autoclass:: libcpuid.info.CPUInfo + :members: + :exclude-members: from_c + +.. autoclass:: libcpuid.info.X86Info + :members: + +.. autoclass:: libcpuid.info.ARMInfo + :members: + +.. autoclass:: libcpuid.sgx.SGX + :members: + +.. autoclass:: libcpuid.sgx.EPC + :members: + +.. autoclass:: libcpuid.info.SystemInfo + :members: + :exclude-members: from_c diff --git a/python/docs/api/libcpuid.rst b/python/docs/api/libcpuid.rst new file mode 100644 index 0000000..ed7a9a5 --- /dev/null +++ b/python/docs/api/libcpuid.rst @@ -0,0 +1,5 @@ +Top-level library functionality +=============================== + +.. automodule:: libcpuid + :members: diff --git a/python/docs/api/msr.rst b/python/docs/api/msr.rst new file mode 100644 index 0000000..702e3f4 --- /dev/null +++ b/python/docs/api/msr.rst @@ -0,0 +1,6 @@ +Model-specific registers +======================== + +.. automodule:: libcpuid.msr + :members: + :undoc-members: diff --git a/python/docs/api/raw.rst b/python/docs/api/raw.rst new file mode 100644 index 0000000..158a64a --- /dev/null +++ b/python/docs/api/raw.rst @@ -0,0 +1,10 @@ +Raw CPU data +============ + +.. autoclass:: libcpuid.raw.CPURawData + :members: + :exclude-members: c_cpu_raw_data + +.. autoclass:: libcpuid.raw.CPURawDataArray + :members: + :exclude-members: c_cpu_raw_data_array \ No newline at end of file diff --git a/python/docs/conf.py b/python/docs/conf.py new file mode 100644 index 0000000..7956e61 --- /dev/null +++ b/python/docs/conf.py @@ -0,0 +1,35 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +import os +import sys + +sys.path.insert(0, os.path.abspath("../src")) + +project = "libcpuid" +copyright = "2024, Pavol Žáčik" +author = "Pavol Žáčik" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.doctest", + "sphinx_rtd_theme", +] + +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +language = "en" + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "sphinx_rtd_theme" +autodoc_member_order = "bysource" diff --git a/python/docs/index.rst b/python/docs/index.rst new file mode 100644 index 0000000..69d3c46 --- /dev/null +++ b/python/docs/index.rst @@ -0,0 +1,51 @@ +Welcome to libcpuid's documentation! +==================================== + +**libcpuid** provides a Python interface +to the libcpuid C library. + +.. code-block:: python + + import sys + import libcpuid + from libcpuid.errors import LibcpuidError + from libcpuid.info import CPUInfo + from libcpuid.enums import CPUFeature, CPUVendor + + # print the version of the libcpuid library + print(libcpuid.version()) + + # print the number of CPU cores + print(libcpuid.get_total_cpus()) + + # check if the cpuid instruction is available + if not libcpuid.cpuid_present(): + print("CPUInfo instruction is not available") + sys.exit(1) + + try: + # identify the current CPU and print some + # information about it + cpu_info = CPUInfo.from_current_cpu() + print(cpu_info.vendor) + print(cpu_info.architecture) + print(CPUFeature.FPU in cpu_info.features) + + # print the list of all Intel CPU code names + print(libcpuid.get_cpu_list(CPUVendor.INTEL)) + except LibcpuidError as err: + print(err.message) + sys.exit(1) + + +.. toctree:: + :maxdepth: 2 + + Home + api/libcpuid + api/info + api/msr + api/enums + api/raw + api/clock + api/errors diff --git a/python/docs/requirements.txt b/python/docs/requirements.txt new file mode 100644 index 0000000..6c5d5d4 --- /dev/null +++ b/python/docs/requirements.txt @@ -0,0 +1 @@ +sphinx-rtd-theme diff --git a/python/ffi_build_rtd.py b/python/ffi_build_rtd.py new file mode 100644 index 0000000..09d09ba --- /dev/null +++ b/python/ffi_build_rtd.py @@ -0,0 +1,31 @@ +""" +Script for compiling the C FFI for the live documentation. +""" + +import sys +import os +from cffi import FFI + +sys.path.append(os.path.dirname(os.path.abspath(__file__))) + +from _ffi_build_utils import ( # pylint: disable=import-error, wrong-import-position + preprocess_header, + eval_sizeofs, +) + +if __name__ == "__main__": + header_path = sys.argv[1] + install_dir = sys.argv[2] + library_dir = os.path.join(os.getcwd(), install_dir, "lib") + include_dir = os.path.join(install_dir, "include", "libcpuid") + ffibuilder = FFI() + ffibuilder.cdef(eval_sizeofs(preprocess_header(header_path), [f"-I{include_dir}"])) + ffibuilder.set_source( + "python.src.libcpuid._libcpuid_cffi", + "#include ", + libraries=["cpuid"], + library_dirs=[library_dir], + include_dirs=[include_dir], + extra_link_args=[f"-Wl,-rpath={library_dir}"], + ) + ffibuilder.compile(verbose=True)