Using fmt in wx

53 views
Skip to first unread message

Vadim Zeitlin

unread,
Jan 14, 2026, 11:31:31 AM (2 days ago) Jan 14
to wx-dev
Hello,

I'd like to start using fmt library (https://fmt.dev/ if anybody is really
not aware of it) in wx instead of wxString::Format() and friends. However,
experimenting with it, I'm running into problems related to CMake install
logic.

I'd like to support both using the system fmt library, if available, and
falling back to using 3rdparty/fmt otherwise, as usual. In the first case,
there is no problem, but it looks like in the second one we need to
actually install fmt ourselves, which doesn't seem right, but I don't see
how to avoid doing it. Or, rather, I do see one way, but it looks ugly: we
could avoid using a separate fmt library and compile its sources as part of
wxbase itself. And we'd also need to avoid using fmt in any public headers.
Should we do it like this or is there some better way?

Thanks in advance,
VZ

Robert Roebling

unread,
Jan 14, 2026, 3:00:22 PM (2 days ago) Jan 14
to wx-...@googlegroups.com


Vadim Zeitlin <vadim@>  wrote

we could avoid using a separate
fmt library and compile its sources as part of
wxbase itself. 

They claim to have a small binary size, so this seems ok to me,

  Robert

Ian McInerney

unread,
Jan 14, 2026, 4:42:47 PM (2 days ago) Jan 14
to wx-...@googlegroups.com
In KiCad we use a bundled version of fmt (currently version 11.1), and while we don't have a way of exposing it as a system-level library yet, we could potentially add one. That might be needed if wx grows an fmt dependency to ensure the versions match and we don't run into problems with incorrect symbols.

-Ian

Mark Roszko

unread,
Jan 14, 2026, 4:57:36 PM (2 days ago) Jan 14
to wx-dev
Yea we depend on fmt inside kicad. We bundle our own copy to ensure no distro breaks it as things like floating point printing is absolute mission critical to saving design data. We also heavily depend on it's default behavior being locale-free.

The only concern for wx using it is to ensure no symbols leak into the wx shared library exports or else we may have conflict galore.

Vadim Zeitlin

unread,
Jan 14, 2026, 5:14:17 PM (2 days ago) Jan 14
to wx-...@googlegroups.com
On Wed, 14 Jan 2026 13:52:53 -0800 (PST) Mark Roszko wrote:

MR> Yea we depend on fmt inside kicad. We bundle our own copy to ensure no
MR> distro breaks it as things like floating point printing is absolute mission
MR> critical to saving design data. We also heavily depend on it's default
MR> behavior being locale-free.
MR>
MR> The only concern for wx using it is to ensure no symbols leak into the wx
MR> shared library exports or else we may have conflict galore.

If we don't use fmt in the headers (which would require installing it, as
per the original message), this shouldn't be a problem, as any symbols we
use wouldn't be exported from the shared library (and I think KiCad uses
shared wx libraries, right?). And even with static libraries it should be
fine, I think.

There is also FMT_BEGIN_NAMESPACE macro which can be predefined before
including fmt headers, I believe, and we could use it to put everything
into "wxfmt" namespace instead of the normal "fmt" one if we really wanted
to isolate it.

MR> On Wednesday, January 14, 2026 at 4:42:47 PM UTC-5 Ian McInerney wrote:
MR>
MR> > In KiCad we use a bundled version of fmt (currently version 11.1),

This is one of the problems with fmt: great as it is, it has
incompatibilities between the releases and the code compiling/working with
fmt 11 may not compile with the current version 12, which we would bundle
with wx. So it looks like we really should forget about using it in the
headers and completely hide our use of fmt from the applications.

Regards,
VZ

Maarten Bent

unread,
Jan 14, 2026, 8:17:34 PM (2 days ago) Jan 14
to wx-...@googlegroups.com
Hi,

Can you elaborate on the install problems? I don't see how this would be different from something like webp.
Except it doesn't seem to have a static/shared option, so maybe wrap it inside:

set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(... fmt ...)
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_OLD})

Note that it also seems to have a header-only mode if you don't want to deal with libraries at all.

Maarten

Vadim Zeitlin

unread,
Jan 15, 2026, 6:47:28 AM (21 hours ago) Jan 15
to wx-...@googlegroups.com
On Thu, 15 Jan 2026 02:17:37 +0100 Maarten Bent wrote:

MB> Can you elaborate on the install problems?

I didn't try adding fmt to wx yet, to be honest, but I tried doing it in
another library using CMake and there doing something like

find_package(fmt QUIET)
if (NOT fmt_FOUND)
add_subdirectory(3rdparty/fmt EXCLUDE_FROM_ALL)
endif()
...
target_link_libraries(mylib PRIVATE fmt::fmt)

resulted in the following error when running CMake for a static (this is
important) mylib build:

CMake Error: install(EXPORT "MyLibTargets" ...) includes target "mylib"
which requires target "fmt" that is not in any export set.

And I think CMake has a point here: when using fmt in a shared library,
it's just part of it, and so doesn't need to be installed (provided its
headers are never included from public headers) with it. But when using a
static library, the application needs to link with libfmt.a as well, so we
do need to install it.

MB> I don't see how this would be different from something like webp.

Good question. I actually have no idea how does it work right now, when
using built-in webp and static wx libraries. Does it, even? I don't see how
it could...

MB> Note that it also seems to have a header-only mode if you don't want to
MB> deal with libraries at all.

This is what I've actually ended up doing in that other library where I
finally have

set(mylib_fmt fmt::fmt)
find_package(fmt QUIET)
if (NOT fmt_FOUND AND NOT MYLIB_SHARED)
add_subdirectory(3rdparty/fmt EXCLUDE_FROM_ALL)
set(mylib_fmt $<BUILD_INTERFACE:fmt::fmt-header-only>)
endif()
...
target_link_libraries(mylib PRIVATE ${mylib_fmt})

But it's not the best solution from the point of view of compile time and
binary sizes, so I'd rather not do this for wx.

Thanks,
VZ

Maarten Bent

unread,
Jan 15, 2026, 7:00:12 AM (21 hours ago) Jan 15
to wx-...@googlegroups.com
For webp we export the install target ourselves:
https://github.com/wxWidgets/wxWidgets/blob/8ada351adf57a4d8240102fe2160b737d264d318/build/cmake/lib/webp.cmake#L74-L79

fmt has a FMT_INSTALL option in CMake, you could turn it off to make sure theirs doesn't interfere.

Maarten

Vadim Zeitlin

unread,
Jan 15, 2026, 7:08:40 AM (21 hours ago) Jan 15
to wx-...@googlegroups.com
On Thu, 15 Jan 2026 13:00:06 +0100 Maarten Bent wrote:

MB> For webp we export the install target ourselves:
MB> https://github.com/wxWidgets/wxWidgets/blob/8ada351adf57a4d8240102fe2160b737d264d318/build/cmake/lib/webp.cmake#L74-L79

I see, thanks. I still don't know if we could/should do the same for fmt,
it's a much wider used library than libwebp.

MB> fmt has a FMT_INSTALL option in CMake, you could turn it off to make
MB> sure theirs doesn't interfere.

But this wouldn't fix the issue, would it? I.e. we still need to install
libfmt.a in this build configuration.

More I think about it, more building it as part of wxBase looks like the
least bad option. I also wonder if we could possibly install fmt headers in
some way to avoid interfering with the rest of the system, e.g. install
them under include/wx? For example, Debian libspdlog-dev package includes
fmt headers like this:

https://packages.debian.org/trixie/amd64/libspdlog-dev/filelist

And we could add wx/format.h which could include either wx/fmt/format.h if
some wxUSE_BUNDLED_FMT is defined or just fmt/format.h otherwise.

What do you think?
VZ

wsu

unread,
Jan 15, 2026, 9:13:55 PM (7 hours ago) Jan 15
to wx-dev
Is using fmt an attempt to avoid using C++20?  It seems like using C++20 would avoid these complexities.
Reply all
Reply to author
Forward
0 new messages