-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
[C++20][modules] Combining modules, concepts (and a JSON library) leads to a linkage error #121797
Comments
@llvm/issue-subscribers-clang-modules Author: None (AlbertSSj)
I have a small module (A) that defines a template function on objects that can be casted to an nlohmann::json object, and a concept to enable the operation. I have a separate module (B) to use the operation.
When used in a module, this leads to a linkage error. The linker seems to believe that the symbols for some of the JSON operation have to be provided by module A.
What is interesting is that by forcing module A to generate the symbols, by creating an exported function that does a bunch of JSON conversions, the linkage can complete successfully. So for now I'm adding one by one the JSON conversions that are required by B in A. I don't even need to use my function to cause the issue, just defining a JSON object is enough. Below is a set of files that can reproduce the problem: module_a.cppm module;
#include <nlohmann/json.hpp>
export module module_a;
namespace module_a {
template <typename T>
concept FromOrderedJson = requires(T t) {
{ static_cast<nlohmann::ordered_json>(t) };
};
template <typename T>
concept FromJson = requires(T t) {
{ static_cast<nlohmann::json>(t) };
};
export template <typename T>
requires(FromOrderedJson<T>)
std::string MakeString(T value)
{
return nlohmann::ordered_json(value);
}
export template <typename T>
requires(FromJson<T>)
std::string MakeString(T value)
{
return nlohmann::json(value);
}
} // namespace module_a module_b.cpp module;
#include <iostream>
#include <nlohmann/json.hpp>
export module module_b;
import module_a;
namespace {
struct MyJsonData
{
std::string a;
int b;
bool c;
};
void to_json(nlohmann::json& j, const MyJsonData& p)
{
j["a"] = p.a;
j["b"] = p.b;
j["c"] = nlohmann::json(p.c);
}
} // namespace
int main(int argc, char* argv[])
{
MyJsonData value;
auto x = nlohmann::json(value);
} CMakeLists.txt add_library(module_a SHARED)
target_sources(
module_a
PUBLIC FILE_SET modules TYPE CXX_MODULES FILES
module_a.cppm
)
target_compile_options(
module_a
#PUBLIC
#-fexperimental-modules-reduced-bmi
)
target_link_libraries(
module_a
)
add_executable(module_b)
target_sources(
module_b
PUBLIC FILE_SET modules TYPE CXX_MODULES FILES
module_b.cpp
)
target_link_libraries(
module_b
PUBLIC
module_a
) The error is this:
Which basically means that the symbol for the JSON conversion from bool is missing (I think). In case it helps, I'm using clang version 19.1.6 and cmake version 3.28.3. |
It will be helpful for me if we can have a reproducer without any dependencies (it will be better if the stl is not needed.) |
@ChuanqiXu9 I can remove stl, however right now I would not know how to recreate the issue without using nlohmann::json, can that stay? |
The |
I have a small module (A) that defines a template function on objects that can be casted to an nlohmann::json object, and a concept to enable the operation. I have a separate module (B) to use the operation.
When used in a module, this leads to a linkage error. The linker seems to believe that the symbols for some of the JSON operation have to be provided by module A.
What is interesting is that by forcing module A to generate the symbols, by creating an exported function that does a bunch of JSON conversions, the linkage can complete successfully. So for now I'm adding one by one the JSON conversions that are required by B in A.
I don't even need to use my function to cause the issue, just defining a JSON object is enough.
Below is a set of files that can reproduce the problem:
module_a.cppm
module_b.cpp
CMakeLists.txt
The error is this:
Which basically means that the symbol for the JSON conversion from bool is missing (I think).
In case it helps, I'm using clang version 19.1.6 and cmake version 3.28.3.
The text was updated successfully, but these errors were encountered: