cons-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Cons with output in Separate Subdirectories.


From: Giovanni Pietrobon
Subject: Re: Cons with output in Separate Subdirectories.
Date: Thu, 16 Nov 2000 13:02:16 -0600

Hi,
thank you really very much for your help.
Not only because the answer came very soon but also because you were
helping me much more than expected.

I have been able to set up almoust completely my Construct file.
The main difficulty for me was the fact that I didn't know the Perl
language.
But to learn it superficially it is not so difficult.

The main problem for a Windows user while using Cons is probably the
fact that his mindset is very different than a Unix user. The fact that
under Window is not possible to set up hard link (but only a true copy
of the files) stress this difference.

For me, I don't have HARD links but it is HARDLY acceptable to copy all
the src (*.c, *.cpp, *.cc, etc) and *.obj files in the build directory.
Also I didn't want to have to create Conscript files in the target
directories for a similar reason.

The following program does the work: it makes a double copy of the
source files only, and without any Conscript files.

Few questions remains, all around the method ProgramExec() which is
called in place of the method Program().
sub cons::ProgramExec {
  my ($env, $tgt, $src) = @_;

  Program $env $tgt, $src;

  # make the src also depend on the target executable.
  # *** commented because takes immediately all the computer's memory
!!! ***
  ### $env->Depends($src,$tgt);

  #print "Removing: $src\n";
  #unlink "$src";

   # make the target also depend on the bin2h executable.
  $cmd = '';
  $env->RunProgram($tgt, $src, $cmd);
}

1)
Cons wants to create the obj files where the src files are so I have to
Install the src files in the build subdirectory in order to be able to
have the obj files there.
It is not so important, but I tried to delete this double copy of the
source files in the build directories after having created the obj
files, but for this I had to use the instruction
    $env->Depends($src,$tgt);
This seems to work but it also makes my computer to absorb in a second
all the memory and more ( > 500 Mb !) until it crashes.

2)  ( THIS IS THE MOST IMPORTANT QUESTION  TO ME)
I need also to run the program just build (to test it) but before
building the next one.
I read carefully your suggestions about how to make sure 'to build the
executable before running it'.
I implemented it as you see in  $env->RunProgram($tgt, $src, $cmd);
but It didn't work.
It his possible to have more than an hint about that (unfortunatly I'm
running out of time for my project) ?
Do I have also to use system(), qx/STRING/, exec() or whatever to be
sure to get the return value before continuing to build the next source
file. Which one, and how ?

3)
I'm not able to understand well how the method Command works.
Which is the difference between a system (or exec ?) call and Command ?
What means %<. It is exactly like , &gt, &%lt ?

4)
Even If I create both debug and release versions, the outcome is only a
release version: I can see that from the dimension of the *.exe file.
Which flag do I have to set., and how ?

5) From your mail 'My Modifications' I see that you did I BIG work to
make easier the life for window users.
It is already existing an optional package for Windows ? I would like to
use at least some functions over there but I will need to time to
understand what they do. They also come to me with a lot of =3A =3D =20.
Perhaps there is already an easier way to use them.

6) Your mailing list is very usefull, but I'm sure that I missed a lot
of hints from there. Infact, it would be much more helpful if the
e-mails would not be divided month by month, but year by year or not at
all.  A search engine would be even better. I think that you would
receive much less question with that. This is told because to know the
opinion of new users can be useful.

6)
My function GetFileTitle() (and others) is horrific for a Perl user.

Despite my difficulties with the Perl language your program is extremely
powerful and able to do exactly what a person would expect to see when
using it..

Thank you very much.

Marcello



-------------------------------------------------------------------------------------------------

#Usage: cons.pl build\debug\tools\hello.exe /cpl=VC98 /bldmod=debug
/verbose=no
#   or: cons.pl . /cpl=VC98 /bldmod=debug /verbose=no


$Suffix_src = ".c";

@types = GetArguments();
SetVariables();

Export qw(CONS INCLUDE LIB PATH BIN BUILD
          BUILDTYPE EXPORT DEFINES COMPILER VERBOSE);

$CONSBASE = new cons ();

map(BuildConfig($_),@types);

sub BuildConfig {
    $BUILDTYPE = shift;

    # Where to put all our shared products.
    $EXPORT = "export\\$COMPILER\\$BUILDTYPE";
    $BUILD = "build\\$COMPILER\\$BUILDTYPE";
    $DEFINES = '/D "WIN32" /U "_WIN32_WINNT" /D "_WIN32_WINNT=0x0400" ';

    $DEFINES .= '/D "_DEBUG" /D "DEBUG" ' if $BUILDTYPE eq 'debug';
    $DEFINES .= '/D "NDEBUG" ' if $BUILDTYPE eq 'release';

    # character set selection
    # $DEFINES .= '/D "_MBCS" ';
    # Windows calls are conditioned on UNICODE rather
    # than _UNICODE, so define both
    $DEFINES .= '/D "_UNICODE" /D "UNICODE" ';

  #From Help Microsoft Visual C++ 6.0
  #/Ox  (Full Optimizations)
  #/Oy (Suppresses creation of frame pointers on the call stack. This
option speeds function calls, since no frame pointers need to be set up
and removed)
  #/Oy- (x86 Specific -> to gain maximum optimization with EBP-based
addressing)
  #/GZ  (Catch release-build errors in debug build and performs:
  #     Auto-initialization of local variables
  #     Function pointer call stack validation
  #     Call stack validation )
  #/Od Disables optimization
  #/Ob0 Disable Disables inline expansion (default)
  #/Ob1 Only __inline
  #/Ob2 Any Suitable

    # the '/Oy-' is so we can unroll the stack when debugging
    # a release build.
    $OPTFLAGS = (($BUILDTYPE eq 'debug') ? '/GZ /Od ' : '/Ob2 /Ox /Oy-
');
    $LDFLAGS = $CONSBASE->{LDFLAGS};

    # only on VTune compiler, only on release variant
    if ($param::compiler eq 'vtune' && $BUILDTYPE ne 'debug') {
      $OPTFLAGS .= '/QaxiMK '; # turn on MMX/SIMD optimization for
PII/III.
      $OPTFLAGS .= '/Qip '; # turn on interprocedure optimization
    }

    # Standard directories for sharing products.
#    $INCLUDE = "$EXPORT/include";
#    $LIB = "$EXPORT/lib";
#    $BIN = "$EXPORT/bin";
    $PATH = $PATH;
    $INCLUDE = $INCLUDE;
    $LIB = $LIB;

  $SubTools = "";    # $SubTools = "\\tools";   # $SubTools = "/tools";
  $SubLib   = "";    # $SubLib  = "\\lib";    # $SubLib  = "/lib";
  $SubCmd   = "";    # $SubCmd  = "\\cmd";    # $SubCmd  = "/cmd";
  $BIN = "$EXPORT$SubTools";

    # build off the "base" CONS object.
    $CONS = $CONSBASE->clone(
    CPPPATH => $INCLUDE,
    ENV => {
     PATH => $PATH,
     INCLUDE => $INCLUDE,
     LIB => $LIB,
    },

        LIBPATH => $LIB,
        DEFINES => $DEFINES,
        BIN2H => "$BIN\\bin2h.exe",   #  BIN2H => "$BIN/bin2h.exe",
#Greg Spencer
        MCCOM => "$vc98\\bin\\mc.exe",  #  MCCOM => "$vc98/bin/mc.exe",
#Greg Spencer
        OPTFLAGS => $OPTFLAGS,
        LDFLAGS => $LDFLAGS,
        THREADFLAGS => (($BUILDTYPE eq 'debug') ? '/MDd' : '/MD'),
        RCOPTFLAGS => (($BUILDTYPE eq 'debug') ? '/d "_DEBUG"' : '/d
"NDEBUG"'),
    CC => (($COMPILER eq 'gcc') ? 'gcc' : (($COMPILER eq 'vtune') ?
'icl' : 'cl')),
    );


  #Commented: under WIndows 2000 copies everything (no hard link)
    #Link "$BUILD$SubTools" => "#tools";
    #Link "$BUILD$SubLib" => "#lib";
    #Link "$BUILD$SubCmd" => "#cmd";

  #print "\$BUILD$SubTools\\Conscript: $BUILD$SubTools\\Conscript\n";
  #Build ("$BUILD$SubTools\\Conscript");
    #Build ("$BUILD$SubTools/Conscript");
    #Build ("$BUILD$SubLib/Conscript");
    #Build ("$BUILD$SubCmd/Conscript");

  if ($VERBOSE eq 'yes') { dump_env(); } ;
  %env= $CONS->copy();
  $Exe_suffix = $env{SUFEXE};

  #Install a copy of source files in build directory so we can have obj
files there
  $wildcard_src = "*$Suffix_src";
  @list_src_files = GetFiles($wildcard_src);

    foreach $Source(@list_src_files) {
   #print "*** $Source\n";
   Install $CONS qq($BUILD$SubTools), qq($Source);
   #Install $CONS "#build\\debug$SubTools", qq($Source);
   $FileTitle = GetFileTitle($Source);

   #Simply changing here EXPORT -> BUILD moves the exe files in the same
'guild' directory of the obj files
   #print "$EXPORT$SubTools\\$FileTitle$Exe_suffix", "-",
"$BUILD$SubTools\\$Source\n";
    ProgramExec $CONS "$EXPORT$SubTools\\$FileTitle$Exe_suffix",
"$BUILD$SubTools\\$Source";
    }

}

sub cons::ProgramExec {
  my ($env, $tgt, $src) = @_;

  Program $env $tgt, $src;

  # make the src also depend on the target executable.
  # *** commented because takes immediately all the computer's memory
!!! ***
  ### $env->Depends($src,$tgt);

  #print "Removing: $src\n";
  #unlink "$src";

   # make the target also depend on the bin2h executable.
  $cmd = '';
  $env->RunProgram($tgt, $src, $cmd);
}

sub cons::RunProgram {
 if ($RUNTEST ne 'yes') {
  return;
 }

 $env = shift;              #not so clear why though !
 my ($tgt, $symbol, $cmd) = @_;
  if ($VERBOSE eq 'yes') {
  print "\$tgt   = $tgt\n";
  print "\$symbol = $symbol\n";
  print "\$cmd    = $cmd\n";
 }

  my ($bin2h) = $env->{BIN2H};
  die "\%BIN2H must be set when calling RunProgram" if !$bin2h;
 print "\$bin2h = $bin2h\n";

  # make the target also depend on the bin2h executable.
  #$env->Depends($target,$bin2h);
  $env->Depends($target,$target);
 print "--------\n";

  # $bin2h =3D $dir::cwd->lookup($bin2h)->path;
  # my $cmd =3D "$bin2h -t $symbol -o %> -d %<";
  # $env->Command($target,@_, $cmd);
  # $env->Depends($target,@_);

 $r = system(qq($tgt));
 if ($r != 0) {
  $exit_value  = $? >> 8;
    $signal_num  = $? & 127;
    $dumped_core = $? & 128;
  die "[$r] system ($tgt) failed\: $?\n \$exit_value = $exit_value\n
\$signal_num = $signal_num \n \$dumped_core = $dumped_core";
 }
}

sub GetArguments {
  # foreach $i(%ARG) { print  $i, "\n"; }

  #We could use options after, but we prefer to avoid
  #cons.pl hello.exe Compiler=Vc98 \BuildType=release -- intel debug
  # $COMPILER = shift;
  # $BUILDTYPE = shift;
  # print "COMPILER  = $COMPILER \n";
  # print "BUILDTYPE = $BUILDTYPE \n";
  # print "RUNTEST  = $RUNTEST \n";

  #print "/cpl=$ARG{'/cpl'}\n";
  #print "/bldmod=$ARG{'/bldmod'}\n";
  $COMPILER = lc $ARG{'/cpl'};     # lc lowercase, ARG is an hash table
  $BUILDTYPE = lc $ARG{'/bldmod'};
  $VERBOSE = lc $ARG{'/verbose'};
  $RUNTEST = lc $ARG{'/runtest'};
  if ($COMPILER eq "intel") { $COMPILER = 'vtune' };
  if ($COMPILER eq "") { $COMPILER = 'vtune' };
  #if ($BUILDTYPE eq "") { $BUILDTYPE = 'debug' };
  (($RUNTEST eq "yes") ? 'yes' : (($RUNTEST eq "y") ? 'yes' : 'no'));
  $RUNTEST = (($RUNTEST eq "yes") ? 'yes' : (($RUNTEST eq "\'yes\'") ?
'yes' : (($RUNTEST eq "\"yes\"") ? 'yes' : (($RUNTEST eq 'y') ? 'yes' :
'no'))));
  $VERBOSE = (($VERBOSE eq "yes") ? 'yes' : (($VERBOSE eq "\'yes\'") ?
'yes' : (($VERBOSE eq "\"yes\"") ? 'yes' : (($VERBOSE eq 'y') ? 'yes' :
'no'))));
  if ($BUILDTYPE ne 'debug' || $BUILDTYPE ne 'release') {
   @types = qw(debug release);
  }
  else {
   @types = qw($BUILDTYPE);
  }

  if ($VERBOSE eq 'yes') {
   print "VERBOSE   = $VERBOSE \n";
   print "COMPILER     = $COMPILER \n";
   print "BUILDTYPE    = $BUILDTYPE \n";
   foreach $i (@types) { print $types[$i] . "\n"; };
  }

  return @types;
}

sub SetVariables {
  # BIN_VC98 =>
"C:\PROGRA~1\MICROS~3\Common\msdev98\BIN;C:\PROGRA~1\MICROS~3\VC98\BIN;C:\PROGRA~1\MICROS~3\Common\TOOLS\WINNT;C:\PROGRA~1\MICROS~3\Common\TOOLS;",

  # BIN_INTEL =>
"C:\PROGRA~1\Intel\edb32\;C:\PROGRA~1\Intel\compiler45\bin;",
  # BIN_SDK =>
"C:\PROGRA~1\MICROS~4\Bin\;C:\PROGRA~1\MICROS~4\Bin\WinNT;",  #
Microsoft Platform SDK
    # INCLUDE_VC98 =>
"C:\PROGRA~1\MICROS~3\VC98\ATL\INCLUDE;C:\PROGRA~1\MICROS~3\VC98\INCLUDE;C:\PROGRA~1\MICROS~3\VC98\MFC\INCLUDE;",

    # INCLUDE_INTEL => "C:\PROGRA~1\Intel\compiler45\include;",
    # INCLUDE_SDK => "C:\PROGRA~1\MICROS~4\Include\;",             #
Microsoft Platform SDK
  # LIB_VC98 =>
"C:\PROGRA~1\MICROS~3\VC98\LIB;C:\PROGRA~1\MICROS~3\VC98\MFC\LIB;",
  # LIB_INTEL => "C:\PROGRA~1\Intel\compiler45\lib;",
  # LIB_SDK => "C:\PROGRA~1\MICROS~4\Lib\;",                 # Microsoft
Platform SDK

  $BASEPATH =
'C:\GNU\Perl\bin\;C:\WINNT\system32;C:\WINNT;C:\WINNT\system32\WBEM;C:\WINNT\system32;C:\WINNT;C:\WINNT\System32\Wbem;';

  if ($COMPILER eq 'vc98') {
     $PATH = $ENV{BIN_VC98};
     $INCLUDE = $ENV{INCLUDE_VC98};
     $LIB = $ENV{LIB_VC98};
     #print "vc98\n";
    }
  elsif ($COMPILER eq 'vtune') {
     $PATH = $ENV{BIN_INTEL} . $ENV{BIN_VC98};
     $INCLUDE = $ENV{INCLUDE_INTEL} . $ENV{INCLUDE_VC98};
     $LIB = $ENV{LIB_INTEL} . $ENV{LIB_VC98};
     #print "vtune\n";
    }
  elsif ($COMPILER eq 'sdk') {
     $PATH = $ENV{BIN_SDK} . $ENV{BIN_VC98};
     $INCLUDE = $ENV{INCLUDE_SDK};
     $LIB = $ENV{LIB_SDK} . $ENV{LIB_VC98};
     #print "sdk\n";
    }
  elsif ($COMPILER eq 'gcc') {
     $GCC_EXEC_PREFIX = $ENV{GCC_EXEC_PREFIX};
     $PATH = $GCC_EXEC_PREFIX . 'bin' ;
     $INCLUDE = $GCC_EXEC_PREFIX . 'include' ;
     $LIB = $GCC_EXEC_PREFIX . 'lib';
     #print "gcc\n";
    }
  else {
     die "unknown value for variable $COMPILER: `$COMPILER'"
    }

 if ($VERBOSE eq 'yes') {
  print "\$PATH    = $PATH\n";
  print "\$INCLUDE = $INCLUDE\n";
  print "\$LIB     = $LIB\n";
 }
}

sub dump_env() {
  print "----- dumping env -------\n";
  %env= $CONS->copy();
  for $i (keys %env) { print "$i => $env{$i}.\n"; }
  print "--- end dummping env -----\n";
}

sub GetFiles {
 #%env= $CONS->copy();
 #$Exe_suffix = $env{SUFOBJ};

 my($wildcard) = @_;
 if ($wildcard eq '*.c') {
  @list_src_files = (<*.c>);
 } elsif ($wildcard eq '*.ccp') {
  @list_src_files = (<*.cpp>);
 } elsif ($wildcard eq '*.cc') {
  @list_src_files = (<*.cc>);
 } else {
  die "no switch case for $wildcard.";
  #undef @list_src_files;
  return undef;
 }

 return @list_src_files;
}

sub GetFileTitle {
 my ($Source) = @_;
 my $FileTitle;
 my $n, @spl, $spl;

   @spl = split(/\./, $Source);  #split $Source in words separated by a
'.'
   #print $Source; foreach $i (@spl) { print $i,":"; };

   $FileTitle .= "$spl[0]";
   for $n (1..($#spl-1)) { $FileTitle .= "\.$spl[$n]"; };

   #$FileTitle =~ s/^([^.]*).*([^.]*)/$+/;

   #print "\$FileTitle = $FileTitle\n";

   return $FileTitle;
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]