Building with MSVC, PowerShell. Errors

Those .vcproj files are from years ago, when we used to build as 32-bit. And in those days the gtk(mm) stuff wasn’t part of Ardour so all I did here was to copy my original .def files that I’d used previously. If yours don’t exist you could maybe try this (using atkmm as an example…)

  • In your PowerShell, navigate to whichever folder contains the .obj files for that project (hopefully you’re keeping them in different folders for different projects…)
  • Type gendef32 (just to check that your PowerShell can find it)
  • Once you’ve enabled PowerShell to find gendef32, type this:- gendef32 libatkmm.def *.obj

You should then end up with a .def file that’s correctly populated - but with a couple of caveats:-

  1. Unfortunately, if you’re still ignoring my previous suggestions, the above might leave you with an empty .def file
  2. AFAICT Robin doesn’t build atkmm as a DLL any more :thinking:

[Edit…] Apologies - I forgot that it’s called ztkmm now!

To my knowledge, waf makes .1.o files, not .obj files. At least in Ardour’s case.

So I assume it’s gendef32 build/libs/tk/libztkmm.def *.1.o? And likewise for the other immediate subfolders of libs/tk? Will ydk’s win32 folder automatically be included or do I have to do something separately?

Which ones?
Also I reckon I’ll have to run something along the lines of the following to have the .1.o files in the right place:

python waf --targets=libydk-pixbuf
python waf --targets=libydk
python waf --targets=libydkmm
python waf --targets=libytk
python waf --targets=libytkmm
python waf --targets=libztk
python waf --targets=libztkmm

Note: Before I asked about building without .def files, I had done something similar:

$objs = Get-ChildItem -Recurse -Path "build\libs\tk\ydk-pixbuf" -Filter "*.1.o"
$objs | ForEach-Object { dumpbin /SYMBOLS $_ } | 
    Select-String "External.*\|\s+_?(gdk_pix\w+)" | 
    ForEach-Object { $_.Line -replace ".*\|\s+_?", "" -replace "\s.*", "" } |
    Sort-Object -Unique |
    ForEach-Object {($_ -join "`n    ") } |
    Set-Content ydk-pixbuf.def

Then I added the lines LIBRARY libydk-pixbuf and EXPORTS at the top, then moved it to libs/tk/ydk-pixbuf, since that’s the path I put in its wscript:

    if sys.platform == 'darwin':
        obj.uselib     += ' OSX'
        obj.ldflags     = ' -lintl'
    elif bld.env['build_target'] == 'msvc':
        def_file = os.path.join(bld.srcnode.abspath(), 'libs', 'tk', 'ydk-pixbuf', 'ydk-pixbuf.def')
        obj.linkflags = ['/DEF:' + def_file]

Is that a better approach? If yes, then I’m struggling to figure out what the best replacement of Select-String "External.*\|\s+_?(gdk_pix\w+)" | is for the other ones.

Also note: The output of that above commands with $objs is just under the result output of using the .def file (After adding LIBRARY libydk-pixbuf and EXPORTS.) at libydk .1.o command stuff - Pastebin.com (Wrong name in title of this one)

In this particular case I was thinking of the examples I gave in post #19:-

Though having said that, many of them could probably go into the top-level wscript file, rather than repeating them for every wscript.

Hmmm… to me that sounds like you’re somehow picking up MinGW’s compiler rather than Microsoft’s. Maybe Robin can help you identify which compiler waf will use if both compilers are installed :frowning:

[Edit…]
What’s strange is that your gdk-pixbuf errors definitely look like Microsoft errors. So what happens if you look at the gdk-pixbuf object files? Do they also use the extension .o? Or are they using .obj?

[Edit2…]

You might need to see if you can build gdk-pixbuf with vcpkg

It’s now called ztkmm (atk[mm] → ztkmm; gtk[mm] → ytk[mm]) and we do build it as dll.

Large parts of the changes that @EZ4Stephen makes are already done in msvc_extra_headers/ however those files are not directly usable.

So instead Stephen modified source file directly e.g.

+#ifdef COMPILER_MSVC
+#define strncasecmp _strnicmp
+#endif

which in your case is defined in msvc_extra_headers/ardourext/misc.h.input

I agree that Ardour’s source does not need to be modified and I also expect that no significant waf/wscript changes are required, but that the crux lies in using header files for compatibility.

One significant difference is apparently pthread/ptw32. Judging by the changes that @EZ4Stephen made, the vcpkg package for VS 2022 differs from the old ptw32.

One way forward might be to

  • drop the .input suffix for header files in msvc_extra_headers/ardourext/

and then, where needed, customize

  • libs/pbd/pbd/msvc_pbd.h
  • libs/ardour/ardour/msvc_libardour.h

and add #ifdef WAF_BUILD clauses there where appropriate.

That should keep actual source-code modifications minimal.

What do you think?

These steps should make my .input files useable for Stephen:-

  1. Left-click on the Ardour folder called ardourext and copy it to the clipboard
  2. Paste it (and its contents) as a subfolder of his main include folder
  3. In the pasted version, edit all the .input files to remove .input from the end of their name (i.e. convert them into conventional header files)
  4. Find the file in include/ardourext/ptw32/pthread.h and replace it with his own version of pthread.h

Sounds like a good idea. The 4th point though, unsure… I reckon I can delete that, since vcpkg has its own pthread(s). Pictured from running vcpkg list:


What do you say?

Why this complicated?

Can’t we just rename them directly to *.h, and add msvc_extra_headers/ to the global include path?

@EZ4Stephen - if you copy your version of pthread.h as described, it shouldn’t do any harm to have 2 x identical copies. What we need to avoid is having 2 x different copies.

@x42 - What I’m suggesting is that if Stephen sets things up as I described he can then edit the copies if he needs to - and at some later stage we can decide which edits are needed and then modify the .input files (and at that stage, rename them)

1 Like

A little late to respond, but It appears that adding the following to the root wscript worked:

conf.env.append_value('CXXFLAGS', ['/FI' + os.path.join(conf.path.abspath(), 'msvc_waf_headers', '1.h')])

Sorry Stephen I’m a total novice when it comes to waf but I don’t quite see how that’ll /ForceInclude targetsxs.h :anguished: As long as you understand it though, that’s all that matters…

One question though… would something similar be needed for the CFLAGS ?

Over on the other place to talk to the devs, Robin gave me the idea of making my own header file that’s force included, so I’ve been editing that.

To my knowledge, no. This has been working fine for me. Currently I have a file that’s 22 lines, combined with a few changes to 3 files in libs/pbd and 4 in libs/pbd/pbd. pbd and wscript diffs (for now) - Pastebin.com

The content of 1.h is currently as follows:

#define _WINSOCKAPI_
#define PATH_MAX _MAX_PATH
#include <sys/timeb.h>
#define NOMINMAX
#include <winsock2.h>

extern "C" inline int gettimeofday(struct timeval *tv, void*) {
    if (tv) {
        struct __timeb64 tb;
        if (!_ftime64_s(&tb)) {
            tv->tv_sec = static_cast<time_t>(tb.time);
            tv->tv_usec = tb.millitm * 1000;
        }
    }
    return 0;
}
#include <io.h>
#define strcasecmp  _stricmp
#define strncasecmp _strnicmp
#define _USE_MATH_DEFINES
#define W_OK 2
typedef intptr_t ssize_t;

Only thing I’m uncertain of is strcasecmp/ strncasecmp.

Thanks Stephen - I’m still not seeing where targetsxs.h gets #included but I guess if you’re happy you don’t need it… :bowing_man:

I have a question regarding your targetsxs.h file: Which lines are vital for compiling libs/tk for you?

It shouldn’t be needed for the tk stuff because that was previously all external to Ardour - but having said that, it won’t be doing any harm.

I’ve figured out how to generate a .def file by modifying the wscript, at least for ydk-pixbuf. I think I’ll be able to use this to make the right .def files. (Well, with a little modification to the .def file, since it seems to give a few extra symbols.)

After a conversation on ardour/github here’s some advice for Stephen / Robin regarding my #defines specified in post #19 above. For the moment I’ll restrict this to the #defines that are definitely needed. Some need to be overall. A few need to be adapted for each project. And some just need to be checked by Robin. Here we go…

Needed ‘per project’ :-

  • BUILDING_PBD // Or its equivalent for the other (non-exe) projects **
  • LIBPBD_DLL_EXPORTS // Or its equivalent for the other (DLL) projects **
  • BUILDING_GETOPT // Only needed when building pbd

** Unfortunately the naming convention for these seems to vary a lot between the different projects. Mostly they can be found in files called visibility.h though even that’s inconsistent. If Stephen can’t figure out some names I should be able to help.

Needed overall (except some aren’t needed for the ‘tk’ builds) :-

  • UINTSDEFINED=1 // I don’t use this for ‘tk’ stuff
  • INCLUDE_ARDOUR_MISCELLANEOUS=1; // I don’t use this for ‘tk’ stuff
  • _SECURE_SCL=0
  • _WIN32
  • _WIN64

These ones are already present overall (but we’d need to check if that still applies for Stephen’s build)

  • PLATFORM_WINDOWS
  • WIN32
  • COMPILER_MSVC
  • NDEBUG // Or DEBUG for a debug build

By chance, did you do these changes on a different branch? Because the last recorded commit I see is ¬3 weeks ago at ardour/msvc_extra_headers/ardourext/sys at master · Ardour/ardour · GitHub .

EZ4Stephen - I’m not familiar with waf so I’m just advising you which changes need to get made. It’ll be up to you and Robin to figure out where to make them.

BTW - when building PBD with MSVC there’s an extra source file (called msvc_pbd.cc) which you’ll need to include in your build.