1#! perl -w
2
3use strict ;
4require 5.006 ;
5
6use lib '.';
7use private::MakeUtil;
8use ExtUtils::MakeMaker 5.16 ;
9use ExtUtils::Install (); # only needed to check for version
10use Config;
11
12my $ZLIB_LIB ;
13my $ZLIB_INCLUDE ;
14my $BUILD_ZLIB = 0 ;
15my $USE_ZLIB_NG = 0;
16my $OLD_ZLIB = '' ;
17my $WALL = '' ;
18my $GZIP_OS_CODE = -1 ;
19my $USE_PPPORT_H = ($ENV{PERL_CORE}) ? '' : '-DUSE_PPPORT_H';
20my $OPTIMIZE = $Config{'optimize'};
21if ($Config{'gccversion'} and $OPTIMIZE =~ /-g (gdb)? 3/x) {
22  $OPTIMIZE =~ s/-g(gdb)?3/-g/g; # [88936] out of memory with -g3 since 2.062
23}
24
25# Windows uses a different name for the zlib library
26my $ZLIB_LIBRARY_NAME = $^O eq 'MSWin32' ? 'zlib' : 'z' ;
27
28# Ticket #18986 says that ExtUtils::Install 1.39 fixes the in-use issue
29# on win32/cygwin, so make the code below conditional on the version of
30# ExtUtils::Install.
31
32# Don't ask if MM_USE_DEFAULT is set -- enables perl core building on cygwin
33if ($^O =~ /cygwin/i and $ExtUtils::Install::VERSION < 1.39
34        and not ($ENV{PERL_MM_USE_DEFAULT} or $ENV{PERL_CORE}))
35{
36    print <<EOM ;
37
38I see you are running Cygwin.
39
40Please note that this module cannot be installed on Cygwin using the CPAN
41shell. The CPAN Shell uses Compress::Raw::Zlib internally and it is not
42possible to delete an active DLL.
43
44If you are running the CPAN shell, please exit it and install this module
45by hand by running 'make install' under the directory
46
47    ~/.cpan/build/Compress-Raw-Zlib-VERSION
48
49EOM
50
51    print "Do you want to continue? [Y/N]: " ;
52    my $answer = <STDIN> ;
53
54    if ($answer =~ /^yes|y/i)
55    {
56        print "continuing...\n"
57    }
58    else
59    {
60        print "exiting...\n" ;
61        exit 1 ;
62    }
63
64}
65
66ParseCONFIG() ;
67
68UpDowngrade(getPerlFiles('MANIFEST'))
69    unless $ENV{PERL_CORE};
70
71my $OPT_Z_PREFIX =  '-DZ_PREFIX' ;
72my $OPT_ZLIB_INCLUDE = "-I$ZLIB_INCLUDE";
73my $OPT_ZLIB_LIB = "-L$ZLIB_LIB" ;
74my $OPT_SOLO = '-DZ_SOLO';
75my $OPT_USE_ZLIB_NG = "";
76
77# For C++ only
78my $OPT_CXX_DEFINES = '-Dregister=' ; # for https://github.com/pmqs/Compress-Raw-Zlib/issues/23
79
80if (!$BUILD_ZLIB)
81{
82    # When using the system supplied zlib, we don't want to use our bespoke prefix
83    $OPT_Z_PREFIX =  '';
84
85    $OPT_ZLIB_INCLUDE = ''
86        if $ZLIB_INCLUDE eq './zlib-src' ;
87
88    $OPT_ZLIB_LIB = ''
89        if $ZLIB_LIB eq './zlib-src' ;
90
91    $OPT_SOLO = '';
92}
93
94if ( $USE_ZLIB_NG)
95{
96    $OPT_USE_ZLIB_NG = '-DUSE_ZLIB_NG';
97    $ZLIB_LIBRARY_NAME = $^O eq 'MSWin32' ? 'zlib-ng' : 'z-ng' ;
98}
99
100my %WriteMakefileArgs = (
101
102    NAME         => 'Compress::Raw::Zlib',
103    VERSION_FROM => 'lib/Compress/Raw/Zlib.pm',
104    INC          => $OPT_ZLIB_INCLUDE ,
105    DEFINE       => "-DNO_VIZ $OPT_SOLO $OLD_ZLIB $WALL $OPT_Z_PREFIX $OPT_USE_ZLIB_NG -DGZIP_OS_CODE=$GZIP_OS_CODE $USE_PPPORT_H -DPerl_crz_BUILD_ZLIB=$BUILD_ZLIB $OPT_CXX_DEFINES" ,
106    XS           => { 'Zlib.xs' => 'Zlib.c'},
107    OPTIMIZE     => $OPTIMIZE,
108    LICENSE      => 'perl',
109    ABSTRACT     => 'Perl interface to zlib/zlib-ng compression libraries',
110    AUTHOR       => 'Paul Marquess <pmqs@cpan.org>',
111    depend       => { Makefile     => 'config.in',
112                      manifypods   => 'READMEmd'
113                    },
114    postamble    => { name => 'Zlib' },
115    clean        => { FILES        => '*.c constants.h constants.xs' },
116    dist         => { COMPRESS     => 'gzip',
117                      TARFLAGS     => '-chvf',
118                      SUFFIX       => 'gz',
119                      DIST_DEFAULT => 'MyTrebleCheck tardist',
120                    },
121
122    (
123      $BUILD_ZLIB
124        ? zlib_files($ZLIB_LIB)
125        : (LIBS => [ "$OPT_ZLIB_LIB -l$ZLIB_LIBRARY_NAME " ])
126    ),
127
128    INSTALLDIRS  => ($] >= 5.009 && $] < 5.011 ? 'perl' : 'site'),
129
130     META_MERGE  => {
131
132                'meta-spec' => { version => 2 },
133
134                no_index => {
135                    directory => [ 't', 'private' ],
136                },
137
138                resources   => {
139
140                    bugtracker  => {
141                        web     => 'https://github.com/pmqs/Compress-Raw-Zlib/issues'
142                    },
143
144                    homepage    => 'https://github.com/pmqs/Compress-Raw-Zlib',
145
146                    repository  => {
147                        type    => 'git',
148                        url     => 'git://github.com/pmqs/Compress-Raw-Zlib.git',
149                        web     => 'https://github.com/pmqs/Compress-Raw-Zlib',
150                    },
151                },
152              },
153
154) ;
155
156delete $WriteMakefileArgs{LICENSE}
157    unless eval { ExtUtils::MakeMaker->VERSION(6.30) } ;
158
159delete $WriteMakefileArgs{META_MERGE}
160    unless eval { ExtUtils::MakeMaker->VERSION(6.46) } ;
161
162delete $WriteMakefileArgs{BUILD_REQUIRES}
163    unless eval { ExtUtils::MakeMaker->VERSION(6.55_03) } ;
164
165WriteMakefile(%WriteMakefileArgs);
166
167sub version_Macro
168{
169    my $ver = shift ;
170
171    return [ "#if ZLIB_VERNUM >= 0x$ver\n", "#endif\n" ];
172}
173
174my @names = qw(
175
176    DEF_WBITS
177    MAX_MEM_LEVEL
178    MAX_WBITS
179    OS_CODE
180
181    Z_ASCII
182    Z_BEST_COMPRESSION
183    Z_BEST_SPEED
184    Z_BINARY
185    Z_BLOCK
186    Z_BUF_ERROR
187    Z_DATA_ERROR
188    Z_DEFAULT_COMPRESSION
189    Z_DEFAULT_STRATEGY
190    Z_DEFLATED
191    Z_ERRNO
192    Z_FILTERED
193    Z_FINISH
194    Z_FIXED
195    Z_FULL_FLUSH
196    Z_HUFFMAN_ONLY
197    Z_MEM_ERROR
198    Z_NEED_DICT
199    Z_NO_COMPRESSION
200    Z_NO_FLUSH
201    Z_OK
202    Z_PARTIAL_FLUSH
203    Z_RLE
204    Z_STREAM_END
205    Z_STREAM_ERROR
206    Z_SYNC_FLUSH
207    Z_UNKNOWN
208    Z_VERSION_ERROR
209
210    ZLIBNG_VERNUM
211    ZLIBNG_VER_MAJOR
212    ZLIBNG_VER_MINOR
213    ZLIBNG_VER_REVISION
214    ZLIBNG_VER_MODIFIED
215);
216
217my %verSpecificNames = (
218    Z_TREES => '1240',
219);
220
221if (eval {require ExtUtils::Constant; 1}) {
222    # Check the constants above all appear in @EXPORT in Zlib.pm
223    my %names = %verSpecificNames, map { $_, 1} @names, 'ZLIB_VERSION';
224    open F, "<lib/Compress/Raw/Zlib.pm" or die "Cannot open Zlib.pm: $!\n";
225    while (<F>)
226    {
227        last if /^\s*\@EXPORT\s+=\s+qw\(/ ;
228    }
229
230    while (<F>)
231    {
232        last if /^\s*\)/ ;
233        /(\S+)/ ;
234        delete $names{$1} if defined $1 ;
235    }
236    close F ;
237
238    if ( keys %names )
239    {
240        my $missing = join ("\n\t", sort keys %names) ;
241        die "The following names are missing from \@EXPORT in Zlib.pm\n" .
242            "\t$missing\n" ;
243    }
244
245    push @names, { name => 'ZLIB_VERSION', type => 'PV' };
246
247    push @names, map { { name => $_,
248                         macro => version_Macro $verSpecificNames{$_}
249                       }
250                     }
251                 keys %verSpecificNames ;
252
253    push @names, { name => 'Z_NULL', type => 'UV' };
254    push @names, { name => 'ZLIBNG_VERSION', type => 'PV' };
255
256    ExtUtils::Constant::WriteConstants(
257                                     NAME => 'Zlib',
258                                     NAMES => \@names,
259                                     C_FILE  => 'constants.h',
260                                     XS_FILE  => 'constants.xs',
261
262                                    );
263
264}
265else {
266    foreach my $name (qw( constants.h constants.xs ))
267    {
268        my $from = catfile('fallback', $name);
269        copy ($from, $name)
270          or die "Can't copy $from to $name: $!";
271    }
272}
273
274sub getBoolean
275{
276    my $name = shift ;
277    my $info = shift;
278
279    my $x = getConfigValue($name, $info);
280
281    return ($x =~ /^yes|on|true|1$/i) ? 1 : 0;
282}
283
284sub getConfigValue
285{
286    my $name = shift ;
287    my $info = shift;
288
289    # Environment variable takes priority
290    my $x = defined $ENV{$name}
291                ? $ENV{$name}
292                : $info->{$name} ;
293
294    return $x;
295}
296
297sub ParseCONFIG
298{
299    my ($k, $v) ;
300    my @badkey = () ;
301    my %Info = () ;
302    my @Options = qw( ZLIB_INCLUDE ZLIB_LIB BUILD_ZLIB OLD_ZLIB GZIP_OS_CODE USE_ZLIB_NG) ;
303    my %ValidOption = map {$_, 1} @Options ;
304    my %Parsed = %ValidOption ;
305    my $CONFIG = 'config.in' ;
306
307    print "Parsing $CONFIG...\n" ;
308
309    open(F, "<$CONFIG") or die "Cannot open file $CONFIG: $!\n" ;
310    while (<F>) {
311        s/^\s*|\s*$//g ;
312        next if /^\s*$/ or /^\s*#/ ;
313        s/\s*#\s*$// ;
314
315        ($k, $v) = split(/\s+=\s+/, $_, 2) ;
316        $k = uc $k ;
317        if ($ValidOption{$k}) {
318            delete $Parsed{$k} ;
319            $Info{$k} = $v ;
320        }
321        else {
322            push(@badkey, $k) ;
323        }
324    }
325    close F ;
326
327    print "Unknown keys in $CONFIG ignored [@badkey]\n"
328        if @badkey ;
329
330    # check parsed values
331    my @missing = () ;
332    die "The following keys are missing from $CONFIG  [@missing]\n"
333        if @missing = keys %Parsed ;
334
335    $ZLIB_INCLUDE = getConfigValue('ZLIB_INCLUDE',  \%Info);
336    $ZLIB_LIB     = getConfigValue('ZLIB_LIB',      \%Info);
337    $GZIP_OS_CODE = getConfigValue('GZIP_OS_CODE',  \%Info);
338
339    $BUILD_ZLIB   = getBoolean('BUILD_ZLIB',        \%Info);
340    $USE_ZLIB_NG  = getBoolean('USE_ZLIB_NG',       \%Info);
341    $OLD_ZLIB     = getBoolean('OLD_ZLIB',          \%Info);
342
343    if ($^O eq 'VMS') {
344        $ZLIB_INCLUDE = VMS::Filespec::vmspath($ZLIB_INCLUDE);
345        $ZLIB_LIB = VMS::Filespec::vmspath($ZLIB_LIB);
346    }
347
348    $OLD_ZLIB = $OLD_ZLIB
349                    ?'-DOLD_ZLIB'
350                    : '';
351
352    if ($BUILD_ZLIB ) {
353
354        die "Cannot have USE_ZLIB_NG when BUILD_ZLIBis true\n"
355            if $USE_ZLIB_NG ;
356
357        # ZLIB_LIB & ZLIB_INCLUDE must point to the same place when
358        # BUILD_ZLIB is specified.
359        die "ZLIB_INCLUDE & ZLIB_LIB must be the same when BUILD_ZLIB is True\n"
360            if $ZLIB_LIB ne $ZLIB_INCLUDE ;
361
362        # Check the zlib source directory exists
363        die "ZLIB_LIB/ZLIB_INCLUDE directory '$ZLIB_LIB' does not exits\n"
364            unless -d $ZLIB_LIB ;
365
366        # check for a well known file
367        die "ZLIB_LIB/ZLIB_INCLUDE directory, '$ZLIB_LIB', doesn't seem to have the zlib source files\n"
368            unless -e catfile($ZLIB_LIB, 'zlib.h') ;
369
370        # write the Makefile
371        print "Building Zlib is enabled\n" ;
372    }
373
374    die "GZIP_OS_CODE not 'AUTO_DETECT' or a number between 0 and 255\n"
375       unless uc $GZIP_OS_CODE eq 'AUTO_DETECT'
376                || ( $GZIP_OS_CODE =~ /^(\d+)$/ && $1 >= 0 && $1 <= 255) ;
377
378    if (uc $GZIP_OS_CODE eq 'AUTO_DETECT')
379    {
380        print "Auto Detect Gzip OS Code..\n" ;
381        $GZIP_OS_CODE = getOSCode() ;
382    }
383
384    my $name = getOSname($GZIP_OS_CODE);
385    print "Setting Gzip OS Code to $GZIP_OS_CODE [$name]\n" ;
386
387    print <<EOM if 0 ;
388    INCLUDE         [$ZLIB_INCLUDE]
389    LIB             [$ZLIB_LIB]
390    GZIP_OS_CODE    [$GZIP_OS_CODE]
391    OLD_ZLIB        [$OLD_ZLIB]
392    BUILD_ZLIB      [$BUILD_ZLIB]
393    USE_ZLIB_NG     [$USE_ZLIB_NG]
394
395EOM
396
397    print "Looks Good.\n" ;
398
399}
400
401
402
403sub zlib_files
404{
405    my $dir = shift ;
406
407    my @h_files = ();
408    my @c_files = ();
409
410    if (-f catfile($dir, "infback.c")) {
411        # zlib 1.2.0 or greater
412        #
413        @h_files = qw(crc32.h    inffast.h inflate.h  trees.h    zconf.in.h
414                      zutil.h    deflate.h inffixed.h inftrees.h zconf.h
415                      zlib.h
416                    );
417        @c_files = qw(adler32  crc32   infback  inflate  uncompr
418                     compress deflate inffast  inftrees
419                     trees    zutil
420                    );
421    }
422    else {
423        # zlib 1.1.x
424
425        @h_files = qw(deflate.h  infcodes.h inftrees.h zconf.h zutil.h
426                     infblock.h inffast.h  infutil.h  zlib.h
427             );
428        @c_files = qw(adler32  compress crc32    uncompr
429                      deflate  trees    zutil    inflate infblock
430                      inftrees infcodes infutil  inffast
431                  );
432    }
433
434    @h_files = map { catfile($dir, $_)  } @h_files ;
435    my @o_files = map { "$_\$(OBJ_EXT)" } 'Zlib', @c_files;
436    @c_files = map { "$_.c" } 'Zlib', @c_files ;
437
438    foreach my $file (@c_files)
439      { copy(catfile($dir, $file), '.') }
440
441    return (
442            'C'         =>  [ @c_files ] ,
443            'OBJECT'    => q[ $(O_FILES) ],
444           ) ;
445}
446
447
448
449use vars qw ( @GZIP_OS_Names  %OSnames) ;
450
451BEGIN
452{
453  @GZIP_OS_Names = (
454    [ ''        => 0,    'MS-DOS'                       ],
455    [ 'amigaos' => 1,    'Amiga'                        ],
456    [ 'VMS'     => 2,    'VMS'                          ],
457    [ ''        => 3,    'Unix/Default'                 ],
458    [ ''        => 4,    'VM/CMS'                       ],
459    [ ''        => 5,    'Atari TOS'                    ],
460    [ 'os2'     => 6,    'HPFS (OS/2, NT)'              ],
461    [ 'MacOS'   => 7,    'Macintosh'                    ],
462    [ ''        => 8,    'Z-System'                     ],
463    [ ''        => 9,    'CP/M'                         ],
464    [ ''        => 10,   'TOPS-20'                      ],
465    [ ''        => 11,   'NTFS (NT)'                    ],
466    [ ''        => 12,   'SMS QDOS'                     ],
467    [ ''        => 13,   'Acorn RISCOS'                 ],
468    [ 'MSWin32' => 14,   'VFAT file system (Win95, NT)' ],
469    [ ''        => 15,   'MVS'                          ],
470    [ 'beos'    => 16,   'BeOS'                         ],
471    [ ''        => 17,   'Tandem/NSK'                   ],
472    [ ''        => 18,   'THEOS'                        ],
473    [ ''        => 255,  'Unknown OS'                   ],
474  );
475
476  %OSnames = map { $$_[1] => $$_[2] }
477             @GZIP_OS_Names ;
478}
479
480sub getOSCode
481{
482    my $default = 3 ; # Unix is the default
483
484    my $uname = $^O;
485
486    for my $h (@GZIP_OS_Names)
487    {
488        my ($pattern, $code, $name) = @$h;
489
490        return $code
491            if $pattern && $uname eq $pattern ;
492    }
493
494    return $default ;
495}
496
497sub getOSname
498{
499    my $code = shift ;
500
501    return $OSnames{$code} || 'Unknown OS' ;
502}
503
504# end of file Makefile.PL
505