1package # 2 inc::Sereal::BuildTools; 3use strict; 4use warnings; 5 6use Config; 7use constant OSNAME => $^O; 8 9my %bare_minimum_files= map { $_ => 1 } qw{ 10 typemap 11 ppport.h 12 srl_stack.h 13 srl_common.h 14 srl_inline.h 15 srl_taginfo.h 16 srl_protocol.h 17 srl_reader_error.h 18 srl_reader_types.h 19 inc/Sereal/BuildTools.pm 20 inc/Devel/CheckLib.pm 21 inc/Sereal 22 inc/Devel 23 inc 24}; 25 26sub link_files { 27 my $shared_dir= shift; 28 my $mode= shift || ""; 29 my $exclude_tests= $mode eq "without_tests"; 30 my $tests_only= $mode eq "tests_only"; 31 my $bare_minimum= $mode eq "bare_minimum"; 32 33 # This fires from a git source tree only. 34 # Right now, all devs are on Linux. Feel free to make portable. 35 eval { 36 # overwrite by default 37 require File::Find; 38 require File::Path; 39 require File::Spec; 40 File::Find::find( { 41 no_chdir => 1, 42 wanted => sub { 43 my $f= $_; 44 s/^\Q$shared_dir\E\/?// or die $_; 45 return unless $_; 46 return if $exclude_tests && m#^/?t/#; 47 return if $tests_only && !m#^/?t/#; 48 return if $bare_minimum && !exists $bare_minimum_files{$_}; 49 50 if ( -d $f ) { 51 File::Path::mkpath($_); 52 } 53 elsif ( -f $f ) { 54 return if $f =~ /(?:\.bak|\.sw[po]|~)$/; 55 my @d= File::Spec->splitdir($_); 56 my $fname= pop @d; 57 my $ref= join "/", ("..") x scalar(@d); 58 my $subd= join "/", @d; 59 chdir $subd if length($ref); 60 my $srcfname= join( "/", grep length, $ref, $shared_dir, $subd, $fname ); 61 if ( OSNAME eq 'MSWin32' ) { 62 die "link($srcfname, $fname) failed: $!" 63 unless link( $srcfname, $fname ); #only NTFS implements it 64 } 65 else { 66 symlink( $srcfname, $fname ); 67 } 68 chdir($ref) if length($ref); 69 } 70 }, 71 }, 72 $shared_dir 73 ); 74 1; 75 } or warn $@; 76} 77 78sub generate_constant_includes { 79 80 # no-op 81} 82 83# Prefer external csnappy and miniz libraries over the bundled ones. 84sub check_external_libraries { 85 my ( $libs, $defines, $objects, $subdirs )= @_; 86 require Devel::CheckLib; 87 88 if ( 89 !$ENV{SEREAL_USE_BUNDLED_LIBS} 90 && !$ENV{SEREAL_USE_BUNDLED_CSNAPPY} 91 && Devel::CheckLib::check_lib( 92 lib => 'csnappy', 93 header => 'csnappy.h' 94 ) ) 95 { 96 print "Using installed csnappy library\n"; 97 $$libs .= ' -lcsnappy'; 98 $$defines .= ' -DHAVE_CSNAPPY'; 99 } 100 else { 101 print "Using bundled csnappy code\n"; 102 } 103 104 if ( 105 !$ENV{SEREAL_USE_BUNDLED_LIBS} 106 && !$ENV{SEREAL_USE_BUNDLED_MINIZ} 107 && Devel::CheckLib::check_lib( 108 lib => 'miniz', 109 header => 'miniz.h' 110 ) ) 111 { 112 print "Using installed miniz library\n"; 113 $$libs .= ' -lminiz'; 114 $$defines .= ' -DHAVE_MINIZ'; 115 } 116 else { 117 print "Using bundled miniz code\n"; 118 $$objects .= ' miniz$(OBJ_EXT)'; 119 } 120 121 if ( 122 !$ENV{SEREAL_USE_BUNDLED_LIBS} 123 && !$ENV{SEREAL_USE_BUNDLED_ZSTD} 124 && Devel::CheckLib::check_lib( 125 lib => 'zstd', 126 header => 'zstd.h' 127 ) ) 128 { 129 print "Using installed zstd library\n"; 130 $$libs .= ' -lzstd'; 131 $$defines .= ' -DHAVE_ZSTD'; 132 } 133 else { 134 print "Using bundled zstd code\n"; 135 push @{$subdirs}, 'zstd'; 136 $$objects .= ' zstd/libzstd$(OBJ_EXT)'; 137 } 138} 139 140sub build_defines { 141 my (@defs)= @_; 142 143 my $defines= join( 144 " ", map { "-D$_" . ( defined $ENV{$_} ? "=$ENV{$_}" : '' ) } 145 grep { exists $ENV{$_} } ( qw(NOINLINE DEBUG MEMDEBUG NDEBUG), @defs ) ); 146 147 $defines .= " -DNDEBUG" unless $ENV{DEBUG}; 148 if ( $Config{osname} eq 'hpux' && not $Config{gccversion} ) { 149 150 # HP-UX cc does not support inline. 151 # Or rather, it does, but it depends on the compiler flags, 152 # assumedly -AC99 instead of -Ae would work. 153 # But we cannot change the compiler config too much from 154 # the one that was used to compile Perl, 155 # so we just fake the inline away. 156 $defines .= " -Dinline= "; 157 } 158 159 return $defines; 160} 161 162sub build_optimize { 163 my $cc_flags= shift || {}; 164 165 my $catch_violations= exists $cc_flags->{catch_violations} ? $cc_flags->{catch_violations} : 1; 166 167 my $OPTIMIZE; 168 169 my $clang= 0; 170 if ( $Config{gccversion} ) { 171 $OPTIMIZE= '-O3'; 172 if ( $Config{gccversion} =~ /[Cc]lang/ ) { # clang. 173 $clang= 1; 174 } 175 176 my $gccversion= 0; 177 if ( $Config{gccversion} =~ /^(\d+\.\d+)/ ) { 178 $gccversion= $1; 179 } 180 181 if ( $catch_violations && ( $clang || $gccversion >= 4.3 ) ) { 182 183 # -Werror= introduced in GCC 4.3 184 # For trapping C++ // comments we would need -std=c89 (aka -ansi) 185 # but that may be asking too much of different platforms. 186 $OPTIMIZE .= ' -Werror=declaration-after-statement '; 187 } 188 189 } 190 elsif ( $Config{osname} eq 'MSWin32' ) { 191 $OPTIMIZE= '-O2 -W4'; 192 } 193 else { 194 $OPTIMIZE= $Config{optimize}; 195 } 196 197 if ( $ENV{DEBUG} ) { 198 $OPTIMIZE .= ' -g'; 199 if ( $ENV{DEBUG} > 0 && $Config{gccversion} ) { 200 $OPTIMIZE .= ' -Wextra' if $ENV{DEBUG} > 1; 201 $OPTIMIZE .= ' -pedantic' if $ENV{DEBUG} > 5; # not pretty 202 $OPTIMIZE .= ' -Weverything' if ( $ENV{DEBUG} > 6 && $clang ); # really not pretty 203 } 204 } 205 206 return $OPTIMIZE; 207} 208 209sub WriteMakefile { 210 require ExtUtils::MakeMaker; 211 212 #Original by Alexandr Ciornii, modified by Yves Orton 213 my %params= @_; 214 my $eumm_version= $ExtUtils::MakeMaker::VERSION; 215 $eumm_version= eval $eumm_version; 216 die "EXTRA_META is deprecated" if exists $params{EXTRA_META}; 217 die "License not specified" if not exists $params{LICENSE}; 218 if ( $params{TEST_REQUIRES} and $eumm_version < 6.6303 ) { 219 $params{BUILD_REQUIRES}= 220 { %{ $params{BUILD_REQUIRES} || {} }, %{ $params{TEST_REQUIRES} } }; 221 delete $params{TEST_REQUIRES}; 222 } 223 if ( $params{BUILD_REQUIRES} and $eumm_version < 6.5503 ) { 224 225 #EUMM 6.5502 has problems with BUILD_REQUIRES 226 $params{PREREQ_PM}= { %{ $params{PREREQ_PM} || {} }, %{ $params{BUILD_REQUIRES} } }; 227 delete $params{BUILD_REQUIRES}; 228 } 229 if ( $params{CONFIGURE_REQUIRES} and $eumm_version < 6.52 ) { 230 $params{PREREQ_PM}= { %{ $params{PREREQ_PM} || {} }, %{ $params{CONFIGURE_REQUIRES} } }; 231 delete $params{CONFIGURE_REQUIRES}; 232 } 233 delete $params{MIN_PERL_VERSION} if $eumm_version < 6.48; 234 delete $params{META_MERGE} if $eumm_version < 6.46; 235 delete $params{META_ADD} if $eumm_version < 6.46; 236 delete $params{LICENSE} if $eumm_version < 6.31; 237 delete $params{AUTHOR} if $] < 5.005; 238 delete $params{ABSTRACT_FROM} if $] < 5.005; 239 delete $params{BINARY_LOCATION} if $] < 5.005; 240 delete $params{OPTIMIZE} if $^O eq 'MSWin32'; 241 242 ExtUtils::MakeMaker::WriteMakefile(%params); 243} 244 2451; 246