#!@pathperl@ # -*- perl -*- # Copyright (c) 2002-2005 Intel Corporation # All rights reserved. # # This file is distributed under the terms in the attached INTEL-LICENSE # file. If you do not find these files, copies can be found by writing to # Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, # 94704. Attention: Intel License Inquiry. # Configuration $TOSDIR = "@TOSDIR@"; $TOSDIR = $ENV{"TOSDIR"} if defined($ENV{"TOSDIR"}); $nescc = "@nescc_prefix@/bin/nescc"; $tossim = 0; $is_tos_1 = 0; $with_scheduler_flag = 1; # Support platform directory renaming for 2.x if (-d "$TOSDIR/platform") { $platform = "platform"; $is_tos_1 = 1; } else { $platform = "platforms"; } my $exeflag=0; my $libs = ""; # Have fun with the arguments for ($i = 0; $i <= $#ARGV; $i++) { $strip = 0; $_ = $ARGV[$i]; if (/^-/) { if (/^-target=(.*)/) { &fail("multiple targets specified") if defined($target); $target = $1; $strip = 1; } elsif (/^-tosdir=(.*)/) { $TOSDIR = $1; $strip = 1; } elsif (/^-tosscheduler=(.*)/) { $scheduler = $1; $strip = 1; } elsif (/^-nostdinc$/) { $nostdinc = 1; } elsif (/^-board=(.*)/) { push @boards, $1; $strip = 1; } elsif (/^-print-tosdir$/) { $print_tosdir = 1; $strip = 1; } elsif (/^-print-target$/) { $print_target = 1; $strip = 1; } elsif (/^-print-platforms$/) { $print_platforms = 1; $strip = 1; } elsif (/^-g$/) { $debugging = 1; } elsif (/^-v$/) { $verbose = 1; } elsif (/^-tossim$/) { $tossim = 1; $strip = 1; } elsif (/^-I/) { ($i, $file) = &extractarg($i); $strip = 1; push @includes, $file; } elsif (/^-safe$/) { $safe = 1; $strip = 1; } elsif (/^-fnesc-cfile=(.*)/){ $appfilename=$1; } elsif (/^-o$/){ $exeflag=1; } elsif (/^-l/) { $libs = $libs . " " . $_; } elsif (/^--version$/) { $print_version = 1; } } elsif ($exeflag) { $exefilename =$_; $exeflag=0; } push @new_args, $_ if !$strip; } if ($print_version) { print "ncc: @PACKAGE_VERSION@\n"; } # Remove trailing / from TOSDIR, if any (it confuses the topdir stuff) chop $TOSDIR if $TOSDIR =~ m!./$!; if ($print_tosdir) { print $TOSDIR, "\n"; exit 0; } if ($print_platforms) { print join(" ", all_platforms()), "\n"; exit 0; } if ($tossim) { push @new_args, "-DTOSSIM"; } if (!defined $target) { if (open DEFTARGET, "$TOSDIR/.default-platform") { $target = ; chomp $target; } else { $target = "@default_target@"; } } my $cpp; my $deputyasmexe; my $gcc; my $safe_home = $TOSDIR."/lib/safe"; push @new_args, "-fnesc-include=${safe_home}/include/annots_stage1"; push @new_args, "-fnesc-genprefix=#include \"${safe_home}/include/annots_stage2.h\""; if ($safe) { if (($target eq "mica2") or ($target eq "micaz")) { $mcu = "avr"; } elsif ($target eq "telosb") { $mcu = "msp430"; } else { print STDERR "Safe TinyOS does not (yet) support the ${target} target.\n"; print STDERR "Supported targets: "; print STDERR "mica2, micaz, telosb\n"; exit 2; } my $deputy_include = $ENV{'DEPUTY_HOME'}."/include"; push @new_args, "-DSAFE_TINYOS"; push @new_args, "-conly"; push @new_args, "-fnesc-deputy"; if (!defined $appfilename) { $appfilename="build/${target}/app.c"; } if (!defined $exefilename) { $exefilename="build/${target}/main.exe"; } $appfilename =~ m/^((.*\/)?)[^\/]+$/; my $directory = $1; # Might be useful to keep this app.c somewhere... # This could probably be avoided by using the deputy script # instead of the executable directly... $cpp = "${mcu}-gcc -E -DSAFE_TINYOS $appfilename -o ${directory}deputy-in.c -I${safe_home}/include"; # Not worrying about racing protection, for now... # --checksnescatomic racing.txt $deputyasmexe = "deputy-${mcu} --FLIDs --out ${directory}deputy-out.c ${directory}deputy-in.c"; $failfile = "${TOSDIR}/lib/safe/${mcu}/fail.c"; my $gccflags; if (($target eq "mica2") or ($target eq "micaz")) { $gccflags = ("-mmcu=atmega128 -Os -fdollars-in-identifiers " . "-finline-limit=1000000 -Winline " . "--param inline-unit-growth=1000000 " . "--param large-function-growth=1000000"); } elsif($target eq "telosb"){ $gccflags = "-Os -mdisable-hwmul -mmcu=msp430x1611"; } $gcc = ("${mcu}-gcc $gccflags -I${deputy_include} ${directory}deputy-out.c " . "$failfile -o $exefilename $libs"); } if (!defined $scheduler && !$is_tos_1) { $scheduler = "TinySchedulerC,TinySchedulerC.TaskBasic,TaskBasic,TaskBasic,runTask,postTask"; } if ($print_target) { print $target, "\n"; exit 0; } # First see if the directory for this platform was explicitly specified foreach $dir (@includes) { if ($dir =~ m!/$target/?$! && -f "$dir/.platform") { $platform_def = "$dir/.platform"; last; } } if (!-f $platform_def) { # Next, check if it's a "plain" platform if (-f "$TOSDIR/$platform/$target/.platform") { $platform_def = "$TOSDIR/$platform/$target/.platform"; } else { # Finally, see if it's in a platform family opendir PLATFORMS, "$TOSDIR/$platform"; foreach $dir (readdir PLATFORMS) { if (-f "$TOSDIR/$platform/$dir/.family") { if (-f "$TOSDIR/$platform/$dir/$target/.platform") { $platform_def = "$TOSDIR/$platform/$dir/$target/.platform"; $family_def = "$TOSDIR/$platform/$dir/.family"; last; } } } closedir PLATFORMS; } } # Use sim directory with tossim $platform_def =~ s!\.platform$!sim/.platform! if $tossim; $family_def =~ s!\.family$!sim/.family! if $tossim && $family_def; if (!-f $platform_def) { print STDERR "Unknown target $target\n"; print STDERR "Known targets for TinyOS directory $TOSDIR\n"; print STDERR "and the specified include directories are:\n"; @platforms = all_platforms(); if (@platforms) { print STDERR " ", join(" ", @platforms); } else { print STDERR "none."; } print STDERR "\n"; exit 2; } # Setup sensor boards push @includes, map "%T/sensorboards/$_", @boards unless $nostdinc; unshift @new_args, map "-DBOARD_\U$_", @boards; # Execute .sensor file in selected sensor board directories if it exists $i = 0; BOARD: while ($i <= $#boards) { $board = $boards[$i]; # First check include path for a .sensor file for this board foreach $dir (@includes) { if ($dir =~ m!/$board/?$! && -f "$dir/.sensor") { # Remove from @boards so that we don't add sensorboards/$board # to the search path splice @boards, $i, 1; do "$dir/.sensor"; next BOARD; } } # If none found, check the standard sensorboards directory $bspec = &idir_subst("%T/sensorboards/$board/.sensor"); do $bspec if -f $bspec; $i++; } # Setup platform $platform_dir = $platform_def; $platform_dir =~ s!/\.platform$!!; push @includes, $platform_dir unless $nostdinc; do $platform_def; do $family_def if -f $family_def; unshift @new_args, "-DPLATFORM_\U$target"; push @new_args, @opts; if(!$is_tos_1) { unshift @new_args, "-fnesc-scheduler=$scheduler"; } # old nesdoc: set the default topdir based on TOSDIR my ($tosparent) = ($TOSDIR =~ m!^(.*)/.*?$!); unshift @new_args, "-topdir=$tosparent"; unshift @new_args, "-fnesc-include=tos"; unshift @new_args, "$nescc"; if (!$nostdinc) { push @includes, map "%T/$platform/$_", @commonplatforms; push @includes, "%T/interfaces"; push @includes, "%T/types"; push @includes, "%T/system"; } if ($tossim) { foreach $idir (@includes) { $idir = &idir_subst($idir); push @new_args, "-I$idir/sim"; } $tossim_dir = &idir_subst("-I%T/lib/tossim"); push @new_args, $tossim_dir; } foreach $idir (@includes) { $idir = &idir_subst($idir); push @new_args, "-I$idir"; } print STDERR join(' ', @new_args), "\n" if $verbose; if ($safe) { # nescc runs and puts in annotations like COUNT etc... system(@new_args)==0 or die "Couldn't execute nescc\n"; # cpp changes annotations into attributes for deputy print STDERR "${cpp}\n" if $verbose; system($cpp)==0 or die "gcc preprocess error!\n"; # deputy inserts the checks print STDERR "${deputyasmexe}\n" if $verbose; system($deputyasmexe)==0 or die "deputy error!\n"; print STDERR "${gcc}\n" if $verbose; system($gcc)==0 or die "cil error!\n"; } else { exec @new_args; print STDERR "Couldn't execute nescc\n"; exit 2; } sub extractarg { local ($i) = @_; if (length($ARGV[$i]) == 2) { $arg = $ARGV[++$i]; } else { $arg = substr($ARGV[$i], 2); } return ($i, $arg); } sub idir_subst { local ($idir) = @_; local $idx = 0; while (($idx = index $idir, "%", $idx) >= 0) { $char = substr $idir, $idx + 1, 1; $rep = 0; $rep = "%" if $char eq "%"; $rep = $TOSDIR if $char eq "T"; $rep = $target if $char eq "p"; $rep = $platform_dir if $char eq "P"; &fail("unknown include-path substitution %" . $char) if !$rep; substr($idir, $idx, 2) = $rep; $idx += length $rep; } return $idir; } sub fail { print STDERR "$_[0]\n"; exit 2; } sub push_platform { my ($p) = @_; push @platforms, $p unless grep $_ eq $p, @platforms; } sub all_platforms() { local(@platforms); foreach $dir (@includes) { push_platform($1) if -f "$dir/.platform" && $dir =~ m!/([^/]*)/?$!; } if (opendir PLATFORMS, "$TOSDIR/$platform") { foreach $d (readdir PLATFORMS) { push_platform($d) if (-f "$TOSDIR/$platform/$d/.platform"); if (-f "$TOSDIR/$platform/$d/.family") { if (opendir SUBPLATFORMS, "$TOSDIR/$platform/$d") { foreach $subdir (readdir SUBPLATFORMS) { push_platform($subdir) if (-f "$TOSDIR/$platform/$d/$subdir/.platform"); } } closedir SUBPLATFORMS; } } closedir PLATFORMS; } return @platforms; }