⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkfiles.pl

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 PL
📖 第 1 页 / 共 3 页
字号:
#!/usr/bin/env perl## Cross-platform Makefile generator.## Reads the file `Recipe' to determine the list of generated# executables and their component objects. Then reads the source# files to compute #include dependencies. Finally, writes out the# various target Makefiles.# PuTTY specifics which could still do with removing:#  - Mac makefile is not portabilised at all. Include directories#    are hardwired, and also the libraries are fixed. This is#    mainly because I was too scared to go anywhere near it.#  - sbcsgen.pl is still run at startup.use FileHandle;use Cwd;open IN, "Recipe" or do {    # We want to deal correctly with being run from one of the    # subdirs in the source tree. So if we can't find Recipe here,    # try one level up.    chdir "..";    open IN, "Recipe" or die "unable to open Recipe file\n";};# HACK: One of the source files in `charset' is auto-generated by# sbcsgen.pl. We need to generate that _now_, before attempting# dependency analysis.eval 'chdir "charset"; require "sbcsgen.pl"; chdir ".."';@srcdirs = ("./");$divert = undef; # ref to scalar in which text is currently being put$help = ""; # list of newline-free lines of help text$project_name = "project"; # this is a good enough default%makefiles = (); # maps makefile types to output makefile pathnames%makefile_extra = (); # maps makefile types to extra Makefile text%programs = (); # maps prog name + type letter to listref of objects/resources%groups = (); # maps group name to listref of objects/resourceswhile (<IN>) {  # Skip comments (unless the comments belong, for example because  # they're part of a diversion).  next if /^\s*#/ and !defined $divert;  chomp;  split;  if ($_[0] eq "!begin" and $_[1] eq "help") { $divert = \$help; next; }  if ($_[0] eq "!end") { $divert = undef; next; }  if ($_[0] eq "!name") { $project_name = $_[1]; next; }  if ($_[0] eq "!srcdir") { push @srcdirs, $_[1]; next; }  if ($_[0] eq "!makefile" and &mfval($_[1])) { $makefiles{$_[1]}=$_[2]; next;}  if ($_[0] eq "!begin") {      if (&mfval($_[1])) {	  $divert = \$makefile_extra{$_[1]};      } else {	  $divert = \$dummy;      }      next;  }  # If we're gathering help text, keep doing so.  if (defined $divert) { ${$divert} .= "$_\n"; next; }  # Ignore blank lines.  next if scalar @_ == 0;  # Now we have an ordinary line. See if it's an = line, a : line  # or a + line.  @objs = @_;  if ($_[0] eq "+") {    $listref = $lastlistref;    $prog = undef;    die "$.: unexpected + line\n" if !defined $lastlistref;  } elsif ($_[1] eq "=") {    $groups{$_[0]} = [] if !defined $groups{$_[0]};    $listref = $groups{$_[0]};    $prog = undef;    shift @objs; # eat the group name  } elsif ($_[1] eq ":") {    $listref = [];    $prog = $_[0];    shift @objs; # eat the program name  } else {    die "$.: unrecognised line type\n";  }  shift @objs; # eat the +, the = or the :  while (scalar @objs > 0) {    $i = shift @objs;    if ($groups{$i}) {      foreach $j (@{$groups{$i}}) { unshift @objs, $j; }    } elsif (($i eq "[G]" or $i eq "[C]" or $i eq "[M]" or              $i eq "[X]" or $i eq "[U]") and defined $prog) {      $type = substr($i,1,1);    } else {      push @$listref, $i;    }  }  if ($prog and $type) {    die "multiple program entries for $prog [$type]\n"        if defined $programs{$prog . "," . $type};    $programs{$prog . "," . $type} = $listref;  }  $lastlistref = $listref;}close IN;# Now retrieve the complete list of objects and resource files, and# construct dependency data for them. While we're here, expand the# object list for each program, and complain if its type isn't set.@prognames = sort keys %programs;%depends = ();@scanlist = ();foreach $i (@prognames) {  ($prog, $type) = split ",", $i;  # Strip duplicate object names.  $prev = undef;  @list = grep { $status = ($prev ne $_); $prev=$_; $status }          sort @{$programs{$i}};  $programs{$i} = [@list];  foreach $j (@list) {    # Dependencies for "x" start with "x.c".    # Dependencies for "x.res" start with "x.rc".    # Dependencies for "x.rsrc" start with "x.r".    # Both types of file are pushed on the list of files to scan.    # Libraries (.lib) don't have dependencies at all.    if ($j =~ /^(.*)\.res$/) {      $file = "$1.rc";      $depends{$j} = [$file];      push @scanlist, $file;    } elsif ($j =~ /^(.*)\.rsrc$/) {      $file = "$1.r";      $depends{$j} = [$file];      push @scanlist, $file;    } elsif ($j =~ /\.lib$/) {      # libraries don't have dependencies    } else {      $file = "$j.c";      $depends{$j} = [$file];      push @scanlist, $file;    }  }}# Scan each file on @scanlist and find further inclusions.# Inclusions are given by lines of the form `#include "otherfile"'# (system headers are automatically ignored by this because they'll# be given in angle brackets). Files included by this method are# added back on to @scanlist to be scanned in turn (if not already# done).## Resource scripts (.rc) can also include a file by means of a line# ending `ICON "filename"'. Files included by this method are not# added to @scanlist because they can never include further files.## In this pass we write out a hash %further which maps a source# file name into a listref containing further source file names.%further = ();while (scalar @scanlist > 0) {  $file = shift @scanlist;  next if defined $further{$file}; # skip if we've already done it  $resource = ($file =~ /\.rc$/ ? 1 : 0);  $further{$file} = [];  $dirfile = &findfile($file);  open IN, "$dirfile" or die "unable to open source file $file\n";  while (<IN>) {    chomp;    /^\s*#include\s+\"([^\"]+)\"/ and do {      push @{$further{$file}}, $1;      push @scanlist, $1;      next;    };    /ICON\s+\"([^\"]+)\"\s*$/ and do {      push @{$further{$file}}, $1;      next;    }  }  close IN;}# Now we're ready to generate the final dependencies section. For# each key in %depends, we must expand the dependencies list by# iteratively adding entries from %further.foreach $i (keys %depends) {  %dep = ();  @scanlist = @{$depends{$i}};  foreach $i (@scanlist) { $dep{$i} = 1; }  while (scalar @scanlist > 0) {    $file = shift @scanlist;    foreach $j (@{$further{$file}}) {      if ($dep{$j} != 1) {        $dep{$j} = 1;        push @{$depends{$i}}, $j;        push @scanlist, $j;      }    }  }#  printf "%s: %s\n", $i, join ' ',@{$depends{$i}};}# Validation of input.sub mfval($) {    my ($type) = @_;    # Returns true if the argument is a known makefile type. Otherwise,    # prints a warning and returns false;    if (grep { $type eq $_ }	("vc","vcproj","cygwin","borland","lcc","gtk","mpw")) {	    return 1;	}    warn "$.:unknown makefile type '$type'\n";    return 0;}# Utility routines while writing out the Makefiles.sub dirpfx {    my ($path) = shift @_;    my ($sep) = shift @_;    my $ret = "", $i;    while (($i = index $path, $sep) >= 0) {	$path = substr $path, ($i + length $sep);	$ret .= "..$sep";    }    return $ret;}sub findfile {  my ($name) = @_;  my $dir, $i, $outdir = "";  unless (defined $findfilecache{$name}) {    $i = 0;    foreach $dir (@srcdirs) {      $outdir = $dir, $i++ if -f "$dir$name";    }    die "multiple instances of source file $name\n" if $i > 1;    $findfilecache{$name} = $outdir . $name;  }  return $findfilecache{$name};}sub objects {  my ($prog, $otmpl, $rtmpl, $ltmpl, $prefix, $dirsep) = @_;  my @ret;  my ($i, $x, $y);  @ret = ();  foreach $i (@{$programs{$prog}}) {    $x = "";    if ($i =~ /^(.*)\.(res|rsrc)/) {      $y = $1;      ($x = $rtmpl) =~ s/X/$y/;    } elsif ($i =~ /^(.*)\.lib/) {      $y = $1;      ($x = $ltmpl) =~ s/X/$y/;    } else {      ($x = $otmpl) =~ s/X/$i/;    }    push @ret, $x if $x ne "";  }  return join " ", @ret;}sub splitline {  my ($line, $width, $splitchar) = @_;  my ($result, $len);  $len = (defined $width ? $width : 76);  $splitchar = (defined $splitchar ? $splitchar : '\\');  while (length $line > $len) {    $line =~ /^(.{0,$len})\s(.*)$/ or $line =~ /^(.{$len,}?\s(.*)$/;    $result .= $1 . " ${splitchar}\n\t\t";    $line = $2;    $len = 60;  }  return $result . $line;}sub deps {  my ($otmpl, $rtmpl, $prefix, $dirsep, $depchar, $splitchar) = @_;  my ($i, $x, $y);  my @deps, @ret;  @ret = ();  $depchar ||= ':';  foreach $i (sort keys %depends) {    if ($i =~ /^(.*)\.(res|rsrc)/) {      next if !defined $rtmpl;      $y = $1;      ($x = $rtmpl) =~ s/X/$y/;    } else {      ($x = $otmpl) =~ s/X/$i/;    }    @deps = @{$depends{$i}};    @deps = map {      $_ = &findfile($_);      s/\//$dirsep/g;      $_ = $prefix . $_;    } @deps;    push @ret, {obj => $x, deps => [@deps]};  }  return @ret;}sub prognames {  my ($types) = @_;  my ($n, $prog, $type);  my @ret;  @ret = ();  foreach $n (@prognames) {    ($prog, $type) = split ",", $n;    push @ret, $n if index($types, $type) >= 0;  }  return @ret;}sub progrealnames {  my ($types) = @_;  my ($n, $prog, $type);  my @ret;  @ret = ();  foreach $n (@prognames) {    ($prog, $type) = split ",", $n;    push @ret, $prog if index($types, $type) >= 0;  }  return @ret;}sub manpages {  my ($types,$suffix) = @_;  # assume that all UNIX programs have a man page  if($suffix eq "1" && $types =~ /X/) {    return map("$_.1", &progrealnames($types));  }  return ();}# Now we're ready to output the actual Makefiles.if (defined $makefiles{'cygwin'}) {    $dirpfx = &dirpfx($makefiles{'cygwin'}, "/");    ##-- CygWin makefile    open OUT, ">$makefiles{'cygwin'}"; select OUT;    print    "# Makefile for $project_name under cygwin.\n".    "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".    "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";    # gcc command line option is -D not /D    ($_ = $help) =~ s/=\/D/=-D/gs;    print $_;    print    "\n".    "# You can define this path to point at your tools if you need to\n".    "# TOOLPATH = c:\\cygwin\\bin\\ # or similar, if you're running Windows\n".    "# TOOLPATH = /pkg/mingw32msvc/i386-mingw32msvc/bin/\n".    "CC = \$(TOOLPATH)gcc\n".    "RC = \$(TOOLPATH)windres\n".    "# Uncomment the following two lines to compile under Winelib\n".    "# CC = winegcc\n".    "# RC = wrc\n".    "# You may also need to tell windres where to find include files:\n".    "# RCINC = --include-dir c:\\cygwin\\include\\\n".    "\n".    &splitline("CFLAGS = -mno-cygwin -Wall -O2 -D_WINDOWS -DDEBUG -DWIN32S_COMPAT".      " -D_NO_OLDNAMES -DNO_MULTIMON " .

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -