fix(windows-sitl): unblock MSVC and MinGW Windows SITL build

Two compiler-portability fixes that the Windows SITL CI matrix flagged:

* MSVC (px4_parameters.hpp): switch the generated parameters_volatile
  and parameters_readonly arrays from a C-style `T arr[] = {}` to
  `std::array<T, N>`. The C form is a GCC/Clang extension; MSVC
  rejects a zero-size array with C2466 ("cannot allocate an array of
  constant size 0"). px4_sitl has no volatile or readonly params, so
  both arrays land at size 0 and the build fails at line 11302 of
  the generated header. std::array<T, 0> is standard, supports the
  existing range-for in parameters_common.cpp, and keeps the storage
  identical for non-empty boards.

* MinGW (windows/runtime/init.cpp): drop the `extern` keyword from the
  three g_usleep_* globals. With an initializer present, `extern T x =
  v;` is a definition, and GCC under -Wextra -Werror flags it as
  ``initialized and declared 'extern'``. The matching `extern T x;`
  declarations stay in windows_shim/unistd.h; we wrap the definitions
  in `extern "C" { ... }` so the C linkage the inline shim relies on
  is preserved.

Local Ninja+MSVC build of build/px4_sitl_default --target px4
succeeds; bin/px4.exe is produced (10.8 MB).

Signed-off-by: Nuno Marques <n.marques21@hotmail.com>
This commit is contained in:
Nuno Marques
2026-05-07 17:24:40 -07:00
parent 3caba73975
commit 044688f8f8
2 changed files with 23 additions and 7 deletions
@@ -95,15 +95,26 @@ volatile LONG g_px4_session_id = 0;
* call. They live at file scope because every translation unit that
* includes <unistd.h> on Windows references them through the inline body
* of usleep(). */
extern "C" long g_usleep_pure_spin_us = 5000;
extern "C" long g_usleep_spin_tail_us = 1000;
/* GCC's -Werror trips on `extern <type> name = init;` because an
* initializer turns the line into a definition, making `extern`
* redundant. The matching `extern` declarations live in
* platforms/posix/include/windows_shim/unistd.h; here we only need
* definitions with external linkage (the default for non-static globals
* at namespace scope). Wrapping in `extern "C"` keeps the C linkage that
* the inline shim relies on. */
extern "C" {
long g_usleep_pure_spin_us = 5000;
long g_usleep_spin_tail_us = 1000;
}
/* Floor for the per-thread adaptive spin tail. Initialised by
* px4_windows_calibrate_usleep_threshold() to the host-measured P95
* waitable-timer jitter so the controller never collapses below the
* value we already know is needed to cover the observed long-tail wakes.
* Defaults to a conservative 700 us when calibration cannot run (e.g.
* pre-1803 Windows with no high-resolution timer). */
extern "C" long g_usleep_adaptive_min_tail_us = 700;
extern "C" {
long g_usleep_adaptive_min_tail_us = 700;
}
/**
* @brief Auto-tune g_usleep_pure_spin_us against the host's measured
@@ -2,6 +2,7 @@
#include <math.h> // NAN
#include <array>
#include <stdint.h>
#include <parameters/param.h>
@@ -38,17 +39,21 @@ static constexpr param_type_t parameters_type[] = {
{%- endfor -%}
};
static constexpr params parameters_volatile[] = {
{# Use std::array so that an empty list (size 0) is well-formed on all
compilers. A C-style "T arr[] = {}" is a GCC/Clang extension; MSVC
rejects it with C2466 ("cannot allocate an array of constant size 0").
std::array<T, 0> is standard and supports range-for. #}
static constexpr std::array<params, {{ volatile_params|length }}> parameters_volatile = { {
{% for param in volatile_params %}
params::{{ param.attrib["name"] }},
{% endfor %}
};
} };
static constexpr params parameters_readonly[] = {
static constexpr std::array<params, {{ readonly_param_names|length }}> parameters_readonly = { {
{% for param_name in readonly_param_names %}
params::{{ param_name }},
{% endfor %}
};
} };
} // namespace px4