| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- #!/usr/bin/perl -w
- use strict;
- use Getopt::Long;
- my $persistence_support;
- eval ( "use Tie::Persistent;" );
- if ( !defined($@) || (length($@) == 0) ) {
- $persistence_support = 1;
- } else {
- $persistence_support = 0;
- }
- my $defaultsearchpaths = "/usr/lib/pkgconfig:/usr/lib64/pkgconfig";
- ####### search_pc_files () // code date : 21.07.09 ######
- sub search_pc_files
- {
- my $search_paths = $ENV{'PKG_CONFIG_PATH'};
- if (!defined($search_paths)) {
- $search_paths = $defaultsearchpaths;
- }
- $search_paths .= ":.";
- my @paths = split /:+/, $search_paths;
- my $pc_locations;
- for my $path ( @paths )
- {
- my @pcfiles = glob ("$path/*.pc");
- for my $pcfile (@pcfiles)
- {
- chomp $pcfile;
- my ($pcname) = ($pcfile =~ /([^\/]+)\.pc$/);
- if ( !defined($pcname) ) {
- die ("unable to parse filename: $pcfile\n");
- }
- # print "$pcname -> $pcfile\n";
- $pc_locations->{$pcname} = "$pcfile";
- }
- }
- return $pc_locations;
- }
- ####### parse_pc_file () // code date : 21.07.09 ######
- sub parse_pc_file
- {
- my $pc_file = shift @_;
- my $data;
- my %vars;
- open ( FILE, "<$pc_file" ) or die ("$pc_file: $!\n");
- while (<FILE>)
- {
- chomp;
- # TODO: If a line contains "Cflags:-DVARIABLE=1 -I...", then this line is erroneously interpreted as a variable definition.
- # Hopefully for the grammar designers of pkg-config files, this case was forbidden, requiring a whitespace after each ":" and "="
- if ( /^(\S+?) *= *(.+?)$/ ) {
- my $key = $1;
- my $value = $2;
-
- for my $var ( keys %vars )
- {
- $value =~ s/\$\{$var\}/$vars{$var}/g;
- }
-
- $vars{$key} = $value;
- } elsif ( /^(\S+?) *: *(.+?)$/ ) {
- my $key = $1;
- my $value = $2;
- for my $var ( keys %vars )
- {
- $value =~ s/\$\{$var\}/$vars{$var}/g;
- }
- $data->{$key} = $value;
- }
- }
-
- close (FILE);
- return $data;
- }
- ####### print_pc_file () // code date : 21.07.09 ######
- sub print_pc_file
- {
- my $data = shift;
- for my $key ( keys %{$data} ) {
- my $value = $data->{$key};
- print "$key = $value\n";
- }
- }
- ####### get_pc_data () // code date : 21.07.09 ######
- sub get_pc_data
- {
- my $pkg = shift @_;
- my $file;
- if ( $pkg =~ /\.pc$/ ) {
- $file = $pkg;
- } else {
- my $pc_locations = shift @_;
- $file = $pc_locations->{$pkg};
- }
- if ( !defined($file) || !-f $file ) {
- print <<PKGNOTFOUND;
- Package $pkg was not found in the pkg-config search path.
- Perhaps you should add the directory containing \`$pkg.pc\'
- to the PKG_CONFIG_PATH environment variable
- No package '$pkg' found
- PKGNOTFOUND
- return undef;
- }
- my $data = parse_pc_file ($file);
- return $data;
- }
- ####### build_dependency_graph () // code date : 21.07.09 ######
- sub build_dependency_graph
- {
- my $pkg = shift @_;
- my $deptree = shift @_;
- my $pc_locations = shift @_;
- if ( exists $deptree->{$pkg} ) {
- # already included in dependency graph
- } else {
- my $data = get_pc_data ( $pkg, $pc_locations );
- $deptree->{$pkg}->{'data'} = $data;
- my $children = undef;
- if ( exists $data->{'Requires'} ) {
- my @pkg_childs = split /[\s\,]+/, $data->{'Requires'};
- for my $pkg_child ( @pkg_childs )
- {
- my $childnode = build_dependency_graph ( $pkg_child, $deptree, $pc_locations );
- push @{ $children }, $pkg_child;
- }
- }
- $deptree->{$pkg}->{'children'} = $children;
- $deptree->{$pkg}->{'childrencount'} = defined($children) ? scalar @{$children} : 0;
- }
- return $deptree->{$pkg};
- }
- ####### get_all_packages () // code date : 21.07.09 ######
- sub get_all_packages
- {
- my $pkg = shift @_;
- my $deptree = shift @_;
- my $pkglist = shift @_;
- my $pkghash = shift @_;
- if ( !exists( $deptree->{$pkg} ) ) {
- die ( "$pkg not found in the dependency graph\n" );
- }
- push @{$pkglist}, $pkg;
- $pkghash->{$pkg} = 1;
- my $children = $deptree->{$pkg}->{'children'};
- my $count = $deptree->{$pkg}->{'childrencount'};
- # print "pkg $pkg ($count)\n";
-
- if ( defined($children) ) {
- for my $child ( @{ $children } )
- {
- # if ( !exists $pkghash->{$child} ) {
- ($pkglist, $pkghash) = get_all_packages ( $child, $deptree, $pkglist, $pkghash );
- # }
- }
- }
- return ($pkglist, $pkghash);
- }
- ####### uniquify () // code date : 21.07.09 ######
- sub uniquify
- {
- my $pkg_list = shift @_;
- my @new_list;
- my %hash;
- for (my $i = scalar(@{$pkg_list})-1 ; $i >= 0 ; $i-- )
- {
- my $val = $pkg_list->[$i];
- next if ( exists $hash{$val} );
- $hash{$val} = 1;
- unshift @new_list, $val;
- }
- return @new_list;
- }
- ####### print_options () // code date : 21.07.09 ######
- sub print_options
- {
- my $root_packages = shift @_;
- my $deptree = shift @_;
- my $new_pkg_list = shift @_;
- my $options = shift @_;
- my $parameters = ""; # all parameters in a string :)
- my @plist_duplicates;
- for my $opt ( keys %{$options} )
- {
- next if ( $options->{$opt} != 1 );
- for my $deppkg ( @{$new_pkg_list} )
- {
- if($deptree->{$deppkg}->{'data'}->{$opt})
- {
- my @para = split /\s+/, $deptree->{$deppkg}->{'data'}->{$opt};
- push @plist_duplicates, @para;
- }
- }
- }
- my @plist = uniquify ( \@plist_duplicates );
- return join (' ', @plist);
- }
- ######################## handle conflicting libs
- ####### handle_known_permutation_difficulties () // code date : 27.01.10 ######
- sub handle_known_permutation_difficulties
- {
- my $options = shift @_;
- # WORKAROUND 1: CUDA and pthread
- if ( $options =~ /-lpthread.+?-lcuda/ )
- {
- $options =~ s/-lpthread//g;
- $options = $options . " " . "-lpthread";
- }
- return $options;
- }
- ################################### MAIN
- my $print_cflags = 0;
- my $print_libs = 0;
- my $print_modversion = 0;
- my $eval_exists = 0;
- my $print_version = 0;
- my $print_all_packages = 0;
- my ( $cache, $use_cache, $rebuild_cache ) = ( "", 0, 0);
- my $result = GetOptions ("libs" => \$print_libs,
- "cflags" => \$print_cflags,
- "cppflags" => \$print_cflags,
- "cxxflags" => \$print_cflags,
- "list-all" => \$print_all_packages,
- "modversion" => \$print_modversion,
- "exists" => \$eval_exists,
- "version" => \$print_version,
- "cache=s" => \$cache,
- "usecache" => \$use_cache );
- if ( $print_version )
- {
- print "slim-pkg-config 0.2 (c) Erik Rodner\n";
- exit;
- }
- my @root_packages = @ARGV;
- my %data;
- if ( !$persistence_support )
- {
- $use_cache = 0;
- }
- if ( $use_cache ) {
- if ( -f $cache ) {
- # read cache
- tie %data, 'Tie::Persistent', $cache, 'r';
- } else {
- $rebuild_cache = 1;
- tie %data, 'Tie::Persistent', $cache, 'rw';
- }
- }
- if ( !$use_cache || $rebuild_cache ) {
- $data{'locations'} = search_pc_files ();
- }
- if ( $eval_exists ) {
- for my $pkg ( @root_packages )
- {
- my $is_a_file = ( -f $pkg );
- if ( (!$is_a_file) && (! exists $data{'locations'}->{$pkg}) ) {
- #warn("$pkg does not exist.");
- exit(-1);
- }
- }
- exit(0);
- }
- if ( $print_all_packages )
- {
- print "Package list\n";
- for my $pkg ( keys %{ $data{'locations'} } )
- {
- my $pcdata = parse_pc_file($data{'locations'}->{$pkg});
- my $d = "";
- if ( exists($pcdata->{'Description'}) )
- {
- $d = $pcdata->{'Description'};
- }
- printf ("%-40s %-60s %s\n", $pkg, $d, $data{'locations'}->{$pkg});
- }
- exit(0);
- }
- # dummy to initialize memory
- $data{'deptree'}->{'_'} = 1;
- if ( !$use_cache || $rebuild_cache ) {
- for my $pkg ( @root_packages )
- {
- build_dependency_graph ( $pkg, $data{'deptree'}, $data{'locations'} );
- }
- }
- if ( $print_modversion ) {
- for my $pkg ( @root_packages )
- {
- print "$data{'deptree'}->{$pkg}->{'data'}->{'Version'}\n";
- }
- }
- if ( $print_cflags || $print_libs )
- {
- my $pkg_list;
- my $pkg_hash;
- for my $pkg ( @root_packages )
- {
- ($pkg_list, $pkg_hash) = get_all_packages ( $pkg, $data{'deptree'}, $pkg_list, $pkg_hash );
- }
- my @new_pkg_list = uniquify ( $pkg_list );
- my %options;
- $options{'Cflags'} = ($print_cflags);
- $options{'Libs'} = ($print_libs);
- my $options = print_options ( \@root_packages, $data{'deptree'}, \@new_pkg_list, \%options );
- if ( $print_libs )
- {
- $options = handle_known_permutation_difficulties ( $options );
- }
- print $options;
- print "\n";
- }
- if ( $rebuild_cache ) {
- # save tree
- (tied %data)->sync();
- }
- if ( $use_cache ) {
- untie %data;
- }
|