Building with MSVC, PowerShell. Errors

Is libs/pbd/debug_rt_alloc.c (and its header) just for your build?

No. AFAICT it’s only used by the non-MSVC builds, whenever DEBUG_RT_ALLOC is #defined (so presumably, only for Debug builds).

I might make a separate post in the future about it, but I’ve switched to using a python script with Python 3.14 and Jinja2 3.1.6 to create MSBuild files for the past several days. Maybe I’ll elaborate, maybe not.

@John_E When building luabindings (which is in libs/ardour), one of the files included from one of the files that are included (or eventually included) is libs/evoral/evoral/note.h.

Note.h has 2 sections addressing COMPILER_MSVC alone:

#ifdef COMPILER_MSVC
class LIBEVORAL_LOCAL Note {
#else
class LIBEVORAL_TEMPLATE_API Note {
#endif
#ifdef COMPILER_MSVC
#include "../src/Note.impl"
#endif

I don’t see this Note.impl anywhere, and am getting an error because of it.

Do you have the .impl file? What are its contents? Can the inclusion of that be replaced with some code, or can it be deleted altogether? And by chance, could you explain the need for that if/else in the first block?

Basically it’s an exact copy of libs/evoral/Note.cc. It’s needed because MSVC doesn’t consider template functions to be exportable from a DLL. You need to implement them somewhere if they’ll be used outside of libevoral. Here are the steps you’ll need to take:-

  1. When building evoral (before starting the compilation) add some code which copies libs/evoral/Note.cc to libs/evoral/src/Note.impl
  2. Add something to ensure you don’t compile Note.cc when building with MSVC. I’d imagine it might look something like this in libs/evoral/wscript (or whatever the perl equivalent would be, of course):-
    ControlSet.cc
    Curve.cc
    Event.cc
    #ifndef _MSC_VER
    Note.cc
    #endif
    SMF.cc
    Sequence.cc
    debug.cc

Hope that helps… BTW I’ve been trying to find out from Microsoft if they ever included the glib stuff (at version 2) in any of their previous vcpkg tags but they’re totally ignoring me (which I assume means they didnt!)

This is crazy! :slight_smile:

Why copy it instead if using it directly is possible?

Is this template issue still present with recent MSVC? We use templated API just fine in other places.

I guess you could change Note.h and add a line saying #include “…/Note.cc” but IMHO, that would make it look like there’s a circular dependency. To me, #including Note.impl makes it a bit clearer we’re #including something for the purpose of ensuring something gets implemented.

Yes, it’s still present in VS2022

1 Like

Sorry if I’m missing something obvious but doesn’t this forum allow users to be contacted via a private message?

It is a public forum. There are no private messages.

Groan… in that case, @EZ4Stephen - please will you stop introducing changes that break my build! Yesterday’s commit #98b9839e58 prevents libpbd from linking here. Whether built with MSVC or Clang, both compilers complain now about multiply defined symbols.

I’ve mentioned previously that the existing code is already buildable with MSVC whereas the support libs from vcpkg are known to not work properly with Ardour. And while I’ve no problem if you prefer finding stuff out the hard way, please make sure you protect code that’s already working (e.g. maybe surround your additions with #ifdef WAF_BUILD and else)

I committed those changes, so blame me…

Replace DECLARE_DEFAULT_COMPARISONS · Ardour/ardour@98b9839 · GitHub is just the inline version of what -DECLARE_DEFAULT_COMPARISONS did.

Could you explain why you have introduced that indirection in the first place. The new code is much cleaner.

What is the actual error message that you get?

Not really. It depend on non-standard headers, which have to copied and renamed to be used. The goal here is to avoid that and use standard headers only.

We try to not break existing builds, here by using WAF_BUILD defines to distinguish them.

Here’s a screenshot after trying to link (with Clang). It’s not massively helpful but neither is MSVC’s :frowning:

To be honest, it doesn’t look like an idea I would’ve come up with myself so it was probably suggested by Todd (or Ben?)

Either way, I’ll stay out of this thread from now on - except to repeat that if we end up with code that won’t build any more with MSVC (which looks increasingly likely…) I won’t be stepping forward to fix it…

I see now. LIBPBD_DLL is never defined [1]. so the correct expansion of DEFAULT_COMPARISONS_DEFINED is

#define DECLARE_DEFAULT_COMPARISONS(Type) \
  extern bool operator >  (const Type& lhs, const Type& rhs); \
  extern bool operator <  (const Type& lhs, const Type& rhs); \
  extern bool operator != (const Type& lhs, const Type& rhs); \
  extern bool operator == (const Type& lhs, const Type& rhs);
#endif

the extern was lost.

Also libs/pbd/pbd/abstract_ui.inc.cc still uses DECLARE_DEFAULT_COMPARISONS which may explain the duplicate conflicting declatations.

[1] libs/pbd/pbd/msvc_pbd.h would define it when statically building libpbd.

That was my first thought so I commented out all the other occurrences except for your new function definitions but I still got the linker errors!

Eventually I remembered that implementations aren’t needed. For each operator you only need to create its declaration!! For MSVC, the corresponding implementation seems to happen via a file called type_traits

I don’t understand what’s going on but that does seem to be true here (by some mechanism I can’t even guess at… :confounded:)

1 Like

My apologies on causing the errors.
I tried reducing the definition to a declaration and got

lld-link: error: undefined symbol: bool __cdecl operator<(struct __ptw32_handle_t const &, struct __ptw32_handle_t const &)

referenced by C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.50.35717\include\type_traits:2388
libs\pbd\pthread_utils.cc.1.o:($LN3)

So I can confirm that type_traits has something to do with this.

Can you edit your file to just a declaration and tell if you get the same error? Also remove the inline part. If it links for you, the files can be edited to give declaration in general and definition only if WAF_BUILD is defined.

Sorry @EZ4Stephen, I’ll be out all day tomorrow but I can confirm that if I change your new version to just declarations, that’s when it builds okay for me. So maybe we just need something like this - which would probably be the best way forward anyway - i.e. wherever you need to change my code…

#ifndef WAF_BUILD
// My original code
#else
// The new code as you'll need it
#endif

Successfully built libs/ardour. Next steps involve dealing with the libs/tk files. And a few errors here and there. I’ll get to committing and making a pull request regarding pthread_utils and abstract_ui later, bear with me a bit longer.

1 Like

Dealt with the libs/tk files. Probably added a minute or two of compile time by making use of the .def generator though, but that’s only for msvc.
Here’s some examples of the task it creates:

For the working of this .def generator, which is needed to make .lib files that don’t miss symbols, only the root wscript and the wscripts of the impacted targets (aka libs/tk/…) need to be edited. I don’t know when I’ll upload it on github, but feels good to have it not giving unresolved externals anymore.

Stuck at the following errors:

[1138/1845] Linking build\libs\widgets\widgets.dll
lld-link: error: undefined symbol: __declspec(dllimport) struct Gtk::BuiltinStockID const Gtk::Stock::DIALOG_QUESTION
>>> referenced by C:\dev\ardour\libs\widgets\choice.cc:46
>>>               libs\widgets\choice.cc.1.o:($LN38)

lld-link: error: undefined symbol: __declspec(dllimport) struct Gtk::BuiltinStockID const Gtk::Stock::CANCEL
>>> referenced by C:\dev\ardour\libs\widgets\paths_dialog.cc:79
>>>               libs\widgets\paths_dialog.cc.1.o:($LN53)
>>> referenced by C:\dev\ardour\libs\widgets\paths_dialog.cc:124
>>>               libs\widgets\paths_dialog.cc.1.o:($LN22)
>>> referenced by C:\dev\ardour\libs\widgets\prompter.cc:57
>>>               libs\widgets\prompter.cc.1.o:($LN13)

lld-link: error: undefined symbol: __declspec(dllimport) struct Gtk::BuiltinStockID const Gtk::Stock::OK
>>> referenced by C:\dev\ardour\libs\widgets\paths_dialog.cc:80
>>>               libs\widgets\paths_dialog.cc.1.o:($LN53)
>>> referenced by C:\dev\ardour\libs\widgets\paths_dialog.cc:125
>>>               libs\widgets\paths_dialog.cc.1.o:($LN22)

lld-link: error: undefined symbol: __declspec(dllimport) struct Gtk::BuiltinStockID const Gtk::Stock::REVERT_TO_SAVED
>>> referenced by C:\dev\ardour\libs\widgets\prompter.cc:71
>>>               libs\widgets\prompter.cc.1.o:($LN13)

Edit: I wonder if the following errors (which I turned to warnings by adding obj.linkflags = [‘/FORCE:MULTIPLE’] to gtkmm2ext’s wscript) when building gtkmm2ext are related to those 4:

lld-link: warning: duplicate symbol: public: __cdecl std::basic_stringstream<char, struct std::char_traits<char>, class std::allocator<char>>::basic_stringstream<char, struct std::char_traits<char>, class std::allocator<char>>(class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> const &, int)
>>> defined at C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.50.35717\include\sstream:873
>>>            libs\gtkmm2ext\colors.cc.1.o
>>> defined at pbd.lib(pbd.dll)

lld-link: warning: duplicate symbol: public: __cdecl std::basic_stringstream<char, struct std::char_traits<char>, class std::allocator<char>>::basic_stringstream<char, struct std::char_traits<char>, class std::allocator<char>>(void)
>>> defined at C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.50.35717\include\sstream:867
>>>            libs\gtkmm2ext\colors.cc.1.o
>>> defined at pbd.lib(pbd.dll)

lld-link: warning: duplicate symbol: public: void __cdecl std::basic_stringstream<char, struct std::char_traits<char>, class std::allocator<char>>::`vbase dtor'(void)
>>> defined at libs\gtkmm2ext\colors.cc.1.o
>>> defined at pbd.lib(pbd.dll)

lld-link: warning: duplicate symbol: public: class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> __cdecl std::basic_stringstream<char, struct std::char_traits<char>, class std::allocator<char>>::str(void) const
>>> defined at C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.50.35717\include\sstream:931
>>>            libs\gtkmm2ext\colors.cc.1.o
>>> defined at pbd.lib(pbd.dll)

Sorry I can’t help with those issues but are you sure you’re building with MSVC?? Back in post #112 you listed various compilers and linkers found on your system, which included both MSVC and Clang. And your object files use the extension of .o and your linker seems to be called lld. Both of these imply that you’re in fact building with Clang, rather than MSVC.

I am indeed, building with MSVC, but with lld-link.
Object files are still .1.o, that’s probably on waf’s end, but I have modified the --use-lld flag to be usable on MSVC, since the latest VS comes with it. (I don’t know which box I checked that gave me some llvm tools, but it’s there.)