1# Copyright (c) 1997-2021 2# Ewgenij Gawrilow, Michael Joswig, and the polymake team 3# Technische Universität Berlin, Germany 4# https://polymake.org 5# 6# This program is free software; you can redistribute it and/or modify it 7# under the terms of the GNU General Public License as published by the 8# Free Software Foundation; either version 2, or (at your option) any 9# later version: http://www.gnu.org/licenses/gpl.txt. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15#------------------------------------------------------------------------------- 16 17use strict; 18use feature 'state'; 19use vars qw( $dirmode $group $permmask $root $ext_root $builddir $config_file %ConfigFlags $buildmode 20 $xsmod @callable @fakelibs ); 21use POSIX qw ( :fcntl_h read write lseek ); 22use File::Path; 23use Config; 24 25use Getopt::Long qw( GetOptions :config require_order no_ignore_case ); 26 27sub collect_arglist { 28 my $list = shift; 29 @$list = @_; 30 while (@ARGV && $ARGV[0] !~ /^-/) { 31 push @$list, shift @ARGV; 32 } 33} 34 35unless (GetOptions( 'root=s' => \$root, 36 'extroot=s' => \$ext_root, 37 'builddir=s' => \$builddir, 38 'config=s' => \$config_file, 39 'mode=s' => \$buildmode, 40 'group=s' => \$group, 41 'perms=i' => \$permmask, 42 'xs=s' => \$xsmod, 43 'callable=s' => sub { collect_arglist(\@callable, $_[1]) }, 44 'fakelibs=s' => sub { collect_arglist(\@fakelibs, $_[1]) } ) && 45 !@ARGV && 46 defined($config_file) && 47 defined($root) && 48 defined($builddir) && 49 defined($buildmode) && 50 -f $config_file && 51 -d $root && 52 -d "$builddir/$buildmode" && 53 (defined($ext_root) ? -d $ext_root && !defined($xsmod) && !@callable && !@fakelibs 54 : defined($xsmod) && -f $xsmod)) { 55 die <<"."; 56usage: $0 --root PATH --builddir PATH --config PATH/config.ninja [ --extroot PATH --extconfig PATH/config.ninja ] 57 --buildmode Opt|Debug [ --group GROUP ] [ --perms MASK ] [ --xsmod | --callable | --fakelib shared_module ... ] 58. 59} 60 61if (defined($group)) { 62 my $gid = getgrnam($group) 63 or die "$0: unknown group '$group'\n"; 64 $group = $gid; 65} 66 67do "$root/support/install_utils.pl"; 68die $@ if $@; 69%ConfigFlags = load_config_file($config_file, $root); 70my @BundledExts = $ConfigFlags{BundledExts} =~ /(\S+)/g; 71 72my @default_exclude_for_copy = qw( \. \.\. \.\#.* .*~ \.git.* \.noexport ); 73 74# these variables may be used in sourced extension scripts 75use vars qw($InstallTop $InstallInc $InstallArch $InstallBin $InstallLib $buildtop $ExtTop $ExtArch); 76 77foreach (qw(InstallTop InstallInc InstallArch InstallBin InstallLib)) { 78 no strict 'refs'; 79 ${$_} = $ConfigFlags{$_}; 80} 81$buildtop = "$builddir/$buildmode"; 82my $ext_name = $ext_root && basename($ext_root); 83 84my $destdir = $ENV{DESTDIR} // $ConfigFlags{DESTDIR}; 85$destdir =~ s{/$}{}; 86if (length($destdir)) { 87 foreach ($InstallTop, $InstallInc, $InstallArch, $InstallBin, $InstallLib) { 88 substr($_,0,0) .= $destdir; 89 } 90} 91 92my $perlxpath = "perlx/$Config::Config{version}/$Config::Config{archname}"; 93 94if ($buildmode eq "San") { 95 load_sanitizer_flags(); 96} 97 98if (defined $permmask) { 99 if (($permmask & 0700) != 0700) { 100 die "--perms must allow full access to the file owner\n"; 101 } 102 umask 0; 103 $dirmode = 0777 & $permmask; 104} else { 105 $permmask = 0777&~umask; 106} 107 108if (defined($ext_root)) { 109 install_extension(); 110} else { 111 install_core(); 112} 113 114sub install_core { 115 make_dir($InstallTop); 116 foreach my $subdir (qw(demo perllib resources scripts upgrades)) { 117 copy_dir("$root/$subdir", "$InstallTop/$subdir", clean_dir => 1); 118 } 119 120 my $clean_dir = 1; 121 foreach my $file (qw(configure.pl.template generate_applib_fake.pl generate_ninja_targets.pl 122 generate_ninja_targets.pl.template generate_cpperl_modules.pl 123 guarded_compiler.pl install.pl install.pl.template install_utils.pl rules.ninja)) { 124 copy_file("$root/support/$file", "$InstallTop/support/$file", clean_dir => $clean_dir); 125 $clean_dir = 0; 126 } 127 128 make_dir("$InstallTop/apps", clean_dir => 1); 129 make_dir("$InstallTop/bundled", clean_dir => 1); 130 131 foreach my $bundled (glob("$root/bundled/*")) { 132 my $ext_file = "$bundled/polymake.ext"; 133 copy_file($ext_file, $InstallTop.substr($ext_file, length($root)), clean_dir => 1); 134 if (-d (my $scripts = "$root/bundled/scripts")) { 135 copy_dir($scripts, $InstallTop.substr($scripts, length($root))); 136 } 137 } 138 139 foreach my $dir (glob_all_apps("{perllib,rules,scripts}")) { 140 copy_dir($dir, $InstallTop.substr($dir, length($root)), clean_dir => 1); 141 } 142 143 make_dir("$InstallInc/polymake", clean_dir => 1); 144 copy_dir("$root/lib/core/include", "$InstallInc/polymake", 145 exclude => [qw(glue.h Ext.h cout_bridge.h)], 146 wrappers => "$root/include/core-wrappers/polymake" 147 ); 148 copy_dir("$root/lib/callable/include", "$InstallInc/polymake"); 149 copy_dir("$root/lib/core/skel", "$InstallTop/lib/core/skel", clean_dir => 1); 150 151 foreach my $dir (glob_all_apps("include")) { 152 my ($app_name) = $dir =~ m{/apps/(\w+)/}; 153 my $wrappers = "$`/include/app-wrappers/polymake/$app_name"; 154 copy_dir($dir, "$InstallInc/polymake/$app_name", 155 -e $wrappers ? (wrappers => $wrappers) : ()); 156 } 157 158 foreach my $ext_dir ($ConfigFlags{ExternalHeaders} =~ /(\S+)/g) { 159 copy_dir("$root/include/external/$ext_dir/$ext_dir", "$InstallInc/polymake/external/$ext_dir", 160 clean_dir => 1); 161 } 162 163 foreach my $dir (glob_all_apps("src")) { 164 copy_dir($dir, $InstallTop.substr($dir, length($root))); 165 } 166 167 make_dir($InstallArch); 168 -d $InstallBin || make_dir($InstallBin); 169 install_bin_scripts(); 170 171 copy_file($config_file, "$InstallArch/config.ninja", 172 transform => \&transform_core_config_file); 173 174 make_dir("$InstallArch/bundled", clean_dir => 1); 175 foreach my $bundled (@BundledExts) { 176 make_dir("$InstallArch/bundled/$bundled"); 177 } 178 179 -d $InstallLib || make_dir($InstallLib); 180 181 if (defined($xsmod)) { 182 $xsmod =~ m{($perlxpath/auto/.*\.$Config::Config{dlext})$}o 183 or die "$0: path of perl extension module does not match the expected pattern\n"; 184 copy_file($xsmod, "$InstallArch/$1", mode => 0555, clean_dir => 1); 185 } 186 187 foreach my $lib_file (@callable) { 188 my $to = $InstallLib."/".basename($lib_file); 189 if (-l $lib_file) { 190 copy_link($lib_file, $to); 191 } else { 192 copy_file($lib_file, $to, mode => 0555, $^O eq "darwin" ? (lib_id => $to) : ()); 193 } 194 } 195 make_dir("$InstallArch/lib", clean_dir => 1); 196 foreach my $app_dir (glob("$root/apps/*")) { 197 my $app_mod = basename($app_dir).".$Config::Config{dlext}"; 198 copy_file("$buildtop/lib/$app_mod", "$InstallArch/lib/$app_mod", mode => 0555); 199 } 200 201 # These symlinks are used by the callable library bootstrap module. 202 # Any change in naming scheme must be reflected in Main.cc as well. 203 rel_symlink($InstallTop, "$InstallArch/shared"); 204 if ($^O eq "darwin" && $ConfigFlags{FinkBase}) { 205 rel_symlink($ConfigFlags{FinkBase}, "$InstallArch/fink-base"); 206 } 207 208 if (@fakelibs) { 209 my $stub_lib_name; 210 foreach my $lib_file (@fakelibs) { 211 my $basename = basename($lib_file); 212 my $to = "$InstallArch/lib/$basename"; 213 if (-l $lib_file) { 214 copy_link($lib_file, $to); 215 copy_link($lib_file, "$InstallLib/$basename"); 216 } else { 217 $stub_lib_name //= $to; 218 copy_file($lib_file, $to, mode => 0555, $^O eq "darwin" ? (lib_id => $stub_lib_name) : ()); 219 # This symlink is also used by the callable library bootstrap module. 220 rel_symlink($to, "$InstallLib/$basename"); 221 } 222 } 223 } 224 225 foreach my $bundled (@BundledExts) { 226 if (-f (my $inst_script = "$root/bundled/$bundled/support/install.pl")) { 227 do $inst_script; 228 die "installation script $inst_script failed: $@" if $@; 229 } 230 } 231} 232 233sub install_extension { 234 $ExtTop = "$InstallTop/ext/$ext_name"; 235 copy_file("$ext_root/polymake.ext", "$ExtTop/polymake.ext", clean_dir => 1); 236 237 foreach my $subdir (qw(resources scripts upgrades)) { 238 if (-d "$ext_root/$subdir") { 239 copy_dir("$ext_root/$subdir", "$ExtTop/$subdir"); 240 } 241 } 242 243 make_dir("$ExtTop/apps"); 244 foreach my $dir (glob("$ext_root/apps/*/{perllib,rules,scripts}")) { 245 copy_dir($dir, $ExtTop.substr($dir, length($ext_root))); 246 } 247 248 foreach my $dir (glob("$ext_root/apps/*/include")) { 249 my ($app_name) = $dir =~ m{/apps/(\w+)/}; 250 my $wrappers = "$`/include/app-wrappers/polymake/$app_name"; 251 copy_dir($dir, "$ExtTop/include/polymake/$app_name", 252 -e $wrappers ? (wrappers => $wrappers) : ()); 253 } 254 255 foreach my $dir (glob("$ext_root/apps/*/src")) { 256 copy_dir($dir, $ExtTop.substr($dir, length($ext_root)), 257 exclude => [ 'perl' ]); 258 } 259 260 $ExtArch = "$InstallArch/ext/$ext_name"; 261 copy_file("$builddir/config.ninja", "$ExtArch/config.ninja", clean_dir => 1, 262 transform => \&transform_extension_config_file); 263 264 make_dir("$ExtArch/lib"); 265 foreach my $app_dir (glob("$ext_root/apps/*")) { 266 my $app_mod = basename($app_dir).".$Config::Config{dlext}"; 267 copy_file("$buildtop/lib/$app_mod", "$ExtArch/lib/$app_mod", mode => 0555); 268 } 269 270 if (-f (my $inst_script = "$ext_root/support/install.pl")) { 271 do $inst_script; 272 die "installation script $inst_script failed: $@" if $@; 273 } 274} 275 276sub glob_all_apps { 277 my ($pattern) = @_; 278 ( glob("$root/apps/*/$pattern"), 279 map { glob("$root/bundled/$_/apps/*/$pattern") } @BundledExts ) 280} 281 282sub copy_file { 283 my ($from, $to, %options) = @_; 284 if (-e $from) { 285 if (!-f $from and !-l $from) { 286 die "$0: $from is neither a regular file nor a symbolic link\n"; 287 } 288 } else { 289 die "$0: $from does not exist\n"; 290 } 291 if ($options{clean_dir}) { 292 make_dir(dirname($to), clean_dir => 1); 293 } elsif (-d $to) { 294 $to .= "/" . basename($from); 295 } 296 copy($from, $to, %options); 297} 298 299sub copy_link { 300 my ($from, $to) = @_; 301 my $target = readlink($from); 302 if (-e $to || -l $to) { 303 unlink $to 304 or die "can't remove old $to: $!\n"; 305 } 306 symlink $target, $to 307 or die "$0: can't create a symbolic link $to -> $target: $!\n"; 308} 309 310sub rel_symlink { 311 my ($target, $link) = @_; 312 if (-e $link || -l $link) { 313 unlink $link 314 or die "$0: can't delete old $link: $!\n"; 315 } 316 my $rel_link = $link; 317 my $common_prefix = 1; 318 while ($rel_link =~ s{^(/[^/]+)(?=/)}{}) { 319 if ($common_prefix && substr($target, 0, length($1)+1) eq "$1/") { 320 $target = substr($target, length($1)); 321 } else { 322 $common_prefix = 0; 323 $target =~ s{^/?}{../}; 324 } 325 } 326 $target =~ s{^/}{}; 327 symlink $target, $link 328 or die "$0: can't create a symbolic link $link -> $target: $!\n"; 329} 330 331sub compile_pattern { 332 my $expr = join('|', map { "(?:^$_\$)" } @_); 333 qr/$expr/; 334} 335 336sub exclude_pattern_for_copy { 337 my ($list) = @_; 338 if (defined $list) { 339 compile_pattern(@$list, @default_exclude_for_copy); 340 } else { 341 state $default_pattern = compile_pattern(@default_exclude_for_copy); 342 } 343} 344 345my $z1024 = pack "x1024"; 346 347sub copy { 348 my ($from, $to, %options) = @_; 349 my $concat; 350 my $mode = $options{mode}; 351 352 if (-e $to) { 353 if (defined(my $conflict = $options{conflict})) { 354 foreach my $c (@$conflict) { 355 if ($to =~ $c->[0]) { 356 if ($c->[1] eq 'abort') { 357 die "$0: can't install $from: file $to already exists\n"; 358 } elsif ($c->[1] eq 'concat') { 359 $concat = 1; 360 } elsif ($c->[1] eq 'keep') { 361 return; 362 } elsif ($c->[1] ne 'replace') { 363 die "$0: unknown conflict action $c->[1]\n"; 364 } 365 last; 366 } 367 } 368 } 369 unless ($concat || unlink $to) { 370 die "$0: can't remove old $to: $!\n"; 371 } 372 } 373 my ($fmode, $mtime) = (stat $from)[2, 9]; 374 if (defined $mode) { 375 # verbatim copy: assuming binary file 376 my $in = POSIX::open $from, O_RDONLY; 377 defined($in) 378 or die "$0: can't read $from: $!\n"; 379 my $dummy = O_WRONLY + O_CREAT + O_TRUNC; # bug in AutoLoader! 380 my $out; 381 if ($concat) { 382 open $out, ">>$to"; 383 } else { 384 $out = creat $to, 0600; 385 } 386 defined($out) 387 or die "$0: can't create $to: $!\n"; 388 389 my $trailing_zeroes; 390 while ((my $size = read $in, $_, 1024) > 0) { 391 if ($_ eq ($size == 1024 ? $z1024 : pack("x$size"))) { 392 lseek $out, $size, SEEK_CUR; 393 $trailing_zeroes = 1; 394 } else { 395 write $out, $_, $size; 396 $trailing_zeroes = 0; 397 } 398 } 399 if ($trailing_zeroes) { 400 lseek $out, -1, SEEK_CUR; 401 write $out, "\0", 1; 402 } 403 POSIX::close $in; 404 POSIX::close $out; 405 406 if (my $lib_id = $options{lib_id}) { 407 substr($lib_id, 0, length($destdir)) = ""; 408 system("install_name_tool -id $lib_id $to") 409 and die "install_name_tool $to failed\n"; 410 } 411 } else { 412 # text file: turn on write protection 413 $mode = $fmode & 0555; 414 local $/; 415 open X, "<", $from 416 or die "$0: can't read $from: $!\n"; 417 $_ = <X>; close X; 418 if (defined (my $transform = $options{transform})) { 419 &$transform; 420 } 421 open X, ">", $to 422 or die "$0: can't create $to: $!\n"; 423 print X; close X; 424 } 425 $mode &= $permmask; 426 chmod $mode, $to 427 or die "can't modify access rights to $to: $!\n"; 428 if (defined($group)) { 429 chown -1, $group, $to 430 or die "$0: can't change group of $to: $!\n"; 431 } 432 utime $mtime, $mtime, $to 433 or die "can't modify mtime of $to: $!\n"; 434} 435 436sub make_dir { 437 my ($dir, %options) = @_; 438 my $clean = $options{clean_dir}; 439 440 if (-e $dir) { 441 if (-d _) { 442 if (defined($dirmode) && ((stat _)[2] & 03777) != $dirmode) { 443 chmod $dirmode, $dir 444 or die "$0: can't change mode of $dir: $!\n"; 445 } 446 if (defined($group) and (stat _)[5] != $group) { 447 chown -1, $group, $dir 448 or die "$0: can't change group of $dir: $!\n"; 449 } 450 if ($clean) { 451 my $error; 452 if (defined(my $exclude = $options{exclude})) { 453 my $exclude_re = compile_pattern(@$exclude, qw(. ..)); 454 opendir my $D, $dir; 455 foreach (readdir $D) { 456 if ($_ !~ $exclude_re) { 457 if (-d "$dir/$_") { 458 File::Path::remove_tree("$dir/_", { error => \$error }); 459 if (@$error) { 460 die "$0: can't remove old files:\n", map { join(": ", %$_)."\n" } @$error; 461 } 462 } else { 463 unlink "$dir/$_" 464 or die "$0: can't remove old $dir/$_: $!\n"; 465 } 466 } 467 } 468 } else { 469 File::Path::remove_tree($dir, { keep_root => 1, error => \$error }); 470 if (@$error) { 471 die "$0: can't clean $dir:\n", map { join(": ", %$_)."\n" } @$error; 472 } 473 } 474 } 475 return; 476 } 477 unlink $dir 478 or die "$0: can't remove old $dir: $!\n"; 479 } 480 File::Path::make_path($dir, { defined($dirmode) ? (mode => $dirmode) : (), 481 defined($group) ? (group => $group) : () }) 482 or die "could not create directory $dir: $!\n"; 483} 484 485sub copy_dir { 486 my ($src, $dst, %options) = @_; 487 my $wrappers = delete $options{wrappers}; 488 my $clean = $options{clean_dir}; 489 my $exclude_re = exclude_pattern_for_copy($options{exclude}); 490 491 if (opendir my $S, $src) { 492 make_dir($dst, clean_dir => $clean); 493 my (%noexport, @noexport_patterns, $next_created); 494 if (-f "$src/.noexport") { 495 open my $noexport, "$src/.noexport" 496 or die "can't read $src/.noexport: $!\n"; 497 local $/="\n"; 498 while (<$noexport>) { 499 if (my ($file, $status) = /^(?!\#)(\S+)\s+(\S+)$/) { 500 if ($file =~ /[?*\[\]]/) { 501 $file =~ s/./\\./g; 502 $file =~ tr/?/./; 503 $file =~ s/\*/.*/g; 504 push @noexport_patterns, [ qr{^$file$}, $status ]; 505 } else { 506 $noexport{$file} = $status; 507 } 508 } 509 } 510 } 511 foreach my $f (grep { $_ !~ $exclude_re } readdir $S) { 512 my $noexport = $noexport{$f}; 513 unless ($noexport) { 514 foreach my $pat (@noexport_patterns) { 515 if ($f =~ $pat->[0]) { 516 $noexport = $pat->[1]; 517 last; 518 } 519 } 520 } 521 if ($noexport) { 522 next if $noexport ne "local"; 523 } 524 my $src_f = "$src/$f"; 525 if (-d $src_f) { 526 copy_dir($src_f, "$dst/$f", %options); 527 } elsif ($wrappers && -f "$wrappers/$f") { 528 $next_created ||= make_dir("$dst/next"); 529 copy($src_f, "$dst/next/$f", %options); 530 copy("$wrappers/$f", "$dst/$f", %options, 531 transform => sub { s{^#include_next +"(.*)/([^/]+)"}{#include "$1/next/$2"}m }); 532 } else { 533 copy($src_f, "$dst/$f", %options); 534 } 535 } 536 } else { 537 die "$0: can't traverse $src: $!\n"; 538 } 539} 540 541sub install_bin_scripts { 542 local $/; 543 open S, "$root/perl/polymake" 544 or die "can't read $root/perl/polymake: $!\n"; 545 $_ = <S>; 546 close S; 547 548 if ($^O eq "darwin" && $ConfigFlags{ARCHFLAGS} =~ /-arch /) { 549 s{^\#!/usr/bin/env perl}{#!/usr/bin/arch $ConfigFlags{ARCHFLAGS} $^X}s; 550 } else { 551 s{^\#!/usr/bin/env perl}{#!$Config::Config{perlpath}}s; 552 } 553 554 my $init_block = <<"---"; 555 \$InstallTop='$ConfigFlags{InstallTop}'; 556 \$InstallArch='$ConfigFlags{InstallArch}'; 557 \$Arch="$ConfigFlags{Arch}"; 558 \@BundledExts=qw(@BundledExts); 559--- 560 if ($^O eq "darwin" && $ConfigFlags{FinkBase}) { 561 $init_block.=" \@addlibs=qw($ConfigFlags{FinkBase}/lib/perl5);\n"; 562 } 563 s/(^BEGIN\s*\{\s*\n)(?s:.*?)(^\}\n)/$1$init_block$2/m; 564 565 if (-e "$InstallBin/polymake") { 566 unlink "$InstallBin/polymake" 567 or die "can't remove old polymake script: $!\n"; 568 } 569 open T, ">$InstallBin/polymake" 570 or die "can't create $InstallBin/polymake: $!\n"; 571 print T; 572 close T; 573 574 chmod(0555, "$InstallBin/polymake") 575 or die "chmod $InstallBin/polymake failed: $!\n"; 576 577 # apply similar transformations to the configuration utility 578 579 my $Version = extract_polymake_version($root); 580 581 open S, "$root/perl/polymake-config" 582 or die "can't read $root/perl/polymake-config: $!\n"; 583 $_ = <S>; 584 close S; 585 586 if ($^O eq "darwin" && $ConfigFlags{ARCHFLAGS} =~ /-arch /) { 587 s{^\#!\S+}{#!/usr/bin/arch $ConfigFlags{ARCHFLAGS} $^X}s; 588 } else { 589 s{^\#!\S+}{#!$Config::Config{perlpath}}s; 590 } 591 592 s{=Version(?=;)}{=$Version}; 593 s{=InstallTop(?=;)}{='$ConfigFlags{InstallTop}'}; 594 s{=InstallArch(?=;)}{='$ConfigFlags{InstallArch}'}; 595 596 if (-e "$InstallBin/polymake-config") { 597 unlink "$InstallBin/polymake-config" 598 or die "can't remove old polymake-config script: $!\n"; 599 } 600 open T, ">$InstallBin/polymake-config" 601 or die "can't create $InstallBin/polymake-config: $!\n"; 602 print T; 603 close T; 604 605 chmod(0555, "$InstallBin/polymake-config") 606 or die "chmod $InstallBin/polymake-config failed: $!\n"; 607} 608 609sub load_sanitizer_flags { 610 open my $BB, "<", "$buildtop/build.ninja" 611 or die "can't read $buildtop/build.ninja: $!\n"; 612 while (<$BB>) { 613 chomp; 614 if (/^\s*PERLSANITIZE\s*=\s*/) { 615 $ConfigFlags{PERLSANITIZE}=$'; 616 } elsif (/^\s*perlxpath\s*=\s*/) { 617 if ($perlxpath ne $') { 618 die "$buildtop/build.ninja does not match the current running environment; expected perlxpath=$perlxpath\n"; 619 } 620 } elsif (/^\s*builddir\s*=\s*/) { 621 if ($builddir ne $') { 622 die "$buildtop/build.ninja does not match the current running environment; expected builddir=$builddir\n"; 623 } 624 } 625 } 626 $ConfigFlags{PERLSANITIZE} or die "$buildtop/build.ninja does not contain PERLSANITIZE flags\n"; 627} 628 629sub transform_core_config_file { 630 s{^\s* configure\.command \s*= .* \n}{}xm; 631 632 s{^\s* root \s*= \K .*}{$ConfigFlags{InstallTop}}xm; 633 s{^\s* core\.includes \s*= \K .*}{-I$ConfigFlags{InstallInc}}xm; 634 635 my $external_includes = $ConfigFlags{ExternalHeaders} =~ /\S/ ? "-I$ConfigFlags{InstallInc}/polymake/external" : ""; 636 s{^\s* app\.includes \s*= \K .*}{$external_includes}xm; 637 638 s{^(?=\s*Arch\s*=)}{PERL = $Config::Config{perlpath}\n}m; 639 s{^\s* BuildModes \s*= \K .*}{$buildmode}xm; 640 s{^\s* (?: DESTDIR | CCACHE | CCWRAPPER ) \s*= .*$}{}xm; 641 642 s{[ =] -Wl,-z, \K now}{lazy}x; 643 644 if ($buildmode eq "San") { 645 s{^\s* PERL \s*= .*\n \K}{PERLSANITIZE = $ConfigFlags{PERLSANITIZE}\n}xm; 646 } 647} 648 649sub transform_extension_config_file { 650 s{^\s* root \s*= \K .*}{$ConfigFlags{InstallTop}}xm; 651 s{^\s* extroot \s*= \K .*}{$ConfigFlags{InstallTop}/ext/$ext_name}xm; 652 s{^\s* app\.includes \s*= \K .*}{-I\${extroot}/include \${super.app.includes}}xm; 653 s{^\s* BuildModes \s*= \K .*}{$buildmode}xm; 654} 655 656# Local Variables: 657# cperl-indent-level:3 658# indent-tabs-mode:nil 659# End: 660