John Emmas via llvm-dev
2021-Sep-22 12:22 UTC
[llvm-dev] Disabling inline compilation (Clang with VS2019)
Hi there - I first asked this question over on clang-users but I got advised to ask it here (sorry about the length...) I'm a VS2019 user and I've been trying to switch it here to use Clang as the compiler, rather than MSVC. But I seem to have hit a common problem. Consider the following code:- #if defined (BUILDING_DLL) #define DLL_API __declspec(dllexport) #else #define DLL_API __declspec(dllimport) #endif namespace Gtkmm2ext { class DLL_API Keyboard { public: Keyboard (); ~Keyboard (); static Keyboard& get_keyboard() { return *_the_keyboard; } protected: static Keyboard* _the_keyboard; }; } /* namespace */ The above code is from a DLL which gets used by an exe. The DLL compiles and links just fine and the exe compiles. But when I try to link the exe, Clang's linker complains that it can't find '_the_keyboard' But here's the thing... '_the_keyboard' is an internal variable that's private to the DLL. It should never need to get accessed by the exe. If I change 'get_keyboard()' to be just a declaration (and then implement it in a DLL source file) Clang is then happy - but unfortunately, this is one of several hundred similar linker errors. So I'm wondering if (maybe) the compiler implemented its call to 'get_keyboard()' as inline code, rather than importing it from the DLL? Maybe for very simple code like this, Clang is trying to be clever and implement stuff inline if it can? VS2019 can disable inline code via a compiler option called "/Ob0" - and typing "clang-cl /?" indicates that "/Ob0" is supported. But I still see the error, even if I specify "/Ob0" during compilation. So will "/Ob0" disable all inline compilation for Clang? Or does it only take effect where there's an actual 'inline' keyword? Hope that all makes sense... John
Dimitry Andric via llvm-dev
2021-Sep-22 12:33 UTC
[llvm-dev] Disabling inline compilation (Clang with VS2019)
On 22 Sep 2021, at 14:22, John Emmas via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > Hi there - I first asked this question over on clang-users but I got advised to ask it here (sorry about the length...) > > I'm a VS2019 user and I've been trying to switch it here to use Clang as the compiler, rather than MSVC. But I seem to have hit a common problem. Consider the following code:- > > #if defined (BUILDING_DLL) > #define DLL_API __declspec(dllexport) > #else > #define DLL_API __declspec(dllimport) > #endif > > namespace Gtkmm2ext { > > class DLL_API Keyboard > { > public: > Keyboard (); > ~Keyboard (); > > static Keyboard& get_keyboard() { return *_the_keyboard; } > > protected: > static Keyboard* _the_keyboard; > }; > > } /* namespace */ > > The above code is from a DLL which gets used by an exe. The DLL compiles and links just fine and the exe compiles. But when I try to link the exe, Clang's linker complains that it can't find '_the_keyboard'As far as I understand it, if you specify __declspec(dllexport) for a whole class, then *all* members, including statics, get explicitly exported in the DLL image. I.e. it is as if you had manually specified __declspec(dllexport) to each and every member. I don't know if there is any way to override that for just a single class member, for example as with gcc you could add a __attribute__((visibility("hidden"))) to one of them. So maybe you can selectively add DLL_API to those class members that you need exported, as described here: https://docs.microsoft.com/en-us/cpp/cpp/using-dllimport-and-dllexport-in-cpp-classes?view=msvc-160#_pluslang_using_dllimport_and_dllexport_in_c2b2bselectivememberimportexport -Dimitry -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 223 bytes Desc: Message signed with OpenPGP URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210922/1798697e/attachment.sig>