fix(uxrce_dds_client): handle empty DDS subscriptions in build (#26846)

When all subscription topics are commented out in dds_topics.yaml,
the build failed in two ways:

1. KeyError in generate_dds_topics.py when the subscriptions key is
   absent from YAML — fixed by using dict.get() with fallback to
   empty list, consistent with how subscriptions_multi is handled.

2. Unused variable errors (-Werror) in the generated dds_topics.h
   when no subscriptions exist — fixed by guarding on_topic_update(),
   time_offset_us, and uxr_set_topic_callback() with conditional
   template blocks. Also marked create_data_reader() as
   __attribute__((unused)) since it is only called from generated
   subscription code.

Closes #26799

Signed-off-by: Pavel Guzenfeld <pavelgu@gmail.com>
This commit is contained in:
Pavel Guzenfeld
2026-03-23 02:10:40 +02:00
committed by GitHub
parent 53bec94205
commit f003fc39cb
3 changed files with 18 additions and 16 deletions

View File

@@ -184,12 +184,13 @@ struct RcvTopicsPubs {
bool init(uxrSession *session, uxrStreamId reliable_out_stream_id, uxrStreamId reliable_in_stream_id, uxrStreamId best_effort_in_stream_id, uxrObjectId participant_id, const char *client_namespace);
};
@[if subscriptions or subscriptions_multi]@
static void on_topic_update(uxrSession *session, uxrObjectId object_id, uint16_t request_id, uxrStreamId stream_id,
struct ucdrBuffer *ub, uint16_t length, void *args)
{
RcvTopicsPubs *pubs = (RcvTopicsPubs *)args;
const int64_t time_offset_us = session->time_offset / 1000; // ns -> us
pubs->num_payload_received += length;
const int64_t time_offset_us = session->time_offset / 1000; // ns -> us
switch (object_id.id) {
@[ for idx, sub in enumerate(subscriptions)]@
@@ -242,6 +243,7 @@ static void on_topic_update(uxrSession *session, uxrObjectId object_id, uint16_t
break;
}
}
@[end if]@
bool RcvTopicsPubs::init(uxrSession *session, uxrStreamId reliable_out_stream_id, uxrStreamId reliable_in_stream_id, uxrStreamId best_effort_in_stream_id, uxrObjectId participant_id, const char *client_namespace)
{
@@ -260,7 +262,9 @@ bool RcvTopicsPubs::init(uxrSession *session, uxrStreamId reliable_out_stream_id
}
@[ end for]@
@[ if subscriptions or subscriptions_multi]@
uxr_set_topic_callback(session, on_topic_update, this);
@[ end if]@
return true;
}

View File

@@ -115,20 +115,18 @@ def process_message_instance(msg_type):
merged_em_globals['namespace'] = namespace
pubs_not_empty = msg_map['publications'] is not None
if pubs_not_empty:
for p in msg_map['publications']:
process_message_type(p)
process_message_instance(p)
pubs = msg_map.get('publications') or []
for p in pubs:
process_message_type(p)
process_message_instance(p)
merged_em_globals['publications'] = msg_map['publications'] if pubs_not_empty else []
merged_em_globals['publications'] = pubs
subs_not_empty = msg_map['subscriptions'] is not None
if subs_not_empty:
for s in msg_map['subscriptions']:
process_message_type(s)
subs = msg_map.get('subscriptions') or []
for s in subs:
process_message_type(s)
merged_em_globals['subscriptions'] = msg_map['subscriptions'] if subs_not_empty else []
merged_em_globals['subscriptions'] = subs
subs_multi = msg_map.get('subscriptions_multi') or []
for sd in subs_multi:

View File

@@ -101,10 +101,10 @@ static bool create_data_writer(uxrSession *session, uxrStreamId reliable_out_str
return true;
}
static bool create_data_reader(uxrSession *session, uxrStreamId reliable_out_stream_id, uxrStreamId input_stream_id,
uxrObjectId participant_id, uint16_t index, const char *client_namespace, const char *topic,
uint32_t message_version,
const char *type_name, uint16_t queue_depth)
static bool __attribute__((unused)) create_data_reader(uxrSession *session, uxrStreamId reliable_out_stream_id, uxrStreamId input_stream_id,
uxrObjectId participant_id, uint16_t index, const char *client_namespace, const char *topic,
uint32_t message_version,
const char *type_name, uint16_t queue_depth)
{
// topic
char topic_name[TOPIC_NAME_SIZE];