-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Fix "undefined reference to `fmt::v7::detail::basic_data<void>::digits'" #2333
Conversation
I wonder why it doesn't happen in CI. Could you provide repro details? |
Pseudocmake:
Because If link |
Adding the combination to the test suite would certainly help catch problems in the future. |
I believe, you are also linking to fmtlib incorrectly because the error occurs not in Note that libfmt is not linked transitively to add_library(mylibrary SHARED lib.cpp)
target_link_libraries(mylibrary PRIVATE libfmt.a) # link with static fmt while you seem to be using libfmt in your add_executable(exe main.cpp)
target_link_libraries(exe PRIVATE mylibrary) # Error: undefined reference to `fmt::v7::detail::basic_data<void>::digits' I think, a clear (non-pseudo) example is necessary to understand the scenario. |
@sergiud, No. The exe target does not use fmt functions anywhere and cannot depend on it. |
I cannot reproduce the problem at ad97258. Here's my MWE:
cmake_minimum_required (VERSION 3.0)
project (fmt-link)
set (CMAKE_CXX_VISIBILITY_PRESET hidden)
find_package (fmt REQUIRED)
add_library (mylib SHARED mylib.cpp)
target_link_libraries (mylib PRIVATE fmt::fmt)
add_executable (myexe myexe.cpp)
target_link_libraries (myexe PRIVATE mylib)
#include <fmt/format.h>
__attribute__((visibility("default")))
std::string foo()
{
return fmt::format("foo bar {}", 42);
}
#include <string>
#include <iostream>
extern std::string foo();
int main()
{
std::cout << foo() << std::endl;
} |
Build:
Error:
|
openSUSE Leap 15.2 |
Still no linker error. I copy pasted your modifications and used a local clone of fmtlib included via I'm on ArchLinux with gcc version 11.1.0. Edit: I missed the |
The culprit seems to be the combination diff --git a/include/fmt/format.h b/include/fmt/format.h
index 3f6ab357..71df6ced 100644
--- a/include/fmt/format.h
+++ b/include/fmt/format.h
@@ -902,7 +902,7 @@ template <typename T = void> struct basic_data {
FMT_API static constexpr const char right_padding_shifts[] = {0, 31, 0, 1, 0};
};
-#ifndef FMT_HEADER_ONLY
+#if !defined(FMT_HEADER_ONLY) && defined(FMT_EXPORT)
// Required for -flto, -fivisibility=hidden and -shared to work
extern template struct basic_data<void>;
#endif @phprus Can you verify this? |
I will check this change a little later today. But anyway static libraries don't need visibility attribute. Therefore, I think it would be better to change the FMT_API as well. |
In this case condition |
@@ -253,9 +253,10 @@ | |||
# endif | |||
#else | |||
# define FMT_CLASS_API | |||
# if defined(__GNUC__) || defined(__clang__) | |||
# define FMT_API __attribute__((visibility("default"))) | |||
# define FMT_EXTERN_TEMPLATE_API FMT_API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you remove FMT_EXTERN_TEMPLATE_API
definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FMT_EXTERN_TEMPLATE_API
was added in the partial incorrect commit 13e6529 and is not used anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, "partial incorrect commit" 👎
FMT_EXTERN_TEMPLATE_API
was used before. But you're correct to note that it is not necessary anymore.
Could you also please add the combination to the test suite? This case is currently not being tested. |
5729075
to
ac89e52
Compare
Test added. |
Great, thanks! LGTM |
Don't merge now. |
Note that you can transform this PR to Draft until you are ready. |
Changes applied. |
Remove unused FMT_EXTERN_TEMPLATE_API
Merged, thank you both! |
If static fmt library is used in shared library.
Error in commit 13e6529.