Building with MSVC, PowerShell. Errors

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.)

Meanwhile I’m testing a small change to my .def generator as a fix, but the link step for widgets hasn’t come yet.

Past the widgets error.
At ~1200/1842, which is over 65% of the way through.

lld-link: error: undefined symbol: public: static struct _VampPlugin::Vamp::RealTime const _VampPlugin::Vamp::RealTime::zeroTime
>>> referenced by C:\dev\ardour\libs\vamp-plugins\BarBeatTrack.cpp:53
>>>               libs\vamp-plugins\BarBeatTrack.cpp.1.o:($LN8)
>>> referenced by C:\dev\ardour\libs\vamp-plugins\BeatTrack.cpp:45
>>>               libs\vamp-plugins\BeatTrack.cpp.1.o:($LN8)
>>> referenced by C:\dev\ardour\libs\vamp-plugins\ChromagramPlugin.cpp:403
>>>               libs\vamp-plugins\ChromagramPlugin.cpp.1.o:($LN13)
>>> referenced 5 more times

Stuck at a new set of errors (faderport):

[1266/1842] Linking build\libs\surfaces\faderport\ardour_faderport.dll
lld-link: error: undefined symbol: public: __cdecl MIDISurface::MIDISurface(class ARDOUR::Session &, class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> const &, class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> const &, bool)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\faderport.cc:69
>>>               libs\surfaces\faderport\faderport.cc.1.o:($LN153)

lld-link: error: undefined symbol: public: virtual __cdecl MIDISurface::~MIDISurface(void)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\faderport.cc:176
>>>               libs\surfaces\faderport\faderport.cc.1.o:($LN5)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(int `public: __cdecl ArdourSurface::FaderPort::FaderPort(class ARDOUR::Session &)'::`1'::dtor$2)

lld-link: error: undefined symbol: public: void __cdecl MIDISurface::write(unsigned char const *, unsigned __int64)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\faderport.cc:403
>>>               libs\surfaces\faderport\faderport.cc.1.o:($LN14)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\faderport.cc:687
>>>               libs\surfaces\faderport\faderport.cc.1.o:($LN18)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\faderport.cc:822
>>>               libs\surfaces\faderport\faderport.cc.1.o:($LN6)
>>> referenced 2 more times

lld-link: error: undefined symbol: public: virtual class XMLNode & __cdecl MIDISurface::get_state(void) const
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\faderport.cc:572
>>>               libs\surfaces\faderport\faderport.cc.1.o:($LN3)

lld-link: error: undefined symbol: public: virtual int __cdecl MIDISurface::set_state(class XMLNode const &, int)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\faderport.cc:594
>>>               libs\surfaces\faderport\faderport.cc.1.o:($LN17)

lld-link: error: undefined symbol: public: virtual class std::list<class std::shared_ptr<class ARDOUR::Bundle>, class std::allocator<class std::shared_ptr<class ARDOUR::Bundle>>> __cdecl MIDISurface::bundles(void)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(const ArdourSurface::FaderPort::`vftable'{for `PBD::Stateful'})

lld-link: error: undefined symbol: public: virtual bool __cdecl MIDISurface::midi_input_handler(enum Glib::IOCondition, class MIDI::Port *)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(const ArdourSurface::FaderPort::`vftable'{for `PBD::Stateful'})

lld-link: error: undefined symbol: public: virtual void __cdecl MIDISurface::midi_connectivity_established(bool)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(const ArdourSurface::FaderPort::`vftable'{for `PBD::Stateful'})

lld-link: error: undefined symbol: protected: virtual void __cdecl MIDISurface::do_request(struct MidiSurfaceRequest *)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(const ArdourSurface::FaderPort::`vftable')

lld-link: error: undefined symbol: protected: virtual void __cdecl MIDISurface::connect_to_parser(void)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(const ArdourSurface::FaderPort::`vftable'{for `PBD::Stateful'})

lld-link: error: undefined symbol: protected: virtual void __cdecl MIDISurface::connect_to_port_parser(class MIDI::Port &)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(const ArdourSurface::FaderPort::`vftable'{for `PBD::Stateful'})

lld-link: error: undefined symbol: protected: virtual void __cdecl MIDISurface::thread_init(void)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(const ArdourSurface::FaderPort::`vftable')

lld-link: error: undefined symbol: protected: virtual void __cdecl MIDISurface::connect_session_signals(void)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(const ArdourSurface::FaderPort::`vftable'{for `PBD::Stateful'})

lld-link: error: undefined symbol: protected: virtual void __cdecl MIDISurface::port_registration_handler(void)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(const ArdourSurface::FaderPort::`vftable'{for `PBD::Stateful'})

lld-link: error: undefined symbol: protected: virtual int __cdecl MIDISurface::ports_acquire(void)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(const ArdourSurface::FaderPort::`vftable'{for `PBD::Stateful'})

lld-link: error: undefined symbol: protected: virtual void __cdecl MIDISurface::ports_release(void)
>>> referenced by libs\surfaces\faderport\faderport.cc.1.o:(const ArdourSurface::FaderPort::`vftable'{for `PBD::Stateful'})

lld-link: error: undefined symbol: protected: virtual int __cdecl MIDISurface::begin_using_device(void)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\faderport.cc:670
>>>               libs\surfaces\faderport\faderport.cc.1.o:($LN18)

lld-link: error: undefined symbol: protected: void __cdecl MIDISurface::drop(void)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\faderport.cc:168
>>>               libs\surfaces\faderport\faderport.cc.1.o:($LN5)

lld-link: error: undefined symbol: protected: void __cdecl MIDISurface::port_setup(void)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\faderport.cc:161
>>>               libs\surfaces\faderport\faderport.cc.1.o:($LN153)

lld-link: error: undefined symbol: public: class std::shared_ptr<class ARDOUR::Port> __cdecl MIDISurface::input_port(void)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\gui.cc:323
>>>               libs\surfaces\faderport\gui.cc.1.o:($LN25)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\gui.cc:482
>>>               libs\surfaces\faderport\gui.cc.1.o:($LN24)
>>> referenced by C:\dev\ardour\libs\surfaces\faderport\gui.cc:491
>>>               libs\surfaces\faderport\gui.cc.1.o:($LN24)
>>> referenced 2 more times

lld-link: error: too many errors emitted, stopping now (use /errorlimit:0 to see all errors)

 -> task in 'libardour_faderport' failed with exit status 1 (run with -v to display more information)

If you’re still using vcpkg it might have a port called vamp-sdk (or vamp-host - or possibly both) in which case you’ll need to build them.