contrib / buildsystems / parse.plon commit Merge branch 'tr/xsize-bits' into maint (745654f)
   1#!/usr/bin/perl -w
   2######################################################################
   3# Do not call this script directly!
   4#
   5# The generate script ensures that @INC is correct before the engine
   6# is executed.
   7#
   8# Copyright (C) 2009 Marius Storm-Olsen <mstormo@gmail.com>
   9######################################################################
  10use strict;
  11use File::Basename;
  12use Cwd;
  13
  14my $file = $ARGV[0];
  15die "No file provided!" if !defined $file;
  16
  17my ($cflags, $target, $type, $line);
  18
  19open(F, "<$file") || die "Couldn't open file $file";
  20my @data = <F>;
  21close(F);
  22
  23while (my $text = shift @data) {
  24    my $ate_next;
  25    do {
  26        $ate_next = 0;
  27        $line++;
  28        chomp $text;
  29        chop $text if ($text =~ /\r$/);
  30        if ($text =~ /\\$/) {
  31            $text =~ s/\\$//;
  32            $text .= shift @data;
  33            $ate_next = 1;
  34        }
  35    } while($ate_next);
  36
  37    if($text =~ / -c /) {
  38        # compilation
  39        handleCompileLine($text, $line);
  40
  41    } elsif ($text =~ / -o /) {
  42        # linking executable
  43        handleLinkLine($text, $line);
  44
  45    } elsif ($text =~ /\.o / && $text =~ /\.a /) {
  46        # libifying
  47        handleLibLine($text, $line);
  48
  49#    } elsif ($text =~ /^cp /) {
  50#        # copy file around
  51#
  52#    } elsif ($text =~ /^rm -f /) {
  53#        # shell command
  54#
  55#    } elsif ($text =~ /^make[ \[]/) {
  56#        # make output
  57#
  58#    } elsif ($text =~ /^echo /) {
  59#        # echo to file
  60#
  61#    } elsif ($text =~ /^if /) {
  62#        # shell conditional
  63#
  64#    } elsif ($text =~ /^tclsh /) {
  65#        # translation stuff
  66#
  67#    } elsif ($text =~ /^umask /) {
  68#        # handling boilerplates
  69#
  70#    } elsif ($text =~ /\$\(\:\)/) {
  71#        # ignore
  72#
  73#    } elsif ($text =~ /^FLAGS=/) {
  74#        # flags check for dependencies
  75#
  76#    } elsif ($text =~ /^'\/usr\/bin\/perl' -MError -e/) {
  77#        # perl commands for copying files
  78#
  79#    } elsif ($text =~ /generate-cmdlist\.sh/) {
  80#        # command for generating list of commands
  81#
  82#    } elsif ($text =~ /^test / && $text =~ /|| rm -f /) {
  83#        # commands removing executables, if they exist
  84#
  85#    } elsif ($text =~ /new locations or Tcl/) {
  86#        # command for detecting Tcl/Tk changes
  87#
  88#    } elsif ($text =~ /mkdir -p/) {
  89#        # command creating path
  90#
  91#    } elsif ($text =~ /: no custom templates yet/) {
  92#        # whatever
  93
  94    } else {
  95#        print "Unhandled (line: $line): $text\n";
  96    }
  97}
  98close(F);
  99
 100# use Data::Dumper;
 101# print "Parsed build structure:\n";
 102# print Dumper(%build_structure);
 103
 104# -------------------------------------------------------------------
 105# Functions under here
 106# -------------------------------------------------------------------
 107my (%build_structure, @defines, @incpaths, @cflags, @sources);
 108
 109sub clearCompileStep
 110{
 111    @defines = ();
 112    @incpaths = ();
 113    @cflags = ();
 114    @sources = ();
 115}
 116
 117sub removeDuplicates
 118{
 119    my (%dupHash, $entry);
 120    %dupHash = map { $_, 1 } @defines;
 121    @defines = keys %dupHash;
 122
 123    %dupHash = map { $_, 1 } @incpaths;
 124    @incpaths = keys %dupHash;
 125
 126    %dupHash = map { $_, 1 } @cflags;
 127    @cflags = keys %dupHash;
 128
 129    %dupHash = map { $_, 1 } @sources;
 130    @sources = keys %dupHash;
 131}
 132
 133sub handleCompileLine
 134{
 135    my ($line, $lineno) = @_;
 136    my @parts = split(' ', $line);
 137    shift(@parts); # ignore cmd
 138    while (my $part = shift @parts) {
 139        if ("$part" eq "-o") {
 140            # ignore object file
 141            shift @parts;
 142        } elsif ("$part" eq "-c") {
 143            # ignore compile flag
 144        } elsif ("$part" eq "-c") {
 145        } elsif ($part =~ /^.?-I/) {
 146            push(@incpaths, $part);
 147        } elsif ($part =~ /^.?-D/) {
 148            push(@defines, $part);
 149        } elsif ($part =~ /^-/) {
 150            push(@cflags, $part);
 151        } elsif ($part =~ /\.(c|cc|cpp)$/) {
 152            push(@sources, $part);
 153        } else {
 154            die "Unhandled compiler option @ line $lineno: $part";
 155        }
 156    }
 157    #print "Sources: @sources\nCFlags: @cflags\nDefine: @defines\nIncpat: @incpaths\n";
 158    #exit(1);
 159}
 160
 161sub handleLibLine
 162{
 163    my ($line, $lineno) = @_;
 164    my (@objfiles, @lflags, $libout, $part);
 165    # kill cmd and rm 'prefix'
 166    $line =~ s/^rm -f .* && .* rcs //;
 167    my @parts = split(' ', $line);
 168    while ($part = shift @parts) {
 169        if ($part =~ /^-/) {
 170            push(@lflags, $part);
 171        } elsif ($part =~ /\.(o|obj)$/) {
 172            push(@objfiles, $part);
 173        } elsif ($part =~ /\.(a|lib)$/) {
 174            $libout = $part;
 175        } else {
 176            die "Unhandled lib option @ line $lineno: $part";
 177        }
 178    }
 179    #print "LibOut: '$libout'\nLFlags: @lflags\nOfiles: @objfiles\n";
 180    #exit(1);
 181    removeDuplicates();
 182    push(@{$build_structure{"LIBS"}}, $libout);
 183    @{$build_structure{"LIBS_${libout}"}} = ("_DEFINES", "_INCLUDES", "_CFLAGS", "_SOURCES",
 184                                             "_OBJECTS");
 185    @{$build_structure{"LIBS_${libout}_DEFINES"}} = @defines;
 186    @{$build_structure{"LIBS_${libout}_INCLUDES"}} = @incpaths;
 187    @{$build_structure{"LIBS_${libout}_CFLAGS"}} = @cflags;
 188    @{$build_structure{"LIBS_${libout}_SOURCES"}} = @sources;
 189    @{$build_structure{"LIBS_${libout}_OBJECTS"}} = @objfiles;
 190    clearCompileStep();
 191}
 192
 193sub handleLinkLine
 194{
 195    my ($line, $lineno) = @_;
 196    my (@objfiles, @lflags, @libs, $appout, $part);
 197    my @parts = split(' ', $line);
 198    shift(@parts); # ignore cmd
 199    while ($part = shift @parts) {
 200        if ($part =~ /^-[GRIDO]/) {
 201            # eat compiler flags
 202        } elsif ("$part" eq "-o") {
 203            $appout = shift @parts;
 204        } elsif ($part =~ /^-/) {
 205            push(@lflags, $part);
 206        } elsif ($part =~ /\.(a|lib)$/) {
 207            push(@libs, $part);
 208        } elsif ($part =~ /\.(o|obj)$/) {
 209            push(@objfiles, $part);
 210        } else {
 211            die "Unhandled lib option @ line $lineno: $part";
 212        }
 213    }
 214    #print "AppOut: '$appout'\nLFlags: @lflags\nLibs  : @libs\nOfiles: @objfiles\n";
 215    #exit(1);
 216    removeDuplicates();
 217    push(@{$build_structure{"APPS"}}, $appout);
 218    @{$build_structure{"APPS_${appout}"}} = ("_DEFINES", "_INCLUDES", "_CFLAGS", "_LFLAGS",
 219                                             "_SOURCES", "_OBJECTS", "_LIBS");
 220    @{$build_structure{"APPS_${appout}_DEFINES"}} = @defines;
 221    @{$build_structure{"APPS_${appout}_INCLUDES"}} = @incpaths;
 222    @{$build_structure{"APPS_${appout}_CFLAGS"}} = @cflags;
 223    @{$build_structure{"APPS_${appout}_LFLAGS"}} = @lflags;
 224    @{$build_structure{"APPS_${appout}_SOURCES"}} = @sources;
 225    @{$build_structure{"APPS_${appout}_OBJECTS"}} = @objfiles;
 226    @{$build_structure{"APPS_${appout}_LIBS"}} = @libs;
 227    clearCompileStep();
 228}