Skip to content

LNK2001 error occurred after update version from V1.5.0 to V1.5.2 via vcpkg #552

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

Open
ahnjs1987 opened this issue Apr 16, 2025 · 12 comments
Milestone

Comments

@ahnjs1987
Copy link

I have a question about this update.
After I installed paho-mqttpp3@1.5.2 via vcpkg, When building using libraries installed in VS, the following error occurs.

unresolved external symbol "private: static class std::basic_string<char,struct std::char_traits,class std::allocator > const mqtt::message::EMPTY_STR" (?EMPTY_STR@message@mqtt@@0V?$basic_string@DU?$char_traits@D@std@@v?$allocator@D@2@@std@@b)

I had checked EMPTY_STR exist in massages.cpp/massages.h.

How do I fix it?

@fpagliughi
Copy link
Contributor

Crazy. The v1.5.2 was released, specifically to fix this, and by my tests, it did. I don't maintain the vcpkg, so am not sure what happened. I can try to investigate.

@fpagliughi fpagliughi added this to the v1.5.4 milestone May 16, 2025
@Masterlovsky
Copy link

I'm having the same issue with the latest release, 1.5.3, and strangely it doesn't seem to have this compilation error on the mac

@Juraj-MEX
Copy link

I had this issue and was able to fix the unresolved external by defining PAHO_MQTTPP_IMPORTS in my project which consumes the Paho C++ library.

@fpagliughi
Copy link
Contributor

🤦‍♂ I guess I should RTFM. (The one I wrote)
https://github.com/eclipse-paho/paho.mqtt.cpp?tab=readme-ov-file#using-paho-c-as-a-windows-dll

If using it as a DLL in your application, you should define the macro PAHO_MQTTPP_IMPORTS before including any Paho C++ include files. Preferably, make it a global definition in the application's build file, like in CMake:

@fpagliughi
Copy link
Contributor

I hate that this is required. I really don't like how Windows works with symbols in DLLs, but after 30yrs, I really need to stop complaining about it.

I had worked around it a while back, but then that broke another compiler. I'l look to see if I can satisfy both with some conditional compilation.

@Masterlovsky, this isn't strange. This is Windows.

It links just fine on Linux and Mac.

@Juraj-MEX
Copy link

I think in the file export.h the definition of PAHO_MQTTPP_EXPORT should be simplified to this:
#if defined(PAHO_MQTTPP_EXPORTS)
#define PAHO_MQTTPP_EXPORT __declspec(dllexport)
#else
#define PAHO_MQTTPP_EXPORT __declspec(dllimport)
#endif

Whenever I create a shared DLL I do it in a similar way. The project which creates the DLL should have PAHO_MQTTPP_EXPORTS defined which will make the symbol exported. In every other project (consumer of the DLL) where PAHO_MQTTPP_EXPORTS is not defined will automatically go into the else branch and will import the symbol from the DLL.

I actually don’t know which use case is the last option (where PAHO_MQTTPP_EXPORT will be empty) in the original code meant for. We need either export (creation of the DLL) or import (use of the DLL) the symbol and nothing else in between.

@fpagliughi
Copy link
Contributor

fpagliughi commented May 23, 2025

I actually don’t know which use case is the last option (where PAHO_MQTTPP_EXPORT will be empty) in the original code meant for.

Well... for every other platform that isn't Windows!
Linux, Mac, and any other UNIX or *nix-style platforms do not use this, so it needs to be empty for them.

@Juraj-MEX
Copy link

I actually don’t know which use case is the last option (where PAHO_MQTTPP_EXPORT will be empty) in the original code meant for.

Well... for every other platform that isn't Windows! Linux, Mac, and any other UNIX or *nix-style platforms do not use this, so it needs to be empty for them.

But I mean the one which is inside the #if defined(_WIN32) block. I think that there is no use case for it on Windows (I don't know other platforms).

@Masterlovsky
Copy link

I actually don’t know which use case is the last option (where PAHO_MQTTPP_EXPORT will be empty) in the original code meant for.我实际上不知道哪个用例是原始代码中的最后一个选项(其中 PAHO_MQTTPP_EXPORT 将为空)。

Well... for every other platform that isn't Windows! Linux, Mac, and any other UNIX or *nix-style platforms do not use this, so it needs to be empty for them.

But I mean the one which is inside the #if defined(_WIN32) block. I think that there is no use case for it on Windows (I don't know other platforms).

I think defining PAHO_MQTTPP_EXPORT only on the Windows platform is sufficient, while on other platforms it can be defined as empty. It can be written similarly to the following code::
#ifdef _WIN32
#if defined(PAHO_MQTTPP_EXPORTS)
#define PAHO_MQTTPP_EXPORT __declspec(dllexport)
#else
#define PAHO_MQTTPP_EXPORT __declspec(dllimport)
#endif
#else
#define PAHO_MQTTPP_EXPORT
#endif

@fpagliughi
Copy link
Contributor

fpagliughi commented May 24, 2025

Couple questions...

  1. What about building and linking to the static library? From this definition, the static library and any application that uses it on Windows would get the __declspec(dllimport) definition. That doesn't sound right to me.
  2. Isn't the DLL export/import only used by the Microsoft compiler on Windows? Don't we need to keep the defined(_MSC_VER) ?

And, yes, my previous comment was incomplete. The empty PAHO_MQTTPP_EXPORT in the Windows part of the conditional compilation is for both the library and applications when building or linking to the static version of the library.

@Masterlovsky
Copy link

Couple questions...

  1. What about building and linking to the static library? From this definition, the static library and any application that uses it on Windows would get the __declspec(dllimport) definition. That doesn't sound right to me.
  2. Isn't the DLL export/import only used by the Microsoft compiler on Windows? Don't we need to keep the defined(_MSC_VER) ?

And, yes, my previous comment was incomplete. The empty PAHO_MQTTPP_EXPORT in the Windows part of the conditional compilation is for both the library and applications when building or linking to the static version of the library.

I don't understand why dynamic libraries cannot use export symbols? I used the paho library before and all depend on dynamic libraries.

@fpagliughi
Copy link
Contributor

Yes, previously the constant that it is complaining about was a static inside a function, but that cause a crash when using the clang compiler, so I moved it into the file scope, and now that's causing linker errors for Windows.

It's infuriating since either way should be valid C++ and yet the different compilers and platforms can't agree how to handle it.

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

4 participants