From c17d4195348ba3da9cda63b07151ef88db68752b Mon Sep 17 00:00:00 2001 From: Stuart Dilts Date: Sat, 3 Jan 2026 18:43:41 -0700 Subject: [PATCH 1/4] Print warning when version of libclang doesn't have needed features Since Debian stable still uses LLVM 19, we can't remove this workaround yet. --- cl_bindgen/processfile.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cl_bindgen/processfile.py b/cl_bindgen/processfile.py index 114fc4b..662493c 100644 --- a/cl_bindgen/processfile.py +++ b/cl_bindgen/processfile.py @@ -40,10 +40,12 @@ def _output_comment(cursor, output, before='', after=''): # This function was added in the llvm-project commit fbcf3cb7fe95d9d420b643ce379f7ee2106a6efc # Which will be released in version 20? It's a simple definition though, # so you can copy it into your cindex.py file and it should work. - print("Has anon record decl", file=sys.stderr) def _is_anonymous_record_decl(cursor): return cursor.is_anonymous_record_decl() else: + print("WARNING: the version of libclang being used doesn't", + "provide a way to detect anonymous records.", + sep='\n ') def _is_anonymous_record_decl(cursor): # This won't work on some versions of libclang (particularlly libclang 17), # as this spelling isn't empty, and is instead something like "(anonymous at ...)" From cea23853928420b3dda759ff50d34dd9837559a3 Mon Sep 17 00:00:00 2001 From: Stuart Dilts Date: Sat, 3 Jan 2026 18:54:51 -0700 Subject: [PATCH 2/4] Require libclang>=19.1.0 Debian stable has 19.1.0, so it's reasonable to require at least that version. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c43c15c..7c822f9 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup requirements = [ - 'clang', + 'clang>=19.1.0', 'PyYAML' ] From 78d8ceefc62d0aa699b75031a0a4dcdbd6f21997 Mon Sep 17 00:00:00 2001 From: Stuart Dilts Date: Sat, 3 Jan 2026 18:58:05 -0700 Subject: [PATCH 3/4] Remove workaround for not having raw_comment libclang 19 has it, so it's safe to remove the no-op workaround. + Add tests --- cl_bindgen/processfile.py | 34 ++++++++++++-------------------- test/inputs/simple_struct.h | 3 +++ test/inputs/standard_types.h | 3 +++ test/outputs/simple-struct.lisp | 1 + test/outputs/standard_types.lisp | 1 + 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/cl_bindgen/processfile.py b/cl_bindgen/processfile.py index 662493c..50ade1c 100644 --- a/cl_bindgen/processfile.py +++ b/cl_bindgen/processfile.py @@ -5,6 +5,7 @@ import io import itertools import typing +import re from enum import Enum from dataclasses import dataclass, field from collections import namedtuple @@ -14,27 +15,18 @@ import clang.cindex as clang from clang.cindex import TypeKind, CursorKind -# the pip version of clang doesn't have the comment functions, -# so define _output_comment accordingly -if hasattr(clang.Cursor, 'raw_comment'): - import re - - doc_decorator_re = re.compile("^\s*[*/]* ?",flags=re.MULTILINE) - - def _lispify_comment(comment): - comment = comment.replace('"', '\\"') - return re.sub(doc_decorator_re, '', comment).strip() - - def _output_comment(cursor, output, before='', after=''): - comment = cursor.raw_comment - if comment: - comment = _lispify_comment(comment) - output.write(before) - output.write(f' "{comment}"') - output.write(after) -else: - def _output_comment(cursor, output, before='', after=''): - pass +def _lispify_comment(comment): + comment = comment.replace('"', '\\"') + return re.sub(_lispify_comment.doc_decorator_re, '', comment).strip() +_lispify_comment.doc_decorator_re = re.compile("^\s*[*/]* ?",flags=re.MULTILINE) + +def _output_comment(cursor, output, before='', after=''): + comment = cursor.raw_comment + if comment: + comment = _lispify_comment(comment) + output.write(before) + output.write(f' "{comment}"') + output.write(after) if hasattr(clang.Cursor, 'is_anonymous_record_decl'): # This function was added in the llvm-project commit fbcf3cb7fe95d9d420b643ce379f7ee2106a6efc diff --git a/test/inputs/simple_struct.h b/test/inputs/simple_struct.h index 65d3a84..6c321e9 100644 --- a/test/inputs/simple_struct.h +++ b/test/inputs/simple_struct.h @@ -1,3 +1,6 @@ +/** + * A very simple struct + */ struct a { int a; int b; diff --git a/test/inputs/standard_types.h b/test/inputs/standard_types.h index f382252..55b1f2a 100644 --- a/test/inputs/standard_types.h +++ b/test/inputs/standard_types.h @@ -2,6 +2,9 @@ #include #include +/** + * A function with a bunch of standard types + **/ int8_t std_int_fn(int16_t foo, int32_t bar, int64_t baz); uint8_t uint_fn(uint16_t foo, uint32_t bar, uint64_t baz); diff --git a/test/outputs/simple-struct.lisp b/test/outputs/simple-struct.lisp index fb933f5..2825feb 100644 --- a/test/outputs/simple-struct.lisp +++ b/test/outputs/simple-struct.lisp @@ -1,5 +1,6 @@ ;; next section imported from file inputs/simple_struct.h (cffi:defcstruct a + "A very simple struct" (a :int) (b :int)) diff --git a/test/outputs/standard_types.lisp b/test/outputs/standard_types.lisp index 4418956..c6199b6 100644 --- a/test/outputs/standard_types.lisp +++ b/test/outputs/standard_types.lisp @@ -1,6 +1,7 @@ ;; next section imported from file inputs/standard_types.h (cffi:defcfun ("std_int_fn" std-int-fn) :int8 + "A function with a bunch of standard types" (foo :int16) (bar :int32) (baz :int64)) From 19c1499c50033cc2250e32397818390bdafcfd2e Mon Sep 17 00:00:00 2001 From: Stuart Dilts Date: Sat, 3 Jan 2026 19:05:37 -0700 Subject: [PATCH 4/4] Fix actions by using system python packages + We need libclang 20 for the anonymous structure declarations + pip can't find the libclang install, so we need to uninstall it after installing cl_bindgen, as it pulls the wrong version. Isn't pip great? --- .github/workflows/python-app.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 7029b13..4ed5a2d 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -15,21 +15,19 @@ permissions: jobs: build: - runs-on: fedora-latest + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up Python 3.13 - uses: actions/setup-python@v3 - with: - python-version: "3.13" - name: Install dependencies run: | - sudo dnf install -y python3-clang - python -m pip install --upgrade pip + sudo apt install -y python3-pip python3-clang-20 + # python -m pip install --upgrade pip + # pip install clang==19.1.7 - name: Install package run: | pip install . + pip uninstall -y clang - name: Run Tests run: | python test/run_tests.py