|
#!/usr/bin/perl |
|
|
|
use strict; |
|
|
|
use FileHandle; |
|
|
|
# setting |
|
my %suf2com = ( |
|
'cc' => 'CXX', |
|
'cpp' => 'CXX', |
|
'cxx' => 'CXX', |
|
'C' => 'CXX', |
|
'c' => 'CC' |
|
); |
|
|
|
# load config |
|
my $cfgfile = new FileHandle("$ENV{'HOME'}/.kati"); |
|
my %cfgs; |
|
while (<$cfgfile>) { |
|
/^([^\s]*)\s+(.*)$/; |
|
$cfgs{$1} = $2; |
|
} |
|
|
|
# get targets |
|
my @targets; |
|
foreach (keys %suf2com) { |
|
if (-e "$ARGV[0].$_") { |
|
push @targets, "$ARGV[0].$_"; |
|
shift @ARGV; |
|
last; |
|
} |
|
elsif (-e $ARGV[0]) { |
|
if ($ARGV[0] =~ /\.$_$/) { |
|
push @targets, $ARGV[0]; |
|
shift @ARGV; |
|
last; |
|
} |
|
} |
|
} |
|
if (!$targets[0]) { |
|
opendir DIR, "."; |
|
foreach my $f (readdir DIR) { |
|
foreach (keys %suf2com) { |
|
if ($f =~ /\.$_$/) { |
|
push @targets, $f; |
|
} |
|
} |
|
} |
|
} |
|
if (!$targets[0]) { |
|
print "cannot find target.\n"; |
|
exit 1; |
|
} |
|
|
|
# set CFLAGS and LDFLAGS |
|
my $cflags; |
|
my $ldflags; |
|
|
|
my %feelings; |
|
my @maintargets; |
|
|
|
# default options |
|
$feelings{'default'} = 1; |
|
|
|
# get feeling options from include, and search main |
|
foreach my $f (@targets) { |
|
my $fh = new FileHandle $f; |
|
while (<$fh>) { |
|
if (/\#include/) { |
|
foreach my $c (keys %cfgs) { |
|
if (length $c > 1 && /$c/) { |
|
$feelings{$c} = 1; |
|
} |
|
} |
|
} |
|
elsif (/ main\s*\(/) { |
|
push @maintargets, $f; |
|
last; |
|
} |
|
} |
|
} |
|
|
|
# get feeling options from argv |
|
while (@ARGV) { |
|
last if ($ARGV[0] =~ /^-/); |
|
my $o = shift @ARGV; |
|
|
|
if ($o =~ /^\+(.*)/) { |
|
$feelings{$1} = -1; |
|
} |
|
else { |
|
$feelings{$o} = 1; |
|
} |
|
} |
|
|
|
# add feeling options |
|
foreach (keys %feelings) { |
|
if ($feelings{$_} == 1) { |
|
feeling_add_opt($_); |
|
} |
|
} |
|
|
|
# add argv options |
|
add_opt(join ' ', @ARGV); |
|
|
|
# create make file |
|
my $make = new FileHandle("Makefile.kati", "w"); |
|
print $make "CFLAGS = $cflags\n"; |
|
print $make "LDFLAGS = $ldflags\n"; |
|
print $make "OBJS = "; |
|
foreach (@targets) { |
|
my $o = to_o($_); |
|
print $make "$o "; |
|
} |
|
print $make "\n"; |
|
|
|
if ($maintargets[0]) { |
|
print $make "EXES = "; |
|
foreach (@maintargets) { |
|
my $e = to_exe($_); |
|
print $make "$e "; |
|
} |
|
print $make "\n"; |
|
print $make "TARGETS = "; |
|
foreach (@targets) { |
|
my $e = $_; |
|
print $make "$e "; |
|
} |
|
print $make "\n"; |
|
print $make "\n"; |
|
print $make "all: \$(EXES)\n"; |
|
} |
|
else { |
|
print $make "\n"; |
|
print $make "all: \$(OBJS)\n"; |
|
} |
|
print $make "\n"; |
|
foreach (@maintargets) { |
|
my $e = to_exe($_); |
|
my $c = $suf2com{get_suf($_)}; |
|
if ($maintargets[1]) { |
|
my $o = to_o($_); |
|
print $make "$e: $o\n"; |
|
print $make "\t\$($c) -o $e $o \$(LDFLAGS) \$(CFLAGS)\n"; |
|
} |
|
else { |
|
print $make "$e: \$(OBJS)\n"; |
|
print $make "\t\$($c) -o $e \$(OBJS) \$(LDFLAGS) \$(CFLAGS)\n"; |
|
} |
|
print $make "\n"; |
|
} |
|
my $suf = ""; |
|
foreach (@targets) { |
|
if (!$suf) { |
|
$suf = get_suf($_); |
|
} |
|
elsif ($suf ne get_suf($_)) { |
|
$suf = ""; |
|
last; |
|
} |
|
} |
|
if ($suf) { |
|
print $make ".$suf.o:\n"; |
|
print $make "\t\$($suf2com{$suf}) -c \$(CFLAGS) \$<\n"; |
|
print $make "\n"; |
|
} |
|
else { |
|
foreach (@targets) { |
|
my $o = to_o($_); |
|
my $c = $suf2com{get_suf($_)}; |
|
print $make "$o: $_\n"; |
|
print $make "\t\$($c) -c $_ \$(CFLAGS)\n"; |
|
print $make "\n"; |
|
} |
|
} |
|
|
|
print $make ".PHONY: clean\n"; |
|
print $make "clean:\n"; |
|
print $make "\t\$(RM) -f \$(OBJS) \$(EXES)\n"; |
|
print $make "\n"; |
|
print $make "depend:\n"; |
|
print $make "\tmakedepend -f Makefile.kati -Y -- \$(CFLAGS) \$(LDFLAGS) -- \$(TARGETS)"; |
|
print $make "\n"; |
|
|
|
$make->close(); |
|
|
|
system("make -f Makefile.kati depend"); |
|
system("make -f Makefile.kati"); |
|
|
|
# feeling add cflags and ldflags |
|
sub feeling_add_opt { |
|
my $opt = shift; |
|
if ($cfgs{$opt}) { |
|
add_opt($cfgs{$opt}); |
|
delete $cfgs{$opt}; |
|
} |
|
} |
|
|
|
sub get_suf { |
|
my $f = shift; |
|
$f =~ /\.([^\.]*)$/; |
|
return $1; |
|
} |
|
|
|
sub to_o { |
|
my $f = shift; |
|
$f =~ /^(.*)\.[^\.]*$/; |
|
return "$1.o"; |
|
} |
|
|
|
sub to_exe { |
|
my $f = shift; |
|
$f =~ /^(.*)\.[^\.]*$/; |
|
return $1; |
|
} |
|
|
|
# is ld option? |
|
sub is_ld { |
|
my $opt = shift; |
|
return $opt =~ /^-([lL]|Wl)/; |
|
} |
|
|
|
# add cflags and ldflags |
|
sub add_opt { |
|
my $opts = shift; |
|
|
|
$opts =~ s/\`([^\`]*)\`/`$1`/ge; |
|
|
|
foreach (split /\s+/, $opts) { |
|
if (/^\$(.*)/) { |
|
if ($feelings{$1} != -1) { |
|
feeling_add_opt($1); |
|
} |
|
} |
|
elsif (is_ld($_)) { |
|
$ldflags .= "$_ "; |
|
} |
|
else { |
|
$cflags .= "$_ "; |
|
} |
|
} |
|
} |