A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.
1 #!/usr/bin/env perl 2 # $Id: install-tl 67839 2023-08-07 21:47:31Z preining $ 3 # Copyright 2007-2023 4 # Reinhard Kotucha, Norbert Preining, Karl Berry, Siep Kroonenberg. 5 # This file is licensed under the GNU General Public License version 2 6 # or any later version. 7 # 8 # TeX Live standalone installer. 9 # 10 # Be careful when changing wording: *every* normal informational message 11 # output here must be recognized by the long grep in tl-update-tlnet. 12 13 use strict; use warnings; 14 15 my $svnrev = '$Revision: 67839 $'; 16 $svnrev =~ m/: ([0-9]+) /; 17 $::installerrevision = ($1 ? $1 : 'unknown'); 18 19 # taken from 00texlive.config: release, $tlpdb->config_release; 20 our $texlive_release; 21 22 BEGIN { 23 $^W = 1; 24 my $Master; 25 my $me = $0; 26 $me =~ s!\\!/!g if $^O =~ /^MSWin/i; 27 if ($me =~ m!/!) { 28 ($Master = $me) =~ s!(.*)/[^/]*$!$1!; 29 } else { 30 $Master = "."; 31 } 32 $::installerdir = $Master; 33 34 # All platforms: add the installer modules 35 unshift (@INC, "$::installerdir/tlpkg"); 36 } 37 38 # debugging communication with external gui: use shared logfile 39 40 our $dblfile = "/tmp/dblog"; 41 $dblfile = $ENV{'TEMP'} . "\\dblog.txt" if ($^O =~ /^MSWin/i); 42 $dblfile = $ENV{'TMPDIR'} . "/dblog" if ($^O eq 'darwin' 43 && exists $ENV{'TMPDIR'}); 44 sub dblog { 45 my $s = shift; 46 open(my $dbf, ">>", $dblfile); 47 print $dbf "PERL: $s\n"; 48 close $dbf; 49 } 50 51 sub dblogsub { 52 my $s = shift; 53 my @stck = (caller(1)); 54 dblog "$stck[3] $s"; 55 } 56 57 # On unix, this run of install-tl may do duty as a wrapper for 58 # install-tl-gui.tcl, which in its turn will start an actual run of install-tl. 59 # Skip this wrapper block if we can easily rule out a tcl gui: 60 61 if (($^O !~ /^MSWin/i) && 62 # this wrapper is only for unix, since windows has its own wrapper 63 ($#ARGV >= 0) && ($ARGV[0] ne '-from_ext_gui') 64 # this run is not invoked by tcl 65 ) { 66 67 # make syntax uniform: --a => -a, a=b => 'a b' 68 my @tmp_args = (); 69 my $p; 70 my $i=-1; 71 while ($i<$#ARGV) { 72 $p = $ARGV[++$i]; 73 $p =~ s/^--/-/; 74 if ($p =~ /^(.*)=(.*)$/) { 75 push (@tmp_args, $1, $2); 76 } else { 77 push (@tmp_args, $p); 78 } 79 } 80 81 # build argument array @new_args for install-tl-gui.tcl. 82 # '-gui' or '-gui tcl' will not be copied to @new_args. 83 # quit scanning and building @new_args once tcl is ruled out. 84 my $want_tcl = 0; 85 my $asked4tcl = 0; 86 my $forbid = 0; 87 my @new_args = (); 88 $i = -1; 89 while ($i < $#tmp_args) { 90 $p = $tmp_args[++$i]; 91 if ($p eq '-gui') { 92 # look ahead at next parameter 93 if ($i == $#tmp_args || $tmp_args[$i+1] =~ /^-/) { 94 # just -gui, without value 95 $want_tcl = 1; 96 $asked4tcl = 1; 97 } elsif ($tmp_args[$i+1] eq 'text') { 98 $want_tcl = 0; 99 $forbid = 1; 100 last; 101 } else { 102 # check all allowed values for -gui 103 my $q = $tmp_args[$i+1]; 104 if ($q eq 'tcl' || $q eq 'perltk' || 105 $q eq 'wizard' || $q eq 'expert') { 106 $want_tcl = 1; 107 $asked4tcl = 1; 108 $i++; 109 } else { 110 die "$0: invalid value for parameter -gui: $q\n"; 111 } 112 } 113 } else { 114 for my $q (qw/in-place profile help print-arch print-platform 115 version no-gui/) { 116 if ($p eq "-$q") { 117 # ignore gui mode 118 $want_tcl = 0; 119 $forbid = 1; 120 last; 121 } 122 } 123 last if $forbid; 124 # not gui-related, continue collecting @new_args 125 push (@new_args, $p); 126 } 127 } 128 # done scanning arguments 129 if ($want_tcl) { 130 unshift (@new_args, "--"); 131 unshift (@new_args, "$::installerdir/tlpkg/installer/install-tl-gui.tcl"); 132 my @wishes = qw /wish wish8.7 wish8.6 wish8.5 tclkit/; 133 unshift @wishes, $ENV{'WISH'} if (defined $ENV{'WISH'}); 134 foreach my $w (@wishes) { 135 if (!exec($w, @new_args)) { 136 next; # no return on successful exec 137 } 138 } 139 # no succesful exec of wish 140 } # else continue with main installer below 141 } 142 # end of wrapper block, start of the real installer 143 144 use Cwd 'abs_path'; 145 use Getopt::Long qw(:config no_autoabbrev); 146 use Pod::Usage; 147 use POSIX (); 148 149 use TeXLive::TLUtils qw(platform platform_desc sort_archs 150 which getenv wndws unix info log debug tlwarn ddebug tldie 151 member process_logging_options rmtree wsystem 152 mkdirhier make_var_skeleton make_local_skeleton install_package copy 153 install_packages dirname setup_programs native_slashify forward_slashify); 154 use TeXLive::TLConfig; 155 use TeXLive::TLCrypto; 156 use TeXLive::TLDownload; 157 use TeXLive::TLPDB; 158 use TeXLive::TLPOBJ; 159 use TeXLive::TLPaper; 160 161 use Encode::Alias; 162 eval { 163 require Encode::Locale; 164 Encode::Locale->import (); 165 debug("Encode::Locale is loaded.\n"); 166 }; 167 if ($@) { 168 if (wndws()) { 169 die ("For Windows, Encode::Locale is required.\n"); 170 } 171 172 debug("Encode::Locale is not found. Assuming all encodings are UTF-8.\n"); 173 Encode::Alias::define_alias('locale' => 'UTF-8'); 174 Encode::Alias::define_alias('locale_fs' => 'UTF-8'); 175 Encode::Alias::define_alias('console_in' => 'UTF-8'); 176 Encode::Alias::define_alias('console_out' => 'UTF-8'); 177 } 178 binmode (STDIN, ':encoding(console_in)'); 179 binmode (STDOUT, ':encoding(console_out)'); 180 binmode (STDERR, ':encoding(console_out)'); 181 182 if (wndws()) { 183 require TeXLive::TLWinGoo; 184 TeXLive::TLWinGoo->import( qw( 185 &admin 186 &non_admin 187 ®_country 188 &expand_string 189 &get_system_path 190 &get_user_path 191 &setenv_reg 192 &unsetenv_reg 193 &adjust_reg_path_for_texlive 194 ®ister_extension 195 &unregister_extension 196 ®ister_file_type 197 &unregister_file_type 198 &broadcast_env 199 &update_assocs 200 &add_menu_shortcut 201 &remove_desktop_shortcut 202 &remove_menu_shortcut 203 &create_uninstaller 204 &maybe_make_ro 205 )); 206 } 207 208 # global list of lines that get logged (see TLUtils.pm::_logit). 209 @::LOGLINES = (); 210 # if --version, --help, etc., this just gets thrown away, which is ok. 211 &log ("TeX Live installer invocation: $0", map { " $_" } @ARGV, "\n"); 212 213 # global list of warnings 214 @::WARNLINES = (); 215 216 # we play around with the environment, place to keep original 217 my %origenv = (); 218 219 # $install{$packagename} == 1 if it should be installed 220 my %install; 221 222 # the different modules have to assign a code blob to this global variable 223 # which starts the installation. 224 # Example: In install-menu-text.pl there is 225 # $::run_menu = \&run_menu_text; 226 # 227 $::run_menu = sub { die "no UI defined." ; }; 228 229 # the default scheme to be installed 230 my $default_scheme='scheme-full'; 231 232 # common fmtutil args, keep in sync with tlmgr.pl. 233 our $common_fmtutil_args = 234 "--no-error-if-no-engine=$TeXLive::TLConfig::PartialEngineSupport"; 235 236 # some arrays where the lists of collections to be installed are saved 237 # our for menus 238 our @collections_std; 239 240 # The global variable %vars is an associative list which contains all 241 # variables and their values which can be changed by the user. 242 # needs to be our since TeXLive::TLUtils uses it 243 # 244 # The following values are taken from the remote tlpdb using the 245 # $tlpdb->tlpdbopt_XXXXX 246 # settings (i.e., taken from tlpkg/tlpsrc/00texlive.installation.tlpsrc 247 # 248 # 'tlpdbopt_sys_bin' => '/usr/local/bin', 249 # 'tlpdbopt_sys_man' => '/usr/local/man', 250 # 'tlpdbopt_sys_info' => '/usr/local/info', 251 # 'tlpdbopt_install_docfiles' => 1, 252 # 'tlpdbopt_install_srcfiles' => 1, 253 # 'tlpdbopt_create_formats' => 0, 254 our %vars=( # 'n_' means 'number of'. 255 'this_platform' => '', 256 'n_systems_available' => 0, 257 'n_systems_selected' => 0, 258 'n_collections_selected' => 0, 259 'n_collections_available' => 0, 260 'total_size' => 0, 261 'src_splitting_supported' => 1, 262 'doc_splitting_supported' => 1, 263 'selected_scheme' => $default_scheme, 264 'instopt_portable' => 0, 265 'instopt_letter' => 0, 266 'instopt_adjustrepo' => 1, 267 'instopt_write18_restricted' => 1, 268 'instopt_adjustpath' => 0, 269 ); 270 271 my %path_keys = ( 272 'TEXDIR' => 1, 273 'TEXMFHOME' => 1, 274 'TEXMFLOCAL' => 1, 275 'TEXMFCONFIG' => 1, 276 'TEXMFSYSCONFIG' => 1, 277 'TEXMFVAR' => 1, 278 'TEXMFSYSVAR' => 1, 279 ); 280 281 # option handling 282 # tcl gui weeded out at start 283 my $opt_allow_ftp = 0; 284 my $opt_continue = 1; 285 my $opt_custom_bin; 286 my $opt_debug_fakenet = 0; 287 my $opt_debug_setup_vars = 0; 288 my $opt_doc_install = 1; 289 my $opt_font; 290 my $opt_force_arch; 291 my $opt_gui = "text"; 292 my $opt_help = 0; 293 my $opt_init_from_profile = ""; 294 my $opt_installation = 1; 295 my $opt_interaction = 1; 296 my $opt_location = ""; 297 my $opt_no_gui = 0; 298 my $opt_no_interaction = 0; 299 my $opt_nonadmin = 0; 300 my $opt_paper = ""; 301 my $opt_persistent_downloads = 1; 302 my $opt_portable = 0; 303 my $opt_print_arch = 0; 304 my $opt_profile = ""; 305 my $opt_scheme = ""; 306 my $opt_src_install = 1; 307 my $opt_texdir = ""; 308 my $opt_texuserdir = ""; 309 my $opt_version = 0; 310 my $opt_warn_checksums = 1; 311 my %pathopts; 312 # unusual cases: 313 $::opt_select_repository = 0; 314 our $opt_in_place = 0; 315 # don't set this to a value, see below 316 my $opt_verify_downloads; 317 318 # show all options even those not relevant for that arch 319 $::opt_all_options = 0; 320 321 # default language for GUI installer 322 $::lang = "en"; 323 324 # use the fancy directory selector for TEXDIR 325 # no longer used, although we still accept the parameter 326 #$::alternative_selector = 0; 327 328 # do not debug translations by default 329 $::debug_translation = 0; 330 331 # List of packages that failed to install but we continued due to --continue 332 @::installation_failed_packages = (); 333 334 # 335 # set up signal handlers to catch SIGINT and SIGTERM 336 $SIG{'INT'} = \&signal_handler; 337 # not necessary AFA we know 338 # $SIG{TERM} = &signal_handler; 339 340 # before we try to interact with the user, we need to know whether or not 341 # install-tl was called from an external gui. This gui will start install-tl 342 # with "-from_ext_gui" as its first command-line option. 343 344 my $from_ext_gui = 0; 345 if ((defined $ARGV[0]) && $ARGV[0] eq "-from_ext_gui") { 346 shift @ARGV; 347 $from_ext_gui = 1; 348 349 # do not buffer output to the frontend 350 select(STDERR); $| = 1; 351 select(STDOUT); $| = 1; 352 353 # windows: suppress console windows when invoking other programs 354 Win32::SetChildShowWindow(0) if wndws(); 355 } 356 357 # If we find a file installation.profile we ask the user whether we should 358 # continue with the installation, unless there shouldn't be interaction. 359 # We are in the directory from which the aborted installation was run. 360 my %profiledata; 361 if (-r "installation.profile" 362 && $opt_interaction 363 && !exists $ENV{"TEXLIVE_INSTALL_NO_RESUME"}) { 364 if ($from_ext_gui) { # prepare for dialog interaction 365 print "mess_yesno\n"; 366 } 367 my $pwd = Cwd::getcwd(); 368 print "ABORTED TL INSTALLATION FOUND: installation.profile (in $pwd)\n"; 369 print 370 "Do you want to continue with the exact same settings as before (y/N): "; 371 print "\nendmess\n" if $from_ext_gui; 372 my $answer = <STDIN>; 373 if ($answer =~ m/^y(es)?$/i) { 374 $opt_profile = "installation.profile"; 375 } 376 } 377 378 379 # first process verbosity/quiet options 380 process_logging_options(); 381 # now the others 382 GetOptions( 383 "all-options" => \$::opt_all_options, 384 "continue!" => \$opt_continue, 385 "custom-bin=s" => \$opt_custom_bin, 386 "debug-fakenet" => \$opt_debug_fakenet, 387 "debug-setup-vars" => \$opt_debug_setup_vars, 388 "debug-translation" => \$::debug_translation, 389 "doc-install!" => \$opt_doc_install, 390 "fancyselector", 391 "font=s" => \$opt_font, 392 "force-platform|force-arch=s" => \$opt_force_arch, 393 "gui:s" => \$opt_gui, 394 "in-place" => \$opt_in_place, 395 "init-from-profile=s" => \$opt_init_from_profile, 396 "installation!", => \$opt_installation, 397 "interaction!", => \$opt_interaction, 398 "lang|gui-lang=s" => \$::opt_lang, 399 "location|url|repository|repos|repo=s" => \$opt_location, 400 "no-cls", # $::opt_no_cls in install-menu-text-pl 401 "N" => \$opt_no_interaction, 402 "no-gui" => \$opt_no_gui, 403 "non-admin" => \$opt_nonadmin, 404 "paper=s" => \$opt_paper, 405 "persistent-downloads!" => \$opt_persistent_downloads, 406 "portable" => \$opt_portable, 407 "print-platform|print-arch" => \$opt_print_arch, 408 "profile=s" => \$opt_profile, 409 "scheme|s=s" => \$opt_scheme, 410 "select-repository" => \$::opt_select_repository, 411 "src-install!" => \$opt_src_install, 412 "tcl", # handled by wrapper 413 "texdir=s" => \$opt_texdir, 414 "texmfconfig=s" => \$pathopts{'texmfconfig'}, 415 "texmfhome=s" => \$pathopts{'texmfhome'}, 416 "texmflocal=s" => \$pathopts{'texmflocal'}, 417 "texmfsysconfig=s" => \$pathopts{'texmfsysconfig'}, 418 "texmfsysvar=s" => \$pathopts{'texmfsysvar'}, 419 "texmfvar=s" => \$pathopts{'texmfvar'}, 420 "texuserdir=s" => \$opt_texuserdir, 421 "verify-downloads!" => \$opt_verify_downloads, 422 "version" => \$opt_version, 423 "warn-checksums!" => \$opt_warn_checksums, 424 "help|?" => \$opt_help) or pod2usage(2); 425 if ($from_ext_gui) { 426 $opt_gui = "extl"; 427 } 428 429 # just so we can use -N as abbreviation for --no-interaction. 430 $opt_interaction = 0 if $opt_no_interaction; 431 432 # informational invocations: help, version, platform 433 434 if ($opt_help) { 435 # theoretically we could make a subroutine with all the same 436 # painful checks as we do in tlmgr, but let's not bother until people ask. 437 my @noperldoc = (); 438 if (wndws() || $ENV{"NOPERLDOC"}) { 439 @noperldoc = ("-noperldoc", "1"); 440 } 441 442 # Tweak less invocation same as tlmgr, though. 443 # less can break control characters and thus the output of pod2usage 444 # is broken. We add/set LESS=-R in the environment and unset 445 # LESSPIPE and LESSOPEN to try to help. 446 # 447 if (defined($ENV{'LESS'})) { 448 $ENV{'LESS'} .= " -R"; 449 } else { 450 $ENV{'LESS'} = "-R"; 451 } 452 delete $ENV{'LESSPIPE'}; 453 delete $ENV{'LESSOPEN'}; 454 455 pod2usage(-exitstatus => 0, -verbose => 2, @noperldoc); 456 die "sorry, pod2usage did not work; maybe a download failure?"; 457 } 458 459 if ($opt_version) { 460 print "install-tl (TeX Live Cross Platform Installer)", 461 " revision $::installerrevision\n"; 462 if (open (REL_TL, "$::installerdir/release-texlive.txt")) { 463 # print first and last lines, which have the TL version info. 464 my @rel_tl = <REL_TL>; 465 print $rel_tl[0]; 466 print $rel_tl[$#rel_tl]; 467 close (REL_TL); 468 } 469 if ($::opt_verbosity > 0) { 470 print "Module revisions:"; 471 print "\nTLConfig: " . TeXLive::TLConfig->module_revision(); 472 print "\nTLCrypto: " . TeXLive::TLCrypto->module_revision(); 473 print "\nTLDownload: ".TeXLive::TLDownload->module_revision(); 474 print "\nTLPDB: " . TeXLive::TLPDB->module_revision(); 475 print "\nTLPOBJ: " . TeXLive::TLPOBJ->module_revision(); 476 print "\nTLTREE: " . TeXLive::TLTREE->module_revision(); 477 print "\nTLUtils: " . TeXLive::TLUtils->module_revision(); 478 print "\nTLWinGoo: " . TeXLive::TLWinGoo->module_revision() if wndws(); 479 print "\n"; 480 } 481 exit 0; 482 } 483 484 if ($opt_print_arch) { 485 print platform()."\n"; 486 exit 0; 487 } 488 489 # now load translations, if applicable 490 if (defined($::opt_lang)) { 491 $::lang = $::opt_lang; 492 } 493 require("TeXLive/trans.pl"); 494 load_translations(); 495 496 # some option checks 497 498 die "$0: Incompatible options: custom-bin and in-place.\n" 499 if ($opt_in_place && $opt_custom_bin); 500 501 die "$0: Incompatible options: in-place and profile ($opt_profile).\n" 502 if ($opt_in_place && $opt_profile); 503 504 die "$0: Incompatible options init-from-profile and in-place.\n" 505 if ($opt_in_place && $opt_init_from_profile); 506 507 # We now allow --texuserdir XXX --texmfhome YYYY 508 # die "$0: Incompatible options: texuserdir ($opt_texuserdir) and " 509 # . "any of texmfhome, texmfconfig, texmfvar (" 510 # . "$pathopts{'texmfhome'}, $pathopts{'texmfvar'}, $pathopts{'texmfconfig'}" 511 # . ").\n" 512 # if ($opt_texuserdir && 513 # ($pathopts{'texmfhome'} || $pathopts{'texmfvar'} 514 # || $pathopts{'texmfconfig'})); 515 516 if ($#ARGV >= 0) { 517 die "$0: Extra arguments `@ARGV'; try --help if you need it.\n"; 518 } 519 520 521 if ($opt_profile) { # not allowed if in_place 522 if (-r $opt_profile && -f $opt_profile) { 523 info("Automated TeX Live installation using profile: $opt_profile\n"); 524 } else { 525 $opt_profile = ""; 526 info( 527 "Profile $opt_profile not readable or not a file, continuing in interactive mode.\n"); 528 } 529 } 530 531 if ($opt_nonadmin and wndws()) { 532 non_admin(); 533 } 534 535 # done with options 536 537 538 # the TLPDB instances we will use. $tlpdb is for the one from the installation 539 # media, while $localtlpdb is for the new installation 540 # $tlpdb must be our because it is used in install-menu-text.pl 541 our $tlpdb; 542 my $localtlpdb; 543 my $location; 544 545 @::info_hook = (); 546 547 our $media; 548 our @media_available; 549 550 TeXLive::TLUtils::initialize_global_tmpdir(); 551 552 if (TeXLive::TLCrypto::setup_checksum_method()) { 553 # try to setup gpg: 554 # either explicitly requested or nothing requested 555 if ((defined($opt_verify_downloads) && $opt_verify_downloads) 556 || 557 (!defined($opt_verify_downloads))) { 558 if (TeXLive::TLCrypto::setup_gpg($::installerdir)) { 559 # make sure we actually do verify ... 560 $opt_verify_downloads = 1; 561 log("Trying to verify cryptographic signatures!\n") 562 } else { 563 if ($opt_verify_downloads) { 564 tldie("$0: No gpg found, but verification explicitly requested " 565 . "on command line, so quitting.\n"); 566 } else { 567 # implicitly requested, just 568 debug("Couldn't detect gpg so will proceed without verification!\n"); 569 } 570 } 571 } 572 } else { 573 if ($opt_warn_checksums) { 574 tldie(<<END_NO_CHECKSUMS); 575 $0: Quitting, cannot find a checksum implementation. 576 Please install Digest::SHA (from CPAN), or openssl, or sha512sum, 577 or use the --no-warn-checksums command line option. 578 END_NO_CHECKSUMS 579 } 580 } 581 582 583 # continuing with normal install 584 585 if (defined($opt_force_arch)) { 586 tlwarn("Overriding platform to $opt_force_arch\n"); 587 $::_platform_ = $opt_force_arch; 588 } 589 590 # initialize the correct platform 591 platform(); 592 $vars{'this_platform'} = $::_platform_; 593 594 # we do not support cygwin < 1.7, so check for that 595 if (!$opt_custom_bin && (platform() eq "i386-cygwin")) { 596 chomp( my $un = `uname -r`); 597 if ($un =~ m/^(\d+)\.(\d+)\./) { 598 if ($1 < 2 && $2 < 7) { 599 tldie("$0: Sorry, the TL binaries require at least cygwin 1.7, " 600 . "not $1.$2\n"); 601 } 602 } 603 } 604 605 # determine which media are available, don't put NET here, it is 606 # assumed to be available at any time 607 { 608 # check the installer dir for what is present 609 my $tmp = $::installerdir; 610 $tmp = abs_path($tmp); 611 # remove trailing \ or / (e.g. root of dvd drive on w32) 612 $tmp =~ s,[\\\/]$,,; 613 if (-d "$tmp/$Archive") { 614 push @media_available, "local_compressed#$tmp"; 615 } 616 if (-r "$tmp/texmf-dist/web2c/texmf.cnf") { 617 push @media_available, "local_uncompressed#$tmp"; 618 } 619 } 620 621 # check command line arguments if given 622 if ($opt_location) { 623 my $tmp = $opt_location; 624 if ($tmp =~ m!^(https?|ftp)://!i) { 625 push @media_available, "NET#$tmp"; 626 627 } elsif ($tmp =~ m!^(rsync|)://!i) { 628 tldie ("$0: sorry, rsync unsupported; use an http or ftp url here.\n"); 629 630 } else { 631 # remove leading file:/+ part 632 $tmp =~ s!^file://*!/!i; 633 $tmp = abs_path($tmp); 634 # remove trailing \ or / (e.g. root of dvd drive on w32) 635 $tmp =~ s,[\\\/]$,,; 636 if (-d "$tmp/$Archive") { 637 push @media_available, "local_compressed#$tmp"; 638 } 639 if (-d "$tmp/texmf-dist/web2c") { 640 push @media_available, "local_uncompressed#$tmp"; 641 } 642 } 643 } 644 645 # find wget, tar, xz 646 if (!setup_programs ("$::installerdir/tlpkg/installer", "$::_platform_")) { 647 tldie("$0: Goodbye.\n"); 648 } 649 650 651 if ($opt_profile eq "" && $opt_interaction) { 652 if ($opt_init_from_profile) { 653 read_profile("$opt_init_from_profile", seed => 1); 654 } 655 # do the normal interactive installation. 656 # 657 # here we could load different menu systems. Currently several things 658 # are "our" so that the menu implementation can use it: The $tlpdb, the 659 # %var, and all the @collection*. 660 # install-menu-*.pl have to assign a code ref to $::run_menu which is 661 # run, and should change ONLY stuff in %vars 662 # The allowed keys in %vars should be specified somewhere ... 663 # the menu implementation should return 664 # MENU_INSTALL do the installation 665 # MENU_ABORT abort every action immediately, no cleanup 666 # MENU_QUIT try to quit and clean up mess 667 our $MENU_INSTALL = 0; 668 our $MENU_ABORT = 1; 669 our $MENU_QUIT = 2; 670 $opt_gui = "text" if ($opt_no_gui); 671 # finally do check for additional screens in the $opt_gui setting: 672 # format: 673 # --gui <plugin>:<a1>,<a2>,... 674 # which will passed to run_menu (<a1>, <a2>, ...) 675 # 676 my @runargs; 677 if ($opt_gui =~ m/^([^:]*):(.*)$/) { 678 $opt_gui = $1; 679 @runargs = split ",", $2; 680 } 681 if (-r "$::installerdir/tlpkg/installer/install-menu-${opt_gui}.pl") { 682 require("installer/install-menu-${opt_gui}.pl"); 683 } else { 684 tlwarn("UI plugin $opt_gui not found,\n"); 685 tlwarn("Using text mode installer.\n"); 686 require("installer/install-menu-text.pl"); 687 } 688 689 # before we start the installation we check for the existence of 690 # a previous installation, and in case we ship inform the UI 691 if (!exists $ENV{"TEXLIVE_INSTALL_NO_RESUME"} && $opt_interaction) { 692 my $tlmgrwhich = which("tlmgr"); 693 if ($tlmgrwhich) { 694 my $dn = dirname($tlmgrwhich); 695 $dn = abs_path("$dn/../.."); 696 # The "make Karl happy" case, check that we are not running install-tl 697 # from the same tree where tlmgr is hanging around 698 my $install_tl_root = abs_path($::installerdir); 699 my $tlpdboldpath 700 = $dn . 701 "/$TeXLive::TLConfig::InfraLocation/$TeXLive::TLConfig::DatabaseName"; 702 if (-r $tlpdboldpath && $dn ne $install_tl_root) { 703 debug ("found old installation in $dn\n"); 704 push @runargs, "-old-installation-found=$dn"; 705 # only the text-mode menu will pay attention! 706 } 707 } 708 } 709 710 my $ret = &{$::run_menu}(@runargs); 711 if ($ret == $MENU_QUIT) { 712 do_cleanup(); # log, profile, temp files 713 flushlog(); 714 exit(1); 715 } elsif ($ret == $MENU_ABORT) { 716 # here, omit do_cleanup() 717 flushlog(); 718 exit(2); 719 } 720 if ($ret != $MENU_INSTALL) { 721 tlwarn("Unknown return value of run_menu: $ret\n"); 722 exit(3); 723 } 724 } else { # no interactive setting of options 725 if (!do_remote_init()) { 726 die ("Exiting installation.\n"); 727 } 728 read_profile($opt_profile) if ($opt_profile ne ""); 729 } 730 731 my $varsdump = ""; 732 foreach my $key (sort keys %vars) { 733 my $val = $vars{$key} || ""; 734 $varsdump .= " $key: \"$val\"\n"; 735 } 736 log("Settings:\n" . $varsdump); 737 738 # portable option overrides any system integration options 739 $vars{'instopt_adjustpath'} = 0 if $vars{'instopt_portable'}; 740 $vars{'tlpdbopt_file_assocs'} = 0 if $vars{'instopt_portable'}; 741 $vars{'tlpdbopt_desktop_integration'} = 0 if $vars{'instopt_portable'}; 742 install_warnlines_hook(); # collect warnings in @::WARNLINES 743 info("Installing to: $vars{TEXDIR}\n"); 744 745 if (!$opt_installation) { 746 print STDERR "Not doing installation due to --no-installation, terminating here.\n"; 747 exit 0; 748 } 749 750 $::env_warns = ""; 751 create_welcome(); 752 my $status = 1; 753 if ($opt_gui eq 'text' or $opt_gui eq 'extl' or $opt_profile ne "") { 754 $status = do_installation(); 755 if (@::WARNLINES) { 756 foreach my $t (@::WARNLINES) { print STDERR $t; } 757 } 758 if ($::env_warns) { tlwarn($::env_warns); } 759 unless ($ENV{"TEXLIVE_INSTALL_NO_WELCOME"}) { 760 info(join("\n", @::welcome_arr)); 761 } 762 do_cleanup(); # sets $::LOGFILENAME if not already defined 763 if ($::LOGFILENAME) { 764 print STDOUT "\nLogfile: $::LOGFILENAME\n"; 765 } else { 766 # do_cleanup sets $::LOGFILENAME to "" 767 #if no logfile could be written 768 print STDERR 769 "Cannot create logfile $vars{'TEXDIR'}/install-tl.log: $!\n"; 770 } 771 printf STDOUT "Installed on platform %s at %s\n", 772 $vars{'this_platform'}, $vars{'TEXDIR'} if ($opt_gui eq 'extl'); 773 774 if (@::installation_failed_packages) { 775 print <<EOF; 776 777 *** PLEASE READ THIS WARNING *********************************** 778 779 The following (inessential) packages failed to install properly: 780 781 @::installation_failed_packages 782 783 You can fix this by running this command: 784 tlmgr update --all --reinstall-forcibly-removed 785 to complete the installation. 786 787 However, if the problem was a failure to download (by far the 788 most common cause), check that you can connect to the chosen mirror 789 in a browser; you may need to specify a mirror explicitly. 790 ****************************************************************** 791 792 EOF 793 } 794 } 795 exit $status; 796 797 798 ################################################################### 799 # 800 # FROM HERE ON ONLY SUBROUTINES 801 # NO VARIABLE DECLARATIONS OR CODE 802 # 803 ################################################################### 804 805 # 806 # SETUP OF REMOTE STUFF 807 # 808 # this is now a sub since it is called from the ui plugins on demand 809 # this allows selecting a mirror first and then continuing 810 811 sub only_load_remote { 812 my $selected_location = shift; 813 814 # determine where we will find the distribution to install from. 815 # 816 $location = $opt_location; 817 $location = $selected_location if defined($selected_location); 818 $location || ($location = "$::installerdir"); 819 if ($location =~ m!^(ctan$|(https?|ftp)://)!i) { 820 # remove any trailing tlpkg[/texlive.tlpdb] or / 821 $location =~ s,/(tlpkg(/texlive\.tlpdb)?|archive)?/*$,,; 822 if ($location =~ m/^ctan$/i) { 823 $location = TeXLive::TLUtils::give_ctan_mirror(); 824 } elsif ($location =~ m/^$TeXLiveServerURLRegexp/) { 825 my $mirrorbase = TeXLive::TLUtils::give_ctan_mirror_base(); 826 $location =~ s,^($TeXLiveServerURLRegexp|ctan$),$mirrorbase,; 827 } 828 $TeXLiveURL = $location; 829 $media = 'NET'; 830 } else { 831 if (scalar grep($_ =~ m/^local_compressed/, @media_available)) { 832 $media = 'local_compressed'; 833 # for in_place option we want local_uncompressed media 834 $media = 'local_uncompressed' if $opt_in_place && 835 member('local_uncompressed', @media_available); 836 } elsif (scalar grep($_ =~ m/^local_uncompressed/, @media_available)) { 837 $media = 'local_uncompressed'; 838 } else { 839 if ($opt_location) { 840 # user gave a --location but nothing can be found there, so die 841 die "$0: cannot find installation source at $opt_location.\n"; 842 } 843 # no --location given, but NET installation 844 $TeXLiveURL = $location = TeXLive::TLUtils::give_ctan_mirror(); 845 $media = 'NET'; 846 } 847 } 848 if ($from_ext_gui) {print "location: $location\n";} 849 return load_tlpdb(); 850 } # only_load_remote 851 852 sub do_remote_init { 853 if (!only_load_remote(@_)) { 854 tlwarn("$0: Could not load TeX Live Database from $location, goodbye.\n"); 855 return 0; 856 } 857 if (!do_version_agree()) { 858 TeXLive::TLUtils::tldie <<END_MISMATCH; 859 ============================================================================= 860 $0: The TeX Live versions of the local installation 861 and the repository being accessed are not compatible: 862 local: $TeXLive::TLConfig::ReleaseYear 863 repository: $texlive_release 864 Perhaps you need to use a different CTAN mirror? 865 (For more, see the output of install-tl --help, especially the 866 -repository option. Online via https://tug.org/texlive/doc.) 867 ============================================================================= 868 END_MISMATCH 869 } 870 final_remote_init(); 871 return 1; 872 } # do_remote_init 873 874 sub do_version_agree { 875 $texlive_release = $tlpdb->config_release; 876 if ($media eq "local_uncompressed") { 877 # existing installation may not have 00texlive.config metapackage 878 # so use TLConfig to establish what release we have 879 $texlive_release ||= $TeXLive::TLConfig::ReleaseYear; 880 } 881 882 # if the release from the remote TLPDB does not agree with the 883 # TLConfig::ReleaseYear in the first 4 places break out here. 884 # Why only the first four places: some optional network distributions 885 # might use 886 # release/2009-foobar 887 if ($media eq "NET" 888 && $texlive_release !~ m/^$TeXLive::TLConfig::ReleaseYear/) { 889 return 0; 890 } else { 891 return 1; 892 } 893 } # do_version_agree 894 895 sub final_remote_init { 896 info("Installing TeX Live $TeXLive::TLConfig::ReleaseYear from: $location" . 897 ($tlpdb->is_verified ? " (verified)" : " (not verified)") . "\n"); 898 899 info("Platform: ", platform(), " => \'", platform_desc(platform), "\'\n"); 900 if ($opt_custom_bin) { 901 if (-d $opt_custom_bin && (-r "$opt_custom_bin/kpsewhich" 902 || -r "$opt_custom_bin/kpsewhich.exe")) { 903 info("Platform overridden, binaries taken from $opt_custom_bin\n" 904 . "and will be installed into .../bin/custom.\n"); 905 } else { 906 tldie("$0: -custom-bin argument must be a directory " 907 . "with TeX Live binaries, not like: $opt_custom_bin\n"); 908 } 909 } 910 if ($media eq "local_uncompressed") { 911 info("Distribution: live (uncompressed)\n"); 912 } elsif ($media eq "local_compressed") { 913 info("Distribution: inst (compressed)\n"); 914 } elsif ($media eq "NET") { 915 info("Distribution: net (downloading)\n"); 916 info("Using URL: $TeXLiveURL\n"); 917 TeXLive::TLUtils::setup_persistent_downloads() if $opt_persistent_downloads; 918 } else { 919 info("Distribution: $media\n"); 920 } 921 info("Directory for temporary files: $::tl_tmpdir\n"); 922 923 if ($opt_in_place and ($media ne "local_uncompressed")) { 924 print "TeX Live not local or not decompressed; 'in_place' option not applicable\n"; 925 $opt_in_place = 0; 926 } elsif ( 927 $opt_in_place and (!TeXLive::TLUtils::texdir_check($::installerdir))) { 928 print "Installer dir not writable; 'in_place' option not applicable\n"; 929 $opt_in_place = 0; 930 } 931 $opt_scheme = "" if $opt_in_place; 932 $vars{'instopt_portable'} = $opt_portable; 933 $vars{'instopt_adjustpath'} = 1 if wndws(); 934 935 log("Installer revision: $::installerrevision\n"); 936 log("Database revision: " . $tlpdb->config_revision . "\n"); 937 938 # correctly set the splitting support 939 # for local_uncompressed we always support splitting 940 if (($media eq "NET") || ($media eq "local_compressed")) { 941 $vars{'src_splitting_supported'} = $tlpdb->config_src_container; 942 $vars{'doc_splitting_supported'} = $tlpdb->config_doc_container; 943 } 944 set_platforms_supported(); 945 set_texlive_default_dirs(); 946 set_install_platform(); 947 initialize_collections(); 948 # size information 949 $vars{'free_size'} = TeXLive::TLUtils::diskfree($vars{'TEXDIR'}); 950 951 update_default_scheme(); 952 update_default_paper(); 953 update_default_src_doc_install(); 954 } # final_remote_init 955 956 sub update_default_scheme { 957 # initialize the scheme from the command line value, if given. 958 if ($opt_scheme) { 959 # add the scheme- prefix if they didn't give it. 960 $opt_scheme = "scheme-$opt_scheme" if $opt_scheme !~ /^scheme-/; 961 # 962 # add "only" if they said "infra" (Tired of making this typo, should 963 # have named it "infra" in the first place, but too late.) 964 $opt_scheme .= "only" if $opt_scheme eq "scheme-infra"; 965 # 966 my $scheme = $tlpdb->get_package($opt_scheme); 967 if (defined($scheme)) { 968 select_scheme($opt_scheme); # select it 969 } else { 970 tlwarn("Scheme $opt_scheme not defined, ignoring it.\n"); 971 } 972 } 973 } # update_default_scheme 974 975 sub update_default_paper { 976 # initialize default paper size from the command line or envvar value, 977 # if either is given. 978 my $env_paper = $ENV{"TEXLIVE_INSTALL_PAPER"}; 979 if ($opt_paper) { 980 if (defined $env_paper && $env_paper ne $opt_paper) { 981 tlwarn("$0: paper selected via both envvar TEXLIVE_INSTALL_PAPER and\n"); 982 tlwarn("$0: cmdline arg --paper, preferring the latter: $opt_paper\n"); 983 } 984 if ($opt_paper eq "letter") { $vars{'instopt_letter'} = 1; } 985 elsif ($opt_paper eq "a4") { $vars{'instopt_letter'} = 0; } 986 else { 987 tlwarn("$0: cmdline option --paper value must be letter or a4, not: " 988 . "$opt_paper (ignoring)\n"); 989 } 990 } elsif ($env_paper) { 991 if ($env_paper eq "letter") { $vars{'instopt_letter'} = 1; } 992 elsif ($env_paper eq "a4") { ; } # do nothing 993 else { 994 tlwarn("$0: TEXLIVE_INSTALL_PAPER value must be letter or a4, not: " 995 . "$env_paper (ignoring)\n"); 996 } 997 } 998 } # update_default_paper 999 1000 sub update_default_src_doc_install { 1001 if (! $opt_src_install) { 1002 $vars{'tlpdbopt_install_srcfiles'} = 0; 1003 } 1004 if (! $opt_doc_install) { 1005 $vars{'tlpdbopt_install_docfiles'} = 0; 1006 } 1007 } # update_default_src_doc_install 1008 1009 1010 1011 sub do_installation { 1012 if (wndws()) { 1013 non_admin() if !$vars{'tlpdbopt_w32_multi_user'}; 1014 } 1015 if ($vars{'instopt_portable'}) { 1016 $vars{'tlpdbopt_desktop_integration'} = 0; 1017 $vars{'tlpdbopt_file_assocs'} = 0; 1018 $vars{'instopt_adjustpath'} = 0; 1019 $vars{'tlpdbopt_w32_multi_user'} = 0; 1020 } 1021 if ($vars{'selected_scheme'} ne "scheme-infraonly" 1022 && $vars{'n_collections_selected'} <= 0) { 1023 tldie("$0: Nothing selected, nothing to install, exiting!\n"); 1024 } 1025 # expand ~ in various variables just to be sure 1026 # (but not the user dirs since we want the ~ to stay literal ... must 1027 # think more ... qqq) 1028 for my $v (qw/TEXDIR TEXMFLOCAL TEXMFSYSVAR TEXMFSYSCONFIG/) { 1029 $vars{$v} = TeXLive::TLUtils::expand_tilde($vars{$v}) if ($vars{$v}); 1030 } 1031 # maybe_make_ro tests for admin, local drive and NTFS before proceeding. 1032 # making the root read-only automatically locks everything below it. 1033 # do TEXDIR now, before it loses its final slash 1034 mkdirhier "$vars{'TEXDIR'}"; 1035 if (wndws()) { 1036 TeXLive::TLWinGoo::maybe_make_ro ($vars{'TEXDIR'}); 1037 } 1038 # check for free disk space 1039 my $diskfree = TeXLive::TLUtils::diskfree($vars{'TEXDIR'}); 1040 # -1 is returned if df not available or some other error 1041 if ($diskfree != -1) { 1042 my $reserve = 100; 1043 if ($diskfree < $reserve + $vars{'total_size'}) { 1044 my $msg = "($diskfree free < $reserve reserve " 1045 . "+ installed $vars{total_size})"; 1046 if ($ENV{'TEXLIVE_INSTALL_NO_DISKCHECK'}) { 1047 tlwarn("$0: Insufficient disk space\n$msg\n" 1048 ." but continuing anyway per envvar TEXLIVE_INSTALL_NO_DISKCHECK\n"); 1049 } else { 1050 tldie("$0: DISK SPACE INSUFFICIENT!\n$msg\nAborting installation.\n" 1051 . " To skip the check, set the environment variable\n" 1052 . " TEXLIVE_INSTALL_NO_DISKCHECK=1\n"); 1053 } 1054 } 1055 } 1056 # now remove final slash from TEXDIR even if it is the root of a drive 1057 $vars{'TEXDIR'} =~ s!/$!!; 1058 # do the actual installation 1059 make_var_skeleton "$vars{'TEXMFSYSVAR'}"; 1060 my $oldlocal = -d $vars{'TEXMFLOCAL'}; 1061 make_local_skeleton "$vars{'TEXMFLOCAL'}"; 1062 mkdirhier "$vars{'TEXMFSYSCONFIG'}"; 1063 if (wndws()) { 1064 TeXLive::TLWinGoo::maybe_make_ro ($vars{'TEXMFSYSVAR'}); 1065 TeXLive::TLWinGoo::maybe_make_ro ($vars{'TEXMFLOCAL'}) unless $oldlocal; 1066 TeXLive::TLWinGoo::maybe_make_ro ($vars{'TEXMFSYSCONFIG'}); 1067 } 1068 1069 if ($opt_in_place) { 1070 $localtlpdb = $tlpdb; 1071 } else { 1072 $localtlpdb=new TeXLive::TLPDB; 1073 $localtlpdb->root("$vars{'TEXDIR'}"); 1074 } 1075 if (!$opt_in_place) { 1076 # have to do top-level release-texlive.txt as a special file, so 1077 # tl-update-images can insert the final version number without 1078 # having to remake any packages. But if the source does not exist, 1079 # or the destination already exists, don't worry about it (even 1080 # though these cases should never arise); it's not that important. 1081 # 1082 if (-e "$::installerdir/release-texlive.txt" 1083 && ! -e "$vars{TEXDIR}/release-texlive.txt") { 1084 copy("$::installerdir/release-texlive.txt", "$vars{TEXDIR}/"); 1085 } 1086 # 1087 calc_depends(); 1088 save_options_into_tlpdb(); 1089 # we need to do that dir, since we use the TLPDB->install_package which 1090 # might change into texmf-dist for relocated packages 1091 mkdirhier "$vars{'TEXDIR'}/texmf-dist"; 1092 do_install_packages(); 1093 if ($opt_custom_bin) { 1094 $vars{'this_platform'} = "custom"; 1095 my $TEXDIR="$vars{'TEXDIR'}"; 1096 mkdirhier("$TEXDIR/bin/custom"); 1097 for my $f (<$opt_custom_bin/*>) { 1098 copy($f, "$TEXDIR/bin/custom"); 1099 } 1100 } 1101 } 1102 # now we save every scheme that is fully covered by the stuff we have 1103 # installed to the $localtlpdb 1104 foreach my $s ($tlpdb->schemes) { 1105 my $stlp = $tlpdb->get_package($s); 1106 die ("This cannot happen, $s not defined in tlpdb") if ! defined($stlp); 1107 my $incit = 1; 1108 foreach my $d ($stlp->depends) { 1109 if (!defined($localtlpdb->get_package($d))) { 1110 $incit = 0; 1111 last; 1112 } 1113 } 1114 if ($incit) { 1115 $localtlpdb->add_tlpobj($stlp); 1116 } 1117 } 1118 1119 # include a 00texlive.config package in the new tlpdb, 1120 # so that further installations and updates using the new installation 1121 # as the source can work. Only include the release info, the other 1122 # 00texlive.config entries are not relevant for this case. 1123 my $tlpobj = new TeXLive::TLPOBJ; 1124 $tlpobj->name("00texlive.config"); 1125 my $t = $tlpdb->get_package("00texlive.config"); 1126 $tlpobj->depends("minrelease/" . $tlpdb->config_minrelease, 1127 "release/" . $tlpdb->config_release); 1128 $localtlpdb->add_tlpobj($tlpobj); 1129 1130 $localtlpdb->save unless $opt_in_place; 1131 1132 my $errcount = do_postinst_stuff(); 1133 1134 #tlwarn("!!! Dummy test warning\n"); 1135 #tlwarn("!!! Another test warning\n"); 1136 #$errcount += 2; 1137 1138 # check environment for possibly tex-related strings: 1139 check_env() unless $ENV{"TEXLIVE_INSTALL_ENV_NOCHECK"}; 1140 1141 # We do clean up in the main installation part 1142 # don't do this here because it closes the log file and 1143 # further messages (warnings, welcome) are not logged. 1144 # log, profile, temp files: 1145 # do_cleanup(); 1146 1147 # create_welcome(); already invoked in main program 1148 if (@::WARNLINES) { 1149 unshift @::WARNLINES, ("\nSummary of warnings:\n"); 1150 } 1151 my $status = 0; 1152 if ($errcount > 0) { 1153 $status = 1; 1154 warn "\n$0: errors in installation reported above\n"; 1155 } 1156 1157 return $status; 1158 } # do_installation 1159 1160 sub run_postinst_cmd { 1161 my ($cmd) = @_; 1162 1163 info ("running $cmd ..."); 1164 my ($out,$ret) = TeXLive::TLUtils::run_cmd ("$cmd 2>&1"); 1165 if ($ret == 0) { 1166 info ("done\n"); 1167 } else { 1168 info ("failed\n"); 1169 tlwarn ("$0: $cmd failed (status $ret): $!\n"); 1170 $ret = 1; # be sure we don't overflow the sum on anything crazy 1171 } 1172 log ($out); 1173 1174 return $ret; 1175 } # run_postinst_cmd 1176 1177 1178 # 1179 # Make texmf.cnf, backup directory, cleanups, path setting, and 1180 # (most importantly) post-install subprograms: mktexlsr, fmtutil, 1181 # and more. Return count of errors detected, hopefully zero. 1182 # 1183 sub do_postinst_stuff { 1184 my $TEXDIR = $vars{'TEXDIR'}; 1185 my $TEXMFSYSVAR = $vars{'TEXMFSYSVAR'}; 1186 my $TEXMFSYSCONFIG = $vars{'TEXMFSYSCONFIG'}; 1187 my $TEXMFVAR = $vars{'TEXMFVAR'}; 1188 my $TEXMFCONFIG = $vars{'TEXMFCONFIG'}; 1189 my $TEXMFLOCAL = $vars{'TEXMFLOCAL'}; 1190 my $tmv; 1191 1192 do_texmf_cnf(); 1193 1194 # clean up useless files in texmf-dist/tlpkg as this is only 1195 # created by the relocatable packages 1196 if (-d "$TEXDIR/$TeXLive::TLConfig::RelocTree/tlpkg") { 1197 rmtree("$TEXDIR/TeXLive::TLConfig::RelocTree/tlpkg"); 1198 } 1199 1200 # create package backup directory for tlmgr autobackup to work 1201 mkdirhier("$TEXDIR/$TeXLive::TLConfig::PackageBackupDir"); 1202 1203 # final program execution 1204 # we have to do several things: 1205 # - clean the environment from spurious TEXMF related variables 1206 # - add the bin dir to the PATH 1207 # - select perl interpreter and set the correct perllib 1208 # - run the programs 1209 1210 # Step 1: Clean the environment. 1211 %origenv = %ENV; 1212 my @TMFVARS=qw(VARTEXFONTS 1213 TEXMF SYSTEXMF VARTEXFONTS 1214 TEXMFDBS WEB2C TEXINPUTS TEXFORMATS MFBASES MPMEMS TEXPOOL MFPOOL MPPOOL 1215 PSHEADERS TEXFONTMAPS TEXPSHEADERS TEXCONFIG TEXMFCNF 1216 TEXMFMAIN TEXMFDIST TEXMFLOCAL TEXMFSYSVAR TEXMFSYSCONFIG 1217 TEXMFVAR TEXMFCONFIG TEXMFHOME TEXMFCACHE); 1218 1219 if (defined($ENV{'TEXMFCNF'})) { 1220 tlwarn "WARNING: environment variable TEXMFCNF is set. 1221 You should know what you are doing. 1222 We will unset it for the post-install actions, but all further 1223 operations might be disturbed.\n\n"; 1224 } 1225 foreach $tmv (@TMFVARS) { 1226 delete $ENV{$tmv} if (defined($ENV{$tmv})); 1227 } 1228 1229 # Step 2: Setup the PATH, switch to the new Perl 1230 1231 my $pathsep = (wndws())? ';' : ':'; 1232 my $plat_bindir = "$TEXDIR/bin/$vars{'this_platform'}"; 1233 my $perl_bindir = "$TEXDIR/tlpkg/tlperl/bin"; 1234 my $perl_libdir = "$TEXDIR/tlpkg/tlperl/lib"; 1235 my $progext = (wndws())? '.exe' : ''; 1236 1237 debug("Prepending $plat_bindir to PATH\n"); 1238 $ENV{'PATH'} = $plat_bindir . $pathsep . $ENV{'PATH'}; 1239 1240 if (wndws()) { 1241 debug("Prepending $perl_bindir to PATH\n"); 1242 $ENV{'PATH'} = "$perl_bindir" . "$pathsep" . "$ENV{'PATH'}"; 1243 $ENV{'PATH'} =~ s!/!\\!g; 1244 } 1245 1246 debug("\nNew PATH is:\n"); 1247 foreach my $dir (split $pathsep, $ENV{'PATH'}) { 1248 debug(" $dir\n"); 1249 } 1250 debug("\n"); 1251 if (wndws()) { 1252 $ENV{'PERL5LIB'} = $perl_libdir; 1253 } 1254 1255 # 1256 # post install actions 1257 # 1258 1259 my $usedtlpdb = $opt_in_place ? $tlpdb : $localtlpdb; 1260 1261 if (wndws()) { 1262 debug("Actual environment:\n" . `set` ."\n\n"); 1263 debug("Effective TEXMFCNF: " . `kpsewhich -expand-path=\$TEXMFCNF` ."\n"); 1264 } 1265 1266 # Step 4: run the programs 1267 my $errcount = 0; 1268 1269 if (!$opt_in_place) { 1270 wsystem("running", 'mktexlsr', "$TEXDIR/texmf-dist") && exit(1); 1271 } 1272 1273 # we have to generate the various config file. That could be done with 1274 # texconfig generate * but Windows does not have texconfig. But we have 1275 # $localtlpdb and this is simple code, so do it directly, i.e., duplicate 1276 # the code from the various generate-*.pl scripts 1277 1278 mkdirhier "$TEXDIR/texmf-dist/web2c"; 1279 info("writing fmtutil.cnf to $TEXDIR/texmf-dist/web2c/fmtutil.cnf\n"); 1280 TeXLive::TLUtils::create_fmtutil($usedtlpdb, 1281 "$TEXDIR/texmf-dist/web2c/fmtutil.cnf"); 1282 1283 # warn if fmtutil-local.cnf is present 1284 if (-r "$TEXMFLOCAL/web2c/fmtutil-local.cnf") { 1285 tlwarn("Old configuration file $TEXMFLOCAL/web2c/fmtutil-local.cnf found.\n"); 1286 tlwarn("fmtutil now reads *all* fmtutil.cnf files, so probably the easiest way\nis to rename the above file to $TEXMFLOCAL/web2c/fmtutil.cnf\n"); 1287 } 1288 1289 info("writing updmap.cfg to $TEXDIR/texmf-dist/web2c/updmap.cfg\n"); 1290 TeXLive::TLUtils::create_updmap ($usedtlpdb, 1291 "$TEXDIR/texmf-dist/web2c/updmap.cfg"); 1292 1293 info("writing language.dat to $TEXMFSYSVAR/tex/generic/config/language.dat\n"); 1294 TeXLive::TLUtils::create_language_dat($usedtlpdb, 1295 "$TEXMFSYSVAR/tex/generic/config/language.dat", 1296 "$TEXMFLOCAL/tex/generic/config/language-local.dat"); 1297 1298 info("writing language.def to $TEXMFSYSVAR/tex/generic/config/language.def\n"); 1299 TeXLive::TLUtils::create_language_def($usedtlpdb, 1300 "$TEXMFSYSVAR/tex/generic/config/language.def", 1301 "$TEXMFLOCAL/tex/generic/config/language-local.def"); 1302 1303 info("writing language.dat.lua to $TEXMFSYSVAR/tex/generic/config/language.dat.lua\n"); 1304 TeXLive::TLUtils::create_language_lua($usedtlpdb, 1305 "$TEXMFSYSVAR/tex/generic/config/language.dat.lua", 1306 "$TEXMFLOCAL/tex/generic/config/language-local.dat.lua"); 1307 1308 wsystem("running", "mktexlsr", 1309 $TEXMFSYSVAR, $TEXMFSYSCONFIG, "$TEXDIR/texmf-dist") 1310 && exit(1); 1311 1312 if (-x "$plat_bindir/updmap-sys$progext") { 1313 $errcount += run_postinst_cmd("updmap-sys --nohash"); 1314 } else { 1315 info("not running updmap-sys (not installed)\n"); 1316 } 1317 1318 # now work through the options if specified at all 1319 1320 # letter instead of a4 1321 if ($vars{'instopt_letter'}) { 1322 # set paper size, but do not execute any post actions, which in this 1323 # case would be mktexlsr and fmtutil-sys -all; clearly premature 1324 # here at this point in the installer. 1325 info("setting default paper size to letter:\n"); 1326 $errcount += run_postinst_cmd("tlmgr --no-execute-actions paper letter"); 1327 } 1328 1329 # option settings in launcher.ini 1330 if (wndws() && !$vars{'instopt_portable'}) { 1331 if ($vars{'tlpdbopt_file_assocs'} != 1 || !$vars{'instopt_adjustpath'}) { 1332 # create higher priority tlaunch.ini with adjusted settings 1333 # whether or not launcher mode (desktop integration 2) 1334 # was selected 1335 rewrite_tlaunch_ini(); 1336 } 1337 } 1338 1339 # now rerun mktexlsr for updmap-sys and tlmgr paper letter updates. 1340 wsystem("re-running", "mktexlsr", $TEXMFSYSVAR, $TEXMFSYSCONFIG) && exit(1); 1341 1342 if (wndws() and !$vars{'instopt_portable'} and !$opt_in_place) { 1343 if ($vars{'tlpdbopt_desktop_integration'} != 2) { 1344 create_uninstaller($vars{'TEXDIR'}); 1345 } else { 1346 $errcount += wsystem ( 1347 'Running','tlaunch.exe', 1348 admin() ? 'admin_inst_silent' : 'user_inst_silent'); 1349 } 1350 } 1351 1352 # lmtx/context setup. The story here is that in 2023, the lmtx binary 1353 # for x86_64-linux was too new to run on the system where we build TL. 1354 # (luametatex: /lib64/libm.so.6: version `GLIBC_2.23' not found) 1355 # So we have to try running it to see it succeeds, not just test for 1356 # the program's existence. And since it exits nonzero given no args, 1357 # we have to specify --version. Hope it keeps working like that ... 1358 my $lmtx = "$plat_bindir/luametatex$progext"; 1359 if (exists($install{"context"}) && $install{"context"} == 1 1360 && !exists $ENV{"TEXLIVE_INSTALL_NO_CONTEXT_CACHE"} 1361 && TeXLive::TLUtils::system_ok("$lmtx --version") 1362 ) { 1363 info("setting up ConTeXt cache: "); 1364 $errcount += run_postinst_cmd("mtxrun --generate"); 1365 $errcount += run_postinst_cmd("context --luatex --generate"); 1366 } else { 1367 debug("skipped ConTeXt cache setup\n"); 1368 } 1369 1370 # all formats option 1371 if ($vars{'tlpdbopt_create_formats'}) { 1372 if (-x "$plat_bindir/fmtutil-sys$progext") { 1373 info("pre-generating all format files, be patient...\n"); 1374 $errcount += run_postinst_cmd( 1375 "fmtutil-sys $common_fmtutil_args --no-strict --all"); 1376 } else { 1377 info("not running fmtutil-sys (script not installed)\n"); 1378 } 1379 } else { 1380 info("not running fmtutil-sys (user option create_formats=0)\n"); 1381 } 1382 1383 # do path adjustments: On Windows add/remove to PATH etc, 1384 # on Unix set symlinks 1385 # for portable, this option should be unset 1386 # it should not be necessary to test separately for portable 1387 $errcount += do_path_adjustments() if 1388 $vars{'instopt_adjustpath'} and $vars{'tlpdbopt_desktop_integration'} != 2; 1389 1390 # now do the system integration: 1391 # on unix this means setting up symlinks 1392 # on w32 this means settting registry values 1393 # on both, we run the postaction directives of the tlpdb 1394 # no need to test for portable or in_place: 1395 # the menus (or profile?) should have set the required options 1396 $errcount += do_tlpdb_postactions(); 1397 1398 return $errcount; 1399 } # do_postinst_stuff 1400 1401 1402 # Run the post installation code in the postaction tlpsrc entries. 1403 # Return number of errors found, or zero. 1404 1405 sub do_tlpdb_postactions { 1406 info ("running package-specific postactions\n"); 1407 1408 # option settings already reflect portable- and in_place options. 1409 my $usedtlpdb = $opt_in_place ? $tlpdb : $localtlpdb; 1410 my $ret = 0; # n. of errors 1411 1412 foreach my $package ($usedtlpdb->list_packages) { 1413 # !!! alert: parameter 4 is menu shortcuts, parameter 5 does nothing !!! 1414 if ($vars{'tlpdbopt_desktop_integration'}==2) { 1415 # skip creation of shortcuts and file associations 1416 if (!TeXLive::TLUtils::do_postaction( 1417 "install", $usedtlpdb->get_package($package), 1418 0, 0, 0, $vars{'tlpdbopt_post_code'})) { $ret += 1; } 1419 } else { 1420 # create shortcuts and file associations 1421 # according to corresponding options 1422 if (!TeXLive::TLUtils::do_postaction( 1423 "install", $usedtlpdb->get_package($package), 1424 $vars{'tlpdbopt_file_assocs'}, 1425 $vars{'tlpdbopt_desktop_integration'}, 0, 1426 $vars{'tlpdbopt_post_code'})) { $ret += 1; } 1427 } 1428 } 1429 # windows: alert the system about changed file associations 1430 if (wndws()) { TeXLive::TLWinGoo::update_assocs(); } 1431 info ("finished with package-specific postactions\n"); 1432 return $ret; 1433 } # do_tlpdb_postactions 1434 1435 sub rewrite_tlaunch_ini { 1436 # create a higher-priority copy of tlaunch.ini in TEXMFSYSVAR 1437 # with appropriate settings in the General section 1438 my $ret = 0; # n. of errors 1439 1440 chomp( my $tmfmain = `kpsewhich -var-value=TEXMFMAIN` ) ; 1441 chomp( my $tmfsysvar = `kpsewhich -var-value=TEXMFSYSVAR` ) ; 1442 if (open IN, "$tmfmain/web2c/tlaunch.ini") { 1443 my $eolsave = $/; 1444 undef $/; 1445 my $ini = <IN>; 1446 close IN; 1447 # remove general section, if any 1448 $ini =~ s/\r\n/\n/g; 1449 $ini =~ s/\[general[^\[]*//si; 1450 mkdirhier("$tmfsysvar/web2c"); 1451 if (open OUT, ">", "$tmfsysvar/web2c/tlaunch.ini") { 1452 my @fts = ('none', 'new', 'overwrite'); 1453 $\ = "\n"; 1454 print OUT $ini; 1455 print OUT "[General]"; 1456 print OUT "FILETYPES=$fts[$vars{'tlpdbopt_file_assocs'}]"; 1457 print OUT "SEARCHPATH=$vars{'instopt_adjustpath'}\n"; 1458 close OUT; 1459 `mktexlsr $tmfsysvar`; 1460 } else { 1461 $ret += 1; 1462 tlwarn("Cannot write modified tlaunch.ini\n"); 1463 } 1464 $/ = $eolsave; 1465 } else { 1466 $ret += 1; 1467 tlwarn("Cannot open tlaunch.ini for reading\n"); 1468 } 1469 return $ret; 1470 } # rewrite_tlaunch_ini 1471 1472 sub do_path_adjustments { 1473 my $ret = 0; 1474 info ("running path adjustment actions\n"); 1475 if (wndws()) { 1476 TeXLive::TLUtils::w32_add_to_path($vars{'TEXDIR'} . '/bin/windows', 1477 $vars{'tlpdbopt_w32_multi_user'}); 1478 broadcast_env(); 1479 } else { 1480 if ($F_OK != TeXLive::TLUtils::add_symlinks($vars{'TEXDIR'}, 1481 $vars{'this_platform'}, 1482 $vars{'tlpdbopt_sys_bin'}, $vars{'tlpdbopt_sys_man'}, 1483 $vars{'tlpdbopt_sys_info'})) { 1484 $ret = 1; 1485 } 1486 } 1487 info ("finished with path adjustment actions\n"); 1488 return $ret; 1489 } # do_path_adjustments 1490 1491 # we have to adjust the texmf.cnf file to the paths set in the configuration! 1492 sub do_texmf_cnf { 1493 open(TMF,"<$vars{'TEXDIR'}/texmf-dist/web2c/texmf.cnf") 1494 or die "$vars{'TEXDIR'}/texmf-dist/web2c/texmf.cnf not found: $!"; 1495 my @texmfcnflines = <TMF>; 1496 close(TMF); 1497 1498 my @changedtmf = (); # install to disk: write only changed items 1499 1500 my $yyyy = $TeXLive::TLConfig::ReleaseYear; 1501 1502 # we have to find TEXMFLOCAL TEXMFSYSVAR and TEXMFHOME 1503 # at this point, a final slash of $vars{TEXDIR} itself has already 1504 # been removed. 1505 foreach my $line (@texmfcnflines) { 1506 if ($line =~ m/^TEXMFLOCAL\b/) { # don't find TEXMFLOCALEDIR 1507 # by default TEXMFLOCAL = TEXDIR/../texmf-local, if this is the case 1508 # we don't have to write a new setting. 1509 my $deftmflocal = Cwd::abs_path($vars{'TEXDIR'}.'/../texmf-local'); 1510 if (!defined $deftmflocal # in case abs_path couldn't resolve 1511 || Cwd::abs_path($vars{TEXMFLOCAL}) ne "$deftmflocal") { 1512 push @changedtmf, "TEXMFLOCAL = $vars{'TEXMFLOCAL'}\n"; 1513 } 1514 } elsif ($line =~ m/^TEXMFSYSVAR/) { 1515 if ("$vars{'TEXMFSYSVAR'}" ne "$vars{'TEXDIR'}/texmf-var") { 1516 push @changedtmf, "TEXMFSYSVAR = $vars{'TEXMFSYSVAR'}\n"; 1517 } 1518 } elsif ($line =~ m/^TEXMFSYSCONFIG/) { 1519 if ("$vars{'TEXMFSYSCONFIG'}" ne "$vars{'TEXDIR'}/texmf-config") { 1520 push @changedtmf, "TEXMFSYSCONFIG = $vars{'TEXMFSYSCONFIG'}\n"; 1521 } 1522 } elsif ($line =~ m/^TEXMFVAR/ && !$vars{'instopt_portable'}) { 1523 if ($vars{"TEXMFVAR"} ne "~/.texlive$yyyy/texmf-var") { 1524 push @changedtmf, "TEXMFVAR = $vars{'TEXMFVAR'}\n"; 1525 } 1526 } elsif ($line =~ m/^TEXMFCONFIG/ && !$vars{'instopt_portable'}) { 1527 if ("$vars{'TEXMFCONFIG'}" ne "~/.texlive$yyyy/texmf-config") { 1528 push @changedtmf, "TEXMFCONFIG = $vars{'TEXMFCONFIG'}\n"; 1529 } 1530 } elsif ($line =~ m/^TEXMFHOME/ && !$vars{'instopt_portable'}) { 1531 if ("$vars{'TEXMFHOME'}" ne "~/texmf") { 1532 push @changedtmf, "TEXMFHOME = $vars{'TEXMFHOME'}\n"; 1533 } 1534 } elsif ($line =~ m/^OSFONTDIR/) { 1535 if (wndws()) { 1536 push @changedtmf, "OSFONTDIR = \$SystemRoot/fonts//;\$LOCALAPPDATA/Microsoft/Windows/Fonts//\n"; 1537 } 1538 } 1539 } 1540 1541 if ($vars{'instopt_portable'}) { 1542 push @changedtmf, "ASYMPTOTE_HOME = \$TEXMFCONFIG/asymptote\n"; 1543 } 1544 1545 my ($TMF, $TMFLUA); 1546 # we want to write only changes to texmf.cnf 1547 # even for in_place installation 1548 $TMF = ">$vars{'TEXDIR'}/texmf.cnf"; 1549 open(TMF, $TMF) || die "open($TMF) failed: $!"; 1550 print TMF <<EOF; 1551 % (Public domain.) 1552 % This texmf.cnf file should contain only your personal changes from the 1553 % original texmf.cnf (for example, as chosen in the installer). 1554 % 1555 % That is, if you need to make changes to texmf.cnf, put your custom 1556 % settings in this file, which is .../texlive/YYYY/texmf.cnf, rather than 1557 % the distributed file (which is .../texlive/YYYY/texmf-dist/web2c/texmf.cnf). 1558 % And include *only* your changed values, not a copy of the whole thing! 1559 % 1560 EOF 1561 foreach (@changedtmf) { 1562 # avoid absolute paths for TEXDIR, use $SELFAUTOPARENT instead 1563 s/^(TEXMF\w+\s*=\s*)\Q$vars{'TEXDIR'}\E/$1\$SELFAUTOPARENT/; 1564 print TMF; 1565 } 1566 if ($vars{'instopt_portable'}) { 1567 print TMF "TEXMFHOME = \$TEXMFLOCAL\n"; 1568 print TMF "TEXMFVAR = \$TEXMFSYSVAR\n"; 1569 print TMF "TEXMFCONFIG = \$TEXMFSYSCONFIG\n"; 1570 } 1571 # 1572 # save the setting of shell_escape to the generated system texmf.cnf 1573 # default in texmf-dist/web2c/texmf.cnf is 1574 # shell_escape = p 1575 # so we write that only if the user *deselected* this option 1576 if (!$vars{"instopt_write18_restricted"}) { 1577 print TMF <<EOF; 1578 1579 % Disable system commands via \\write18{...}. See texmf-dist/web2c/texmf.cnf. 1580 shell_escape = 0 1581 EOF 1582 ; 1583 } 1584 1585 # external perl for third-party scripts? 1586 # the wrapper batchfile has set the environment variable extperl 1587 # to its version if available and 0 otherwise. 1588 if (wndws()) { 1589 my $use_ext = 0; 1590 if (!$vars{'instopt_portable'} && 1591 defined $ENV{'extperl'} && $ENV{'extperl'} =~ /^(\d+\.\d+)/) { 1592 $use_ext = 1 if $1 >= 5.14; 1593 } 1594 print TMF <<EOF; 1595 1596 % Prefer external Perl for third-party TeXLive Perl scripts 1597 % Was set to 1 if at install time a sufficiently recent Perl was detected. 1598 EOF 1599 ; 1600 print TMF "TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL = " . $use_ext; 1601 log("Configuring for using external perl for third-party scripts\n") 1602 } 1603 1604 close(TMF) || warn "close($TMF) failed: $!"; 1605 1606 $TMFLUA = ">$vars{'TEXDIR'}/texmfcnf.lua"; 1607 open(TMFLUA, $TMFLUA) || die "open($TMFLUA) failed: $!"; 1608 print TMFLUA <<EOF; 1609 -- (Public domain.) 1610 -- This texmfcnf.lua file should contain only your personal changes from the 1611 -- original texmfcnf.lua (for example, as chosen in the installer). 1612 -- 1613 -- That is, if you need to make changes to texmfcnf.lua, put your custom 1614 -- settings in this file, which is .../texlive/YYYY/texmfcnf.lua, rather than 1615 -- the distributed file (.../texlive/YYYY/texmf-dist/web2c/texmfcnf.lua). 1616 -- And include *only* your changed values, not a copy of the whole thing! 1617 1618 return { 1619 content = { 1620 variables = { 1621 EOF 1622 ; 1623 foreach (@changedtmf) { 1624 my $luavalue = $_; 1625 $luavalue =~ s/^(\w+\s*=\s*)(.*)\s*$/$1\"$2\",/; 1626 $luavalue =~ s/\$SELFAUTOPARENT/selfautoparent:/g; 1627 print TMFLUA " $luavalue\n"; 1628 } 1629 if ($vars{'instopt_portable'}) { 1630 print TMFLUA " TEXMFHOME = \"\$TEXMFLOCAL\",\n"; 1631 print TMFLUA " TEXMFVAR = \"\$TEXMFSYSVAR\",\n"; 1632 print TMFLUA " TEXMFCONFIG = \"\$TEXMFSYSCONFIG\",\n"; 1633 } 1634 print TMFLUA " },\n"; 1635 print TMFLUA " },\n"; 1636 if (!$vars{"instopt_write18_restricted"}) { 1637 print TMFLUA <<EOF; 1638 directives = { 1639 -- Disable system commands. See texmf-dist/web2c/texmfcnf.lua 1640 ["system.commandmode"] = "none", 1641 }, 1642 EOF 1643 ; 1644 } 1645 print TMFLUA "}\n"; 1646 close(TMFLUA) || warn "close($TMFLUA) failed: $!"; 1647 } # do_texmf_cnf 1648 1649 # Determine which platforms are supported. 1650 sub set_platforms_supported { 1651 my @binaries = $tlpdb->available_architectures; 1652 for my $binary (@binaries) { 1653 unless (defined $vars{"binary_$binary"}) { 1654 $vars{"binary_$binary"}=0; 1655 } 1656 } 1657 for my $key (keys %vars) { 1658 ++$vars{'n_systems_available'} if ($key=~/^binary/); 1659 } 1660 } # set_platforms_supported 1661 1662 sub dump_vars { 1663 my $filename=shift; 1664 my $fh; 1665 if (ref($filename)) { 1666 $fh = $filename; 1667 } else { 1668 open VARS, ">$filename"; 1669 $fh = \*VARS; 1670 } 1671 foreach my $key (keys %vars) { 1672 print $fh "$key $vars{$key}\n"; 1673 } 1674 close VARS if (!ref($filename)); 1675 debug("\n%vars dumped to '$filename'.\n"); 1676 } # dump_vars 1677 1678 1679 # Environment variables and default values on UNIX: 1680 # TEXLIVE_INSTALL_PREFIX /usr/local/texlive => $tex_prefix 1681 # $tex_prefix/2010 => $TEXDIR 1682 # TEXLIVE_INSTALL_TEXMFSYSVAR $TEXDIR/texmf-var 1683 # TEXLIVE_INSTALL_TEXMFSYSCONFIG $TEXDIR/texmf-config 1684 # TEXLIVE_INSTALL_TEXMFLOCAL $tex_prefix/texmf-local 1685 # TEXLIVE_INSTALL_TEXMFHOME '$HOME/texmf' 1686 # TEXLIVE_INSTALL_TEXMFVAR ~/.texlive2010/texmf-var 1687 # TEXLIVE_INSTALL_TEXMFCONFIG ~/.texlive2010/texmf-config 1688 1689 sub set_var_from_alternatives { 1690 my ($what, $whatref, @alternatives) = @_; 1691 my @alt_text; 1692 for my $i (@alternatives) { 1693 push @alt_text, ($i ? $i : "undef") 1694 } 1695 my $final; 1696 while (@alternatives) { 1697 my $el = pop @alternatives; 1698 $final = $el if ($el); 1699 } 1700 debug("setting $what to $final from @alt_text\n"); 1701 $$whatref = $final; 1702 } 1703 1704 sub set_standard_var { 1705 my ($what, $envstr, $cmdlinestr, $default) = @_; 1706 # warn if a value was set from both the profile and 1707 # via env var 1708 my $envvar = getenv($envstr); 1709 my $cmdlinevar = $pathopts{$cmdlinestr}; 1710 my %nrdefs; 1711 $nrdefs{$vars{$what}} = 1 if ($vars{$what}); 1712 $nrdefs{$envvar} = 1 if ($envvar); 1713 $nrdefs{$cmdlinevar} = 1 if ($cmdlinevar); 1714 # texmfhome/texmfvar/texmfconfig have actually been set by 1715 # via $opt_texuserdir/.... 1716 # So warn about this 1717 my $actual_cmdline_str = $cmdlinestr; 1718 my $actual_cmdline_var = $cmdlinevar; 1719 if ($opt_texuserdir) { 1720 if ($cmdlinestr eq "texmfhome" || $cmdlinestr eq "texmfvar" || $cmdlinestr eq "texmfconfig") { 1721 $actual_cmdline_str = "opt_texuserdir"; 1722 $actual_cmdline_var = $opt_texuserdir; 1723 } 1724 } 1725 if (scalar keys %nrdefs > 1) { 1726 # multiple conflicting definitions, fail! 1727 tlwarn("Trying to define $what via conflicting settings:\n"); 1728 tlwarn(" from envvar $envstr = $envvar\n") if ($envvar); 1729 tlwarn(" from profile = $vars{$what}\n") if ($vars{$what}); 1730 tlwarn(" from command line argument $actual_cmdline_str = $actual_cmdline_var\n") if ($actual_cmdline_var); 1731 tlwarn(" Preferring the last value from above!\n"); 1732 # actual preference order is given via the below call 1733 } 1734 # default for most variables, in increasing priority 1735 # - some default 1736 # - environment variable 1737 # - setting from profile saved already in $vars{$what} 1738 # - command line 1739 set_var_from_alternatives( $what, \$vars{$what}, 1740 $cmdlinevar, 1741 $vars{$what}, 1742 $envvar, 1743 $default); 1744 } 1745 1746 sub set_texlive_default_dirs { 1747 my $homedir = (platform() =~ m/darwin/) ? "~/Library" : "~"; 1748 my $yyyy = $TeXLive::TLConfig::ReleaseYear; 1749 # 1750 # If the --texuserdir is given, assign values to texmfhome/var/config 1751 # unless the separate cmd line options are also present. 1752 if ($opt_texuserdir) { 1753 $pathopts{'texmfhome'} = "$opt_texuserdir/texmf" if (!$pathopts{'texmfhome'}); 1754 $pathopts{'texmfvar'} = "$opt_texuserdir/texmf-var" if (!$pathopts{'texmfvar'}); 1755 $pathopts{'texmfconfig'} = "$opt_texuserdir/texmf-config" if (!$pathopts{'texmfconfig'}); 1756 } 1757 # 1758 # Sources of target directory settings in priority order: 1759 # - env variable TEXLIVE_INSTALL_PREFIX 1760 # will be used with YYYY (in portable case without) 1761 # - --texdir cmd line option 1762 # will be used as is, similar to profile setting 1763 # - profile setting 1764 # 1765 # first compare whether profile setting and cmd line agree if both given 1766 if ($opt_texdir && $vars{'TEXDIR'}) { 1767 if ($opt_texdir ne $vars{'TEXDIR'}) { 1768 tlwarn("Conflicting settings for installation path given:\n"); 1769 tlwarn(" from profile TEXDIR = $vars{'TEXDIR'}\n"); 1770 tlwarn(" from command line option --texdir = $opt_texdir\n"); 1771 tlwarn(" Preferring the command line value!\n"); 1772 # actual setting of preference is done below in the 1773 # set_var_from_alternatives( \$vars{'TEXDIR'}, 1774 # call, where the order determines the preference! 1775 } 1776 } 1777 my $tlprefixenv = getenv('TEXLIVE_INSTALL_PREFIX'); 1778 if ($tlprefixenv && ($opt_texdir || $vars{'TEXDIR'})) { 1779 # NOTE we cannot compare these two values because the one might 1780 # contain the YYYY part (TEXDIR) while the other is the one without. 1781 tlwarn("Trying to set up basic path using two incompatible methods:\n"); 1782 tlwarn(" from envvar TEXLIVE_INSTALL_PREFIX = $tlprefixenv\n"); 1783 tlwarn(" from profile TEXDIR = $vars{'TEXDIR'}\n") if ($vars{'TEXDIR'}); 1784 tlwarn(" from command line option --texdir = $opt_texdir\n") if ($opt_texdir); 1785 tlwarn(" Preferring the later value!\n"); 1786 $tlprefixenv = undef; 1787 } 1788 # first set $tex_prefix 1789 my $tex_prefix; 1790 set_var_from_alternatives("TEX_PREFIX", \$tex_prefix, 1791 ($opt_in_place ? abs_path($::installerdir) : undef), 1792 $tlprefixenv, 1793 (wndws() ? getenv('SystemDrive') . '/texlive' : '/usr/local/texlive')); 1794 # 1795 set_var_from_alternatives("TEXDIR", \$vars{'TEXDIR'}, 1796 $opt_texdir, 1797 $vars{'TEXDIR'}, 1798 ($vars{'instopt_portable'} || $opt_in_place) 1799 ? $tex_prefix : "$tex_prefix/$texlive_release"); 1800 # 1801 set_standard_var('TEXMFSYSVAR', 'TEXLIVE_INSTALL_TEXMFSYSVAR', 1802 'texmfsysvar', "$vars{'TEXDIR'}/texmf-var"); 1803 # 1804 set_standard_var('TEXMFSYSCONFIG', 'TEXLIVE_INSTALL_TEXMFSYSCONFIG', 1805 'texmfsysconfig', "$vars{'TEXDIR'}/texmf-config"); 1806 # 1807 # TEXMFLOCAL is special because the default in texmf.cnf 1808 # TEXMFLOCAL = $SELFAUTOGRANDPARENT/texmf-local 1809 # that is 1810 # ..../texlive/texmf-local 1811 # 1812 set_standard_var('TEXMFLOCAL', 'TEXLIVE_INSTALL_TEXMFLOCAL', 1813 'texmflocal', ($opt_texdir ? "$vars{'TEXDIR'}/texmf-local" :"$tex_prefix/texmf-local")); 1814 # 1815 set_standard_var('TEXMFHOME', 'TEXLIVE_INSTALL_TEXMFHOME', 1816 'texmfhome', "$homedir/texmf"); 1817 # 1818 set_standard_var('TEXMFVAR', 'TEXLIVE_INSTALL_TEXMFVAR', 'texmfvar', 1819 (platform() =~ m/darwin/) ? "$homedir/texlive/$yyyy/texmf-var" 1820 : "$homedir/.texlive$yyyy/texmf-var"); 1821 # 1822 set_standard_var('TEXMFCONFIG', 'TEXLIVE_INSTALL_TEXMFCONFIG', 'texmfconfig', 1823 (platform() =~ m/darwin/) ? "$homedir/texlive/$yyyy/texmf-config" 1824 : "$homedir/.texlive$yyyy/texmf-config"); 1825 1826 # for portable installation we want everything in one directory 1827 if ($vars{'instopt_portable'}) { 1828 $vars{'TEXMFHOME'} = "\$TEXMFLOCAL"; 1829 $vars{'TEXMFVAR'} = "\$TEXMFSYSVAR"; 1830 $vars{'TEXMFCONFIG'} = "\$TEXMFSYSCONFIG"; 1831 } 1832 1833 if ($opt_debug_setup_vars) { 1834 print "DV:final values from setup of paths:\n"; 1835 for my $i (qw/TEXDIR TEXMFSYSVAR TEXMFSYSCONFIG TEXMFHOME TEXMFVAR 1836 TEXMFCONFIG TEXMFLOCAL/) { 1837 print "$i = $vars{$i}\n"; 1838 } 1839 } 1840 } # set_texlive_default_dirs 1841 1842 1843 sub calc_depends { 1844 # we have to reset the install hash EVERY TIME otherwise everything will 1845 # always be installed since the default is scheme-full which selects 1846 # all packages and never deselects. 1847 %install=(); 1848 my $p; 1849 my $a; 1850 1851 # initialize the %install hash with what should be installed 1852 1853 if ($vars{'selected_scheme'} ne "scheme-custom") { 1854 # First look for packages in the selected scheme. 1855 my $scheme=$tlpdb->get_package($vars{'selected_scheme'}); 1856 if (!defined($scheme)) { 1857 if ($vars{'selected_scheme'}) { 1858 # something is written in the selected scheme but not defined, that 1859 # is strange, so warn and die 1860 die ("Scheme $vars{'selected_scheme'} not defined, vars:\n"); 1861 dump_vars(\*STDOUT); 1862 } 1863 } else { 1864 for my $scheme_content ($scheme->depends) { 1865 $install{"$scheme_content"}=1 unless $scheme_content =~ /^collection-/; 1866 } 1867 } 1868 } 1869 1870 # Now look for collections in the %vars hash. These are not 1871 # necessarily the collections required by a scheme. The final 1872 # decision is made in the collections/languages menu. 1873 foreach my $key (keys %vars) { 1874 if ($key=~/^collection-/) { 1875 $install{$key} = 1 if $vars{$key}; 1876 } 1877 } 1878 1879 # compute the list of archs to be installed 1880 my @archs; 1881 foreach (keys %vars) { 1882 if (m/^binary_(.*)$/ ) { 1883 if ($vars{$_}) { push @archs, $1; } 1884 } 1885 } 1886 1887 # 1888 # ensure that packages listed in InstallExtraRequiredPackages are installed 1889 for my $p (@TeXLive::TLConfig::InstallExtraRequiredPackages) { 1890 $install{$p} = 1; 1891 } 1892 1893 # if programs for arch=windows are installed we also have to install 1894 # tlperl.windows which provides the "hidden" perl that will be used 1895 # to run all the perl scripts. 1896 # Furthermore we install tlgs.windows 1897 if (grep(/^windows$/,@archs)) { 1898 $install{"tlperl.windows"} = 1; 1899 $install{"tlgs.windows"} = 1; 1900 # tlpsv is gone 1901 } 1902 1903 # loop over all the packages until it is getting stable 1904 my $changed = 1; 1905 while ($changed) { 1906 # set $changed to 0 1907 $changed = 0; 1908 1909 # collect the already selected packages 1910 my @pre_selected = keys %install; 1911 debug("calc_depends: number of packages to install: $#pre_selected\n"); 1912 1913 # loop over all the pre_selected and add them 1914 foreach $p (@pre_selected) { 1915 ddebug("pre_selected $p\n"); 1916 my $pkg = $tlpdb->get_package($p); 1917 if (!defined($pkg)) { 1918 tlwarn("$p is mentioned somewhere but not available, disabling it.\n"); 1919 $install{$p} = 0; 1920 next; 1921 } 1922 foreach my $p_dep ($tlpdb->get_package($p)->depends) { 1923 if ($p_dep =~ m/^(.*)\.ARCH$/) { 1924 my $foo = "$1"; 1925 foreach $a (@archs) { 1926 $install{"$foo.$a"} = 1 if defined($tlpdb->get_package("$foo.$a")); 1927 } 1928 } elsif ($p_dep =~ m/^(.*)\.windows$/) { 1929 # a windows package should *only* be installed if we are installing 1930 # the windows arch 1931 if (grep(/^windows$/,@archs)) { 1932 $install{$p_dep} = 1; 1933 } 1934 } else { 1935 $install{$p_dep} = 1; 1936 } 1937 } 1938 } 1939 1940 # check for newly selected packages 1941 my @post_selected = keys %install; 1942 debug("calc_depends: after resolution, #packages: $#post_selected\n"); 1943 1944 # set repeat condition 1945 if ($#pre_selected != $#post_selected) { 1946 $changed = 1; 1947 } 1948 } 1949 1950 # after loop, now do the size computation. 1951 my $size = 0; 1952 foreach $p (keys %install) { 1953 my $tlpobj = $tlpdb->get_package($p); 1954 if (not(defined($tlpobj))) { 1955 tlwarn("$p should be installed but " 1956 . "is not in texlive.tlpdb; disabling.\n"); 1957 $install{$p} = 0; 1958 next; 1959 } 1960 $size+=$tlpobj->docsize if $vars{'tlpdbopt_install_docfiles'}; 1961 $size+=$tlpobj->srcsize if $vars{'tlpdbopt_install_srcfiles'}; 1962 $size+=$tlpobj->runsize; 1963 foreach $a (@archs) { 1964 $size += $tlpobj->binsize->{$a} if defined($tlpobj->binsize->{$a}); 1965 } 1966 } 1967 $vars{'total_size'} = 1968 sprintf "%d", ($size * $TeXLive::TLConfig::BlockSize)/1024**2; 1969 } # calc_depends 1970 1971 sub load_tlpdb { 1972 my $master = $location; 1973 info("Loading $master/$TeXLive::TLConfig::InfraLocation/$TeXLive::TLConfig::DatabaseName\n"); 1974 $tlpdb = TeXLive::TLPDB->new( 1975 root => $master, 'verify' => $opt_verify_downloads); 1976 if (!defined($tlpdb)) { 1977 my $do_die = 1; 1978 # if that failed, and: 1979 # - we are installing from the network 1980 # - the location string does not contain "tlnet" 1981 # then we simply add "/systems/texlive/tlnet" in case someone just 1982 # gave an arbitrary CTAN mirror address without the full path 1983 if ($media eq "NET" && $location !~ m/tlnet/) { 1984 tlwarn("First attempt for net installation failed;\n"); 1985 tlwarn(" repository url does not contain \"tlnet\",\n"); 1986 tlwarn(" retrying with \"/systems/texlive/tlnet\" appended.\n"); 1987 $location .= "/systems/texlive/tlnet"; 1988 $master = $location; 1989 # 1990 # since we change location, we reset the error count of the 1991 # download object 1992 $::tldownload_server->enable if defined($::tldownload_server); 1993 # 1994 $tlpdb = TeXLive::TLPDB->new( 1995 root => $master, 'verify' => $opt_verify_downloads); 1996 if (!defined($tlpdb)) { 1997 tlwarn("Oh well, adding tlnet did not help.\n"); 1998 tlwarn(<<END_EXPLICIT_MIRROR); 1999 2000 You may want to try specifying an explicit or different CTAN mirror; 2001 see the information and examples for the -repository option at 2002 https://tug.org/texlive/doc/install-tl.html 2003 (or in the output of install-tl --help). 2004 2005 You can also rerun the installer with -select-repository 2006 to choose a mirror from a menu. 2007 2008 END_EXPLICIT_MIRROR 2009 } else { 2010 # hurray, that worked out 2011 info("Loading $master/$TeXLive::TLConfig::InfraLocation/$TeXLive::TLConfig::DatabaseName\n"); 2012 $do_die = 0; 2013 } 2014 } 2015 #die "$0: Could not load TeX Live Database from $master, goodbye.\n" 2016 return 0 2017 if $do_die; 2018 } 2019 # set the defaults to what is specified in the tlpdb 2020 # since we might have loaded values via -init-from-profile, 2021 # make sure that we don't overwrite default values 2022 for my $o (keys %TeXLive::TLConfig::TLPDBOptions) { 2023 $vars{"tlpdbopt_$o"} = $tlpdb->option($o) 2024 if (!defined($profiledata{"tlpdbopt_$o"})); 2025 } 2026 if (wndws()) { 2027 # below, we really mean (start) menu integration. 2028 # 2016: always menu shortcuts, never desktop shortcuts, whatever the setting 2029 # 2017: new option value 2: launcher instead of menu. 2030 # in portable case, shortcuts sanitized away elsewhere 2031 $vars{'tlpdbopt_desktop_integration'} = 1; 2032 # we have to make sure that this option is set to 0 in case 2033 # that a non-admin is running the installations program 2034 $vars{'tlpdbopt_w32_multi_user'} = 0 if (!admin()); 2035 } 2036 2037 # select scheme: either $vars{'selected_scheme'} or $default_scheme 2038 # check that the default scheme is actually present, otherwise switch to 2039 # scheme-minimal. 2040 my $selscheme; 2041 if ($opt_scheme) { 2042 $selscheme = $opt_scheme; 2043 } elsif ($vars{"selected_scheme"}) { 2044 $selscheme = $vars{"selected_scheme"}; 2045 } else { 2046 $selscheme = $default_scheme; 2047 } 2048 if (!defined($tlpdb->get_package($selscheme))) { 2049 # let us try scheme-minimal, and if also that is not available, scheme-infra 2050 # which is required to be installed 2051 if (!defined($tlpdb->get_package("scheme-minimal"))) { 2052 if (!defined($tlpdb->get_package("scheme-infra"))) { 2053 die("Aborting, cannot find either $selscheme or scheme-minimal or scheme-infra"); 2054 } 2055 $default_scheme = "scheme-infra"; 2056 } else { 2057 $default_scheme = "scheme-minimal"; 2058 } 2059 tlwarn("$0: No $selscheme, switching to $default_scheme.\n"); 2060 $vars{'selected_scheme'} = $default_scheme; 2061 } else { 2062 $vars{'selected_scheme'} = $selscheme; 2063 } 2064 # make sure that we update %vars for collection_* if only selected_scheme 2065 # is there, but no collection information 2066 my $found_collection = 0; 2067 for my $k (keys(%vars)) { 2068 if ($k =~ m/^collection-/) { 2069 $found_collection = 1; 2070 last; 2071 } 2072 } 2073 if (!$found_collection) { 2074 for my $p ($tlpdb->get_package($vars{'selected_scheme'})->depends) { 2075 $vars{$p} = 1 if ($p =~ m/^collection-/); 2076 } 2077 } 2078 return 1; 2079 } # load_tlpdb 2080 2081 sub initialize_collections { 2082 foreach my $pkg ($tlpdb->list_packages) { 2083 my $tlpobj = $tlpdb->{'tlps'}{$pkg}; 2084 if ($tlpobj->category eq "Collection") { 2085 $vars{"$pkg"} = 0 if (!defined($vars{$pkg})); 2086 ++$vars{'n_collections_available'}; 2087 push (@collections_std, $pkg); 2088 } 2089 } 2090 my $selscheme = ($vars{'selected_scheme'} || $default_scheme); 2091 my $scheme_tlpobj = $tlpdb->get_package($selscheme); 2092 if (defined ($scheme_tlpobj)) { 2093 $vars{'n_collections_selected'}=0; 2094 foreach my $dependent ($scheme_tlpobj->depends) { 2095 if ($dependent=~/^(collection-.*)/) { 2096 $vars{"$1"}=1; 2097 } 2098 } 2099 } 2100 for my $c (keys(%vars)) { 2101 if ($c =~ m/^collection-/ && $vars{$c}) { 2102 ++$vars{'n_collections_selected'}; 2103 } 2104 } 2105 if ($vars{"binary_windows"}) { 2106 $vars{"collection-wintools"} = 1; 2107 ++$vars{'n_collections_selected'}; 2108 } 2109 } # initialize_collections 2110 2111 sub set_install_platform { 2112 my $detected_platform=platform; 2113 if ($opt_custom_bin) { 2114 $detected_platform = "custom"; 2115 } 2116 my $warn_nobin; 2117 my $warn_nobin_x86_64_linux; 2118 my $nowarn=""; 2119 my $wp='***'; # warning prefix 2120 2121 $warn_nobin="\n$wp WARNING: No binaries for your platform found. "; 2122 $warn_nobin_x86_64_linux="$warn_nobin" . 2123 "$wp No binaries for x86_64-linux found, using i386-linux instead.\n"; 2124 2125 my $ret = $warn_nobin; 2126 if (defined $vars{"binary_$detected_platform"}) { 2127 $vars{"binary_$detected_platform"}=1; 2128 $vars{'inst_platform'}=$detected_platform; 2129 $ret = $nowarn; 2130 } elsif ($detected_platform eq 'x86_64-linux') { 2131 $vars{'binary_i386-linux'}=1; 2132 $vars{'inst_platform'}='i386-linux'; 2133 $ret = $warn_nobin_x86_64_linux; 2134 } else { 2135 if ($opt_custom_bin) { 2136 $ret = "$wp Using custom binaries from $opt_custom_bin.\n"; 2137 } else { 2138 $ret = $warn_nobin; 2139 } 2140 } 2141 foreach my $key (keys %vars) { 2142 if ($key=~/^binary.*/) { 2143 ++$vars{'n_systems_selected'} if $vars{$key}==1; 2144 } 2145 } 2146 return($ret); 2147 } # set_install_platform 2148 2149 sub create_profile { 2150 my $profilepath = shift; 2151 # The file "TLprofile" is created at the beginning of the 2152 # installation process and contains information about the current 2153 # setup. The purpose is to allow non-interactive installations. 2154 my $fh; 2155 if (ref($profilepath)) { 2156 $fh = $profilepath; 2157 } else { 2158 open PROFILE, ">$profilepath"; 2159 $fh = \*PROFILE; 2160 } 2161 # 2162 # determine whether the set of selected collections exactly 2163 # agrees with the selected scheme. In this case we do *not* 2164 # save the actual collection setting but only the selected 2165 # scheme, as reading the profile will load all collections 2166 # if only the scheme is given. 2167 my %instcols; 2168 foreach my $key (sort keys %vars) { 2169 $instcols{$key} = 1 if $key=~/^collection/ and $vars{$key}==1; 2170 } 2171 # for anything but "scheme-custom" we delete the contained 2172 # collections from the list 2173 if ($vars{'selected_scheme'} ne "scheme-custom") { 2174 my $scheme=$tlpdb->get_package($vars{'selected_scheme'}); 2175 if (!defined($scheme)) { 2176 die ("Scheme $vars{selected_scheme} not defined.\n"); 2177 } 2178 for my $scheme_content ($scheme->depends) { 2179 delete($instcols{"$scheme_content"}) if ($scheme_content=~/^collection-/); 2180 } 2181 } 2182 # if there are still collection left, we keep all of them 2183 my $save_cols = (keys(%instcols) ? 1 : 0); 2184 2185 # start 2186 my $tim = gmtime(time); 2187 print $fh "# texlive.profile written on $tim UTC\n"; 2188 print $fh "# It will NOT be updated and reflects only the\n"; 2189 print $fh "# installation profile at installation time.\n"; 2190 print $fh "selected_scheme $vars{selected_scheme}\n"; 2191 foreach my $key (sort keys %vars) { 2192 print $fh "$key $vars{$key}\n" 2193 if $save_cols and $key=~/^collection/ and $vars{$key}==1; 2194 # we don't save tlpdbopt_location 2195 next if ($key eq "tlpdbopt_location"); 2196 print $fh "$key $vars{$key}\n" if $key =~ /^tlpdbopt_/; 2197 print $fh "$key $vars{$key}\n" if $key =~ /^instopt_/; 2198 print $fh "$key $vars{$key}\n" if defined($path_keys{$key}); 2199 print $fh "$key $vars{$key}\n" if (($key =~ /^binary_/) && $vars{$key}); 2200 } 2201 if (!ref($profilepath)) { 2202 close PROFILE; 2203 } 2204 } # create_profile 2205 2206 sub read_profile { 2207 my $profilepath = shift; 2208 my %opts = @_; 2209 my %keyrename = ( 2210 'option_doc' => 'tlpdbopt_install_docfiles', 2211 'option_fmt' => 'tlpdbopt_create_formats', 2212 'option_src' => 'tlpdbopt_install_srcfiles', 2213 'option_sys_bin' => 'tlpdbopt_sys_bin', 2214 'option_sys_info' => 'tlpdbopt_sys_info', 2215 'option_sys_man' => 'tlpdbopt_sys_man', 2216 'option_file_assocs' => 'tlpdbopt_file_assocs', 2217 'option_backupdir' => 'tlpdbopt_backupdir', 2218 'option_w32_multi_user' => 'tlpdbopt_w32_multi_user', 2219 'option_post_code' => 'tlpdbopt_post_code', 2220 'option_autobackup' => 'tlpdbopt_autobackup', 2221 'option_desktop_integration' => 'tlpdbopt_desktop_integration', 2222 'option_adjustrepo' => 'instopt_adjustrepo', 2223 'option_letter' => 'instopt_letter', 2224 'option_path' => 'instopt_adjustpath', 2225 'option_symlinks' => 'instopt_adjustpath', 2226 'portable' => 'instopt_portable', 2227 'option_write18_restricted' => 'instopt_write18_restricted', 2228 ); 2229 my %keylost = ( 2230 'option_menu_integration' => 1, 2231 'in_place' => 1, 2232 ); 2233 2234 open PROFILE, "<$profilepath" 2235 or die "$0: Cannot open profile $profilepath for reading.\n"; 2236 # %pro is used to see whether there are non-recognized keys, 2237 # while %profiledata is used to make sure that the values 2238 # from the tlpdb do not overwrite -seed-profile values. 2239 my %pro; 2240 while (<PROFILE>) { 2241 # don't use chomp here since we might use files written for Windows 2242 # on Unix or the other way round. 2243 # \R is a general line terminator, \z is end of string 2244 s{\R\z}{}; 2245 next if m/^[[:space:]]*$/; # skip empty lines 2246 next if m/^[[:space:]]*#/; # skip comment lines 2247 s/^[[:space:]]+//; # ignore leading (but not trailing) whitespace 2248 my ($k,$v) = split (" ", $_, 2); # value might have spaces 2249 # skip TEXDIRW, seems not used anymore, but might be around 2250 # in some profiles 2251 next if ($k eq "TEXDIRW"); 2252 # convert old keys to new keys 2253 $k = $keyrename{$k} if ($keyrename{$k}); 2254 if ($keylost{$k}) { 2255 tlwarn("Profile key `$k' is now ignored, please remove it.\n"); 2256 next; 2257 } 2258 $pro{$k} = $v; 2259 $profiledata{$k} = $v; 2260 } 2261 foreach (keys %vars) { 2262 # clear out collections from var, just to be sure 2263 if (m/^collection-/) { $vars{$_} = 0; } 2264 } 2265 # initialize installer and tlpdb options 2266 foreach (keys %pro) { 2267 if (m/^instopt_/) { 2268 if (defined($vars{$_})) { 2269 $vars{$_} = $pro{$_}; 2270 delete($pro{$_}); 2271 } 2272 } elsif (m/^tlpdbopt_/) { 2273 my $o = $_; 2274 $o =~ s/^tlpdbopt_//; 2275 # we do not support setting the location in the profile 2276 # could be done, but might be tricky .. 2277 next if ($o eq 'location'); 2278 if (defined($TeXLive::TLConfig::TLPDBOptions{$o})) { 2279 $vars{$_} = $pro{$_}; 2280 delete($pro{$_}); 2281 } 2282 2283 } elsif (defined($path_keys{$_}) || m/^selected_scheme$/) { 2284 if ($pro{$_}) { 2285 $vars{$_} = $pro{$_}; 2286 delete($pro{$_}); 2287 } else { 2288 tldie("$0: Quitting, profile key for path $_ must not be empty.\n"); 2289 } 2290 2291 } elsif (m/^(binary|collection-)/) { 2292 if ($pro{$_} =~ /^[01]$/) { 2293 $vars{$_} = $pro{$_}; 2294 delete($pro{$_}); 2295 } else { 2296 tldie("$0: Quitting, profile key for $_ must be 0 or 1, not: $pro{$_}\n"); 2297 } 2298 } 2299 } 2300 #require Data::Dumper; 2301 #$Data::Dumper::Indent = 1; 2302 #print Data::Dumper->Dump([\%vars], [qw(vars)]); 2303 # 2304 # if there are still keys in the %pro array, some unknown keys have 2305 # been written in the profile, bail out 2306 if (my @foo = keys(%pro)) { 2307 tlwarn("Unknown key(s) in profile $profilepath: @foo\n"); 2308 tlwarn("Stopping here.\n"); 2309 exit 1; 2310 } 2311 2312 # if a profile contains *only* the selected_scheme setting without 2313 # any collection, we assume that exactely that scheme should be installed 2314 my $coldefined = 0; 2315 foreach my $k (keys %profiledata) { 2316 if ($k =~ m/^collection-/) { 2317 $coldefined = 1; 2318 last; 2319 } 2320 } 2321 # if we are in seed mode, do not try to load remote db as it is 2322 # not initialized by now 2323 return if $opts{'seed'}; 2324 # 2325 # check whether the collections are actually present in case of 2326 # changes on the server 2327 foreach my $k (keys %profiledata) { 2328 if ($k =~ m/^collection-/) { 2329 if (!defined($tlpdb->get_package($k))) { 2330 tlwarn("The profile references a non-existing collection: $k\n"); 2331 tlwarn("Exiting.\n"); 2332 exit(1); 2333 } 2334 } 2335 } 2336 # Cmdline argument --scheme should override scheme selection in the profile 2337 update_default_scheme(); 2338 2339 # if at least one collection has been defined return here 2340 return if $coldefined; 2341 # since no collections have been defined in the profile, we 2342 # set those to be installed on which the scheme depends 2343 my $scheme=$tlpdb->get_package($vars{'selected_scheme'}); 2344 if (!defined($scheme)) { 2345 dump_vars(\*STDOUT); 2346 die ("Scheme $vars{selected_scheme} not defined.\n"); 2347 } 2348 for my $scheme_content ($scheme->depends) { 2349 $vars{"$scheme_content"}=1 if ($scheme_content=~/^collection-/); 2350 } 2351 } # read_profile 2352 2353 sub do_install_packages { 2354 # We split installation of packages into two stages: 2355 # - first critical packages, those absolutely necessary for working 2356 # - all the other packages, that can be also installed afterwards 2357 # via tlmgr 2358 # If something fails in the first group, we stop the installation. 2359 # If something fails in the second group: 2360 # - if --continue is given, try to continue install 2361 # - if --continue is not given, terminate (behaviour till now) 2362 # 2363 my @criticalwhat = (); 2364 my @what = (); 2365 my @surely_fail_packages = ( @CriticalPackagesList, @TeXLive::TLConfig::InstallExtraRequiredPackages ); 2366 for my $package (keys %install) { 2367 if (member($package, @surely_fail_packages)) { 2368 push @criticalwhat, $package if ($install{$package} == 1); 2369 } else { 2370 push @what, $package if ($install{$package} == 1); 2371 } 2372 } 2373 @criticalwhat = sort @criticalwhat; 2374 @what = sort @what; 2375 # determine retrial behavior 2376 my $retry = $opt_debug_fakenet || ($media eq "NET"); 2377 # temporary unset the localtlpdb options responsible for 2378 # running all kind of postactions, since install_packages 2379 # would call them without the PATH already set up 2380 # we are doing this anyway in do_postinstall_actions 2381 $localtlpdb->option ("desktop_integration", "0"); 2382 $localtlpdb->option ("file_assocs", "0"); 2383 $localtlpdb->option ("post_code", "0"); 2384 if (!install_packages($tlpdb,$media,$localtlpdb,\@criticalwhat, 2385 $vars{'tlpdbopt_install_srcfiles'}, 2386 $vars{'tlpdbopt_install_docfiles'}, 2387 $retry, 0) 2388 || 2389 !install_packages($tlpdb,$media,$localtlpdb,\@what, 2390 $vars{'tlpdbopt_install_srcfiles'}, 2391 $vars{'tlpdbopt_install_docfiles'}, 2392 $retry, $opt_continue)) { 2393 my $profile_name = "installation.profile"; 2394 create_profile($profile_name); 2395 tlwarn("Installation failed.\n"); 2396 tlwarn("Rerunning the installer will try to restart the installation.\n"); 2397 if (-r $profile_name) { 2398 # only suggest rerunning with the profile if it exists. 2399 tlwarn("Or you can restart by running the installer with:\n"); 2400 my $repostr = ($opt_location ? " --repository $location" : ""); 2401 my $args = "--profile $profile_name [YOUR-EXTRA-ARGS]"; 2402 if (wndws()) { 2403 tlwarn(" install-tl-windows.bat$repostr $args\n"); 2404 } else { 2405 tlwarn(" install-tl$repostr $args\n"); 2406 } 2407 } 2408 flushlog(); 2409 exit(1); 2410 } 2411 # restore options in tlpdb 2412 $localtlpdb->option ( 2413 "desktop_integration", $vars{'tlpdbopt_desktop_integration'}); 2414 $localtlpdb->option ("file_assocs", $vars{'tlpdbopt_file_assocs'}); 2415 $localtlpdb->option ("post_code", $vars{'tlpdbopt_post_code'} ? "1" : "0"); 2416 $localtlpdb->save; 2417 } # do_install_packages 2418 2419 # for later complete removal we want to save some options and values 2420 # into the local tlpdb: 2421 # - should links be set, and if yes, the destination (bin,man,info) 2422 # 2423 sub save_options_into_tlpdb { 2424 # if we are told to adjust the repository *and* we are *not* 2425 # installing from the network already, we adjust the repository 2426 # to the default mirror.ctan.org 2427 if ($vars{'instopt_adjustrepo'} && ($media ne 'NET')) { 2428 $localtlpdb->option ("location", $TeXLiveURL); 2429 } else { 2430 my $final_loc = ($media eq 'NET' ? $location : abs_path($location)); 2431 $localtlpdb->option ("location", $final_loc); 2432 } 2433 for my $o (keys %TeXLive::TLConfig::TLPDBOptions) { 2434 next if ($o eq "location"); # done above already 2435 $localtlpdb->option ($o, $vars{"tlpdbopt_$o"}); 2436 } 2437 my @archs; 2438 foreach (keys %vars) { 2439 if (m/^binary_(.*)$/ ) { 2440 if ($vars{$_}) { push @archs, $1; } 2441 } 2442 } 2443 if ($opt_custom_bin) { 2444 push @archs, "custom"; 2445 } 2446 if (! @archs) { 2447 tldie("$0: Quitting, no binary platform specified/available.\n" 2448 ."$0: See https://tug.org/texlive/custom-bin.html for\n" 2449 ."$0: information on other precompiled binary sets.\n"); 2450 } 2451 # only if we forced the platform we do save this option into the tlpdb 2452 if (defined($opt_force_arch)) { 2453 $localtlpdb->setting ("platform", $::_platform_); 2454 } 2455 $localtlpdb->setting("available_architectures", @archs); 2456 $localtlpdb->save() unless $opt_in_place; 2457 } # save_options_into_tlpdb 2458 2459 sub import_settings_from_old_tlpdb { 2460 my $dn = shift; 2461 my $tlpdboldpath = 2462 "$dn/$TeXLive::TLConfig::InfraLocation/$TeXLive::TLConfig::DatabaseName"; 2463 my $previoustlpdb; 2464 if (-r $tlpdboldpath) { 2465 # we found an old installation, so read that one in and save 2466 # the list installed collections into an array. 2467 info ("Trying to load old TeX Live Database,\n"); 2468 $previoustlpdb = TeXLive::TLPDB->new(root => $dn); 2469 if ($previoustlpdb) { 2470 info ("Importing settings from old installation in $dn\n"); 2471 } else { 2472 tlwarn ("Cannot load old TLPDB, continuing with normal installation.\n"); 2473 return; 2474 } 2475 } else { 2476 return; 2477 } 2478 ############# OLD CODE ################### 2479 # in former times we sometimes didn't change from scheme-full 2480 # to scheme-custom when deselecting some collections 2481 # this is fixed now. 2482 # 2483 # # first import the collections 2484 # # since the scheme is not the final word we select scheme-custom here 2485 # # and then set the single collections by hand 2486 # $vars{'selected_scheme'} = "scheme-custom"; 2487 # $vars{'n_collections_selected'} = 0; 2488 # # remove the selection of all collections 2489 # foreach my $entry (keys %vars) { 2490 # if ($entry=~/^(collection-.*)/) { 2491 # $vars{"$1"}=0; 2492 # } 2493 # } 2494 # for my $c ($previoustlpdb->collections) { 2495 # my $tlpobj = $tlpdb->get_package($c); 2496 # if ($tlpobj) { 2497 # $vars{$c} = 1; 2498 # ++$vars{'n_collections_selected'}; 2499 # } 2500 # } 2501 ############ END OF OLD CODE ############ 2502 2503 ############ NEW CODE ################### 2504 # we simply go through all installed schemes, install 2505 # all depending collections 2506 # if we find scheme-full we use this as 'selected_scheme' 2507 # otherwise we use 'scheme_custom' as we don't know 2508 # and there is no total order on the schemes. 2509 # 2510 # we cannot use select_scheme from tlmgr.pl, as this one clears 2511 # previous selctions (hmm :-( 2512 $vars{'selected_scheme'} = "scheme-custom"; 2513 $vars{'n_collections_selected'} = 0; 2514 # remove the selection of all collections 2515 foreach my $entry (keys %vars) { 2516 if ($entry=~/^(collection-.*)/) { 2517 $vars{"$1"}=0; 2518 } 2519 } 2520 # now go over all the schemes *AND* collections and select them 2521 foreach my $s ($previoustlpdb->schemes) { 2522 my $tlpobj = $tlpdb->get_package($s); 2523 if ($tlpobj) { 2524 foreach my $e ($tlpobj->depends) { 2525 if ($e =~ /^(collection-.*)/) { 2526 # do not add collections multiple times 2527 if (!$vars{$e}) { 2528 $vars{$e} = 1; 2529 ++$vars{'n_collections_selected'}; 2530 } 2531 } 2532 } 2533 } 2534 } 2535 # Now do the same for collections: 2536 for my $c ($previoustlpdb->collections) { 2537 my $tlpobj = $tlpdb->get_package($c); 2538 if ($tlpobj) { 2539 if (!$vars{$c}) { 2540 $vars{$c} = 1; 2541 ++$vars{'n_collections_selected'}; 2542 } 2543 } 2544 } 2545 ########### END NEW CODE ############# 2546 2547 2548 # now take over the path 2549 my $oldroot = $previoustlpdb->root; 2550 my $newroot = abs_path("$oldroot/..") . "/$texlive_release"; 2551 $vars{'TEXDIR'} = $newroot; 2552 $vars{'TEXMFSYSVAR'} = "$newroot/texmf-var"; 2553 $vars{'TEXMFSYSCONFIG'} = "$newroot/texmf-config"; 2554 # only TEXMFLOCAL is treated differently, we use what is found by kpsewhich 2555 # in 2008 and onward this is defined as 2556 # TEXMFLOCAL = $SELFAUTOPARENT/../texmf-local 2557 # so kpsewhich -var-value=TEXMFLOCAL returns 2558 # ..../2008/../texmf-local 2559 # TODO TODO TODO 2560 chomp (my $tml = `kpsewhich -var-value=TEXMFLOCAL`); 2561 $tml = abs_path($tml); 2562 $vars{'TEXMFLOCAL'} = $tml; 2563 # 2564 # now for the settings 2565 # set the defaults to what is specified in the tlpdb 2566 $vars{'tlpdbopt_install_docfiles'} 2567 = $previoustlpdb->option_pkg("00texlive.installation", "install_docfiles"); 2568 $vars{'tlpdbopt_install_srcfiles'} 2569 = $previoustlpdb->option_pkg("00texlive.installation", "install_srcfiles"); 2570 $vars{'tlpdbopt_create_formats'} 2571 = $previoustlpdb->option_pkg("00texlive.installation", "create_formats"); 2572 $vars{'tlpdbopt_desktop_integration'} = 1 if wndws(); 2573 $vars{'instopt_adjustpath'} 2574 = $previoustlpdb->option_pkg("00texlive.installation", "path"); 2575 $vars{'instopt_adjustpath'} = 0 if !defined($vars{'instopt_adjustpath'}); 2576 $vars{'instopt_adjustpath'} = 1 if wndws(); 2577 $vars{'tlpdbopt_sys_bin'} 2578 = $previoustlpdb->option_pkg("00texlive.installation", "sys_bin"); 2579 $vars{'tlpdbopt_sys_man'} 2580 = $previoustlpdb->option_pkg("00texlive.installation", "sys_man"); 2581 $vars{'sys_info'} 2582 = $previoustlpdb->option_pkg("00texlive.installation", "sys_info"); 2583 # 2584 # import the set of selected architectures 2585 my @aar = $previoustlpdb->setting_pkg("00texlive.installation", 2586 "available_architectures"); 2587 if (@aar) { 2588 for my $b ($tlpdb->available_architectures) { 2589 $vars{"binary_$b"} = member( $b, @aar ); 2590 } 2591 $vars{'n_systems_available'} = 0; 2592 for my $key (keys %vars) { 2593 ++$vars{'n_systems_available'} if ($key=~/^binary/); 2594 } 2595 } 2596 # 2597 # try to import paper settings 2598 my $xdvi_paper; 2599 if (!wndws()) { 2600 $xdvi_paper = TeXLive::TLPaper::get_paper("xdvi"); 2601 } 2602 my $pdftex_paper = TeXLive::TLPaper::get_paper("pdftex"); 2603 my $dvips_paper = TeXLive::TLPaper::get_paper("dvips"); 2604 my $dvipdfmx_paper = TeXLive::TLPaper::get_paper("dvipdfmx"); 2605 my $context_paper; 2606 if (defined($previoustlpdb->get_package("context"))) { 2607 $context_paper = TeXLive::TLPaper::get_paper("context"); 2608 } 2609 my $common_paper = ""; 2610 if (defined($xdvi_paper)) { 2611 $common_paper = $xdvi_paper; 2612 } 2613 $common_paper = 2614 ($common_paper ne $context_paper ? "no-agree-on-paper" : $common_paper) 2615 if (defined($context_paper)); 2616 $common_paper = 2617 ($common_paper ne $pdftex_paper ? "no-agree-on-paper" : $common_paper) 2618 if (defined($pdftex_paper)); 2619 $common_paper = 2620 ($common_paper ne $dvips_paper ? "no-agree-on-paper" : $common_paper) 2621 if (defined($dvips_paper)); 2622 $common_paper = 2623 ($common_paper ne $dvipdfmx_paper ? "no-agree-on-paper" : $common_paper) 2624 if (defined($dvipdfmx_paper)); 2625 if ($common_paper eq "no-agree-on-paper") { 2626 tlwarn("Previous installation uses different paper settings.\n"); 2627 tlwarn("You will need to select your preferred paper sizes manually.\n\n"); 2628 } else { 2629 if ($common_paper eq "letter") { 2630 $vars{'instopt_letter'} = 1; 2631 } elsif ($common_paper eq "a4") { 2632 # do nothing 2633 } else { 2634 tlwarn( 2635 "Previous installation has common paper setting of: $common_paper\n"); 2636 tlwarn("After installation has finished, you will need\n"); 2637 tlwarn(" to redo this setting by running:\n"); 2638 } 2639 } 2640 # update size information 2641 $vars{'free_size'} = TeXLive::TLUtils::diskfree($vars{'TEXDIR'}); 2642 } # import_settings_from_old_tlpdb 2643 2644 # do everything to select a scheme 2645 # 2646 sub select_scheme { 2647 my $s = shift; 2648 # set the selected scheme to $s 2649 $vars{'selected_scheme'} = $s; 2650 debug("setting selected scheme: $s\n"); 2651 # if we are working on scheme-custom simply return 2652 return if ($s eq "scheme-custom"); 2653 # remove the selection of all collections 2654 foreach my $entry (keys %vars) { 2655 if ($entry=~/^(collection-.*)/) { 2656 $vars{"$1"}=0; 2657 } 2658 } 2659 # select the collections belonging to the scheme 2660 my $scheme_tlpobj = $tlpdb->get_package($s); 2661 if (defined ($scheme_tlpobj)) { 2662 $vars{'n_collections_selected'}=0; 2663 foreach my $dependent ($scheme_tlpobj->depends) { 2664 if ($dependent=~/^(collection-.*)/) { 2665 $vars{"$1"}=1; 2666 ++$vars{'n_collections_selected'}; 2667 } 2668 } 2669 } 2670 # we have first set all collection-* keys to zero and than 2671 # set to 1 only those which are required by the scheme 2672 # since now scheme asks for collection-wintools we set its vars value 2673 # to 1 in case we are installing windows binaries 2674 if ($vars{"binary_windows"}) { 2675 $vars{"collection-wintools"} = 1; 2676 ++$vars{'n_collections_selected'}; 2677 } 2678 # for good measure, update the deps 2679 calc_depends(); 2680 } # select_scheme 2681 2682 # try to give a decent order of schemes, but be so general that 2683 # if we change names of schemes nothing bad happnes (like forgetting one) 2684 sub schemes_ordered_for_presentation { 2685 my @scheme_order; 2686 my %schemes_shown; 2687 for my $s ($tlpdb->schemes) { $schemes_shown{$s} = 0 ; } 2688 # first try the size-name-schemes in decreasing order 2689 for my $sn (qw/full medium small basic minimal infraonly/) { 2690 if (defined($schemes_shown{"scheme-$sn"})) { 2691 push @scheme_order, "scheme-$sn"; 2692 $schemes_shown{"scheme-$sn"} = 1; 2693 } 2694 } 2695 # now push all the other schemes if they are there and not already shown 2696 for my $s (sort keys %schemes_shown) { 2697 push @scheme_order, $s if !$schemes_shown{$s}; 2698 } 2699 return @scheme_order; 2700 } # schemes_ordered_for_presentation 2701 2702 sub update_numbers { 2703 $vars{'n_collections_available'}=0; 2704 $vars{'n_collections_selected'} = 0; 2705 $vars{'n_systems_available'} = 0; 2706 $vars{'n_systems_selected'} = 0; 2707 foreach my $key (keys %vars) { 2708 if ($key =~ /^binary/) { 2709 ++$vars{'n_systems_available'}; 2710 ++$vars{'n_systems_selected'} if $vars{$key} == 1; 2711 } 2712 if ($key =~ /^collection-/) { 2713 ++$vars{'n_collections_available'}; 2714 ++$vars{'n_collections_selected'} if $vars{$key} == 1; 2715 } 2716 } 2717 } # update_numbers 2718 2719 # signal handler for interrupts SIGINT AND SIGTERM 2720 sub signal_handler { 2721 my ($sig) = @_; 2722 flushlog(); 2723 print STDERR "$0: caught SIG$sig -- exiting\n"; 2724 exit(1); 2725 } 2726 2727 # to be called at exit when the installation did not complete 2728 sub flushlog { 2729 if (!defined($::LOGFILENAME)) { 2730 my $fh; 2731 my $logfile = "install-tl.log"; 2732 if (open (LOG, ">$logfile")) { 2733 my $pwd = Cwd::getcwd(); 2734 $logfile = "$pwd/$logfile"; 2735 print "$0: Writing log in current directory: $logfile\n"; 2736 $fh = \*LOG; 2737 } else { 2738 $fh = \*STDERR; 2739 print 2740 "$0: Could not write to $logfile, so flushing messages to stderr.\n"; 2741 } 2742 foreach my $l (@::LOGLINES) { 2743 print $fh $l; 2744 } 2745 } 2746 } # flushlog 2747 2748 sub do_cleanup { 2749 # remove temporary files from TEXDIR/temp 2750 if (($media eq "local_compressed") or ($media eq "NET")) { 2751 debug("Remove temporary downloaded containers...\n"); 2752 rmtree("$vars{'TEXDIR'}/temp") if (-d "$vars{'TEXDIR'}/temp"); 2753 } 2754 2755 # write the profile out 2756 if ($opt_in_place) { 2757 create_profile("$vars{'TEXDIR'}/texlive.profile"); 2758 debug("Profile written to $vars{'TEXDIR'}/texlive.profile\n"); 2759 } else { 2760 create_profile("$vars{'TEXDIR'}/$InfraLocation/texlive.profile"); 2761 debug("Profile written to $vars{'TEXDIR'}/$InfraLocation/texlive.profile\n"); 2762 } 2763 2764 # now open the log file and write out the log lines if needed. 2765 # the user could have given the -logfile option in which case all the 2766 # stuff is already dumped to it and $::LOGFILE defined. So do not 2767 # redefine it. 2768 if (!defined($::LOGFILE)) { 2769 # no -logfile option; nothing written yet 2770 $::LOGFILENAME = "$vars{'TEXDIR'}/install-tl.log"; 2771 if (open(LOGF,">:utf8", $::LOGFILENAME)) { 2772 $::LOGFILE = \*LOGF; 2773 foreach my $line(@::LOGLINES) { 2774 print $::LOGFILE "$line"; 2775 } 2776 } else { 2777 tlwarn("$0: Cannot create log file $::LOGFILENAME: $!\n" 2778 . "Not writing out log lines.\n"); 2779 } 2780 } 2781 2782 # Close log file if present 2783 close($::LOGFILE) if (defined($::LOGFILE)); 2784 if (!defined($::LOGFILENAME) and (-e "$vars{'TEXDIR'}/install-tl.log")) { 2785 $::LOGFILENAME = "$vars{'TEXDIR'}/install-tl.log"; 2786 } 2787 if (!(defined($::LOGFILENAME)) or !(-e $::LOGFILENAME)) { 2788 $::LOGFILENAME = ""; 2789 } 2790 } # do_cleanup 2791 2792 sub check_env { 2793 # check for tex-related envvars. 2794 $::env_warns = ""; 2795 for my $evar (sort keys %origenv) { 2796 next if $evar =~ /^(_.* 2797 |.*PWD 2798 |ARGS 2799 |GENDOCS_TEMPLATE_DIR 2800 |INSTROOT 2801 |INFOPATH 2802 |MANPATH 2803 |PATH 2804 |PERL5LIB 2805 |SHELLOPTS 2806 |WISH 2807 )$/x; # don't worry about these 2808 if ("$evar $origenv{$evar}" =~ /tex/i) { # check both key and value 2809 $::env_warns .= " $evar=$origenv{$evar}\n"; 2810 } 2811 } 2812 if ($::env_warns) { 2813 $::env_warns = <<"EOF"; 2814 2815 ---------------------------------------------------------------------- 2816 The following environment variables contain the string "tex" 2817 (case-independent). If you're doing anything but adding personal 2818 directories to the system paths, they may well cause trouble somewhere 2819 while running TeX. If you encounter problems, try unsetting them. 2820 2821 Please ignore spurious matches unrelated to TeX. (To omit this check, 2822 set the environment variable TEXLIVE_INSTALL_ENV_NOCHECK.) 2823 2824 $::env_warns ---------------------------------------------------------------------- 2825 EOF 2826 } 2827 } 2828 2829 2830 # Create a welcome message. 2831 sub create_welcome { 2832 @::welcome_arr = (); 2833 push @::welcome_arr, "\n"; 2834 push @::welcome_arr, __("Welcome to TeX Live!"); 2835 push @::welcome_arr, "\n"; 2836 push @::welcome_arr, __( 2837 "See %s/index.html for links to documentation.\nThe TeX Live web site (https://tug.org/texlive/) contains any updates and corrections. TeX Live is a joint project of the TeX user groups around the world; please consider supporting it by joining the group best for you. The list of groups is available on the web at https://tug.org/usergroups.html.", 2838 $::vars{'TEXDIR'}); 2839 if (wndws() 2840 || ($vars{'instopt_adjustpath'} 2841 && $vars{'tlpdbopt_desktop_integration'} != 2)) { 2842 ; # don't tell them to make path adjustments on Windows, 2843 # or if they chose to "create symlinks". 2844 } else { 2845 push @::welcome_arr, "\n"; 2846 push @::welcome_arr, __( 2847 "Add %s/texmf-dist/doc/man to MANPATH.\nAdd %s/texmf-dist/doc/info to INFOPATH.\nMost importantly, add %s/bin/%s\nto your PATH for current and future sessions.", 2848 $::vars{'TEXDIR'}, $::vars{'TEXDIR'}, $::vars{'TEXDIR'}, 2849 $::vars{'this_platform'}); 2850 } 2851 } 2852 2853 2854 # remember the warnings issued 2855 sub install_warnlines_hook { 2856 push @::warn_hook, sub { push @::WARNLINES, @_; }; 2857 } 2858 2859 ## a summary of warnings if there were any 2860 #sub warnings_summary { 2861 # return '' unless @::WARNLINES; 2862 # my $summary = <<EOF; 2863 # 2864 #Summary of warning messages during installation: 2865 #EOF 2866 # $summary .= join ("", map { " $_" } @::WARNLINES); # indent each warning 2867 # $summary .= "\n"; # extra blank line 2868 # return $summary; 2869 #} 2870 2871 2872 2873 # some helper functions 2874 # 2875 sub select_collections { 2876 my $varref = shift; 2877 foreach (@_) { 2878 $varref->{$_} = 1; 2879 } 2880 } 2881 2882 sub deselect_collections { 2883 my $varref = shift; 2884 foreach (@_) { 2885 $varref->{$_} = 0; 2886 } 2887 } 2888 2889 2890 __END__ 2891 2892 =head1 NAME 2893 2894 install-tl - TeX Live cross-platform installer 2895 2896 =head1 SYNOPSIS 2897 2898 install-tl [I<option>]... 2899 2900 install-tl-windows.bat [I<option>]... 2901 2902 =head1 DESCRIPTION 2903 2904 This installer creates a runnable TeX Live installation from various 2905 media, including over the network, from local hard disk, a DVD, etc. The 2906 installer works on all platforms supported by TeX Live. For information 2907 on initially downloading TeX Live, see 2908 L<https://tug.org/texlive/acquire.html>. 2909 2910 The basic idea of TeX Live installation is for you to choose one of the 2911 top-level I<schemes>, each of which is defined as a different set of 2912 I<collections> and I<packages>, where a collection is a set of packages, 2913 and a package is what contains actual files. Each package is in exactly 2914 one collection, while schemes can contain any combination of packages 2915 and collections. 2916 2917 Within the installer, you can choose a scheme, and further customize the 2918 set of collections to install, but not the set of the packages. To work 2919 at the package level, use C<tlmgr> (reference just below) after the 2920 initial installation is complete. 2921 2922 The default is C<scheme-full>, which installs everything, and this is 2923 highly recommended. 2924 2925 =head1 REFERENCES 2926 2927 Post-installation configuration, package updates, and more, are 2928 handled through B<tlmgr>(1), the TeX Live Manager 2929 (L<https://tug.org/texlive/tlmgr.html>). 2930 2931 The most up-to-date version of this installer documentation is on the 2932 Internet at L<https://tug.org/texlive/doc/install-tl.html>. 2933 2934 For step-by-step instructions, see 2935 L<https://tug.org/texlive/quickinstall.html>. 2936 2937 For the full documentation of TeX Live, see 2938 L<https://tug.org/texlive/doc>. 2939 2940 =head1 EXAMPLES 2941 2942 With no options, C<install-tl> drops you into an interactive menu where 2943 essentially all default settings can be changed. With options, you can 2944 initialize the settings in various ways, or perform the installation 2945 without interaction. Some examples: 2946 2947 =over 4 2948 2949 =item C<install-tl --paper=letter> 2950 2951 Initialize paper size setting. The only values allowed are C<letter> and 2952 (the default) C<a4>. 2953 2954 =item C<install-tl --scheme> I<scheme> 2955 2956 Initialize the installation scheme; the default is C<full>. For a list 2957 of schemes, see the interactive C<S> menu. 2958 2959 =item C<install-tl --no-interaction> 2960 2961 Perform the installation immediately after parsing options, without 2962 entering the interactive menu. 2963 2964 =item C<install-tl --profile> I<texlive.profile> 2965 2966 Install, without interaction, according to the given TL profile file; 2967 see L</PROFILES> below. To initialize from the profile and then enter the 2968 interactive menu, add C<--init-from-profile>. 2969 2970 =back 2971 2972 Full documentation follows. 2973 2974 =head1 OPTIONS 2975 2976 As usual, all options can be specified in any order, and with either a 2977 leading C<-> or C<-->. An argument value can be separated from its 2978 option by either a space or C<=>. 2979 2980 The options relating to customization of the installation can also be 2981 selected in the interactive installation menus (GUI or text). 2982 2983 =over 4 2984 2985 =item B<-gui> [[=]I<module>] 2986 2987 =item B<-no-gui> 2988 2989 If no I<module> is given, starts the Tcl/Tk (see below) GUI installer. 2990 2991 If I<module> is given loads the given installer module. Currently the 2992 following modules are supported: 2993 2994 =over 4 2995 2996 =item C<text> 2997 2998 The text mode user interface (default on Unix systems, including Macs). 2999 Same as the C<-no-gui> option. 3000 3001 =item C<tcl> (or "perltk" or "wizard" or "expert" or nothing) 3002 3003 The Tcl/Tk user interface (default on Windows). It starts 3004 with a small number of configuration options, roughly equivalent 3005 to what the former wizard option offers, but a button C<Advanced> 3006 takes you to a screen with roughly the same options as the former 3007 C<perltk> interface. 3008 3009 =back 3010 3011 The default GUI requires Tcl/Tk. This was standard on Macs, but has been 3012 removed in the latest macOS releases. It's often already installed on 3013 GNU/Linux, or can be easily installed through a distro package manager. 3014 For Windows, TeX Live provides a Tcl/Tk runtime. 3015 3016 =for comment Keep language list in sync with tlmgr. 3017 3018 =item B<-lang> I<llcode> 3019 3020 By default, the Tcl GUI uses the language detection built into 3021 Tcl/Tk. If that fails you can select a different language by 3022 giving this option with a language code (based on ISO 639-1). 3023 Currently supported (but not necessarily completely translated) are: 3024 English (en, default), Czech (cs), German (de), French (fr), Italian 3025 (it), Japanese (ja), Dutch (nl), Polish (pl), Brazilian Portuguese 3026 (pt_BR), Russian (ru), Slovak (sk), Slovenian (sl), Serbian (sr), 3027 Ukrainian (uk), Vietnamese (vi), simplified Chinese (zh_CN), and 3028 traditional Chinese (zh_TW). 3029 3030 =item B<-repository> I<url|path> 3031 3032 Specify the package repository to be used as the source of the 3033 installation. In short, this can be a directory name or a url using 3034 http(s), ftp, or scp. The documentation for C<tlmgr> has the details 3035 (L<https://tug.org/texlive/doc/tlmgr.html#OPTIONS>). 3036 3037 For installation, the default is to pick a mirror automatically, using 3038 L<https://mirror.ctan.org/systems/texlive/tlnet>; the chosen mirror is 3039 then used for the entire download. You can use the special argument 3040 C<ctan> as an abbreviation for this. (See L<https://ctan.org> for more 3041 about CTAN and its mirrors.) 3042 3043 After installation is complete, you can use that installation as the 3044 repository for another installation. If you chose to install less than 3045 the full scheme containing all packages, the list of available schemes 3046 will be adjusted accordingly. 3047 3048 =item B<-select-repository> 3049 3050 This option allows you to choose a particular mirror from the current 3051 list of active CTAN mirrors. This option is supported in the C<text> 3052 and C<gui> installer modes, and will also offer to install 3053 from local media if available, or from a repository specified on the 3054 command line. It's useful when the (default) automatic redirection does 3055 not choose a good host for you. 3056 3057 =item B<-all-options> 3058 3059 Normally options not relevant to the current platform are not shown 3060 (e.g., when running on Unix, Windows-specific options are omitted). 3061 Giving this command line option allows configuring such "foreign" 3062 settings. 3063 3064 =item B<-custom-bin> I<path> 3065 3066 If you have built your own set of TeX Live binaries (e.g., because 3067 precompiled binaries were not provided by TL for your platform), this 3068 option allows you to specify the I<path> to a directory where the 3069 binaries for the current system are present. The installation will 3070 continue as usual, but at the end all files from I<path> are copied over 3071 to C<bin/custom/> under your installation directory and this 3072 C<bin/custom/> directory is what will be added to the path for the 3073 post-install actions. To install multiple custom binary sets, manually 3074 rename C<custom> before doing each. 3075 3076 For more information on custom binaries, see 3077 L<https://tug.org/texlive/custom-bin.html>. For general information on 3078 building TeX Live, see L<https://tug.org/texlive/build.html>. 3079 3080 =item B<-debug-fakenet> 3081 3082 Pretend we're doing a network install. This is for the sole purpose of 3083 testing the code to handle broken downloads, via moving package files 3084 aside in a tlnet mirror hierarchy. 3085 3086 =item B<-debug-setup-vars> 3087 3088 Print final values of directory variables; for more debugging 3089 information on how they were set, also specify C<-v>. 3090 3091 =item B<-debug-translation> 3092 3093 In the former Perl/Tk GUI modes, this option reported any missing, 3094 or more likely untranslated, messages to standard error. Not yet 3095 implemented for the Tcl interface. Helpful for translators to see 3096 what remains to be done. 3097 3098 =item B<-force-platform> I<platform> 3099 3100 Instead of auto-detecting the current platform, use I<platform>. 3101 Binaries for this platform must be present in C<bin/>I<platform>C</> and 3102 they must be runnable, or installation will fail. C<-force-arch> is a 3103 synonym. 3104 3105 =item B<-help>, B<--help>, B<-?> 3106 3107 Display this help and exit. (This help is also on the web at 3108 L<https://tug.org/texlive/doc/install-tl.html>). Sometimes the C<perldoc> 3109 and/or C<PAGER> programs on the system have problems, possibly resulting 3110 in control characters being literally output. This can't always be 3111 detected, but you can set the C<NOPERLDOC> environment variable and 3112 C<perldoc> will not be used. 3113 3114 =item B<-in-place> 3115 3116 This is a quick-and-dirty installation option in case you already have 3117 an rsync or svn checkout of TeX Live. It will use the checkout as-is 3118 and will just do the necessary post-install. Be warned that the file 3119 C<tlpkg/texlive.tlpdb> may be rewritten, that removal has to be done 3120 manually, and that the only realistic way to maintain this installation 3121 is to redo it from time to time. This option is not available via the 3122 installer interfaces. USE AT YOUR OWN RISK. 3123 3124 =item B<-init-from-profile> I<profile_file> 3125 3126 Similar to B<-profile> (see L</PROFILES> below), but only initializes 3127 the installation configuration from I<profile_file> and then starts a 3128 normal interactive session. Environment variables are not ignored. 3129 3130 =item B<-logfile> I<file> 3131 3132 Write both all messages (informational, debugging, warnings) to I<file>, 3133 in addition to standard output or standard error. 3134 3135 If this option is not given, the installer will create a log file 3136 in the root of the writable installation tree, 3137 for example, C</usr/local/texlive/YYYY/install-tl.log> for the I<YYYY> 3138 release. 3139 3140 =item B<-no-cls> 3141 3142 For the text mode installer only: do not clear the screen when entering 3143 a new menu. For debugging. 3144 3145 =item B<-no-continue> 3146 3147 Quit early on installation failure of a non-core package. 3148 3149 By default, a few core packages are installed first; then, a failed 3150 installation of any other (non-core) package is noted, but does not stop 3151 the installation. Any such failed packages are retried, once. 3152 3153 If the retry also fails, by default the installer proceeds to completion 3154 anyway, with the idea that it was a transient network problem and 3155 reinstallation will succeed later. If this option is specified, and the 3156 retry fails, the installer aborts. 3157 3158 =item B<-no-doc-install> 3159 3160 =item B<-no-src-install> 3161 3162 Do not install the documentation resp. source package files, both for 3163 the immediate installation and for future updates. After installation, 3164 inclusion of the doc/src files can be re-enabled via C<tlmgr>: 3165 3166 tlmgr option docfiles 1 3167 tlmgr option srcfiles 1 3168 3169 If you later find that you want the doc/src files for a package that has 3170 been installed without them, you can get them like this (using the 3171 C<fontspec> package as the example): 3172 3173 tlmgr install --reinstall --with-doc --with-src fontspec 3174 3175 The source files mentioned here are those relating to TeX packages, such 3176 as C<.dtx> files. The sources that are compiled to make the binaries are 3177 available separately: see L<https://tug.org/texlive/svn/>. 3178 3179 =item B<-no-installation> 3180 3181 Do not perform any installation. This is for debugging the 3182 initialization and setup routines without touching the disk. 3183 3184 =item B<-no-interaction> 3185 3186 Do not enter the interactive menu; immediately perform the installation 3187 after initialization and option parsing. Also omit the check for a 3188 previous installation and asking about importing previous settings. 3189 3190 =item B<-no-persistent-downloads> 3191 3192 =item B<-persistent-downloads> 3193 3194 For network installs, activating this option makes the installer try to 3195 set up a persistent connection using the C<LWP> Perl module. This 3196 opens only one connection between your computer and the server per 3197 session and reuses it, instead of initiating a new download for each 3198 package, which typically yields a significant speed-up. 3199 3200 This option is turned on by default, and the installation program will 3201 fall back to using C<wget> if this is not possible. To disable usage of 3202 LWP and persistent connections, use C<-no-persistent-downloads>. 3203 3204 =item B<-no-verify-downloads> 3205 3206 By default, if a GnuPG C<gpg> binary is found in PATH, downloads are 3207 verified against a cryptographic signature. This option disables such 3208 verification. The full description is in the Crytographic Verification 3209 section of the C<tlmgr> documentation, e.g., 3210 L<https://tug.org/texlive/doc/tlmgr.html#CRYPTOGRAPHIC-VERIFICATION> 3211 3212 =item B<-non-admin> 3213 3214 For Windows only: configure for the current user, not for all users. 3215 3216 =item B<-paper> C<a4>B<|>C<letter> 3217 3218 Set the default paper size for all TeX Live programs, as specified. 3219 The default is C<a4>. The paper size can be set after installation with 3220 the C<tlmgr paper> command. 3221 3222 =item B<-portable> 3223 3224 Install for portable use, e.g., on a USB stick. See the 3225 C<instopt_portable> description below for details. 3226 3227 =item B<-print-platform> 3228 3229 Print the TeX Live identifier for the detected platform 3230 (hardware/operating system) combination to standard output, and exit. 3231 C<-print-arch> is a synonym. 3232 3233 =item B<-profile> I<profile_file> 3234 3235 Load I<profile_file> and do the installation with no user interaction, 3236 that is, a batch (unattended) install. Environment variables are 3237 ignored. See L</PROFILES> below. 3238 3239 =item B<-q> 3240 3241 Omit normal informational messages. 3242 3243 =item B<-scheme> I<scheme> 3244 3245 Schemes are the highest level of package grouping in TeX Live; the 3246 default is to use the C<full> scheme, which includes everything. This 3247 option overrides that default. The I<scheme> argument value may 3248 optionally have a prefix C<scheme->. The list of supported scheme names 3249 depends on what your package repository provides; see the interactive 3250 menu list. 3251 3252 =item B<-texdir> I<dir> 3253 3254 Specify the system installation directory; the default is 3255 C</usr/local/texlive/YYYY> for release YYYY. Specifying this option also 3256 causes the C<TEXMFLOCAL>, C<TEXMFSYSCONFIG>, and C<TEXMFSYSVAR> 3257 directories to be set as subdirectories of I<dir>, so they don't have to 3258 be set individually. 3259 3260 There is a brief summary of these directories trees at L</DIRECTORY 3261 TREES> below; for details on the trees set up by default, and their 3262 intended usage, see the main TeX Live documentation at 3263 L<https://tug.org/texlive/doc>. 3264 3265 =item B<-texuserdir> I<dir> 3266 3267 Specify the user installation directory; the default is 3268 C<~/.texliveYYYY> (except on Macs, where there is no leading dot). 3269 Specifying this also causes the C<TEXMFHOME>, C<TEXMFCONFIG>, and 3270 C<TEXMFVAR> directories to be set as subdirectories of I<dir>. 3271 3272 =item B<-texmflocal> I<dir> 3273 3274 Specify the C<TEXMFLOCAL> directory; the default is 3275 C</usr/local/texlive/texmf-local>, that is, one level up from the main 3276 installation. This is so locally-installed packages can be easily used 3277 across releases, which is usually desirable. Specifying the C<-texdir> 3278 option changes this, putting C<TEXMFLOCAL> under the main tree. The 3279 C<-texmflocal> option can be used to specify an explicit directory. 3280 3281 Anything installed here must follow the TeX directory structure (TDS), 3282 e.g., C<TEXMFHOME/tex/latex/mypkg/mypkg.sty>. TDS reference: 3283 L<https://tug.org/tds>. 3284 3285 =item B<-texmfhome> I<dir> 3286 3287 Specify the C<TEXMFHOME> directory; the default is C<~/texmf>, except on 3288 Macs, where it is C<~/Library/texmf>. Analogously to C<TEXMFLOCAL>, the 3289 C<-texuserdir> option changes this default. 3290 3291 Also as with C<TEXMFLOCAL>, anything installed here must follow the TDS. 3292 3293 =item B<-texmfsysconfig> I<dir> 3294 3295 =item B<-texmfsysvar> I<dir> 3296 3297 Specify the C<TEXMFSYSCONFIG> and C<TEXMFSYSVAR> system directories. 3298 3299 =item B<-texmfconfig> I<dir> 3300 3301 =item B<-texmfvar> I<dir> 3302 3303 Specify the C<TEXMFCONFIG> and C<TEXMFVAR> user directories. 3304 The defaults are C<~/.texliveYYYY/texmf-{config,var}>, except on Macs, 3305 where the leading dot is omitted (C<~/texliveYYYY/...>). 3306 3307 =item B<-v> 3308 3309 Include verbose debugging messages; repeat for maximum debugging: C<-v 3310 -v>. (Further repeats are accepted but ignored.) 3311 3312 =item B<-version>, B<--version> 3313 3314 Output version information and exit. If C<-v> is also given, the 3315 versions of the TeX Live modules used are also reported. 3316 3317 =back 3318 3319 =head1 PROFILES 3320 3321 A I<profile> file normally contains all the values needed to perform an 3322 installation. After a normal installation has finished, a profile for 3323 that exact installation is written to the file C<tlpkg/texlive.profile>. 3324 In addition, from the text menu one can select C<P> to save the current 3325 setup as a profile at any time. These are small text files; feel free to 3326 peruse and edit them according to your needs. 3327 3328 Such a profile file can be given as the argument to C<-profile>, for 3329 example to redo the exact same installation on a different system. 3330 Alternatively, you can use a custom profile, most easily created by 3331 starting from a generated one and changing values. An empty profile 3332 file will cause the installer to use the defaults. 3333 3334 As mentioned above, the installer only supports selection by scheme and 3335 collections, not individual packages, so packages cannot be specified in 3336 profile files either. Use C<tlmgr> to work at the package level. 3337 3338 Within a profile file, each line consists of 3339 3340 I<variable> [I<value>] 3341 3342 except for comment lines starting with C<#>. The possible variable 3343 names are listed below. Values, when present, are either C<0> or C<1> 3344 for booleans, or strings (which must be specified without any quote 3345 characters). Leading whitespace is ignored. 3346 3347 If the variable C<selected_scheme> is defined and I<no> collection 3348 variables at all are defined, then the collections required by the 3349 specified scheme (which might change over time) are installed, without 3350 explicitly listing them. This eases maintenance of profile files. If any 3351 collections are specified in a profile, though, then the scheme is 3352 ignored and all desired collections must be given explicitly. 3353 3354 For example, a line 3355 3356 selected_scheme scheme-small 3357 3358 along with definitions for the installation directories (given below 3359 under "path options") suffices to install the "small" scheme with all 3360 default options. The schemes are described in the C<S> menu in the 3361 text installer, or equivalent. 3362 3363 In addition to C<selected_scheme>, here are the other variable names 3364 supported in a profile: 3365 3366 B<collection options> (prefix C<collection->) 3367 3368 Collections are specified with a variable name with the prefix 3369 C<collection-> followed by a collection name; there is no value. For 3370 instance, C<collection-basic>. The collections are described in the 3371 C<C> menu. 3372 3373 Schemes and collections (and packages) are ultimately defined by the 3374 files in the C<tlpkg/tlpsrc/> source directory. 3375 3376 B<path options> 3377 3378 It is best to define all of these, even though they may not be used in a 3379 given installation, so as to avoid unintentionally getting a default 3380 value that could cause problems later. 3381 3382 TEXDIR 3383 TEXMFLOCAL 3384 TEXMFSYSCONFIG 3385 TEXMFSYSVAR 3386 TEXMFCONFIG 3387 TEXMFVAR 3388 TEXMFHOME 3389 3390 B<installer options> (prefix C<instopt_>) 3391 3392 =over 4 3393 3394 =item C<instopt_adjustpath> (default 0 on Unix, 1 on Windows) 3395 3396 Adjust C<PATH> environment variable. 3397 3398 =item C<instopt_adjustrepo> (default 1) 3399 3400 Set remote repository to a multiplexed CTAN mirror after installation; 3401 see C<-repository> above. 3402 3403 =item C<instopt_letter> (default 0) 3404 3405 Set letter size paper as the default, instead of a4. 3406 3407 =item C<instopt_portable> (default 0) 3408 3409 Install for portable use, e.g., on a USB stick, without touching the 3410 host system. Specifically, this forces the user directories 3411 C<TEXMFHOME>, C<TEXMFCONFIG>, C<TEXMFVAR> to be identical to the system 3412 directories C<TEXMFLOCAL>, C<TEXMFSYSCONFIG>, C<TEXMFSYSVAR>, 3413 respectively (regardless of other options and environment variable.) 3414 3415 In addition, on Windows, it disables the desktop integration, path 3416 adjustment, and file associations actions usually performed. 3417 3418 =item C<instopt_write18_restricted> (default 1) 3419 3420 Enable C<\write18> for a restricted set of programs. 3421 3422 =back 3423 3424 B<tlpdb options> (prefix C<tlpdbopt_>) 3425 3426 The definitive list is given in C<tlpkg/TeXLive/TLConfig.pm>, in the hash 3427 C<%TeXLive::TLConfig::TLPDBOptions>, together with explanations. All 3428 items given there I<except> for C<tlpdbopt_location> can be specified. 3429 Here is the current list: 3430 3431 tlpdbopt_autobackup 3432 tlpdbopt_backupdir 3433 tlpdbopt_create_formats 3434 tlpdbopt_desktop_integration 3435 tlpdbopt_file_assocs 3436 tlpdbopt_generate_updmap 3437 tlpdbopt_install_docfiles 3438 tlpdbopt_install_srcfiles 3439 tlpdbopt_post_code 3440 tlpdbopt_sys_bin 3441 tlpdbopt_sys_info 3442 tlpdbopt_sys_man 3443 tlpdbopt_w32_multi_user 3444 3445 B<platform options> (prefix C<binary_>) 3446 3447 For each supported platform in TeX Live (directories under C<bin/>), the 3448 variable C<binary_>I<PLATFORM> can be set with value 1. For example: 3449 3450 binary_x86_64-linux 1 3451 3452 If no C<binary_> settings are made, the default is whatever the 3453 current machine is running. 3454 3455 In releases before 2017, many profile variables had different 3456 names (not documented here; see the C<install-tl> source). They are 3457 accepted and transformed to the names given above. When a profile is 3458 written, the names above are always used. 3459 3460 For more details on all of the above options, consult the TeX Live 3461 installation manual, linked from L<https://tug.org/texlive/doc>. 3462 3463 =head1 ENVIRONMENT VARIABLES 3464 3465 For ease in scripting and debugging, C<install-tl> looks for the 3466 following environment variables. They are not of interest for normal 3467 user installations. 3468 3469 =over 4 3470 3471 =item C<NOPERLDOC> 3472 3473 Don't try to run the C<--help> message through C<perldoc>. 3474 3475 =item C<TEXLIVE_DOWNLOADER> 3476 3477 =item C<TL_DOWNLOAD_PROGRAM> 3478 3479 =item C<TL_DOWNLOAD_ARGS> 3480 3481 These override the normal choice of a download program; see the C<tlmgr> 3482 documentation, e.g., 3483 L<https://tug.org/texlive/doc/tlmgr.html#ENVIRONMENT-VARIABLES>. 3484 3485 =item C<TEXLIVE_INSTALL_ENV_NOCHECK> 3486 3487 Omit the check for environment variables containing the string C<tex>. 3488 People developing TeX-related software are likely to have many such 3489 variables. 3490 3491 =item C<TEXLIVE_INSTALL_NO_CONTEXT_CACHE> 3492 3493 Omit creating the ConTeXt cache. This is useful for redistributors. 3494 3495 =item C<TEXLIVE_INSTALL_NO_DISKCHECK> 3496 3497 If set to 1, omit free disk space check. By default, if a 3498 POSIX-compliant C<df> program (supporting C<-Pk>) is available, the 3499 installer checks for available disk space in the selected installation 3500 location, and will abort installation if there is insufficient disk 3501 space, plus a margin of 100MB. An equivalent check is made on Windows 3502 (not involving C<df>). 3503 3504 =item C<TEXLIVE_INSTALL_NO_RESUME> 3505 3506 Omit check for installing on top of a previous installation and then 3507 asking about importing previous settings. 3508 3509 =item C<TEXLIVE_INSTALL_NO_WELCOME> 3510 3511 Omit printing the welcome message after successful installation, e.g., 3512 when testing. 3513 3514 =item C<TEXLIVE_INSTALL_PAPER> 3515 3516 Set the default paper size for all relevant programs; must be either 3517 C<letter> or C<a4>. The default is C<a4>. 3518 3519 =item C<TEXLIVE_INSTALL_PREFIX> 3520 3521 =item C<TEXLIVE_INSTALL_TEXMFCONFIG> 3522 3523 =item C<TEXLIVE_INSTALL_TEXMFVAR> 3524 3525 =item C<TEXLIVE_INSTALL_TEXMFHOME> 3526 3527 =item C<TEXLIVE_INSTALL_TEXMFLOCAL> 3528 3529 =item C<TEXLIVE_INSTALL_TEXMFSYSCONFIG> 3530 3531 =item C<TEXLIVE_INSTALL_TEXMFSYSVAR> 3532 3533 Specify the respective directories. C<TEXLIVE_INSTALL_PREFIX> defaults 3534 to C</usr/local/texlive>. All the defaults can be seen by running the 3535 installer interactively and then typing C<D> for the directory menu. 3536 3537 The various command line options for specifying directories override 3538 these environment variables; since specifying both is usually 3539 accidental, a warning is given if the values are different. 3540 3541 =back 3542 3543 =head1 DIRECTORY TREES 3544 3545 There are a plethora of ways to specify the plethora of directory trees 3546 used by TeX Live. By far the simplest, and recommended, approach is not 3547 to change anything. The defaults suffice for the vast majority of 3548 installations. 3549 3550 But, for the sake of explanation, here is a table of the trees and the 3551 command line options that change them. The first group of three are 3552 system directories, and the second group of three are user directories; 3553 the two groups are quite analogous. 3554 3555 +----------------+--------------------------------------+--------------+------------------+ 3556 | tree | default | group change | single change | 3557 +----------------+--------------------------------------+--------------+------------------+ 3558 | TEXMFLOCAL | /usr/local/texlive/texmf-local | --texdir | --texmflocal | 3559 | TEXMFSYSVAR | /usr/local/texlive/YYYY/texmf-var | --texdir | --texmfsysvar | 3560 | TEXMFSYSCONFIG | /usr/local/texlive/YYYY/texmf-config | --texdir | --texmfsysconfig | 3561 +----------------+--------------------------------------+--------------+------------------+ 3562 | TEXMFHOME | ~/texmf | --texuserdir | --texmfhome | 3563 | TEXMFVAR | ~/.texliveYYYY/texmf-var | --texuserdir | --texmfvar | 3564 | TEXMFCONFIG | ~/.texliveYYYY/texmf-config | --texuserdir | --texmfconfig | 3565 +----------------+--------------------------------------+--------------+------------------+ 3566 3567 In addition, as mentioned in the previous section, each tree has an 3568 environment variable C<TEXLIVE_INSTALL_>I<tree> which overrides the 3569 default; command line and profile settings both override environment 3570 variable settings. 3571 3572 The defaults vary slightly on Macs, as explained above in L</OPTIONS>. 3573 3574 For the user trees, the default value uses C<~>, and this is left as a 3575 literal C<~> in C<texmf.cnf>. That way, each user can have their own 3576 C<TEXMFHOME>, etc., as intended. On the other hand, for the system 3577 trees, if C<~> is used during the installation, this is assumed to 3578 simply be a typing shorthand, and the expanded home directory is written 3579 in C<texmf.cnf>, since it doesn't make sense to have user-specific 3580 system directories. 3581 3582 For more on the directory trees and their intended usage, see the main 3583 TeX Live documentation at L<https://tug.org/texlive/doc>. 3584 3585 =head1 BUGS 3586 3587 The C<install-tl> script copies itself into the installed tree. 3588 Usually, it can be run from there, using the installed tree as the 3589 source for another installation. Occasionally, however, there may be 3590 incompatibilities in the code of the new C<install-tl> and the 3591 infrastructure, resulting in (probably) inscrutable Perl errors. The 3592 way forward is to run C<install-tl> out of the installer package 3593 (C<install-tl-unx.tar.gz> or C<install-tl.zip>) instead of the 3594 installation. Feel free to also report the issue; usually the code 3595 can be easily synced up again. 3596 3597 By the way, do not try to use C<install-tl> to adjust options or 3598 installed packages in an existing installed tree. Use C<tlmgr> instead. 3599 3600 =head1 AUTHORS AND COPYRIGHT 3601 3602 This script and its documentation were written for the TeX Live 3603 distribution (L<https://tug.org/texlive>) and both are licensed under the 3604 GNU General Public License Version 2 or later. 3605 3606 $Id: install-tl 67839 2023-08-07 21:47:31Z preining $ 3607 =cut 3608 3609 # to remake HTML version: pod2html --cachedir=/tmp install-tl >/tmp/itl.html 3610 3611 ### Local Variables: 3612 ### perl-indent-level: 2 3613 ### tab-width: 2 3614 ### indent-tabs-mode: nil 3615 ### End: 3616 # vim:set tabstop=2 expandtab: #