Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pj_base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ target_compile_options(pj_base PRIVATE
)
# Header-only implementation dependencies stay off installed targets so
# downstream consumers inherit neither their include paths nor link requirements.
# Header-only fmt is deliberately NOT linked here: even header-only, its
# implementation symbols land in the installed static archive and collide
# with a consumer's own fmt under MSVC (see test_sdk_install.sh guard).
target_link_libraries(pj_base PRIVATE
$<BUILD_INTERFACE:FastFloat::fast_float>
$<BUILD_INTERFACE:pj_internal_fmt>
)
set_target_properties(pj_base PROPERTIES
POSITION_INDEPENDENT_CODE ON
Expand Down
26 changes: 20 additions & 6 deletions pj_base/src/time_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@

#include "pj_base/time_format.hpp"

#include <fmt/format.h>

#include <cctype>
#include <chrono>
#include <cstdio>

#include "pj_base/time_math.hpp"

Expand Down Expand Up @@ -38,13 +37,23 @@ UtcTime utcFromNanoseconds(int64_t ts_ns) {
static_cast<int>(time.seconds().count())};
}

// Plain snprintf, deliberately: linking fmt here would embed fmt
// implementation symbols in the installed pj_base archive, which collide
// (LNK2005) with any consumer that links its own fmt on MSVC.
std::string formatDate(const UtcTime& utc, char separator, bool day_first) {
return day_first ? fmt::format("{:02}{}{:02}{}{:04}", utc.day, separator, utc.month, separator, utc.year)
: fmt::format("{:04}{}{:02}{}{:02}", utc.year, separator, utc.month, separator, utc.day);
char buffer[32];
if (day_first) {
std::snprintf(buffer, sizeof buffer, "%02d%c%02d%c%04d", utc.day, separator, utc.month, separator, utc.year);
} else {
std::snprintf(buffer, sizeof buffer, "%04d%c%02d%c%02d", utc.year, separator, utc.month, separator, utc.day);
}
return buffer;
}

std::string formatTime(const UtcTime& utc) {
return fmt::format("{:02}:{:02}:{:02}", utc.hour, utc.minute, utc.second);
char buffer[16];
std::snprintf(buffer, sizeof buffer, "%02d:%02d:%02d", utc.hour, utc.minute, utc.second);
return buffer;
}

bool isDigit(char character) {
Expand All @@ -70,7 +79,12 @@ bool parseFixedDigits(std::string_view text, std::size_t offset, std::size_t cou

std::string formatTimestamp(int64_t ts_ns, bool long_format) {
const auto utc = utcFromNanoseconds(ts_ns);
return long_format ? fmt::format("{:02}/{:02} {}", utc.day, utc.month, formatTime(utc)) : formatTime(utc);
if (!long_format) {
return formatTime(utc);
}
char day_month[16];
std::snprintf(day_month, sizeof day_month, "%02d/%02d ", utc.day, utc.month);
return day_month + formatTime(utc);
}

std::string formatDuration(int64_t duration_ns) {
Expand Down
17 changes: 17 additions & 0 deletions test_sdk_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,22 @@ if [[ $LEAKED -ne 0 ]]; then
exit 1
fi

# ---------------------------------------------------------------------------
# 6. Verify pj_base ships no fmt implementation symbols
# ---------------------------------------------------------------------------

echo ""
echo "--- Step 6: Verify libpj_base.a defines no fmt symbols ---"

# fmt is a private, header-only implementation detail. If its implementation
# symbols land in the installed archive (weak on ELF, so Linux links fine),
# the MSVC build of the same code collides (LNK2005) with any consumer that
# links its own fmt — this check makes the Windows failure visible on Linux.
if nm -C "$STAGING_DIR/lib/libpj_base.a" | grep -E " [TWuVvW] " | grep -q "fmt::"; then
echo "ERROR: installed libpj_base.a defines fmt symbols (collides with a consumer's fmt on MSVC):"
nm -C "$STAGING_DIR/lib/libpj_base.a" | grep -E " [TWuVvW] " | grep "fmt::" | head -10
exit 1
fi

echo ""
echo "=== plotjuggler_sdk install test PASSED ==="
Loading