From 78a94f7ae232ad95f7e67429d68304a1ae9dced7 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Mon, 9 Nov 2026 08:42:15 -0800 Subject: [PATCH] libdc1394: Fix build with clang The juju backend uses variable length arrays in structs, a GCC extension which clang does not support: error: fields must have a constant size: 'variable length array in structure' extension will never be supported Allocate the buffers with alloca() and use the flexible array members of the kernel event structs instead. AI-Generated: Uses Claude Code Signed-off-by: Khem Raj --- ...se-variable-length-arrays-in-structs.patch | 233 ++++++++++++++++++ .../libdc1394/libdc1394_2.2.7.bb | 3 +- 2 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 meta-multimedia/recipes-multimedia/libdc1394/files/0001-juju-Do-not-use-variable-length-arrays-in-structs.patch diff --git a/meta-multimedia/recipes-multimedia/libdc1394/files/0001-juju-Do-not-use-variable-length-arrays-in-structs.patch b/meta-multimedia/recipes-multimedia/libdc1394/files/0001-juju-Do-not-use-variable-length-arrays-in-structs.patch new file mode 100644 index 0000000000..b246af85e4 --- /dev/null +++ b/meta-multimedia/recipes-multimedia/libdc1394/files/0001-juju-Do-not-use-variable-length-arrays-in-structs.patch @@ -0,0 +1,233 @@ +From a78265d465723a7c7b6354c04756d8cbf3045e72 Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Mon, 9 Nov 2026 08:37:30 -0800 +Subject: [PATCH] juju: Do not use variable length arrays in structs + +Variable length arrays in structs are a GCC extension which clang does +not support: + + error: fields must have a constant size: 'variable length array in structure' extension will never be supported + +The kernel event structs already end with a flexible array member for +the payload, so allocate the same amount of stack with alloca() and use +the payload member instead. + +Upstream-Status: Pending +Signed-off-by: Khem Raj +--- + dc1394/juju/capture.c | 19 ++++++----- + dc1394/juju/control.c | 76 +++++++++++++++++++++++-------------------- + 2 files changed, 51 insertions(+), 44 deletions(-) + +diff --git a/dc1394/juju/capture.c b/dc1394/juju/capture.c +index e9da6e3..36e6031 100644 +--- a/dc1394/juju/capture.c ++++ b/dc1394/juju/capture.c +@@ -22,6 +22,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -319,10 +320,10 @@ dc1394_juju_capture_dequeue (platform_camera_t * craw, + return DC1394_CAPTURE_IS_NOT_SET; + } + +- struct { +- struct fw_cdev_event_iso_interrupt i; +- __u32 headers[craw->packets_per_frame*2 + 16]; // HPK 20161209 +- } iso; ++ /* the iso headers follow struct fw_cdev_event_iso_interrupt */ ++ size_t iso_size = sizeof (struct fw_cdev_event_iso_interrupt) + ++ (craw->packets_per_frame*2 + 16) * sizeof (__u32); // HPK 20161209 ++ struct fw_cdev_event_iso_interrupt *iso = alloca (iso_size); + + if ( (policyDC1394_CAPTURE_POLICY_MAX) ) + return DC1394_INVALID_CAPTURE_POLICY; +@@ -344,13 +345,13 @@ dc1394_juju_capture_dequeue (platform_camera_t * craw, + return DC1394_SUCCESS; + } + +- len = read (craw->iso_fd, &iso, sizeof iso); ++ len = read (craw->iso_fd, iso, iso_size); + if (len < 0) { + dc1394_log_error("Juju: dequeue failed to read a response: %m"); + return DC1394_FAILURE; + } + +- if (iso.i.type == FW_CDEV_EVENT_ISO_INTERRUPT) ++ if (iso->type == FW_CDEV_EVENT_ISO_INTERRUPT) + break; + } + +@@ -358,7 +359,7 @@ dc1394_juju_capture_dequeue (platform_camera_t * craw, + f = craw->frames + craw->current; + + dc1394_log_debug("Juju: got iso event, cycle 0x%04x, header_len %d", +- iso.i.cycle, iso.i.header_length); ++ iso->cycle, iso->header_length); + + f->frame.frames_behind = 0; + f->frame.timestamp = 0; +@@ -368,14 +369,14 @@ dc1394_juju_capture_dequeue (platform_camera_t * craw, + /* Current bus time in usec as retrieved by the ioctl */ + uint32_t bus_time = bus_time_to_usec(tm.cycle_timer); + /* Bus time of the interrupt packet (end of frame) */ +- uint32_t dma_time = iso.i.cycle; ++ uint32_t dma_time = iso->cycle; + /* Estimated usec between start of frame and end of frame */ + uint32_t diff = + (craw->frames[0].frame.packets_per_frame - 1) * 125; + + /* If per-packet timestamps are available in the headers use them */ + if (craw->header_size >= 8) { +- uint8_t * b = (uint8_t *)(iso.i.header + 1); ++ uint8_t * b = (uint8_t *)(iso->header + 1); + /* Bus time of the first frame in the packet */ + dma_time = (b[2] << 8) | b[3]; + dc1394_log_debug("Juju: using cycle 0x%04x (diff was %d)", +diff --git a/dc1394/juju/control.c b/dc1394/juju/control.c +index 4a4acbb..26ed292 100644 +--- a/dc1394/juju/control.c ++++ b/dc1394/juju/control.c +@@ -22,6 +22,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -280,41 +281,46 @@ typedef struct _juju_response_info { + static int + juju_handle_event (platform_camera_t * cam) + { +- union { +- struct { +- struct fw_cdev_event_response r; +- __u32 buffer[cam->max_response_quads]; +- } response; ++ union juju_event { ++ struct fw_cdev_event_response response; + struct fw_cdev_event_bus_reset reset; + struct fw_cdev_event_iso_resource resource; +- } u; ++ } *u; ++ size_t size; + int len, i; + juju_response_info *resp_info; + juju_iso_info *iso_info; + +- len = read (cam->fd, &u, sizeof u); ++ /* the response data follows struct fw_cdev_event_response */ ++ size = sizeof (struct fw_cdev_event_response) + ++ cam->max_response_quads * sizeof (__u32); ++ if (size < sizeof *u) ++ size = sizeof *u; ++ u = alloca (size); ++ ++ len = read (cam->fd, u, size); + if (len < 0) { + dc1394_log_error("juju: Read failed: %m"); + return -1; + } + +- switch (u.reset.type) { ++ switch (u->reset.type) { + case FW_CDEV_EVENT_BUS_RESET: +- cam->generation = u.reset.generation; +- cam->node_id = u.reset.node_id; ++ cam->generation = u->reset.generation; ++ cam->node_id = u->reset.node_id; + dc1394_log_debug ("juju: Bus reset, gen %d, node 0x%x", + cam->generation, cam->node_id); + break; + + case FW_CDEV_EVENT_RESPONSE: +- if (!u.response.r.closure) { ++ if (!u->response.closure) { + dc1394_log_warning ("juju: Unsolicited response, rcode %x len %d", +- u.response.r.rcode, u.response.r.length); ++ u->response.rcode, u->response.length); + break; + } +- resp_info = u64_to_ptr(u.response.r.closure); +- resp_info->rcode = u.response.r.rcode; +- resp_info->actual_num_quads = u.response.r.length/4; ++ resp_info = u64_to_ptr(u->response.closure); ++ resp_info->rcode = u->response.rcode; ++ resp_info->actual_num_quads = u->response.length/4; + resp_info->got_response = 1; + if (resp_info->rcode || !resp_info->data) + break; +@@ -326,48 +332,48 @@ juju_handle_event (platform_camera_t * cam) + + len = MIN(resp_info->actual_num_quads, resp_info->num_quads); + for (i = 0; i < len; i++) +- resp_info->data[i] = ntohl (u.response.r.data[i]); ++ resp_info->data[i] = ntohl (u->response.data[i]); + break; + + case FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED: +- if (!u.resource.closure) { ++ if (!u->resource.closure) { + dc1394_log_warning ("juju: Spurious ISO allocation event: " +- "handle %d, chan %d, bw %d", u.resource.handle, +- u.resource.channel, u.resource.bandwidth); ++ "handle %d, chan %d, bw %d", u->resource.handle, ++ u->resource.channel, u->resource.bandwidth); + break; + } +- iso_info = u64_to_ptr(u.resource.closure); +- if (iso_info->handle != u.resource.handle) ++ iso_info = u64_to_ptr(u->resource.closure); ++ if (iso_info->handle != u->resource.handle) + dc1394_log_warning ("juju: ISO alloc handle was %d, expected %d", +- u.resource.handle, iso_info->handle); ++ u->resource.handle, iso_info->handle); + dc1394_log_debug ("juju: Allocated handle %d: chan %d bw %d", +- u.resource.handle, u.resource.channel, u.resource.bandwidth); ++ u->resource.handle, u->resource.channel, u->resource.bandwidth); + iso_info->got_alloc = 1; +- iso_info->channel = u.resource.channel; +- iso_info->bandwidth = u.resource.bandwidth; ++ iso_info->channel = u->resource.channel; ++ iso_info->bandwidth = u->resource.bandwidth; + break; + + case FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED: +- if (!u.resource.closure) { ++ if (!u->resource.closure) { + dc1394_log_warning ("juju: Spurious ISO deallocation event: " +- "handle %d, chan %d, bw %d", u.resource.handle, +- u.resource.channel, u.resource.bandwidth); ++ "handle %d, chan %d, bw %d", u->resource.handle, ++ u->resource.channel, u->resource.bandwidth); + break; + } +- iso_info = u64_to_ptr(u.resource.closure); +- if (iso_info->handle != u.resource.handle) ++ iso_info = u64_to_ptr(u->resource.closure); ++ if (iso_info->handle != u->resource.handle) + dc1394_log_warning ("juju: ISO dealloc handle was %d, expected %d", +- u.resource.handle, iso_info->handle); ++ u->resource.handle, iso_info->handle); + dc1394_log_debug ("juju: Deallocated handle %d: chan %d bw %d", +- u.resource.handle, u.resource.channel, u.resource.bandwidth); ++ u->resource.handle, u->resource.channel, u->resource.bandwidth); + iso_info->got_dealloc = 1; +- iso_info->channel = u.resource.channel; +- iso_info->bandwidth = u.resource.bandwidth; ++ iso_info->channel = u->resource.channel; ++ iso_info->bandwidth = u->resource.bandwidth; + break; + + default: + dc1394_log_warning ("juju: Unhandled event type %d", +- u.reset.type); ++ u->reset.type); + break; + } + diff --git a/meta-multimedia/recipes-multimedia/libdc1394/libdc1394_2.2.7.bb b/meta-multimedia/recipes-multimedia/libdc1394/libdc1394_2.2.7.bb index 8cac780d64..e1f3b0f2fb 100755 --- a/meta-multimedia/recipes-multimedia/libdc1394/libdc1394_2.2.7.bb +++ b/meta-multimedia/recipes-multimedia/libdc1394/libdc1394_2.2.7.bb @@ -13,7 +13,8 @@ DEPENDS += "libusb1 libraw1394 libsdl \ SRC_URI = "${SOURCEFORGE_MIRROR}/${BPN}/${BP}.tar.gz \ file://install_examples.patch \ - " + file://0001-juju-Do-not-use-variable-length-arrays-in-structs.patch \ + " SRC_URI[sha256sum] = "537ceb78dd3cef271a183f4a176191d1cecf85f025520e6bd3758b0e19e6609f" inherit autotools pkgconfig