pj_base: drop fmt from time_format.cpp (MSVC LNK2005 in consumers) - #195
Merged
Conversation
…consumers Header-only fmt still emits its implementation symbols (vformat, format_facet::do_put, detail::write_loc, …) into time_format.o. On ELF they are weak and dedupe silently, but MSVC emits them as COMDATs that collide (LNK2005) with the strong definitions in a consumer's own fmt.lib — exactly what happened to toolbox_mosaico linking plotjuggler_sdk/0.31.0 plus its own fmt on Windows. time_format.cpp only zero-pads small integers, so format with snprintf and drop the pj_internal_fmt link from pj_base entirely. Add an install guard (test_sdk_install.sh Step 6) that fails if the installed libpj_base.a defines any fmt symbol, making the Windows-only collision visible on Linux CI: the released 0.31.0 archive trips it with 92 matches; this branch ships zero. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TTJvEsHX26rG4cHmqppvQg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
0.31.0's new
pj_base/src/time_format.cppformats via the private header-only fmt (pj_internal_fmt). Header-only mode still emits fmt's implementation symbols (vformat,format_facet<locale>::do_put,detail::is_printable,detail::write_loc, …) intotime_format.o:libfmt, so nothing failed.fmt.lib(strong, non-COMDATformat.cc.obj) gets LNK2005 "already defined" → LNK1169. This broke pj-official-plugins PR #291's Windows build (toolbox_mosaico_plugin.dlllinks bothpj_base.libandfmt.lib).The 0.31.0 "no fmt in installed exports" validation was true at the CMake-interface level; the archive contents were the gap. The released
libpj_base.acarries 92 defined fmt:: symbols.Fix
time_format.cpponly zero-pads small integers —snprintfdoes that. Rewrite the three format helpers withsnprintfand remove thepj_internal_fmtlink frompj_baseentirely. Output is byte-identical (the existing 24 formatter test vectors pin it).pj_plugins(plugin_catalog.cpp) still usespj_internal_fmt; that archive is linked by the host, not by plugins, so it is not part of this collision surface — left as is.Regression guard
test_sdk_install.shStep 6: fail if the installedlibpj_base.adefines anyfmt::symbol (nm -C | grep). Verified it trips on the released 0.31.0 package archive (92 matches) and passes on this branch (0).Validation
./build.sh+./test.sh: 95/95./test_sdk_install.sh: PASSED incl. the new Step 6nm -C build/pj_base/libpj_base.a | grep -c fmt::→ 0No tag/release here — a 0.31.1 patch release is the maintainer's call; pj-official-plugins #291 then just bumps its pin.
🤖 Generated with Claude Code
https://claude.ai/code/session_01TTJvEsHX26rG4cHmqppvQg