fmt icon indicating copy to clipboard operation
fmt copied to clipboard

undefined symbol: protected: virtual bool __cdecl fmt::v9::format_facet<class std::locale>::do_put --- while linking format-test.exe using clang-msvc

Open denchat opened this issue 3 years ago • 2 comments

My clang-msvc build has a linking issue on format-test.exe :

[44/60] Linking CXX executable bin\format-test.exe
FAILED: bin/format-test.exe
cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=test\CMakeFiles\format-test.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100220~1.0\x64\rc.exe --mt=C:\PROGRA~1\LLVM\bin\llvm-mt.exe --manifests  -- C:\PROGRA~1\LLVM\bin\lld-link.exe /nologo test\CMakeFiles\format-test.dir\format-test.cc.obj  /out:bin\format-test.exe /implib:test\format-test.lib /pdb:bin\format-test.pdb /version:0.0 /INCREMENTAL:NO /subsystem:console  test\test-main.lib  fmt.lib  test\gtest\gtest.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
LINK: command "C:\PROGRA~1\LLVM\bin\lld-link.exe /nologo test\CMakeFiles\format-test.dir\format-test.cc.obj /out:bin\format-test.exe /implib:test\format-test.lib /pdb:bin\format-test.pdb /version:0.0 /INCREMENTAL:NO /subsystem:console test\test-main.lib fmt.lib test\gtest\gtest.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:bin\format-test.exe.manifest" failed (exit code 1) with the following output:
lld-link: error: undefined symbol: protected: virtual bool __cdecl fmt::v9::format_facet<class std::locale>::do_put(class fmt::v9::appender, class fmt::v9::loc_value, struct fmt::v9::basic_format_specs<char> const &) const
>>> referenced by test\CMakeFiles\format-test.dir\format-test.cc.obj:(const fmt::v9::format_facet<class std::locale>::`vftable')
ninja: build stopped: subcommand failed.

This is part of format-test.cc :

class format_facet : public fmt::format_facet<std::locale> {
 protected:
  struct int_formatter {
    fmt::appender out;

    template <typename T, FMT_ENABLE_IF(fmt::detail::is_integer<T>::value)>
    auto operator()(T value) -> bool {
      fmt::format_to(out, "[{}]", value);
      return true;
    }

    template <typename T, FMT_ENABLE_IF(!fmt::detail::is_integer<T>::value)>
    auto operator()(T) -> bool {
      return false;
    }
  };

  auto do_put(fmt::appender out, fmt::loc_value val,
              const fmt::format_specs&) const -> bool override;
};

auto format_facet::do_put(fmt::appender out, fmt::loc_value val,
                          const fmt::format_specs&) const -> bool {
  return val.visit(int_formatter{out});
}

TEST(format_test, format_facet) {
  auto loc = std::locale(std::locale(), new format_facet());
  EXPECT_EQ(fmt::format(loc, "{:L}", 42), "[42]");
  EXPECT_EQ(fmt::format(loc, "{:L}", -42), "[-42]");
}

denchat avatar Sep 13 '22 14:09 denchat

Not sure why clang-msvc is complaining because the function in question is defined here: https://github.com/fmtlib/fmt/blob/94ceb38a0943c50ea9939050a7f4e8e4c9da43d2/include/fmt/format-inl.h#L144-L145

vitaut avatar Sep 13 '22 14:09 vitaut

The linker could not find:

error: undefined symbol: protected: virtual bool __cdecl fmt::v9::format_facet<class std::locale>::do_put(class fmt::v9::appender, class fmt::v9::loc_value, struct fmt::v9::basic_format_specs<char> const &) const

With command:

dumpbin.exe -headers fmt.lib | findstr /c:"sym="  > fmt-exports.txt

I found this line

sym= "protected: virtual bool __cdecl fmt::v9::format_facet<class std::locale>::do_put(class fmt::v9::appender,class fmt::v9::loc_value,struct fmt::v9::basic_format_specs<char> const &)const " (?do_put@?$format_facet@Vlocale@std@@@v9@fmt@@MEBA_NVappender@23@Vloc_value@23@AEBU?$basic_format_specs@D@23@@Z)

It seems right there, how come linker can not find it?

denchat avatar Sep 17 '22 08:09 denchat

Closing for now since this doesn't look actionable. Feel free to reopen if additional information comes up that indicates that the problem is on the {fmt} side.

vitaut avatar Dec 21 '22 23:12 vitaut