Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clang build error with version 8.0: undefined symbol: void ... vformat_to<char>(...) #2377

Closed
jdrouhard opened this issue Jun 22, 2021 · 3 comments

Comments

@jdrouhard
Copy link

Given the following code:

#include <fmt/format.h>
#include <vector>

void fooImpl(std::vector<char> & chars, fmt::string_view fmt, fmt::format_args args) {
    fmt::vformat_to(std::back_inserter(chars), fmt, args);
}

template <typename S, typename... T>
std::vector<char> foo(const S& s, T &&... args) {
    using namespace fmt;
    std::vector<char> val;
    fooImpl(val, to_string_view(s), make_args_checked<T...>(s, args...));
    return val;
}

int main(int argc, char ** argv) {
    auto chars = foo("testing {}: {}", argc, argv[0]);
    return 0;
}

I get:

ld.lld: error: undefined symbol: void fmt::v7::detail::vformat_to(fmt::v7::detail::buffer&, fmt::v7::basic_string_view, fmt::v7::basic_format_args<fmt::v7::basic_format_context<std::conditional<std::is_same<fmt::v7::type_identity::type, char>::value, fmt::v7::appender, std::back_insert_iterator<fmt::v7::detail::buffer<fmt::v7::type_identity::type> > >::type, fmt::v7::type_identity::type> >, fmt::v7::detail::locale_ref)

Same exact problem with ld and gold, but lld prints the demangled symbol. I know that symbol is defined:

$ nm -C -D libfmt.so.8.0.0
0000000000020d30 W void fmt::v7::detail::vformat_to(fmt::v7::detail::buffer&, fmt::v7::basic_string_view, fmt::v7::basic_format_args<fmt::v7::basic_format_context<std::conditional<std::is_same<fmt::v7::type_identity::type, char>::value, fmt::v7::appender, std::back_insert_iterator<fmt::v7::detail::buffer<fmt::v7::type_identity::type> > >::type, fmt::v7::type_identity::type> >, fmt::v7::detail::locale_ref)

Tested on clang 12 and trunk, using all 3 main linkers (ld, lld, and gold). I'm attempting to link the shared object (not using the header-only version).

GCC 8 and 9 (and presumably 10, 11, and trunk) all seem to handle this fine. clang also works fine with 7.1.3, so it's something new in 8.0.0 that it doesn't like. If it's a clang problem, I'm wondering if there's a workaround? I believe vformat_to<char> was already an extern template with an explicit instantiation in 7.1.3, so I'm not sure what else might be causing this.

@jdrouhard jdrouhard changed the title clang build error with version 8.0: "undefined symbol: void ... vformat_to<char>(...)" clang build error with version 8.0: undefined symbol: void ... vformat_to<char>(...) Jun 23, 2021
@vitaut
Copy link
Contributor

vitaut commented Jul 2, 2021

Looks like the error is due to incompatibility between clang and gcc. I was able to repro it on xenial as follows:

$ git clone https://github.com/fmtlib/fmt.git
$ cd fmt
$ CXX=clang++-8 cmake -DBUILD_SHARED_LIBS=TRUE .
$ make -j10
$ c++ path/to/test.cc -lfmt -L. -I include -std=c++11

/tmp/ccnVNvdV.o: In function `std::back_insert_iterator<std::vector<char, std::allocator<char> > > fmt::v8::vformat_to<std::back_insert_iterator<std::vector<char, std::allocator<char> > >, 0>(std::back_insert_iterator<std::vector<char, std::allocator<char> > >, fmt::v8::basic_string_view<char>, fmt::v8::basic_format_args<fmt::v8::basic_format_context<fmt::v8::appender, char> >)':
test.cc:(.text._ZN3fmt2v810vformat_toISt20back_insert_iteratorISt6vectorIcSaIcEEELi0EEET_S7_NS0_17basic_string_viewIcEENS0_17basic_format_argsINS0_20basic_format_contextINS0_8appenderEcEEEE[_ZN3fmt2v810vformat_toISt20back_insert_iteratorISt6vectorIcSaIcEEELi0EEET_S7_NS0_17basic_string_viewIcEENS0_17basic_format_argsINS0_20basic_format_contextINS0_8appenderEcEEEE]+0x63): undefined reference to `void fmt::v8::detail::vformat_to<char>(fmt::v8::detail::buffer<char>&, fmt::v8::basic_string_view<char>, fmt::v8::basic_format_args<fmt::v8::basic_format_context<std::conditional<std::is_same<fmt::v8::type_identity<char>::type, char>::value, fmt::v8::appender, std::back_insert_iterator<fmt::v8::detail::buffer<fmt::v8::type_identity<char>::type> > >::type, fmt::v8::type_identity<char>::type> >, fmt::v8::detail::locale_ref)'

@vitaut
Copy link
Contributor

vitaut commented Jul 2, 2021

Should be fixed in 3e7a29c. Thanks for reporting.

@vitaut vitaut closed this as completed Jul 2, 2021
@sangelovic
Copy link

Just for the record, I got the same linking errors with Clang 14.0.3 while it's working with gcc. I already am using fmtlib v8.1.1, which should have fixed that. After some investigations, I found the cause: I included core.h header file: #include <fmt/core.h>. Replacing that with #include <fmt/format.h> fixed the problem. Hope it helps others experiencing the same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants