New flag for GenLibDeps, and llvm-config-perobjincl.

This allows to show the explicit files that need to be built/linked to get an
LLVM component.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95300 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Torok Edwin 2010-02-04 09:31:35 +00:00
parent 7db21bdb7d
commit 18743f4502
3 changed files with 187 additions and 1 deletions

View File

@ -53,6 +53,46 @@ llvm-config.in: $(ConfigInIn) $(ConfigStatusScript)
$(Verb) cd $(PROJ_OBJ_ROOT) ; \
$(ConfigStatusScript) tools/llvm-config/llvm-config.in
llvm-config-perobj: llvm-config.in $(GenLibDeps) $(LibDir) $(wildcard $(LibDir)/*.a)
$(Echo) "Generating llvm-config-perobj"
$(Verb) $(PERL) $(GenLibDeps) -perobj -flat $(LibDir) "$(NM_PATH)" >PerobjDeps.txt
$(Echo) "Checking for cyclic dependencies between LLVM objects."
$(Verb) $(PERL) $(PROJ_SRC_DIR)/find-cycles.pl < PerobjDepsIncl.txt > PerobjDepsInclFinal.txt || rm -f $@
$(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \
> temp.sed
$(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \
>> temp.sed
$(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \
>> temp.sed
$(Verb) $(ECHO) 's/@LLVM_LDFLAGS@/$(subst /,\/,$(SUB_LDFLAGS))/' \
>> temp.sed
$(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(BuildMode))/' \
>> temp.sed
$(Verb) $(SED) -f temp.sed < $< > $@
$(Verb) $(RM) temp.sed
$(Verb) cat PerobjDepsFinal.txt >> $@
$(Verb) chmod +x $@
llvm-config-perobjincl: llvm-config.in $(GenLibDeps) $(LibDir) $(wildcard $(LibDir)/*.a)
$(Echo) "Generating llvm-config-perobjincl"
$(Verb) $(PERL) $(GenLibDeps) -perobj -perobjincl -flat $(LibDir) "$(NM_PATH)" >PerobjDepsIncl.txt
$(Echo) "Checking for cyclic dependencies between LLVM objects."
$(Verb) $(PERL) $(PROJ_SRC_DIR)/find-cycles.pl < PerobjDepsIncl.txt > PerobjDepsInclFinal.txt
$(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \
> temp.sed
$(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \
>> temp.sed
$(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \
>> temp.sed
$(Verb) $(ECHO) 's/@LLVM_LDFLAGS@/$(subst /,\/,$(SUB_LDFLAGS))/' \
>> temp.sed
$(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(BuildMode))/' \
>> temp.sed
$(Verb) $(SED) -f temp.sed < $< > $@
$(Verb) $(RM) temp.sed
$(Verb) cat PerobjDepsInclFinal.txt >> $@
$(Verb) chmod +x $@
# Build our final script.
$(ToolDir)/llvm-config: llvm-config.in $(FinalLibDeps)
$(Echo) "Building llvm-config script."

View File

@ -62,6 +62,11 @@ foreach my $cycle (@CYCLES) {
print STDERR "find-cycles.pl: Circular dependency between *.a files:\n";
print STDERR "find-cycles.pl: ", join(' ', @archives), "\n";
push @modules, @archives; # WORKAROUND: Duplicate *.a files. Ick.
} elsif (@modules > 1) {
$cycles_found = $cycles_found + 1;
print STDERR "find-cycles.pl: Circular dependency between *.o files:\n";
print STDERR "find-cycles.pl: ", join(' ', @modules), "\n";
push @modules, @modules; # WORKAROUND: Duplicate *.o files. Ick.
}
# Add to our output. (@modules is already as sorted as we need it to be.)

View File

@ -9,10 +9,12 @@
# Syntax: GenLibDeps.pl [-flat] <directory_with_libraries_in_it> [path_to_nm_binary]
#
use strict;
use warnings;
# Parse arguments...
my $FLAT = 0;
my $WHY = 0;
my $PEROBJ = 0;
my $PEROBJINCL = 0;
while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) {
shift;
last if /^--$/; # Stop processing arguments on --
@ -20,6 +22,8 @@ while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) {
# List command line options here...
if (/^-flat$/) { $FLAT = 1; next; }
if (/^-why/) { $WHY = 1; $FLAT = 1; next; }
if (/^-perobj$/) { $PEROBJ = 1; next; }
if (/^-perobjincl/) { $PEROBJINCL = 1; next;}
print "Unknown option: $_ : ignoring!\n";
}
@ -47,6 +51,19 @@ if (!defined($nmPath) || $nmPath eq "") {
die "Can't find 'nm'" if (! -x "$nmPath");
}
my $ranlibPath;
if ($PEROBJ) {
$ranlibPath = $ARGV[2];
if (defined($ENV{RANLIB})) {
chomp($ranlibPath=$ENV{RANLIB});
}
if (!defined($ranlibPath) || $ranlibPath eq "") {
chomp($ranlibPath=`which ranlib`);
die "Can't find 'ranlib'" if (! -x "$ranlibPath");
}
}
# Open the directory and read its contents, sorting by name and differentiating
# by whether its a library (.a) or an object file (.o)
opendir DIR,$Directory;
@ -60,6 +77,93 @@ my @objs = grep(/LLVM.*\.o$/,sort(@files));
my %libdefs;
my %objdefs;
my %libobjs;
my %objdeps=();
# Gather library definitions at object file granularity (optional)
if ($PEROBJ) {
foreach my $lib (@libs ) {
`$ranlibPath $Directory/$lib`;
my $libpath = $lib;
$libpath =~ s/^libLLVM(.*)\.a/$1/;
$libpath =~ s/(.+)CodeGen$/Target\/$1/;
$libpath =~ s/(.+)AsmPrinter$/Target\/$1\/AsmPrinter/;
$libpath =~ s/(.+)AsmParser$/Target\/$1\/AsmParser/;
$libpath =~ s/(.+)Info$/Target\/$1\/TargetInfo/;
$libpath =~ s/(.+)Disassembler$/Target\/$1\/Disassembler/;
$libpath =~ s/SelectionDAG/CodeGen\/SelectionDAG/;
$libpath =~ s/^AsmPrinter/CodeGen\/AsmPrinter/;
$libpath =~ s/^BitReader/Bitcode\/Reader/;
$libpath =~ s/^BitWriter/Bitcode\/Writer/;
$libpath =~ s/^CBackend/Target\/CBackend/;
$libpath =~ s/^CppBackend/Target\/CppBackend/;
$libpath =~ s/^MSIL/Target\/MSIL/;
$libpath =~ s/^Core/VMCore/;
$libpath =~ s/^Instrumentation/Transforms\/Instrumentation/;
$libpath =~ s/^Interpreter/ExecutionEngine\/Interpreter/;
$libpath =~ s/^JIT/ExecutionEngine\/JIT/;
$libpath =~ s/^ScalarOpts/Transforms\/Scalar/;
$libpath =~ s/^TransformUtils/Transforms\/Utils/;
$libpath =~ s/^ipa/Analysis\/IPA/;
$libpath =~ s/^ipo/Transforms\/IPO/;
$libpath =~ s/^pic16passes/Target\/PIC16\/PIC16Passes/;
$libpath = "lib/".$libpath."/";
open DEFS, "$nmPath -sg $Directory/$lib|";
while (<DEFS>) {
chomp;
if (/^([^ ]*) in ([^ ]*)/) {
my $objfile = $libpath.$2;
$objdefs{$1} = $objfile;
$objdeps{$objfile} = {};
$libobjs{$lib}{$objfile}=1;
# my $p = "../llvm/".$objfile;
# $p =~ s/Support\/reg(.*).o/Support\/reg$1.c/;
# $p =~ s/.o$/.cpp/;
# unless (-e $p) {
# die "$p\n"
# }
}
}
close DEFS or die "nm failed";
}
foreach my $lib (@libs ) {
my $libpath = $lib;
$libpath =~ s/^libLLVM(.*)\.a/$1/;
$libpath =~ s/(.+)CodeGen$/Target\/$1/;
$libpath =~ s/(.+)AsmPrinter$/Target\/$1\/AsmPrinter/;
$libpath =~ s/(.+)AsmParser$/Target\/$1\/AsmParser/;
$libpath =~ s/(.+)Info$/Target\/$1\/TargetInfo/;
$libpath =~ s/(.+)Disassembler$/Target\/$1\/Disassembler/;
$libpath =~ s/SelectionDAG/CodeGen\/SelectionDAG/;
$libpath =~ s/^AsmPrinter/CodeGen\/AsmPrinter/;
$libpath =~ s/^BitReader/Bitcode\/Reader/;
$libpath =~ s/^BitWriter/Bitcode\/Writer/;
$libpath =~ s/^CBackend/Target\/CBackend/;
$libpath =~ s/^CppBackend/Target\/CppBackend/;
$libpath =~ s/^MSIL/Target\/MSIL/;
$libpath =~ s/^Core/VMCore/;
$libpath =~ s/^Instrumentation/Transforms\/Instrumentation/;
$libpath =~ s/^Interpreter/ExecutionEngine\/Interpreter/;
$libpath =~ s/^JIT/ExecutionEngine\/JIT/;
$libpath =~ s/^ScalarOpts/Transforms\/Scalar/;
$libpath =~ s/^TransformUtils/Transforms\/Utils/;
$libpath =~ s/^ipa/Analysis\/IPA/;
$libpath =~ s/^ipo/Transforms\/IPO/;
$libpath =~ s/^pic16passes/Target\/PIC16\/PIC16Passes/;
$libpath = "lib/".$libpath."/";
open UDEFS, "$nmPath -Aup $Directory/$lib|";
while (<UDEFS>) {
chomp;
if (/:([^:]+):/) {
my $obj = $libpath.$1;
s/[^ ]+: *U //;
if (defined($objdefs{$_})) {
$objdeps{$obj}{$objdefs{$_}}=1;
}
}
}
close UDEFS or die "nm failed"
}
} else {
# Gather definitions from the libraries
foreach my $lib (@libs ) {
open DEFS, "$nmPath -g $Directory/$lib|";
@ -72,6 +176,7 @@ foreach my $lib (@libs ) {
}
close DEFS or die "nm failed";
}
}
# Gather definitions from the object files.
foreach my $obj (@objs ) {
@ -109,6 +214,11 @@ sub gen_one_entry {
$DepLibs{$libdefs{$_}} = [] unless exists $DepLibs{$libdefs{$_}};
push(@{$DepLibs{$libdefs{$_}}}, $_);
} elsif (defined($objdefs{$_}) && $objdefs{$_} ne $lib) {
if ($PEROBJ && !$PEROBJINCL) {
# -perobjincl makes .a files depend on .o files they contain themselves
# default is don't depend on these.
next if defined $libobjs{$lib}{$objdefs{$_}};
}
my $libroot = $lib;
$libroot =~ s/lib(.*).a/$1/;
if ($objdefs{$_} ne "$libroot.o") {
@ -144,6 +254,25 @@ sub gen_one_entry {
}
close UNDEFS or die "nm failed";
}
if ($PEROBJINCL) {
# include the .a's objects
for my $obj (keys %{$libobjs{$lib}}) {
$DepLibs{$obj} = ["<.a object>"] unless exists $DepLibs{$obj};
}
my $madechange = 1;
while($madechange) {
$madechange = 0;
my %temp = %DepLibs;
foreach my $obj (keys %DepLibs) {
foreach my $objdeps (keys %{$objdeps{$obj}}) {
next if defined $temp{$objdeps};
push(@{$temp{$objdeps}}, $obj);
$madechange = 1;
}
}
%DepLibs = %temp;
}
}
for my $key (sort keys %DepLibs) {
if ($FLAT) {
@ -209,6 +338,18 @@ foreach my $lib (@libs) {
gen_one_entry($lib);
}
if ($PEROBJ) {
foreach my $obj (keys %objdeps) {
print "$obj:";
if (!$PEROBJINCL) {
foreach my $dep (keys %{$objdeps{$obj}}) {
print " $dep";
}
}
print "\n";
}
}
if (!$FLAT) {
print DOT "}\n";
close DOT;