                      GAST: Gcc Automatically Save Temps
                                      Copyright (C) 2009 Tadashi Koike (T.K)
                                      ** Please overlook my weak English. **
Table of contents
============
  1. Purpose of this project
  2. Product contents
  3. Environment to be needed
  4. Install & setup
  5. How to use
  6. Environment variables to control 'gast'
  7. Use case
  8. Weak point of this tool
============

1. Purpose of this project
  A purpose of this project (GAST) is to support getting preprocessed
  source codes (.i file) automatically which corresponds directly to a
  generated object file (.o file), If you want.

2. Product contents
  This project provides three tools (=bash scripts) at present.

  - gast : wrapper script for gcc

      This script must be executed by alias name which is same as real
      compiler ('gcc','cc', etc...).
      In build process, these alias names must be found before real
      compile in command path search, so those directory path must be
      set PATH environment at least before of real compiler's command
      path.

      When this script is executed (by alias name), do below processes:

      1) Analisys of command line arguments. If arguments are for
         compiling C/C++ language source file, this script executes real
         compiler (same as alias name) with these arguments addittionaly
         '-save-temps' option.
         If arguments are not for compiling C/C++ language source file,
         this script executes real compiler (same as alias name) only
         with these arguments and then exit.

      2) After compiling C/C++ language source file, preprocessed source
         file (.i extension, called 'temporary file') is there.
         If directory for preserving temporary file is specified (by
         environment variable), temporary file is moved to that directory.

      3) Delete temporary file for assembler (.s extension).

      Before using this script, you have to set some environment variables
      to control 'gast' action. For more information, see "6. Environment
      variables to control 'gast'".

      [ NOTICE ]
      If C/C++ source file compiling is done under 'make' process, you
      perhaps need support by 'gast_make' script (below).

  - gast_make : wrapper script for make command

      This script must be executed by alias name which is same as real
      make-utility ('make','gmake', etc...).

      In build process, these alias names must be found before real make
      utility in command path search, so those directory path must be set
      PATH environment at least before of real make-utility command path.

      When this script is executed (by alias name), do below processes:

      1) Analisys of command line arguments. If arguments has '-j <n>'
         or '--jobs=<n>' option, this script force number of jobs <n> to
         set 1 and execute real make-utility (same as alias name) with
         these arguments.
         If arguments does not have '-j <n>' or '--jobs=<n>', this script
         executes real make-utility (same as alias name) with given
         arguments and additionally '-j1' option.

      [ NOTICE ]
      gcc (version 4.4 or under) creates temporary files in current/working
      directory. If GNU make utility runs simultaneously by specified
      '-j|--jobs' option, and one C/C++ source file is compiled simultaneously
      for respective purpose, build process maybe failed because temporary
      files are in conflict. So this script support you to set simultaneous
      job number to 1 by force.

  - gast_rpmbuild : wrapper script for rpmbuild command

      This script must be executed by alias name 'rpmbuild'.
      (for Red Hat Enterprise Linux, CentOS, Fedora, ...)

      This script is substitution for rpmbuild command to set environment
      variable for 'gast' automatically.
      Additional option '--save-temps-dir' is abailable to specify
      directory name for preserving temporary files.

      In build process, these alias names must be found before real
      rpmbuild in command path search, so those directory path must be set
      PATH environment at least before of real rpmbuild command path.

      When this script is executed (by alias name), do below processes:

      1) Analisys of command line arguments. If arguments contains
         '--save-temps-dir' option, followed argument is recognized
         as directory name for preserving temporary files and set to
         environment variable for controling 'gast'.

      2) Set some other environment variables (contains PATH) for
         preserving temporary files.

      3) Executes real rpmbuild command with arguments given to this
         script, except for '--save-temps-dir' and followed directory
         name argument.

3. Environment to be needed

  To use these scripts, some utilities are needed below:

    ・GNU gcc compiler
    ・GNU Make utility
    ・bash (version 3.0 or later are desirable)

  and strongly recommended utility are below:

    ・perl

    * If perl is not vailable, bash script processes text-filtering
      all by itself, but processing speed became more slowly.

4. Install & setup

  [ Install ]
    This product is provided by tar+gzip archive format.
    Extracting that archive file means just installing.
    If you extract archive file, a directory is created and utility scripts
    is in there.

    for example) extracting archive file on /home/foo.
                 archive file supposed 'gast-0.1.2.tar.gz'

        $ cd /home/foo
        $ tar -xvzf /tmp/gast-0.1.2.tar.gz
        gast-0.1.2/
        gast-0.1.2/gast
        gast-0.1.2/gast_make
        gast-0.1.2/gast_rpmbuild
        gast-0.1.2/README.ja_JP.UTF-8

  [ setup ]
    Change a working directory to an extracted directory, and execte
    each scripts with no argument.
    Symbolic link file are created at same directory.

        $ cd /home/foo/gast-0.1.2
        $ ./gast
        gast : Create symbolic link 'gcc'
        gast : Create symbolic link 'cc'
        gast : Create symbolic link 'g++'

        $ ./gast_make
        gast_make : Create symbolic link 'make'
        gast_make : Create symbolic link 'gmake'

        $ ./gast_rpmbuild
        gast_rpmbuild : Create symbolic link 'rpmbuild'

  [ NOTICE ]
    - gast, gast_make, gast_rpmbuild must be in same directory.
      Don't move these scripts in several directories separately.

    - gast, gast_make, gast_rpmbuild must not be in same directory as
      real commands/utilities. (gcc,cc,make,gmake,rpmbuild,...)
      I recommended using these tools as in extracted directory.

    - Of course, build process spends more time. perhaps spends 1.2 to 3
      times as long as usually.

5. How to use

  =======================================================================
  Seen A) to build RPM package from SRPM by using rpmbuild command.

    You can start using this tools. Please execute rpmbuild script
    (= aliases name of gast_rpmbuild) directory.

      Example) get temporary files of kernel build on CentOS
      +------------------------------------------------------------------
      |$ /home/foo/gast-0.1.2/rpmbuild --save-temps-dir /home/foo/tmp \
      |  --rebuild /tmp/kernel-2.6.18-92.1.10.el5.src.rpm
      +------------------------------------------------------------------

    Option arguments for real rpmbuild are all available .
    additiona option '--save-temps-dir' are available to specifiy
    preserving temporary files. (in above example, /home/foo/tmp)

    If you need, you define GAST_CONTENT_WITHOUT_H, GAST_CONTENT_UNIQUE
    environment variables.
      +------------------------------------------------------------------
      |$ export GAST_CONTENT_WITHOUT_H=
      |$ export GAST_CONTENT_UNIQUE=
      +------------------------------------------------------------------
      see "6. Environment variables to control 'gast'".

    [ !! NOTICE !! ]
    If you build a big package (like a linux kernel), I strongly
    recommend defining GAST_CONTENT_WITHOUT_H environment variable or
    specifying a big-size filesystem to preserve temporary files.
    Otherwise, filesystem to preserve temporary files might be full !!

  =======================================================================
  Seen B) to build a configure/make/make install/ style product.

    You need these steps:
      1. Set environment variables to control 'gast'.
      2. Set the directory path of this scripts to the top of the value
         of PATH environment variable, and continue build process.

    Example) build of Apache HTTPD 2.2 (httpd-2.2.11.tar.gz)
      +------------------------------------------------------------------
      |$ cd /tmp
      |$ tar -xvzf httpd-2.2.11.tar.gz
      |$ cd /tmp/httpd-2.2.11
      |$ ./configure --prefix=/home/foo/local
      |             :
      |             :
      | $ # before doing 'make', we set environment variable for 'gast'
      | $ export GAST_ENABLE=
      | $ export GAST_SOURCE_DIR=/tmp
      | $ export GAST_SAVE_DIR=/home/foo/tmp
      | $ export GAST_CONTENT_WITHOUT_H=
      | $ export GAST_CONTENT_UNIQUE=
      | $
      | $ # do build
      | $ PATH=/home/foo/gast-0.1.2:${PATH} make
      |             ：
      |             ：
      | $ make install
      +------------------------------------------------------------------
      see "6. Environment variables to control 'gast'".

    [ NOTICE ]
      I recommend that changing PATH environment variable must be
      temporary. So in above example, setting PATH environment variable
      is specified at the top of build command line.

    If you finished, delete environment variables.
      +------------------------------------------------------------------
      |$ unset GAST_ENABLE  GAST_SOURCE_DIR  GAST_SAVE_DIR
      |$ unset GAST_CONTENT_WITHOUT_H GAST_CONTENT_UNIQUE
      +------------------------------------------------------------------

  =======================================================================
  Seen C) only compile one C/C++ source file.

    Same as configure/make/make install/ style build process.

    Below is an another example:
      +------------------------------------------------------------------
      |$ GAST_ENABLE= GAST_SOURCE_DIR=/tmp GAST_SAVE_DIR=/home/foo/tmp \
      |> GAST_CONTENT_WITHOUT_H=  PATH=/home/foo/gast-0.1.2:$PATH \
      |> gcc test.c
      +------------------------------------------------------------------
      ... confusing.

6. Environment variables to control 'gast'

  If you want to get temporary (=preprocessed) file using 'gast', you
  must specify some environment variables to control 'gast' before
  compileing/building your target source/product.

    GAST_ENABLE
      When this environment variable is defined (however excludes its
      value is "no"), gast works to generate compiler's temporary file
      (.i file) automatically, and preserve it.
      When this environment variable is not defined, gast behaves
      itself like just same as an real compiler.

    GAST_SAVE_DIR=<DIR>
      When this environment variable is defined and its value can be
      recognized a directory name, a genrerated temporary file (.i file)
      by compiler is moved to this directory.
      When this directory does not exist, gast attempt to create this
      directory.

      [ CAUTION!! ]
      I strongly recommend to define GAST_SAVE_DIR environment variable.
      If you don't define GAST_SAVE_DIR environment variable, temporary
      files (.i file) are created in current/working directory, but
      filename of these temporary files are changed as below:

        Example) test.i ---> test.0.i

      Why do I change filename? Because there is a case that the C/C++ source
      file is compiled any number of times with different compile options.
      When temporary files are created in 'current/working' directory and
      compiled any number of times, older temporary files are overwritten,
      so I assume that case and prevent to be overwritten , I rename
      original temporary filename with adding '.0'.

    GAST_SOURCE_DIR=<DIR>
      When this environment variable is defined and its value can be
      recognized a directory name, gast tries to obtain a relative
      path-name from a source file path-name by removing a directory
      name which this environment means. And that relative path-name
      applies under the GAST_SAVE_DIR directory to moved a temporary
      file (.i file).
      When this environment variable is not defined or the value does
      not match a header of source file path-name, gast obtain a
      relative path-name by removing "/" from a top of source file
      path-name.

      [ NOTICE ]
      When this environment variable is not defined and gast is executed
      under a build process by 'rpmbuild' command, gast tries to define
      GAST_SOURCE_DIR automatically with a value of RPM_BUILD_DIR.

    GAST_CONTENT_WITHOUT_H
      When this environment variable is defined (however excludes its
      value is "no"), created temporary file (.i file) is modified.
      Most of all the contents from header files are removed.

      [NOTICE]
      Only a track of including header file is left.

    GAST_CONTENT_UNIQUE
      When this environment variable is not defined, If C/C++ source file
      is compiled any number of times with different compile options, gast
      preserve each temporary files by adding number.

      When this environment variable is defined (however excludes its
      value is "no"), If compile options are different but content of
      current temporary file is same as one of the preserved files,
      gast does not preserve current temporary file.

7. Use case

  1) Assistance for researching source code (to understand  macro
     expanding).
  2) To gather error messages not from C/C++ source file but from temporary
     files.
  3) ...

8. Weak point of this tool

  If compiler is executed by absolute path in build process, gast script
  is not able to work, so at that case, we cannot get temporary files.

===
