Csound Csound-dev Csound-tekno Search About

[Csnd-dev] Windows Update

Date2016-12-23 22:50
FromSteven Yi
Subject[Csnd-dev] Windows Update
Hi All,

Just FYI, I had done a bit of working on getting things to compile
with Visual Studio but found it a bit frustrating with various things
that required changes.  For the moment, I'll be back on the develop
branch and will work on removing direct use of pthread around the
codebase there.  This should be a bit simpler for me to focus on just
the one thing first, then move back to Visual Studio afterwards.

Thanks!

Date2016-12-24 02:06
Fromrasmus ekman
Subject[Csnd-dev] Compiling on Visual Studio
Hi,

I'm trying to compile the Csound console version using Visual Studio 2015, just to play at adding some opcode.
I found a few things that seem to be misspellings.


==========

In /Top/csound.c  line 48
works if winsock2.h is included BEFORE windows.h
-- winsock2 has a flag to prevent inclusion of the earlier winsock version:
#if defined(WIN32) && !defined(__CYGWIN__)
# include 
# include 
#endif

==========
/Engine/linevent.c (93) uses _O_RDONLY flag.
Adding around line 26 seems to work:

#if defined(MSVC)
#include 
#endif

For VStudio 2015 this allows deleting the lines 91-93:

#if defined(MSVC)
#define O_RDONLY _O_RDONLY
#endif

-- I think it should work with earlier VS versions

==========

Pointer arithmetic is done to void* in some places -- this is not valid in C (gcc allows it as an extension)
The obvious (char*) casts should work.

/Engine/insert.c (1943):
             memset(((char*)out) + g_ksmps, '\0', sizeof(MYFLT) * early);

/Opcodes/pvlock.c (589):
     p->indata[1] = ((char*)p->fdata.auxp) + size/2;

/Opcodes/mp3in.c (509):
     p->indataL[1] = ((char*)p->fdata[0].auxp) + size/2;

/Opcodes/mp3in.c (513):
     p->indataR[1] = ((char*)p->fdata[1].auxp) + size/2;

/Engine/twarp.c (138):
           csound->tplim = ((char*)csound->tseg) + csound->tseglen-1;

/Engine/twarp.c (177)
       csound->tplim = ((char*)csound->tseg) + csound->tseglen-1;

==========

/Opcodes/ fareyseq.c and fareygen.c both have declaration

const int MAX_PFACTOR = 16;

...later used to declare an array:
     PFACTOR p[MAX_PFACTOR];

The replacement
#define MAX_PFACTOR 16

works of course, but it's not pretty.
Apparently C99 would allow this use, but VS doesn't comply
(or, VS now claims compliance EXCEPT some vague statement about "compiler features not supported").

I didn't pursue this to the full extent of the standard, just slapped on a lazy compiler version flag:

#if defined(_MSC_VER) && (_MSC_VER <= 1900)
/* 1900 is VS 2015 - check again with next version... */
#define MAX_PFACTOR 16
#else
const int MAX_PFACTOR = 16;
#endif

- which takes us from the "not pretty" into the "pretty hideous" range...

==========

/Include/text.h (115): the declaration
   char *csoundLocalizeString(const char *s)
      __attribute__ ((format (printf, 1,0)));

- doesn't match the one in /Top/getstring.c (lines 65 and 96):
PUBLIC char *csoundLocalizeString(const char *s)

I added PUBLIC to the text.h, it seems to work.


The same in prototyp.h (81):
int     argdecode(CSOUND *, int, const char **);

doesn't match argdecode.c (1145):
PUBLIC int argdecode(CSOUND *csound, int argc, const char **argv_)

The PUBLIC macro is not used elsewhere in prototyp.h, not sure which direction to go.
Adding there or removing in argdecode.c works the same.

==========

The function used in \Engine\cs_new_dispatch.c(303):
#define ATOMIC_CAS(x,current,new)  __sync_bool_compare_and_swap(x,current,new)

exists in gcc, not C, not supported in VS.

But this sits behind the BUILD_MULTI_CORE flag,
perhaps there's no equivalent on Windows?  - I dropped those files for now.

==========

/Engine/envvar.c  line 31: include windows.h and direct.h:

#if defined(MSVC)
#include 
#include 
#endif

also, getcwd should be _getcwd in
/Engine/envvar.c (735)

Since _getcwd() is in header direct.h instead of unistd.h on windows, we can rephrase
/Opcodes/date.c (27):

#if defined(__MACH__)
#include 
#elif defined(MSVC)
#include 
#endif

==========

/Opcodes/paulstretch.c  line 32
#include "H/fftlib.h"

works better as
#include "../H/fftlib.h"


/Opcodes/gab/newgabopc.c, line 392, add "../" to the include path:
#include "../Opcodes/uggab.h"

/Opcodes/gab/gab.h(25): add same prefix: "../"

#include "../H/ugrw1.h"    /* for zread function */

==========

MSVC still doesn't support C99 complex, so
/Opcodes/paulstretch.c (88):
       complex ph =  cos(x) + I*sin(x);

must be replaced. Not sure about this:
#if defined(_MSC_VER) && _MSC_VER <= 1900
       complex ph;
       ph._Val[0] = cos(x);
       ph._Val[1] = sin(x);
#else
       complex ph =  cos(x) + I*sin(x);
#endif

Fail my 8th grade math if you will...

And therefore _complex doesn't exist in MSVC stdlib, so a macro is needed to import some constant names from math.h,
so I add this before math.h is included:

#ifdef WIN32
#define _USE_MATH_DEFINES
#define _complex _Fcomplex
#endif


==========

sockrecv.c and socksend.c both have header unistd.h top level.
This must be moved into the not-WIN32 case

#if defined(WIN32) && !defined(__CYGWIN__)
/* ...*/
#else
#include 
/* ...*/

==========


/Top/csound.c lines 676 and 684
#if defined(WIN32) //&& (__GNUC_VERSION__ < 40800)
     {0, 0},   /* file_io_thread    */
#else
     (pthread_t)0,   /* file_io_thread    */
#endif

and
#if defined(WIN32) //&& (__GNUC_VERSION__ < 40800)
     {0, 0},   /* init pass thread    */
#else
     (pthread_t)0,   /* init pass thread */
#endif


the pthread_t values can't be cast, so the parenthesized type must be removed,
ie THIS does not work:
     (pthread_t){0, 0},   /* file_io_thread    */

for reasons unclear to me.


/Top/csound.c (800 something) change to:
     0l,            /*  beatTime            */

should be int64, not double 0.0 (just a warning)


==========

On building the static library I'm getting a bunch of link warnings, like
     _csoundModuleInfo already defined in xyz.obj; second definition ignored

Not sure if that's a problem, it's just a warning.

==========

For console version,
/frontends/csound/csound_main.c (260)

     /* set stdout to non buffering if not outputing to console window */
     if (!isatty(fileno(stdout))) {
#if !defined(WIN32)
       setvbuf(stdout, (char*) NULL, _IONBF, 0);
#endif
     }

isatty is marked deprecated, use _isatty

Nonstandard header  is required in Visual studio for some Posix functions

And the lines seem inconsistent, either we skip the block entirely:

#if !defined(WIN32)
     /* set stdout to non buffering if not outputing to console window */
     if (!isatty(fileno(stdout))) {
       setvbuf(stdout, (char*) NULL, _IONBF, 0);
     }
#endif

- or make the changes, something like
#if defined(_MSC_VER)
#include 
#endif


==========


Whew, that's a lot of almost-nothing.
Sorry about that.

Date2016-12-24 02:49
FromSteven Yi
SubjectRe: [Csnd-dev] Compiling on Visual Studio
Hi Rasmus,

Thanks very much for this! I was working on getting VS to compile and
ran into a lot of these as well. I'm working on removing dependence on
pthread at the moment in the develop branch.  There is a
feature/vs2015 branch that has some of the changes I had started on;
others are here locally on my machine.

One thing I didn't get from your email: did you manage to get a build going?

Thanks,
steven

On Fri, Dec 23, 2016 at 9:06 PM, rasmus ekman  wrote:
> Hi,
>
> I'm trying to compile the Csound console version using Visual Studio 2015,
> just to play at adding some opcode.
> I found a few things that seem to be misspellings.
>
>
> ==========
>
> In /Top/csound.c  line 48
> works if winsock2.h is included BEFORE windows.h
> -- winsock2 has a flag to prevent inclusion of the earlier winsock version:
> #if defined(WIN32) && !defined(__CYGWIN__)
> # include 
> # include 
> #endif
>
> ==========
> /Engine/linevent.c (93) uses _O_RDONLY flag.
> Adding around line 26 seems to work:
>
> #if defined(MSVC)
> #include 
> #endif
>
> For VStudio 2015 this allows deleting the lines 91-93:
>
> #if defined(MSVC)
> #define O_RDONLY _O_RDONLY
> #endif
>
> -- I think it should work with earlier VS versions
>
> ==========
>
> Pointer arithmetic is done to void* in some places -- this is not valid in C
> (gcc allows it as an extension)
> The obvious (char*) casts should work.
>
> /Engine/insert.c (1943):
>             memset(((char*)out) + g_ksmps, '\0', sizeof(MYFLT) * early);
>
> /Opcodes/pvlock.c (589):
>     p->indata[1] = ((char*)p->fdata.auxp) + size/2;
>
> /Opcodes/mp3in.c (509):
>     p->indataL[1] = ((char*)p->fdata[0].auxp) + size/2;
>
> /Opcodes/mp3in.c (513):
>     p->indataR[1] = ((char*)p->fdata[1].auxp) + size/2;
>
> /Engine/twarp.c (138):
>           csound->tplim = ((char*)csound->tseg) + csound->tseglen-1;
>
> /Engine/twarp.c (177)
>       csound->tplim = ((char*)csound->tseg) + csound->tseglen-1;
>
> ==========
>
> /Opcodes/ fareyseq.c and fareygen.c both have declaration
>
> const int MAX_PFACTOR = 16;
>
> ...later used to declare an array:
>     PFACTOR p[MAX_PFACTOR];
>
> The replacement
> #define MAX_PFACTOR 16
>
> works of course, but it's not pretty.
> Apparently C99 would allow this use, but VS doesn't comply
> (or, VS now claims compliance EXCEPT some vague statement about "compiler
> features not supported").
>
> I didn't pursue this to the full extent of the standard, just slapped on a
> lazy compiler version flag:
>
> #if defined(_MSC_VER) && (_MSC_VER <= 1900)
> /* 1900 is VS 2015 - check again with next version... */
> #define MAX_PFACTOR 16
> #else
> const int MAX_PFACTOR = 16;
> #endif
>
> - which takes us from the "not pretty" into the "pretty hideous" range...
>
> ==========
>
> /Include/text.h (115): the declaration
>   char *csoundLocalizeString(const char *s)
>      __attribute__ ((format (printf, 1,0)));
>
> - doesn't match the one in /Top/getstring.c (lines 65 and 96):
> PUBLIC char *csoundLocalizeString(const char *s)
>
> I added PUBLIC to the text.h, it seems to work.
>
>
> The same in prototyp.h (81):
> int     argdecode(CSOUND *, int, const char **);
>
> doesn't match argdecode.c (1145):
> PUBLIC int argdecode(CSOUND *csound, int argc, const char **argv_)
>
> The PUBLIC macro is not used elsewhere in prototyp.h, not sure which
> direction to go.
> Adding there or removing in argdecode.c works the same.
>
> ==========
>
> The function used in \Engine\cs_new_dispatch.c(303):
> #define ATOMIC_CAS(x,current,new)
> __sync_bool_compare_and_swap(x,current,new)
>
> exists in gcc, not C, not supported in VS.
>
> But this sits behind the BUILD_MULTI_CORE flag,
> perhaps there's no equivalent on Windows?  - I dropped those files for now.
>
> ==========
>
> /Engine/envvar.c  line 31: include windows.h and direct.h:
>
> #if defined(MSVC)
> #include 
> #include 
> #endif
>
> also, getcwd should be _getcwd in
> /Engine/envvar.c (735)
>
> Since _getcwd() is in header direct.h instead of unistd.h on windows, we can
> rephrase
> /Opcodes/date.c (27):
>
> #if defined(__MACH__)
> #include 
> #elif defined(MSVC)
> #include 
> #endif
>
> ==========
>
> /Opcodes/paulstretch.c  line 32
> #include "H/fftlib.h"
>
> works better as
> #include "../H/fftlib.h"
>
>
> /Opcodes/gab/newgabopc.c, line 392, add "../" to the include path:
> #include "../Opcodes/uggab.h"
>
> /Opcodes/gab/gab.h(25): add same prefix: "../"
>
> #include "../H/ugrw1.h"    /* for zread function */
>
> ==========
>
> MSVC still doesn't support C99 complex, so
> /Opcodes/paulstretch.c (88):
>       complex ph =  cos(x) + I*sin(x);
>
> must be replaced. Not sure about this:
> #if defined(_MSC_VER) && _MSC_VER <= 1900
>       complex ph;
>       ph._Val[0] = cos(x);
>       ph._Val[1] = sin(x);
> #else
>       complex ph =  cos(x) + I*sin(x);
> #endif
>
> Fail my 8th grade math if you will...
>
> And therefore _complex doesn't exist in MSVC stdlib, so a macro is needed to
> import some constant names from math.h,
> so I add this before math.h is included:
>
> #ifdef WIN32
> #define _USE_MATH_DEFINES
> #define _complex _Fcomplex
> #endif
>
>
> ==========
>
> sockrecv.c and socksend.c both have header unistd.h top level.
> This must be moved into the not-WIN32 case
>
> #if defined(WIN32) && !defined(__CYGWIN__)
> /* ...*/
> #else
> #include 
> /* ...*/
>
> ==========
>
>
> /Top/csound.c lines 676 and 684
> #if defined(WIN32) //&& (__GNUC_VERSION__ < 40800)
>     {0, 0},   /* file_io_thread    */
> #else
>     (pthread_t)0,   /* file_io_thread    */
> #endif
>
> and
> #if defined(WIN32) //&& (__GNUC_VERSION__ < 40800)
>     {0, 0},   /* init pass thread    */
> #else
>     (pthread_t)0,   /* init pass thread */
> #endif
>
>
> the pthread_t values can't be cast, so the parenthesized type must be
> removed,
> ie THIS does not work:
>     (pthread_t){0, 0},   /* file_io_thread    */
>
> for reasons unclear to me.
>
>
> /Top/csound.c (800 something) change to:
>     0l,            /*  beatTime            */
>
> should be int64, not double 0.0 (just a warning)
>
>
> ==========
>
> On building the static library I'm getting a bunch of link warnings, like
>     _csoundModuleInfo already defined in xyz.obj; second definition ignored
>
> Not sure if that's a problem, it's just a warning.
>
> ==========
>
> For console version,
> /frontends/csound/csound_main.c (260)
>
>     /* set stdout to non buffering if not outputing to console window */
>     if (!isatty(fileno(stdout))) {
> #if !defined(WIN32)
>       setvbuf(stdout, (char*) NULL, _IONBF, 0);
> #endif
>     }
>
> isatty is marked deprecated, use _isatty
>
> Nonstandard header  is required in Visual studio for some Posix
> functions
>
> And the lines seem inconsistent, either we skip the block entirely:
>
> #if !defined(WIN32)
>     /* set stdout to non buffering if not outputing to console window */
>     if (!isatty(fileno(stdout))) {
>       setvbuf(stdout, (char*) NULL, _IONBF, 0);
>     }
> #endif
>
> - or make the changes, something like
> #if defined(_MSC_VER)
> #include 
> #endif
>
>
> ==========
>
>
> Whew, that's a lot of almost-nothing.
> Sorry about that.
>

Date2016-12-24 03:39
Fromrasmus ekman
SubjectRe: [Csnd-dev] Compiling on Visual Studio
Further,

==========

/Engine/insert.c (317):
       while(ip->init_done != 1) usleep(1);

inconsistent, I used solution as line 2501:

#if defined(MACOSX) || defined(LINUX) || defined(HAIKU)
	  while (ip->init_done != 1)
		  usleep(1);
#else
	  while (ip->init_done != 1)
		  csoundSleep(1);
#endif

- repeating the while statement for clarity.

==========

/Opcodes/sftype.h
DWORD is not defined unless some windows header is included, I just removed the #if in
line 47:

#if !defined(WIN32) || defined(__CYGWIN__)
typedef uint32_t    DWORD;
#endif

so to me it's just

typedef uint32_t    DWORD;

==========

/Engine/cs_new_dispatch.c(303):

It looks like GCC intrinsic __sync_bool_compare_and_swap(x,current,new)
would be the same as InterlockedCompareExchange on Windows.

So I added after other headers

#if defined(_MSC_VER)
/* For InterlockedCompareExchange */
#include 
#endif


-- and replace the line 303 (now 308) with
#if defined(_MSC_VER)
#define ATOMIC_CAS(x,current,new)  InterlockedCompareExchange(x, current, new)
#else
#define ATOMIC_CAS(x,current,new)  __sync_bool_compare_and_swap(x,current,new)
#endif


... and it compiles, but would need some testing.
If the values were 64-bit there's InterlockedCompareExchange64,
but the ATOMIC_CAS is done on enum values which should fit into 32 bits.


SO ignore this comment in previous post:

> ==========
>
> The function used in \Engine\cs_new_dispatch.c(303):
> #define ATOMIC_CAS(x,current,new)  __sync_bool_compare_and_swap(x,current,new)
>
> exists in gcc, not C, not supported in VS.
>
> But this sits behind the BUILD_MULTI_CORE flag,
> perhaps there's no equivalent on Windows?  - I dropped those files for now.
>
> ==========
>


Now it compiles somehow, but this Csound is sunk into the DLL swamp.
Will try to work around that later.

NOT TESTED yet. Didn't even include all opcodes in subdirectory of /Opcodes,
so the build is quite a hack.

Two build targets:
- Csound-6.08.lib; a static lib

- Consound.exe, just the command-line frontend using
/frontends/csound/csound_main.c


The Csound-6.08.lib uses preproc flags:

__BUILDING_LIBCSOUND;YY_NO_UNISTD_H;_CRT_SECURE_NO_WARNINGS;__SSE__;HAVE_STRUCT_TIMESPEC;MSVC;WIN32;_DEBUG;_CONSOLE;_MBCS;

Consound.exe has:

_CRT_SECURE_NO_WARNINGS;__SSE__;HAVE_STRUCT_TIMESPEC;MSVC;WIN32;_DEBUG;_CONSOLE;_MBCS

(and PTW32_STATIC_LIB; - but i'm not sure that works)


Some flags:
Character Set: Use Multi-Byte Character Set (= preproc define _MBCS)

Runtime library: Multithreaded Debug (/MTd)


Include directories for Csound code:
/H, /Engine, /Include

and path to whereever you keep the pthread, libsndfile, libpng, zlib and whatever libraries needed

Link of Consound.exe requires
Csound-6.08.lib;libpng.lib;libsndfile-1.lib;pthreadVC2.lib;zlib.lib;ws2_32.lib;wsock32.lib;

plus (most of) the standard windows libraries you get by default with a new VS project.


Regards,

Date2016-12-26 04:01
Fromrasmus ekman
SubjectRe: [Csnd-dev] Compiling on Visual Studio
Simple allocation size error in

/Engine/envvar.c (1023 on)

#if defined(WIN32)
       /* To handle Widows errors in file name characters. */
--      size_t sz = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
++      size_t sz = 2 * MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
       wchar_t *wfname = alloca(sz);
       wchar_t *wmode = 0;

       MultiByteToWideChar(CP_UTF8, 0, name, -1, wfname, sz);
--      sz = MultiByteToWideChar(CP_UTF8, 0, param, -1, NULL, 0);
++      sz = 2 * MultiByteToWideChar(CP_UTF8, 0, param, -1, NULL, 0);

The size (sz) value is 2-byte wide-chars.



...and now I can generate Trapped, in less than 20 secs :)