0

I'm trying to use fmt with ESP32 toolchain (xtensa 32bit GCC with Cxx11 support - see https://github.com/espressif/esp-idf for mode details). Unfortunately they have their own "flavor" of CMake (https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html) so I created new ESP32 component for fmt which is very simple:

set (FMT_SDK "${CMAKE_CURRENT_LIST_DIR}/../../src/lib/fmt")

set (COMPONENT_ADD_INCLUDEDIRS
        "${FMT_SDK}/include")

set (COMPONENT_SRCS
        "${FMT_SDK}/src/format.cc"
        "${FMT_SDK}/src/os.cc"
        )

register_component()

However when trying to use even simple named parameters (int, float) e.g.:

fmt::format("Test: {Test:.2f}", fmt::arg("Test", 125.0f));

I'm getting following error during the build:

../src/lib/fmt/include/fmt/core.h: In instantiation of 'fmt::v8::detail::value<Context> fmt::v8::detail::make_arg(T&&) [with bool IS_PACKED = true; Context = fmt::v8::basic_format_context<fmt::v8::appender, char>; fmt::v8::detail::type <anonymous> = (fmt::v8::detail::type)15; T = fmt::v8::format_arg_store<fmt::v8::basic_format_context<fmt::v8::appender, char>, fmt::v8::detail::named_arg<char, float> >; typename std::enable_if<IS_PACKED, int>::type <anonymous> = 0]':
../src/lib/fmt/include/fmt/core.h:1855:77:   required from 'fmt::v8::format_arg_store<Context, Args>::format_arg_store(T&& ...) [with T = {fmt::v8::format_arg_store<fmt::v8::basic_format_context<fmt::v8::appender, char>, fmt::v8::detail::named_arg<char, float> >}; Context = fmt::v8::basic_format_context<fmt::v8::appender, char>; Args = {fmt::v8::detail::named_arg<char, float>}]'
../src/lib/fmt/include/fmt/core.h:1728:7: error: static assertion failed: Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt

I tried including format-inl.h but I think I'm missing some compiler flag.

shrpq
  • 467
  • 3
  • 8
  • Not sure if that's the problem but usually creating an IDF component using CMake is to pass the arguments directly to the register call like this: `idf_component_register(SRCS "file.c" INCLUDE_DIRS "include_dir")` – StrawHat Feb 15 '22 at 07:38

1 Answers1

1

The easiest way is to use it as a single header library.

idf_build_get_property(target IDF_TARGET)

idf_component_register(
                    INCLUDE_DIRS "fmtlib/include"
                    )

And you need to define FMT_HEADER_ONLY before including fmt headers.

I have created a quick example here.