jk2addict has asked for the wisdom of the Perl Monks concerning the following question:

First of all, I know exactly jack squat about c/cpp or xs. Be gentle. I've tried to read the how tos for XS, but it makes my brain hurt.

For the longest time I've wanted Data::UUID on win32. When I started on Handel, I had looked into using Class::DBI::UUID for the primary columns, but the fact that it required Data::UUID and Data::UID didn't compile on win32 left me out of luck. I instead turned to using any of the various GUID/UUID modules on CPAN; using whatever the user had installed. Sometimes that was Data::UUID, or Win32::GUIDgen, Win32API::GUID or UUID. Life was good.

Today I cought the tinker bug and decided to get Data::UUID to compile on win32 come hell or high water. Not knowing a damn thing about c and any Makefile.PL->xs/linker magic, I actually managed to make it work.

There were two problems, first there was Makefile.PL errors:

C:\Data-UUID-0.11>perl Makefile.PL Checking if your kit is complete... Looks good UUID state storage (/var/tmp): C:\ default umask (0007): Note (probably harmless): No library found for -lsocket Writing Makefile for Data::UUID

I ignored that for the time being. Then there was the compile/linker errors. All I did was turn the top of UUID.h from this:

#include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include "md5.h"

into this

#define __CYGWIN__ #include <string.h> #include <stdio.h> #include <stdlib.h> //#include <unistd.h> #include <time.h> #include "md5.h"

Now, nmake compiles and links the dll without errors and nmake test passes completely. Awesome. So, what's the problem you may ask? I'd like to submit the necessary patches to the author but I have no idea what the hell I just did or what to actually tweak in Makefile.PL/.h/.c

First, Data::UUID appears to run under CYGWIN and MING32. But of course on win32, neither of those are defined; hence the #define __CYGWIN__ line. Is there some magic that goes in Makefile.PL to get __CYGWIN__ defined or is that part of the compilers ENV?

Second, what about that "No library found" error? Should I simply ditch the LIBS => 'lsocket' def is we're on MSWin32?

I'm sure I could just describe my fixes to the author and wash my hands of it, but I wouldn't learn much that way.


Considered (GrandFather): move to meditations.
Unconsidered (holli): Enough Keep Votes (Keep/Edit/Delete: 11/14/1)

Replies are listed 'Best First'.
Re: Fixing an XS based dist
by Fletch (Bishop) on Aug 09, 2005 at 19:55 UTC

    Just to be pedantic: you haven't "fixed" anything, you've gotten it to compile.

    Specifically you've gotten it to compile by lying about what platform you're on to the preprocessor and compiler. While this may be OK for emergencies, it's not the kind of thing you'd want to trust for a real, long term solution (think the equivalent of a mechanic using duct tape to strap something down in the middle of a race versus actually repairing or replacing the broken part). There could be subtle differences, for instance in edge cases where some routine returns different values on Cygwin than Win32 (hence the reason it was trying to distinguish between the two to begin with).

    The "right" thing to do is for someone who is familiar with C to look at it and figure out what really does need to be conditional on just Cygwin and what will behave nice on naked Wintendo. But certainly send the results to the maintainer or the relevant mailing list to let them know what you've gotten working, and ask if anyone can take a crack at it (offering to help by trying patches if they don't have access to a Windows box will probably get you much further as well).

    We're looking for people in ATL

      While I agree on the "Right things", I've been down that road. The current culture is mostly "we accept patches" with a side of "win32 suxOrs"; not from the author though.

      With that said, it DID pass its test suite, so it's certainly no more broken now than any other version of itself on any other platform at this point.

        Well it might not be passing its test suite or even building on any other platform unless you have built and tested on a variety of other platforms. The best way to go is to supply the output of diff -u <original_file> <changed_file> so that others can apply the patch and test on a variety of platforms.


Re: Fixing an XS based dist
by gellyfish (Monsignor) on Aug 09, 2005 at 21:00 UTC

    Don't worry about the missing lib error - this will happen on a number of OS - (I get it on Linux here).

    Personally I think that would do something like this - but I can't test it right now:

    --- UUID.h 2003-08-27 20:38:35.000000000 +0100 +++ 2005-08-09 21:57:39.000000000 +0100 @@ -1,10 +1,15 @@ #if !defined __UUID_H__ # define __UUID_H__ +#if defined __CYGWIN__ || __MINGW32__ || WIN32 +# define USE_WIN32 +#endif #include <string.h> #include <stdio.h> #include <stdlib.h> -#include <unistd.h> +#ifndef WIN32 +# include <unistd.h> +#endif #include <time.h> #include "md5.h" --- UUID.xs 2003-08-27 20:38:35.000000000 +0100 +++ 2005-08-09 21:58:27.000000000 +0100 @@ -105,7 +105,7 @@ } static void get_system_time(uuid_time_t *uuid_time) { -#if defined __CYGWIN__ || __MINGW32__ +#if defined USE_WIN32 /* ULARGE_INTEGER time; */ LARGE_INTEGER time; @@ -129,7 +129,7 @@ static void get_random_info(unsigned char seed[16]) { MD5_CTX c; -#if defined __CYGWIN__ || __MINGW32__ +#if defined USE_WIN32 typedef struct { MEMORYSTATUS m; SYSTEM_INFO s; @@ -150,7 +150,7 @@ MD5Init(&c); -#if defined __CYGWIN__ || __MINGW32__ +#if defined USE_WIN32 GlobalMemoryStatus(&r.m); GetSystemInfo(&r.s); GetSystemTimeAsFileTime(&r.t);


      Hmm. I checked, and I have compiled Data-UUID at one time, and my diff looks like
      diff -ubr Data-UUID-0.11/Makefile.PL myData-UUID-0.11/Makefile.PL --- Data-UUID-0.11/Makefile.PL 2003-08-27 12:38:36.000000000 -0700 +++ myData-UUID-0.11/Makefile.PL 2005-06-22 07:21:04.375000000 -070 +0 @@ -1,5 +1,7 @@ use ExtUtils::MakeMaker; use Config; +my $tmp = $ENV{TEMP}||$ENV{TMP}||"/var/tmp"; +$tmp =~ s~\\~/~g;; # See lib/ExtUtils/ for details of how to influence # the contents of the Makefile that is written. @@ -52,14 +54,15 @@ my ($d, $m); # automate installations - as per Heath Malmstrom if(!$ENV{PERL_MM_USE_DEFAULT}) { - do { print "UUID state storage (/var/tmp): "; + do { print "UUID state storage ($tmp): "; } while !($d = <STDIN>, chop $d, -d $d || !$d); do { print "default umask (0007): "; } while !($m = <STDIN>, chop $m, ($m =~ /[0-7]{3}/) || !$m); } - chmod(0666, sprintf("%s/%s", $d||"/var/tmp", ".UUID_NODEID" +)); - chmod(0666, sprintf("%s/%s", $d||"/var/tmp", ".UUID_STATE") +); - return { 'DEFINE' => qq(-D_STDIR=\\").($d||"/var/tmp").qq(\\"). + chmod(0666, sprintf("%s/%s", $d||"$tmp", ".UUID_NODEID")); + chmod(0666, sprintf("%s/%s", $d||"$tmp", ".UUID_STATE")); + $d =~ s~\\~/~g; + return { 'DEFINE' => qq(-D_STDIR=\\").($d||"$tmp").'\\" '. qq( -D__$Config{osname}__). qq( -D_DEFAULT_UMASK=).($m||"0007")}; } diff -ubr Data-UUID-0.11/UUID.h myData-UUID-0.11/UUID.h --- Data-UUID-0.11/UUID.h 2003-08-27 12:38:36.000000000 -0700 +++ myData-UUID-0.11/UUID.h 2005-06-22 07:22:58.656250000 -0700 @@ -4,7 +4,9 @@ #include <string.h> #include <stdio.h> #include <stdlib.h> +#ifndef WIN32 #include <unistd.h> +#endif #include <time.h> #include "md5.h" @@ -29,7 +31,7 @@ #else # define PTR2ul(p) INT2PTR(unsigned long,p) #endif -#if defined __cygwin__ || __mingw32__ +#if defined __cygwin__ || __mingw32__ || WIN32 #include <windows.h> #endif #if defined __darwin__ @@ -49,8 +51,14 @@ #define UUID_STATE_NV_STORE _STDIR"/"UUID_STATE #define UUID_NODEID_NV_STORE _STDIR"/"UUID_NODEID + #define UUIDS_PER_TICK 1024 +/*podmaster*/ +#ifdef WIN32 +#define I64(C) ((unsigned __int64) C##) +#else #define I64(C) C##LL +#endif #define F_BIN 0 #define F_STR 1 @@ -63,7 +71,12 @@ typedef unsigned short unsigned16; typedef unsigned char unsigned8; typedef unsigned char byte; +/*podmaster*/ +#ifdef WIN32 +typedef unsigned __int64 unsigned64_t; +#else typedef unsigned long long unsigned64_t; +#endif typedef unsigned64_t uuid_time_t; #if defined __solaris__ || defined __linux__ @@ -116,7 +129,7 @@ ); static void get_current_time(uuid_time_t * timestamp); static unsigned16 true_random(void); -static void get_system_time(uuid_time_t *uuid_time); +static void get_system_time(uuid_time_t * uuid_time); static void get_random_info(unsigned char seed[16]); static char *base64 = diff -ubr Data-UUID-0.11/UUID.xs myData-UUID-0.11/UUID.xs --- Data-UUID-0.11/UUID.xs 2003-08-27 12:38:36.000000000 -0700 +++ myData-UUID-0.11/UUID.xs 2005-06-22 07:30:22.640625000 -0700 @@ -105,7 +105,7 @@ } static void get_system_time(uuid_time_t *uuid_time) { -#if defined __CYGWIN__ || __MINGW32__ +#if defined __CYGWIN__ || __MINGW32__ || WIN32 /* ULARGE_INTEGER time; */ LARGE_INTEGER time; @@ -129,7 +129,7 @@ static void get_random_info(unsigned char seed[16]) { MD5_CTX c; -#if defined __CYGWIN__ || __MINGW32__ +#if defined __CYGWIN__ || __MINGW32__ || WIN32 typedef struct { MEMORYSTATUS m; SYSTEM_INFO s; @@ -150,7 +150,7 @@ MD5Init(&c); -#if defined __CYGWIN__ || __MINGW32__ +#if defined __CYGWIN__ || __MINGW32__ || WIN32 GlobalMemoryStatus(&r.m); GetSystemInfo(&r.s); GetSystemTimeAsFileTime(&r.t);

      MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
      I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
      ** The third rule of perl club is a statement of fact: pod is sexy.

        Is that under VC6++? As it tured out I get two completely different sets of problems under VC6++. On my .NET install at work, my original hack works fine. Looks like c on win32 is now more of a mess than it ever was before.

Re: Fixing an XS based dist
by jk2addict (Chaplain) on Aug 09, 2005 at 20:55 UTC

    I do find it fascinating the it compiles under normal VC when unistd.h commented out since there is no such thing; but fails under VC++ Tookit 2003 where apparently there is a unistd.h.