OSDN Git Service

BuildSystem: general, configure and Xcode updates.
authorkonablend <konablend@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sun, 8 Mar 2009 22:50:57 +0000 (22:50 +0000)
committerkonablend <konablend@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sun, 8 Mar 2009 22:50:57 +0000 (22:50 +0000)
*** NOTICE:
This changeset requires a clean build directory. Please issue 'make xclean' inside
build dir(s) after 'svn up'. This will help ensure there are no unexpected results.

*** GENERAL:
- renamed makevar PROJECT/ -> SRC/ for clarity.
- renamed makevar PREFIX.install/ -> PREFIX/ for clarity.
- split custom GNUmakefile overrides into defs/rules files.
- inserted optional level of make customization at SRC/ level; see docs.
- dropped HB.repo.wcversion (svnversion is no longer used).
- corrected several 'rm' usages to use -f flag which avoids some build errors.
- refreshed generated 00-Building.*.txt docs; work still in progress on the wiki front.

*** CONFIGURE:
- made configure more robust; configure may now be run outside of build directory!
- adding log recording of configure activities.
- improved readability of default options for configure
- added:

    --force             overwrite existing build config
    --src=DIR           specify top-level source dir [.]
    --build=DIR         specify build scratch/output dir [.]
    --prefix=DIR        specify install dir for products [/Applications]

- dropped --launch-force (replaced by --force)
- dropped --launch-dir (replaced by --build)
- dropped --launch-log

*** XCODE:
- renamed pbxproj definition EXTERNAL_PROJECT -> EXTERNAL_SRC for clarity.
- fixed all configurations to default to EXTERNAL_JOBS=1 .
- enabled Xcode internal parallelization (libhb, HandBrakeCLI and HandBrake benefit).
- make now tickles Xcode build files to cause Info.plist regeneration and posting to HandBrake.app output;
  ie: svn up; click build and HandBrake.app's about panel will reflect the new repository rev.

*** DARWIN:
- added support to build universal binaries; see docs.

git-svn-id: svn://localhost/HandBrake/trunk@2242 b64f7644-9d1e-0410-96f1-a4d463321fa5

34 files changed:
00-Building.cygwin.txt
00-Building.linux.txt
00-Building.osx.txt
configure
contrib/bzip2/module.defs
contrib/ffmpeg/module.defs
contrib/xvidcore/module.defs
doc/module.defs
doc/module.rules
doc/texi/Building.osx.texi
doc/texi/base/handbrake.texi.m4
doc/texi/building/chapter.quickstart.texi
doc/texi/building/chapter.via.terminal.texi
doc/texi/building/chapter.via.xcode.texi
doc/texi/building/command.texi
gtk/module.defs
gtk/module.rules
libhb/module.defs
libhb/module.rules
libhb/project.h.m4
macosx/HandBrake.xcodeproj/project.pbxproj
macosx/module.defs
macosx/module.rules
macosx/module.xcode
make/configure.py
make/include/contrib.defs
make/include/main.defs
make/include/main.rules
make/variant/darwin.defs
make/variant/darwin.rules
make/variant/freebsd.defs
make/xcodemake
test/module.defs
test/module.rules

index dca7d90..70cbd53 100644 (file)
@@ -1,4 +1,4 @@
-Guide to Building HandBrake svn2213 (2009030301) on Cygwin
+Guide to Building HandBrake svn2241 (2009030801) on Cygwin
 **********************************************************
 
 Table of Contents
@@ -16,7 +16,8 @@ Table of Contents
     5.4.1 Global
     5.4.2 General Modules
     5.4.3 Contrib Modules
-    5.4.4 Contrib Aggregates
+    5.4.4 Contrib Touch and Untouch
+    5.4.5 Contrib Aggregates
   5.5 Customizing Make
 
 
@@ -81,14 +82,17 @@ recommended you use these versions or similar:
 ************
 
 This chapter is for building from a terminal/shell environment in as
-few commands as possible. If more flexibility is required you should
-skip this chapter and jump to *Note overview::.
+few commands as possible. Upon completion of the following commands you
+should have a fresh build of HandBrake. Further instructions are
+available beginning with *Note overview:: which describes procedures
+suitable for repeating builds. This chapter should be skipped by those
+seeking more than a minimalist build.
 
      svn checkout svn://svn.handbrake.fr/HandBrake/trunk hb-trunk
      cd hb-trunk
      ./configure --launch
 
-The special option `--launch' selected launch mode and performs the
+The special option `--launch' selects launch mode and performs the
 following steps:
 
    * assert scratch directory `build/' does not exist
@@ -99,10 +103,14 @@ following steps:
 
    * launch `make'
 
-   * capture build output to `build/log.txt'
+   * capture build output to `build/log/build.txt'
 
    * echo build output
 
+   * print elapsed time
+
+   * indicate if build ultimately succeeded or failed
+
 4 Overview
 **********
 
@@ -133,16 +141,14 @@ use Subversion 1.5.0 or higher. Lower versions should also work.
 
 Configure the build system.
 
-     rm -fr build/
-     mkdir build/
-     cd build/
-     ../configure
+     ./configure
 
-Create a scratch directory which will contain all files created during
-the build process. The directory name is arbitrary but we recommend
-something simple and descriptive. One directory is required for each
-distinctly configured build. We name our directory `build' for example
-purposes.
+Configure will automatically create a scratch build directory `build'
+unless you use GNU-style build procedures and first `cd' to a directory
+other than top-level source. Additionally you may specify use `--build'
+to specify the directory. The name of the directory is arbitrary but it
+is recommended to use something which indicates transient files which
+are not checked into the repository.
 
 The `configure' utility accepts many options. It is recommended that
 you specify `--help' for the complete list of options. The following
@@ -151,14 +157,26 @@ options are also documented here:
 `--help'
      List available options.
 
-`--prefix=PREFIX'
+`--src=DIR'
+     Specify top-level source directory for HandBrake sources.
+
+`--build=DIR'
+     Specify destination directory for final product install. The
+     default is to use either `build' if in the top-level source
+     directory, otherwise `.'
+
+`--prefix=DIR'
      Specify destination directory for final product install.  This
      defaults to a reasonable platform-specific value.
 
+`--launch'
+     All-in-one option which launches the build and logs output
+     automatically.  Useful for novices and quickstart procedures.
+
 `--disable-xcode'
-     Disable driving the build through Xcode. If this option is
-     disabled only `HandBrakeCLI' will be produced and Xcode will not
-     be invoked. Mac OS X only.
+     Disable shunting the build through Xcode. If this option is
+     applied, `HandBrakeCLI' will be produced in a similare fashion as
+     it is on other platforms; sans Xcode. Mac OS X only.
 
 `--disable-gtk'
      Disable building the GTK GUI on applicable platforms such as
@@ -179,10 +197,6 @@ options are also documented here:
      architectures. The available choices are hard-coded per platform
      and no sanity checks for the required tools are performed.
 
-`--gcc=EXE'
-     Specify the `gcc' executable to use where EXE is the executable
-     name which is either absolute or environment `PATH' is searched
-     accordingly.
 
 Clean-room procedures dictate that when certain factors change, old
 builds should be scrapped and new builds configured. This is the main
@@ -261,6 +275,14 @@ period.
      Build auto-generated project documentation. Various articles are
      produced and may be found in `build/doc/articles'.
 
+`make report.help'
+     Print list of available makefile vars report targets.  These
+     reports detail var definitions and expanded values used by the
+     build system.  For experts only.
+
+`make report.all'
+     Convenience target which aggregates all reports.  For experts only.
+
 5.4.2 General Modules
 ---------------------
 
@@ -313,7 +335,36 @@ Contrib modules such as `a52dec', `bzip2', `faac', `faad2', `ffmpeg',
      Extra clean module; first invokes uninstall then recursively
      removes the module build directory.
 
-5.4.4 Contrib Aggregates
+5.4.4 Contrib Touch and Untouch
+-------------------------------
+
+Also available are some very granular targets which help force builds
+from specific cycle points. The following targets are available to
+touch and untouch the respective module target; this will force the
+build system to treat the target as satisfied after a touch or
+unsatisfied after an untouch:
+
+   * make MODULE.extract.touch
+
+   * make MODULE.extract.untouch
+
+   * make MODULE.patch.touch
+
+   * make MODULE.patch.untouch
+
+   * make MODULE.configure.touch
+
+   * make MODULE.configure.untouch
+
+   * make MODULE.build.touch
+
+   * make MODULE.build.untouch
+
+   * make MODULE.install.touch
+
+   * make MODULE.install.untouch
+
+5.4.5 Contrib Aggregates
 ------------------------
 
 For convenience, the following targets aggregate the all contrib
@@ -341,15 +392,34 @@ modules' respective targets together:
 ====================
 
 If the need arises to override settings in the build system
-(essentially gnu-make variables) the recommended method is to
-create/edit the optional include file `build/GNUmakefile.custom' which
-sits adjacent to the top-level makefile. Do not check this file into
-the respository. The sole purpose is to allow a place to store local
-build settings for testing, tweaking, and experimenting with build
-configuration without losing your settings if `configure' is invoked;
-ie: `configure' would overwrite `GNUmakefile' and any customizations
-contained therein would be lost. Here is a short example of what the
-contents of `build/GNUmakefile.custom' might contain:
+(essentially gnu-make variables) the recommended method is to create
+optional include files which are automatically included if present and
+follow this naming convention; Do not check these files into the
+respository:
+
+`_SRC_/custom.defs'
+     Custom makevar definitions outside `build'. Suitable for settings
+     which apply across all builds for a particular checkout; or which
+     survives manual removal of `build'.
+
+`_SRC_/custom.rules'
+     Custom make rules outside `build'. Suitable for settings which
+     apply across all builds for a particular checkout; or which
+     survives manual removal of `build'.
+
+`_BUILD_/GNUmakefile.custom.defs'
+     Custom makevar definitions specific to a `build' directory.
+
+`_BUILD_/GNUmakefile.custom.rules'
+     Custom makevar rules specific to a `build' directory.
+
+
+The purpose is to allow a place to store local build settings for
+testing, tweaking, and experimenting with build configuration without
+losing your settings if `configure' is invoked; ie: `configure' would
+overwrite `GNUmakefile' and any customizations contained therein would
+be lost. Here is a short example of what the contents of
+`_SRC_/custom.defs' might contain:
 
      ## bump to gcc-4.2 in current path
      GCC.gcc = gcc-4.2
@@ -357,3 +427,6 @@ contents of `build/GNUmakefile.custom' might contain:
      ## replace optimize for 'speed' with more agressive settings
      GCC.args.O.speed = -O3 -fomit-frame-pointer -msse4.2
 
+See also `make report.help' which displays a set of reports used to
+dump makefile vars.
+
index ae6158e..955e4cd 100644 (file)
@@ -1,4 +1,4 @@
-Guide to Building HandBrake svn2213 (2009030301) on Linux
+Guide to Building HandBrake svn2241 (2009030801) on Linux
 *********************************************************
 
 Table of Contents
@@ -16,7 +16,8 @@ Table of Contents
     5.4.1 Global
     5.4.2 General Modules
     5.4.3 Contrib Modules
-    5.4.4 Contrib Aggregates
+    5.4.4 Contrib Touch and Untouch
+    5.4.5 Contrib Aggregates
   5.5 Customizing Make
 
 
@@ -147,14 +148,17 @@ To install these packages:
 ************
 
 This chapter is for building from a terminal/shell environment in as
-few commands as possible. If more flexibility is required you should
-skip this chapter and jump to *Note overview::.
+few commands as possible. Upon completion of the following commands you
+should have a fresh build of HandBrake. Further instructions are
+available beginning with *Note overview:: which describes procedures
+suitable for repeating builds. This chapter should be skipped by those
+seeking more than a minimalist build.
 
      svn checkout svn://svn.handbrake.fr/HandBrake/trunk hb-trunk
      cd hb-trunk
      ./configure --launch
 
-The special option `--launch' selected launch mode and performs the
+The special option `--launch' selects launch mode and performs the
 following steps:
 
    * assert scratch directory `build/' does not exist
@@ -165,10 +169,14 @@ following steps:
 
    * launch `make'
 
-   * capture build output to `build/log.txt'
+   * capture build output to `build/log/build.txt'
 
    * echo build output
 
+   * print elapsed time
+
+   * indicate if build ultimately succeeded or failed
+
 4 Overview
 **********
 
@@ -199,16 +207,14 @@ use Subversion 1.5.0 or higher. Lower versions should also work.
 
 Configure the build system.
 
-     rm -fr build/
-     mkdir build/
-     cd build/
-     ../configure
+     ./configure
 
-Create a scratch directory which will contain all files created during
-the build process. The directory name is arbitrary but we recommend
-something simple and descriptive. One directory is required for each
-distinctly configured build. We name our directory `build' for example
-purposes.
+Configure will automatically create a scratch build directory `build'
+unless you use GNU-style build procedures and first `cd' to a directory
+other than top-level source. Additionally you may specify use `--build'
+to specify the directory. The name of the directory is arbitrary but it
+is recommended to use something which indicates transient files which
+are not checked into the repository.
 
 The `configure' utility accepts many options. It is recommended that
 you specify `--help' for the complete list of options. The following
@@ -217,14 +223,26 @@ options are also documented here:
 `--help'
      List available options.
 
-`--prefix=PREFIX'
+`--src=DIR'
+     Specify top-level source directory for HandBrake sources.
+
+`--build=DIR'
+     Specify destination directory for final product install. The
+     default is to use either `build' if in the top-level source
+     directory, otherwise `.'
+
+`--prefix=DIR'
      Specify destination directory for final product install.  This
      defaults to a reasonable platform-specific value.
 
+`--launch'
+     All-in-one option which launches the build and logs output
+     automatically.  Useful for novices and quickstart procedures.
+
 `--disable-xcode'
-     Disable driving the build through Xcode. If this option is
-     disabled only `HandBrakeCLI' will be produced and Xcode will not
-     be invoked. Mac OS X only.
+     Disable shunting the build through Xcode. If this option is
+     applied, `HandBrakeCLI' will be produced in a similare fashion as
+     it is on other platforms; sans Xcode. Mac OS X only.
 
 `--disable-gtk'
      Disable building the GTK GUI on applicable platforms such as
@@ -245,10 +263,6 @@ options are also documented here:
      architectures. The available choices are hard-coded per platform
      and no sanity checks for the required tools are performed.
 
-`--gcc=EXE'
-     Specify the `gcc' executable to use where EXE is the executable
-     name which is either absolute or environment `PATH' is searched
-     accordingly.
 
 Clean-room procedures dictate that when certain factors change, old
 builds should be scrapped and new builds configured. This is the main
@@ -327,6 +341,14 @@ period.
      Build auto-generated project documentation. Various articles are
      produced and may be found in `build/doc/articles'.
 
+`make report.help'
+     Print list of available makefile vars report targets.  These
+     reports detail var definitions and expanded values used by the
+     build system.  For experts only.
+
+`make report.all'
+     Convenience target which aggregates all reports.  For experts only.
+
 5.4.2 General Modules
 ---------------------
 
@@ -379,7 +401,36 @@ Contrib modules such as `a52dec', `bzip2', `faac', `faad2', `ffmpeg',
      Extra clean module; first invokes uninstall then recursively
      removes the module build directory.
 
-5.4.4 Contrib Aggregates
+5.4.4 Contrib Touch and Untouch
+-------------------------------
+
+Also available are some very granular targets which help force builds
+from specific cycle points. The following targets are available to
+touch and untouch the respective module target; this will force the
+build system to treat the target as satisfied after a touch or
+unsatisfied after an untouch:
+
+   * make MODULE.extract.touch
+
+   * make MODULE.extract.untouch
+
+   * make MODULE.patch.touch
+
+   * make MODULE.patch.untouch
+
+   * make MODULE.configure.touch
+
+   * make MODULE.configure.untouch
+
+   * make MODULE.build.touch
+
+   * make MODULE.build.untouch
+
+   * make MODULE.install.touch
+
+   * make MODULE.install.untouch
+
+5.4.5 Contrib Aggregates
 ------------------------
 
 For convenience, the following targets aggregate the all contrib
@@ -407,15 +458,34 @@ modules' respective targets together:
 ====================
 
 If the need arises to override settings in the build system
-(essentially gnu-make variables) the recommended method is to
-create/edit the optional include file `build/GNUmakefile.custom' which
-sits adjacent to the top-level makefile. Do not check this file into
-the respository. The sole purpose is to allow a place to store local
-build settings for testing, tweaking, and experimenting with build
-configuration without losing your settings if `configure' is invoked;
-ie: `configure' would overwrite `GNUmakefile' and any customizations
-contained therein would be lost. Here is a short example of what the
-contents of `build/GNUmakefile.custom' might contain:
+(essentially gnu-make variables) the recommended method is to create
+optional include files which are automatically included if present and
+follow this naming convention; Do not check these files into the
+respository:
+
+`_SRC_/custom.defs'
+     Custom makevar definitions outside `build'. Suitable for settings
+     which apply across all builds for a particular checkout; or which
+     survives manual removal of `build'.
+
+`_SRC_/custom.rules'
+     Custom make rules outside `build'. Suitable for settings which
+     apply across all builds for a particular checkout; or which
+     survives manual removal of `build'.
+
+`_BUILD_/GNUmakefile.custom.defs'
+     Custom makevar definitions specific to a `build' directory.
+
+`_BUILD_/GNUmakefile.custom.rules'
+     Custom makevar rules specific to a `build' directory.
+
+
+The purpose is to allow a place to store local build settings for
+testing, tweaking, and experimenting with build configuration without
+losing your settings if `configure' is invoked; ie: `configure' would
+overwrite `GNUmakefile' and any customizations contained therein would
+be lost. Here is a short example of what the contents of
+`_SRC_/custom.defs' might contain:
 
      ## bump to gcc-4.2 in current path
      GCC.gcc = gcc-4.2
@@ -423,3 +493,6 @@ contents of `build/GNUmakefile.custom' might contain:
      ## replace optimize for 'speed' with more agressive settings
      GCC.args.O.speed = -O3 -fomit-frame-pointer -msse4.2
 
+See also `make report.help' which displays a set of reports used to
+dump makefile vars.
+
index 471ffda..0d91d75 100644 (file)
@@ -1,4 +1,4 @@
-Guide to Building HandBrake svn2213 (2009030301) on Mac OS X
+Guide to Building HandBrake svn2241 (2009030801) on Mac OS X
 ************************************************************
 
 Table of Contents
@@ -16,8 +16,10 @@ Table of Contents
     5.4.1 Global
     5.4.2 General Modules
     5.4.3 Contrib Modules
-    5.4.4 Contrib Aggregates
+    5.4.4 Contrib Touch and Untouch
+    5.4.5 Contrib Aggregates
   5.5 Customizing Make
+  5.6 Universal Binaries
 6 Building via Xcode
   6.1 Checkout Sources
   6.2 Build
@@ -80,14 +82,17 @@ recommended you use these versions or similar:
 ************
 
 This chapter is for building from a terminal/shell environment in as
-few commands as possible. If more flexibility is required you should
-skip this chapter and jump to *Note overview::.
+few commands as possible. Upon completion of the following commands you
+should have a fresh build of HandBrake. Further instructions are
+available beginning with *Note overview:: which describes procedures
+suitable for repeating builds. This chapter should be skipped by those
+seeking more than a minimalist build.
 
      svn checkout svn://svn.handbrake.fr/HandBrake/trunk hb-trunk
      cd hb-trunk
      ./configure --launch
 
-The special option `--launch' selected launch mode and performs the
+The special option `--launch' selects launch mode and performs the
 following steps:
 
    * assert scratch directory `build/' does not exist
@@ -98,10 +103,14 @@ following steps:
 
    * launch `make'
 
-   * capture build output to `build/log.txt'
+   * capture build output to `build/log/build.txt'
 
    * echo build output
 
+   * print elapsed time
+
+   * indicate if build ultimately succeeded or failed
+
 4 Overview
 **********
 
@@ -135,16 +144,14 @@ use Subversion 1.5.0 or higher. Lower versions should also work.
 
 Configure the build system.
 
-     rm -fr build/
-     mkdir build/
-     cd build/
-     ../configure
+     ./configure
 
-Create a scratch directory which will contain all files created during
-the build process. The directory name is arbitrary but we recommend
-something simple and descriptive. One directory is required for each
-distinctly configured build. We name our directory `build' for example
-purposes.
+Configure will automatically create a scratch build directory `build'
+unless you use GNU-style build procedures and first `cd' to a directory
+other than top-level source. Additionally you may specify use `--build'
+to specify the directory. The name of the directory is arbitrary but it
+is recommended to use something which indicates transient files which
+are not checked into the repository.
 
 The `configure' utility accepts many options. It is recommended that
 you specify `--help' for the complete list of options. The following
@@ -153,14 +160,26 @@ options are also documented here:
 `--help'
      List available options.
 
-`--prefix=PREFIX'
+`--src=DIR'
+     Specify top-level source directory for HandBrake sources.
+
+`--build=DIR'
+     Specify destination directory for final product install. The
+     default is to use either `build' if in the top-level source
+     directory, otherwise `.'
+
+`--prefix=DIR'
      Specify destination directory for final product install.  This
      defaults to a reasonable platform-specific value.
 
+`--launch'
+     All-in-one option which launches the build and logs output
+     automatically.  Useful for novices and quickstart procedures.
+
 `--disable-xcode'
-     Disable driving the build through Xcode. If this option is
-     disabled only `HandBrakeCLI' will be produced and Xcode will not
-     be invoked. Mac OS X only.
+     Disable shunting the build through Xcode. If this option is
+     applied, `HandBrakeCLI' will be produced in a similare fashion as
+     it is on other platforms; sans Xcode. Mac OS X only.
 
 `--disable-gtk'
      Disable building the GTK GUI on applicable platforms such as
@@ -181,10 +200,6 @@ options are also documented here:
      architectures. The available choices are hard-coded per platform
      and no sanity checks for the required tools are performed.
 
-`--gcc=EXE'
-     Specify the `gcc' executable to use where EXE is the executable
-     name which is either absolute or environment `PATH' is searched
-     accordingly.
 
 Clean-room procedures dictate that when certain factors change, old
 builds should be scrapped and new builds configured. This is the main
@@ -263,6 +278,14 @@ period.
      Build auto-generated project documentation. Various articles are
      produced and may be found in `build/doc/articles'.
 
+`make report.help'
+     Print list of available makefile vars report targets.  These
+     reports detail var definitions and expanded values used by the
+     build system.  For experts only.
+
+`make report.all'
+     Convenience target which aggregates all reports.  For experts only.
+
 5.4.2 General Modules
 ---------------------
 
@@ -315,7 +338,36 @@ Contrib modules such as `a52dec', `bzip2', `faac', `faad2', `ffmpeg',
      Extra clean module; first invokes uninstall then recursively
      removes the module build directory.
 
-5.4.4 Contrib Aggregates
+5.4.4 Contrib Touch and Untouch
+-------------------------------
+
+Also available are some very granular targets which help force builds
+from specific cycle points. The following targets are available to
+touch and untouch the respective module target; this will force the
+build system to treat the target as satisfied after a touch or
+unsatisfied after an untouch:
+
+   * make MODULE.extract.touch
+
+   * make MODULE.extract.untouch
+
+   * make MODULE.patch.touch
+
+   * make MODULE.patch.untouch
+
+   * make MODULE.configure.touch
+
+   * make MODULE.configure.untouch
+
+   * make MODULE.build.touch
+
+   * make MODULE.build.untouch
+
+   * make MODULE.install.touch
+
+   * make MODULE.install.untouch
+
+5.4.5 Contrib Aggregates
 ------------------------
 
 For convenience, the following targets aggregate the all contrib
@@ -343,15 +395,34 @@ modules' respective targets together:
 ====================
 
 If the need arises to override settings in the build system
-(essentially gnu-make variables) the recommended method is to
-create/edit the optional include file `build/GNUmakefile.custom' which
-sits adjacent to the top-level makefile. Do not check this file into
-the respository. The sole purpose is to allow a place to store local
-build settings for testing, tweaking, and experimenting with build
-configuration without losing your settings if `configure' is invoked;
-ie: `configure' would overwrite `GNUmakefile' and any customizations
-contained therein would be lost. Here is a short example of what the
-contents of `build/GNUmakefile.custom' might contain:
+(essentially gnu-make variables) the recommended method is to create
+optional include files which are automatically included if present and
+follow this naming convention; Do not check these files into the
+respository:
+
+`_SRC_/custom.defs'
+     Custom makevar definitions outside `build'. Suitable for settings
+     which apply across all builds for a particular checkout; or which
+     survives manual removal of `build'.
+
+`_SRC_/custom.rules'
+     Custom make rules outside `build'. Suitable for settings which
+     apply across all builds for a particular checkout; or which
+     survives manual removal of `build'.
+
+`_BUILD_/GNUmakefile.custom.defs'
+     Custom makevar definitions specific to a `build' directory.
+
+`_BUILD_/GNUmakefile.custom.rules'
+     Custom makevar rules specific to a `build' directory.
+
+
+The purpose is to allow a place to store local build settings for
+testing, tweaking, and experimenting with build configuration without
+losing your settings if `configure' is invoked; ie: `configure' would
+overwrite `GNUmakefile' and any customizations contained therein would
+be lost. Here is a short example of what the contents of
+`_SRC_/custom.defs' might contain:
 
      ## bump to gcc-4.2 in current path
      GCC.gcc = gcc-4.2
@@ -359,6 +430,36 @@ contents of `build/GNUmakefile.custom' might contain:
      ## replace optimize for 'speed' with more agressive settings
      GCC.args.O.speed = -O3 -fomit-frame-pointer -msse4.2
 
+See also `make report.help' which displays a set of reports used to
+dump makefile vars.
+
+5.6 Universal Binaries
+======================
+
+This section outlines convenience procedures for creating Universal
+Binaries for all the architectures.
+
+     Note: The dummy (container) build configuration uses
+     `--disable-xcode'; but the nested architecture builds will all
+     make full use of Xcode.
+
+Create a dummy (container) build configuration and use it to launch a
+nested-build for each architecture serially; optionally you may
+substitute `make ub.build.serial' for `make ub.build.parallel' if your
+machine has the horsepower:
+
+     ./configure --disable-xcode
+     cd build/
+     make ub.build.serial
+     make ub.combine
+
+To specify a subset of architectures to be built first create/edit
+`_SRC_/custom.defs' with the following override to build UB for `i386'
+and `x86_64' before invoking `make':
+
+     ## prefer i386 (order is important)
+     UB.archs = i386 x86_64
+
 6 Building via Xcode
 ********************
 
@@ -470,21 +571,21 @@ The following user defined settings are used in Xcode project for the
 external build system:
 
 `EXTERNAL_BUILD'
-     Specifies the build location for each configuration.  It is highly
-     recommended the locations always evaluate to a unique pathname
-     when factoring the configuration name.
+     Specifies the build (scratch) directory for each configuration.
 
 `EXTERNAL_JOBS'
      Specifies the concurrency factor for the external build system
-     when builds are launched from within Xcode.  This variable is
-     meant to be customized by the developer for faster builds if the
-     host supports it.
+     when builds are launched from within Xcode.  Modify for faster
+     external builds if your system has the horsepower and resources.
+     Specifying a value greater than the number of CPU cores (or
+     virtual cores) in your system is unlikely to produce gains and
+     will needlessly consume extra resources.
 
 `EXTERNAL_METHOD'
-     This variable is used for internal/external build coordination and
+     Do not modify; Used for internal/external build coordination and
      must always be `xcode'.
 
-`EXTERNAL_PROJECT'
-     Specifies the directory which is top of HandBrake source tree.
+`EXTERNAL_SRC'
+     Specifies the top-level source directory for HandBrake.
 
 
index 8ea57ef..09c80b7 100755 (executable)
--- a/configure
+++ b/configure
@@ -13,7 +13,7 @@ inpath()
     return 1
 }
 
-for p in python2.6 python2.5 python2.4
+for p in python2.7 python2.6 python2.5 python2.4 python2 python
 do
     if ( inpath $p ); then
         exec $p `dirname $0`/make/configure.py "$@"
index bda2a13..4384f83 100644 (file)
@@ -19,7 +19,7 @@ define BZIP2.INSTALL
 endef
 
 define BZIP2.UNINSTALL
-    $(RM.exe) $(CONTRIB.build/)lib/libbz2.a
-    $(RM.exe) $(CONTRIB.build/)include/bzlib.h
+    $(RM.exe) -f $(CONTRIB.build/)lib/libbz2.a
+    $(RM.exe) -f $(CONTRIB.build/)include/bzlib.h
     $(RM.exe) -f $(BZIP2.INSTALL.target)
 endef
index b412910..04b0609 100644 (file)
@@ -28,5 +28,5 @@ FFMPEG.CONFIGURE.extra = \
     --extra-ldflags="$(call fn.ARGS,FFMPEG.GCC,*archs) -L$(call fn.ABSOLUTE,$(CONTRIB.build/)lib)"
 
 ifeq ($(BUILD.cross),1)
-    FFMPEG.CONFIGURE.extra += --enable-cross-compile --arch=$(FFMPEG.GCC.archs)
+    FFMPEG.CONFIGURE.extra += --enable-cross-compile --arch=$(BUILD.machine)
 endif
index f25d89d..dee8b3e 100644 (file)
@@ -9,6 +9,8 @@ XVIDCORE.CONFIGURE.dir = $(XVIDCORE.EXTRACT.dir/)build/generic/
 XVIDCORE.BUILD.dir      = $(XVIDCORE.EXTRACT.dir/)build/generic/
 XVIDCORE.BUILD.ntargets = libxvidcore.a
 
+XVIDCORE.CLEAN.dir      = $(XVIDCORE.EXTRACT.dir/)build/generic/
+
 define XVIDCORE.INSTALL
     $(CP.exe) $(XVIDCORE.EXTRACT.dir/)build/generic/=build/libxvidcore.a $(CONTRIB.build/)lib/
     $(CP.exe) $(XVIDCORE.EXTRACT.dir/)src/xvid.h $(CONTRIB.build/)include/
@@ -16,7 +18,7 @@ define XVIDCORE.INSTALL
 endef
 
 define XVIDCORE.UNINSTALL
-    $(RM.exe) $(CONTRIB.build/)lib/libxvidcore.a
-    $(RM.exe) $(CONTRIB.build/)include/xvid.h
+    $(RM.exe) -f $(CONTRIB.build/)lib/libxvidcore.a
+    $(RM.exe) -f $(CONTRIB.build/)include/xvid.h
     $(RM.exe) -f $(XVIDCORE.INSTALL.target)
 endef
index 1697c9b..84d924a 100644 (file)
@@ -1,6 +1,6 @@
 $(eval $(call import.MODULE.defs,DOC,doc))
 
-DOC.in/  = $(PROJECT/)doc/
+DOC.in/  = $(SRC/)doc/
 DOC.out/ = $(BUILD/)doc/
 
 DOC.out.api/      = $(DOC.out/)api/
index f86b66c..54fec6d 100644 (file)
@@ -32,6 +32,8 @@ $(DOC.m4.out): $(DOC.M4.deps)
 $(DOC.m4.out): $(DOC.out/)%: $(DOC.in/)%.m4
        $(call DOC.M4,$@,$<)
 
+clean: doc.clean
+
 ###############################################################################
 
 #.PHONY: wiki.post wiki.sync wiki.rm wiki.add wiki.propset wiki.clean
index a554f7a..a02ec61 100644 (file)
@@ -37,5 +37,33 @@ Building on @value{OS.osx} is well supported. It is the reference platform for @
 @chapter Overview
 The two general methods to build on @value{OS.osx} are building from @b{terminal} or @b{Xcode}. The preferred method for automated and repeatable builds is to use the terminal. Otherwise the choice is generally up to the individual. In essence, the terminal actually invokes @command{xcodebuild} to build the very same targets contained in the Xcode project.
 
+@c %**-------------------------------------------------------------------------
 @include building/chapter.via.terminal.texi
+
+@c %**-------------------------------------------------------------------------
+@anchor{terminal.ub}
+@section Universal Binaries
+This section outlines convenience procedures for creating Universal Binaries for all the architectures.
+
+@quotation Note
+The dummy (container) build configuration uses @command{--disable-xcode}; but the nested architecture builds will all make full use of Xcode.
+@end quotation
+
+Create a dummy (container) build configuration and use it to launch a nested-build for each architecture @i{serially}; optionally you may substitute @command{make ub.build.serial} for @command{make ub.build.parallel} if your machine has the horsepower:
+
+@example
+./configure --disable-xcode
+cd build/
+make ub.build.serial
+make ub.combine
+@end example
+
+To specify a subset of architectures to be built first create/edit @file{_SRC_/custom.defs} with the following override to build UB for @samp{i386} and @samp{x86_64} before invoking @command{make}:
+
+@example
+## prefer i386 (order is important)
+UB.archs = i386 x86_64
+@end example
+
+@c %**-------------------------------------------------------------------------
 @include building/chapter.via.xcode.texi
index efcfa8d..0466df7 100644 (file)
@@ -25,6 +25,5 @@ dnl
 @set HB.repo.uuid       __HB_repo_uuid
 @set HB.repo.rev        __HB_repo_rev
 @set HB.repo.date       __HB_repo_date
-@set HB.repo.wcversion  __HB_repo_wcversion
 @set HB.repo.official   __HB_repo_official
 @set HB.repo.type       __HB_repo_type
index 9e18db7..6aee76b 100644 (file)
@@ -5,7 +5,6 @@ This chapter is for building from a terminal/shell environment in as few command
 @example
 @COMMAND.checkout{}
 ./configure --launch
-cd build/
 @end example
 
 The special option @command{--launch} selects launch mode and performs the following steps:
@@ -15,6 +14,8 @@ The special option @command{--launch} selects launch mode and performs the follo
 @item create scratch directory @file{build/}
 @item change to directory @file{build/}
 @item launch @command{make}
-@item capture build output to @file{build/log.txt}
+@item capture build output to @file{build/log/build.txt}
 @item echo build output
+@item print elapsed time
+@item indicate if build ultimately succeeded or failed
 @end itemize
index 2901481..56afb81 100644 (file)
 Configure the build system.
 
 @example
-rm -fr build/
-mkdir build/
-cd build/
-../configure
+./configure
 @end example
 
-Create a scratch directory which will contain all files created during the build process. The directory name is arbitrary but we recommend something simple and descriptive. One directory is required for each distinctly configured build. We name our directory @file{build} for example purposes.
+Configure will automatically create a scratch build directory @file{build} unless you use GNU-style build procedures and first @command{cd} to a directory other than top-level source. Additionally you may specify use @command{--build} to specify the directory. The name of the directory is arbitrary but it is recommended to use something which indicates transient files which are @b{not} checked into the repository.
 
 The @command{configure} utility accepts many options. It is recommended that you specify @command{--help} for the complete list of options. The following options are also documented here:
 
@@ -26,12 +23,22 @@ The @command{configure} utility accepts many options. It is recommended that you
 @item --help
 List available options.
 
-@item --prefix=PREFIX
+@item --src=DIR
+Specify top-level source directory for @value{HB.name} sources.
+
+@item --build=DIR
+Specify destination directory for final product install. The default is to use either @file{build} if in the top-level source directory, otherwise @file{.} 
+
+@item --prefix=DIR
 Specify destination directory for final product install.
 This defaults to a reasonable platform-specific value.
 
+@item --launch
+All-in-one option which launches the build and logs output automatically.
+Useful for novices and quickstart procedures.
+
 @item --disable-xcode
-Disable driving the build through Xcode. If this option is disabled only @command{HandBrakeCLI} will be produced and Xcode will not be invoked. @value{OS.osx} only.
+Disable shunting the build through Xcode. If this option is applied, @command{HandBrakeCLI} will be produced in a similare fashion as it is on other platforms; sans Xcode. @value{OS.osx} only.
 
 @item --disable-gtk
 Disable building the GTK GUI on applicable platforms such as @value{OS.linux}.
@@ -47,8 +54,6 @@ This generally maps to gcc options @samp{-g0}, @samp{-O0}, @samp{-O3}, @samp{-Os
 @item --arch=MODE
 Select build architecture. The available architectures vary by platform. Most platforms support exactly one architecture except @value{OS.osx} which has support for various universal binary architectures. The available choices are hard-coded per platform and no sanity checks for the required tools are performed.
 
-@item --gcc=EXE
-Specify the @command{gcc} executable to use where @b{EXE} is the executable name which is either absolute or environment @samp{PATH} is searched accordingly.
 @end table
 
 Clean-room procedures dictate that when certain factors change, old builds should be scrapped and new builds configured. This is the main reason for requiring a scratch directory; to promote consistent, reliable and clean software builds. The following is a short list of some of the reasons why someone may choose to scrap an existing build:
@@ -207,7 +212,24 @@ For convenience, the following targets aggregate the all contrib modules' respec
 @c %**-------------------------------------------------------------------------
 @anchor{terminal.customizing}
 @section Customizing Make
-If the need arises to override settings in the build system (essentially gnu-make variables) the recommended method is to create/edit the optional include file @file{build/GNUmakefile.custom} which sits adjacent to the top-level makefile. @b{Do not check this file into the respository}. The sole purpose is to allow a place to store local build settings for testing, tweaking, and experimenting with build configuration without losing your settings if @command{configure} is invoked; ie: @command{configure} would overwrite @file{GNUmakefile} and any customizations contained therein would be lost. Here is a short example of what the contents of @file{build/GNUmakefile.custom} might contain:
+If the need arises to override settings in the build system (essentially gnu-make variables) the recommended method is to create optional include files which are automatically included if present and follow this naming convention; @b{Do not check these files into the respository}:
+
+@table @file
+@item _SRC_/custom.defs
+Custom makevar definitions @i{outside} @file{build}. Suitable for settings which apply across all builds for a particular checkout; or which survives manual removal of @file{build}.
+
+@item _SRC_/custom.rules
+Custom make rules @i{outside} @file{build}. Suitable for settings which apply across all builds for a particular checkout; or which survives manual removal of @file{build}.
+
+@item _BUILD_/GNUmakefile.custom.defs
+Custom makevar definitions specific to a @file{build} directory.
+
+@item _BUILD_/GNUmakefile.custom.rules
+Custom makevar rules specific to a @file{build} directory.
+
+@end table
+
+The purpose is to allow a place to store local build settings for testing, tweaking, and experimenting with build configuration without losing your settings if @command{configure} is invoked; ie: @command{configure} would overwrite @file{GNUmakefile} and any customizations contained therein would be lost. Here is a short example of what the contents of @file{_SRC_/custom.defs} might contain:
 
 @example
 ## bump to gcc-4.2 in current path
index df42fac..a78e080 100644 (file)
@@ -72,17 +72,16 @@ The following user defined settings are used in Xcode project for the external b
 
 @table @samp
 @item EXTERNAL_BUILD
-Specifies the build location for each configuration.
-It is highly recommended the locations always evaluate to a unique pathname when factoring the configuration name.
+Specifies the build (scratch) directory for each configuration.
 
 @item EXTERNAL_JOBS
 Specifies the concurrency factor for the external build system when builds are launched from within Xcode.
-This variable is meant to be customized by the developer for faster builds if the host supports it.
+Modify for faster external builds if your system has the horsepower and resources. Specifying a value greater than the number of CPU cores (or virtual cores) in your system is unlikely to produce gains and will needlessly consume extra resources.
 
 @item EXTERNAL_METHOD
-This variable is used for internal/external build coordination and must always be @samp{xcode}.
+Do not modify; Used for internal/external build coordination and must always be @samp{xcode}.
 
-@item EXTERNAL_PROJECT
-Specifies the directory which is top of @value{HB.name} source tree.
+@item EXTERNAL_SRC
+Specifies the top-level source directory for @value{HB.name}.
 
 @end table
index 4c21e98..3acddc3 100644 (file)
@@ -1,4 +1,4 @@
 @macro COMMAND.checkout{}
-svn checkout @value{HB.repo.url} @value{HB.acro.lower}@value{HB.repo.branch}
-cd @value{HB.acro.lower}@value{HB.repo.branch}
+svn checkout @value{HB.repo.url} @value{HB.acro.lower}-@value{HB.repo.branch}
+cd @value{HB.acro.lower}-@value{HB.repo.branch}
 @end macro
index ed46be5..7550a82 100644 (file)
@@ -1,7 +1,7 @@
 $(eval $(call import.MODULE.defs,GTK,gtk,LIBHB))
 $(eval $(call import.GCC,GTK))
 
-GTK.src/   = $(PROJECT/)gtk/
+GTK.src/   = $(SRC/)gtk/
 GTK.build/ = $(BUILD/)gtk/
 
 GTK.CONFIGURE.stamp = $(GTK.build/).stamp.configure
index f66bbbb..c280078 100644 (file)
@@ -14,7 +14,7 @@ $(GTK.CONFIGURE.stamp): | $(dir $(GTK.CONFIGURE.stamp))
                PKG_CONFIG_DIR=$(BUILD/)contrib/lib/pkgconfig \
            CFLAGS="$(call fn.ARGS,GTK.GCC,.g .O)" \
            LDFLAGS="$(call fn.ARGS,GTK.GCC,?strip .g .O)" \
-           --prefix=$(INSTALL.prefix) \
+           --prefix=$(PREFIX) \
            --with-hb=$(call fn.ABSOLUTE,$(BUILD/))
        $(TOUCH.exe) $@
 
index e36d1a8..9853a10 100644 (file)
@@ -1,14 +1,14 @@
 $(eval $(call import.MODULE.defs,LIBHB,libhb,A52DEC BZIP2 FAAC FAAD2 FFMPEG LAME LIBDCA LIBDVDREAD LIBMKV LIBMP4V2 LIBOGG LIBSAMPLERATE LIBTHEORA LIBVORBIS MPEG2DEC X264 XVIDCORE ZLIB LIBHB TEST DOC))
 $(eval $(call import.GCC,LIBHB))
 
-LIBHB.src/   = $(PROJECT/)libhb/
+LIBHB.src/   = $(SRC/)libhb/
 LIBHB.build/ = $(BUILD/)libhb/
 
 LIBHB.m4.in  = $(wildcard $(LIBHB.src/)*.m4)
 LIBHB.m4.out = $(patsubst $(LIBHB.src/)%.m4,$(LIBHB.build/)%,$(LIBHB.m4.in))
 
 LIBHB.c   = $(wildcard $(LIBHB.src/)*.c)
-LIBHB.c.o = $(patsubst $(PROJECT/)%.c,$(BUILD/)%.o,$(LIBHB.c))
+LIBHB.c.o = $(patsubst $(SRC/)%.c,$(BUILD/)%.o,$(LIBHB.c))
 LIBHB.d   = $(LIBHB.m4.out) $(LIBHB.h.out) \
     $(foreach n, \
     A52DEC BZIP2 FAAC FAAD2 FFMPEG LAME LIBDCA LIBDVDREAD LIBMKV LIBMP4V2 LIBOGG \
@@ -16,7 +16,7 @@ LIBHB.d   = $(LIBHB.m4.out) $(LIBHB.h.out) \
     $($n.INSTALL.target) )
 
 LIBHB.h.in  = $(wildcard $(LIBHB.src/)*.h)
-LIBHB.h.out = $(patsubst $(PROJECT/)%,$(BUILD/)%,$(LIBHB.h.in))
+LIBHB.h.out = $(patsubst $(SRC/)%,$(BUILD/)%,$(LIBHB.h.in))
 
 ###############################################################################
 
index 396deb0..7ac6e3f 100644 (file)
@@ -8,7 +8,7 @@ $(LIBHB.a): $(LIBHB.c.o)
 
 $(LIBHB.c.o): $(LIBHB.d)
 $(LIBHB.c.o): | $(dir $(LIBHB.c.o))
-$(LIBHB.c.o): $(BUILD/)%.o: $(PROJECT/)%.c
+$(LIBHB.c.o): $(BUILD/)%.o: $(SRC/)%.c
        $(call LIBHB.GCC.C_O,$@,$<)
 
 $(LIBHB.m4.out): $(BUILD/)project/handbrake.m4
@@ -17,7 +17,7 @@ $(LIBHB.m4.out): $(LIBHB.build/)%: $(LIBHB.src/)%.m4
        $(M4.exe) -Iproject $< > $@
 
 $(LIBHB.h.out): | $(dir $(LIBHB.h.out))
-$(LIBHB.h.out): $(BUILD/)%: $(PROJECT/)%
+$(LIBHB.h.out): $(BUILD/)%: $(SRC/)%
        $(CP.exe) $< $@
 
 libhb.clean:
index 73388fd..a7baa22 100644 (file)
@@ -25,7 +25,6 @@ dnl
 <<#>>define HB_PROJECT_REPO_UUID       "__HB_repo_uuid"
 <<#>>define HB_PROJECT_REPO_REV        __HB_repo_rev
 <<#>>define HB_PROJECT_REPO_DATE       "__HB_repo_date"
-<<#>>define HB_PROJECT_REPO_WCVERSION  "__HB_repo_wcversion"
 <<#>>define HB_PROJECT_REPO_OFFICIAL   __HB_repo_official
 <<#>>define HB_PROJECT_REPO_TYPE       "__HB_repo_type"
 
index 690e8b9..c93959c 100644 (file)
 /* Begin PBXLegacyTarget section */
                27F143770F5DF34F00A684FF /* external */ = {
                        isa = PBXLegacyTarget;
-                       buildArgumentsString = "\"$EXTERNAL_PROJECT/make/xcodemake";
+                       buildArgumentsString = "\"$EXTERNAL_SRC/make/xcodemake";
                        buildConfigurationList = 27F1438E0F5DF3EA00A684FF /* Build configuration list for PBXLegacyTarget "external" */;
                        buildPhases = (
                        );
                };
                27F1437E0F5DF36000A684FF /* contrib */ = {
                        isa = PBXLegacyTarget;
-                       buildArgumentsString = "\"$EXTERNAL_PROJECT/make/xcodemake";
+                       buildArgumentsString = "\"$EXTERNAL_SRC/make/xcodemake";
                        buildConfigurationList = 27F1438F0F5DF3EA00A684FF /* Build configuration list for PBXLegacyTarget "contrib" */;
                        buildPhases = (
                        );
                };
                27F143850F5DF37600A684FF /* libhb */ = {
                        isa = PBXLegacyTarget;
-                       buildArgumentsString = "\"$EXTERNAL_PROJECT/make/xcodemake";
+                       buildArgumentsString = "\"$EXTERNAL_SRC/make/xcodemake";
                        buildConfigurationList = 27F143900F5DF3EA00A684FF /* Build configuration list for PBXLegacyTarget "libhb" */;
                        buildPhases = (
                        );
 /* Begin PBXProject section */
                29B97313FDCFA39411CA2CEA /* Project object */ = {
                        isa = PBXProject;
+                       attributes = {
+                               BuildIndependentTargetsInParallel = YES;
+                       };
                        buildConfigurationList = 4D4E7BC4087804870051572B /* Build configuration list for PBXProject "HandBrake" */;
                        compatibilityVersion = "Xcode 3.1";
                        hasScannedForEncodings = 1;
                                ARCHS = i386;
                                CONFIGURATION_BUILD_DIR = "$(EXTERNAL_BUILD)";
                                CONFIGURATION_TEMP_DIR = "$(SYMROOT)";
-                               EXTERNAL_BUILD = "$(EXTERNAL_PROJECT)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 8;
+                               EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
-                               EXTERNAL_PROJECT = ..;
+                               EXTERNAL_SRC = ..;
                                GCC_DYNAMIC_NO_PIC = YES;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
                                GCC_MODEL_TUNING = G5;
                                ARCHS = ppc;
                                CONFIGURATION_BUILD_DIR = "$(EXTERNAL_BUILD)";
                                CONFIGURATION_TEMP_DIR = "$(SYMROOT)";
-                               EXTERNAL_BUILD = "$(EXTERNAL_PROJECT)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 8;
+                               EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
-                               EXTERNAL_PROJECT = ..;
+                               EXTERNAL_SRC = ..;
                                GCC_DYNAMIC_NO_PIC = YES;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
                                GCC_MODEL_TUNING = G5;
                                ARCHS = x86_64;
                                CONFIGURATION_BUILD_DIR = "$(EXTERNAL_BUILD)";
                                CONFIGURATION_TEMP_DIR = "$(SYMROOT)";
-                               EXTERNAL_BUILD = "$(EXTERNAL_PROJECT)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 8;
+                               EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
-                               EXTERNAL_PROJECT = ..;
+                               EXTERNAL_SRC = ..;
                                GCC_DYNAMIC_NO_PIC = YES;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
                                GCC_MODEL_TUNING = G5;
                                ARCHS = ppc64;
                                CONFIGURATION_BUILD_DIR = "$(EXTERNAL_BUILD)";
                                CONFIGURATION_TEMP_DIR = "$(SYMROOT)";
-                               EXTERNAL_BUILD = "$(EXTERNAL_PROJECT)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 8;
+                               EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
-                               EXTERNAL_PROJECT = ..;
+                               EXTERNAL_SRC = ..;
                                GCC_DYNAMIC_NO_PIC = YES;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
                                GCC_MODEL_TUNING = G5;
                                CONFIGURATION_TEMP_DIR = "$(SYMROOT)";
                                COPY_PHASE_STRIP = NO;
                                DEBUG_INFORMATION_FORMAT = dwarf;
-                               EXTERNAL_BUILD = "$(EXTERNAL_PROJECT)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 8;
+                               EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
-                               EXTERNAL_PROJECT = ..;
+                               EXTERNAL_SRC = ..;
                                GCC_DYNAMIC_NO_PIC = YES;
                                GCC_ENABLE_FIX_AND_CONTINUE = YES;
                                GCC_OPTIMIZATION_LEVEL = 0;
                        buildSettings = {
                                CONFIGURATION_BUILD_DIR = "$(EXTERNAL_BUILD)";
                                CONFIGURATION_TEMP_DIR = "$(SYMROOT)";
-                               EXTERNAL_BUILD = "$(EXTERNAL_PROJECT)/build.$(CONFIGURATION)";
+                               EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
                                EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
-                               EXTERNAL_PROJECT = ..;
+                               EXTERNAL_SRC = ..;
                                GCC_DYNAMIC_NO_PIC = YES;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
                                GCC_MODEL_TUNING = G5;
index fec467d..75b9655 100644 (file)
@@ -1,10 +1,13 @@
 $(eval $(call import.MODULE.defs,MACOSX,macosx))
 
-MACOSX.src/   = $(PROJECT/)macosx/
+MACOSX.src/   = $(SRC/)macosx/
 MACOSX.build/ = $(BUILD/)macosx/
 
 MACOSX.m4.in  = $(wildcard $(MACOSX.src/)*.m4)
-MACOSX.m4.out = $(patsubst $(MACOSX.src/)%.m4,$(MACOSX.build/)%,$(MACOSX.m4.in))
+MACOSX.m4.out = $(MACOSX.m4.in:$(MACOSX.src/)%.m4=$(MACOSX.build/)%)
+
+## optional special command to run post macro processing
+MACOSX.m4.post.Info.h = $(RM.exe) -f $(MACOSX.build/)HandBrake.build/Preprocessed-Info.plist
 
 MACOSX.targs = HandBrakeCLI HandBrake
 MACOSX.conf  = standard$(if $(filter 1,$(BUILD.cross)),.$(BUILD.arch))
@@ -12,6 +15,7 @@ MACOSX.conf  = standard$(if $(filter 1,$(BUILD.cross)),.$(BUILD.arch))
 ###############################################################################
 
 BUILD.out += $(MACOSX.m4.out)
+BUILD.out += $(MACOSX.m4.wc.out)
 
 ###############################################################################
 
@@ -30,10 +34,11 @@ MACOSX.XCODE = $(strip \
         -project $(MACOSX.XCODE.project) \
         -configuration $(MACOSX.conf) \
         $(foreach t,$(1),-target $t) \
-        EXTERNAL_BUILD='$(CURDIR)' \
+        EXTERNAL_SRC='$(XCODE.external.src)' \
+        EXTERNAL_BUILD='$(XCODE.external.build)' \
+        EXTERNAL_PREFIX='$(XCODE.external.prefix)' \
         EXTERNAL_JOBS='$(BUILD.jobs)' \
         EXTERNAL_METHOD='$(CONF.method)' \
-        EXTERNAL_PROJECT='$(PROJECT/)' \
         EXTERNAL_GOALS='$(3)' \
         EXTERNAL_VARS='$(-*-command-variables-*-)' \
         $(2) )
index 9873e90..c662364 100644 (file)
@@ -2,10 +2,14 @@ $(eval $(call import.MODULE.rules,MACOSX))
 
 macosx.build: $(MACOSX.m4.out)
 
+macosx.clean:
+       $(RM.exe) -f $(MACOSX.m4.out)
+
 $(MACOSX.m4.out): $(BUILD/)project/handbrake.m4
 $(MACOSX.m4.out): | $(dir $(MACOSX.m4.out))
 $(MACOSX.m4.out): $(MACOSX.build/)%: $(MACOSX.src/)%.m4
        $(M4.exe) -Iproject $< > $@
+       $(MACOSX.m4.post.$(notdir $@))
 
 ###############################################################################
 
index 81f6616..fc52b36 100644 (file)
@@ -20,7 +20,7 @@ xclean: clean
 
 ###############################################################################
 
-MACOSX.goals = $(filter-out build clean install xclean,$(MAKECMDGOALS))
+MACOSX.goals = $(filter-out build clean install,$(MAKECMDGOALS))
 
 $(MACOSX.goals): __goals__
        @true
index ce28840..c984ccc 100644 (file)
@@ -1,3 +1,12 @@
+###############################################################################
+##
+## This script is coded for minimum version of Python 2.4 .
+## Pyhthon3 is incompatible.
+##
+## Authors: konablend
+##
+###############################################################################
+
 import fnmatch
 import optparse
 import os
@@ -13,408 +22,514 @@ from optparse import OptionParser
 from sys import stderr
 from sys import stdout
 
+class AbortError( Exception ):
+    def __init__( self, format, *args ):
+        self.value = format % args
+    def __str__( self ):
+        return self.value
+
 ###############################################################################
+##
+## Main configure object.
+##
+## dir = containing this configure script
+## cwd = current working dir at time of script launch
+##
+class Configure( object ):
+    OUT_QUIET   = 0
+    OUT_INFO    = 1
+    OUT_VERBOSE = 2
+
+    def __init__( self, verbose ):
+        self._log_info    = []
+        self._log_verbose = []
+        self._record      = False
+
+        self.verbose = verbose
+        self.dir = os.path.dirname( sys.argv[0] )
+        self.cwd = os.getcwd()
+
+        self.build_dir = '.'
+
+        ## compute src dir which is 2 dirs up from this script
+        self.src_dir = os.path.normpath( sys.argv[0] )
+        for i in range( 2 ):
+            self.src_dir = os.path.dirname( self.src_dir )
+        if len( self.src_dir ) == 0:
+            self.src_dir = os.curdir
+
+    def _final_dir( self, chdir, dir ):
+        dir = os.path.normpath( dir )
+        if not os.path.isabs( dir ):
+            if os.path.isabs( chdir ):
+                dir = os.path.normpath( os.path.abspath(dir ))
+            else:
+                dir = os.path.normpath( self.relpath( dir, chdir ))
+        return dir
+
+    ## output functions
+    def errln( self, format, *args ):
+        s = (format % args)
+        if re.match( '^.*[!?:;.]$', s ):
+            stderr.write( 'ERROR: %s configure stop.\n' % (s) )
+        else:
+            stderr.write( 'ERROR: %s; configure stop.\n' % (s) )
+        self.record_log()
+        sys.exit( 1 )
+    def infof( self, format, *args ):
+        line = format % args
+        self._log_verbose.append( line )
+        if cfg.verbose >= Configure.OUT_INFO:
+            self._log_info.append( line )
+            stdout.write( line )
+    def verbosef( self, format, *args ):
+        line = format % args
+        self._log_verbose.append( line )
+        if cfg.verbose >= Configure.OUT_VERBOSE:
+            stdout.write( line )
+
+    ## doc is ready to be populated
+    def doc_ready( self ):
+        ## compute final paths as they are after chdir into build
+        self.build_final  = os.curdir
+        self.src_final    = self._final_dir( self.build_dir, self.src_dir )
+        self.prefix_final = self._final_dir( self.build_dir, self.prefix_dir )
+
+        cfg.infof( 'compute: makevar SRC/    = %s\n', self.src_final )
+        cfg.infof( 'compute: makevar BUILD/  = %s\n', self.build_final )
+        cfg.infof( 'compute: makevar PREFIX/ = %s\n', self.prefix_final )
+
+        ## xcode does a chdir so we need appropriate values
+        macosx = os.path.join( self.src_dir, 'macosx' )
+        self.xcode_x_src    = self._final_dir( macosx, self.src_dir )
+        self.xcode_x_build  = self._final_dir( macosx, self.build_dir )
+        self.xcode_x_prefix = self._final_dir( macosx, self.prefix_dir )
+
+    ## perform chdir and enable log recording
+    def chdir( self ):
+        if os.path.abspath( self.build_dir ) == os.path.abspath( self.src_dir ):
+            cfg.errln( 'build (scratch) directory must not be the same as top-level source root!' )
+
+        if self.build_dir != os.curdir:
+            if os.path.exists( self.build_dir ):
+                if not options.force:
+                    self.errln( 'build directory already exists: %s (use --force to overwrite)', self.build_dir )
+            else:
+                self.mkdirs( self.build_dir )
+            self.infof( 'chdir: %s\n', self.build_dir )
+            os.chdir( self.build_dir )
+
+        ## enable logging
+        self._record = True
+
+    def mkdirs( self, dir ):
+        if len(dir) and not os.path.exists( dir ):
+            self.infof( 'mkdir: %s\n', dir )
+            os.makedirs( dir )
+
+    def open( self, *args ):
+        dir = os.path.dirname( args[0] )
+        if len(args) > 1 and args[1].find('w') != -1:
+            self.mkdirs( dir )
+        m = re.match( '^(.*)\.tmp$', args[0] )
+        if m:
+            self.infof( 'write: %s\n', m.group(1) )
+        else:
+            self.infof( 'write: %s\n', args[0] )
 
-def errf( format, *args ):
-    stderr.write( ('ERROR: ' + format + '\n') % args )
-    sys.exit( 1 )
+        try:
+            return open( *args )
+        except Exception, x:
+            cfg.errln( 'open failure: %s', x )
 
-def outf( format, *args ):
-    stdout.write( (format + '\n') % args )
+    def record_log( self ):
+        if not self._record:
+            return
+        self._record = False
+        self.verbose = Configure.OUT_QUIET
+        file = cfg.open( 'log/config.info.txt', 'w' )
+        for line in self._log_info:
+            file.write( line )
+        file.close()
+        file = cfg.open( 'log/config.verbose.txt', 'w' )
+        for line in self._log_verbose:
+            file.write( line )
+        file.close()
+
+    ## Find executable by searching path.
+    ## On success, returns full pathname of executable.
+    ## On fail, returns None.
+    def findExecutable( self, name ):
+        if len( os.path.split(name)[0] ):
+            if os.access( name, os.X_OK ):
+                return name
+            return None
+        
+        if not os.environ.has_key( 'PATH' ) or os.environ[ 'PATH' ] == '':
+            path = os.defpath
+        else:
+            path = os.environ['PATH']
+        
+        for dir in path.split( os.pathsep ):
+            f = os.path.join( dir, name )
+            if os.access( f, os.X_OK ):
+                return f
+        return None
+
+    ## taken from python2.6 -- we need it
+    def relpath( self, path, start=os.curdir ):
+        """Return a relative version of a path"""
+
+        if not path:
+            raise ValueError("no path specified")
+
+        start_list = os.path.abspath(start).split(os.sep)
+        path_list = os.path.abspath(path).split(os.sep)
+
+        # Work out how much of the filepath is shared by start and path.
+        i = len(os.path.commonprefix([start_list, path_list]))
+
+        rel_list = [os.pardir] * (len(start_list)-i) + path_list[i:]
+        if not rel_list:
+            return os.curdir
+        return os.path.join(*rel_list)
+
+    ## update with parsed cli options
+    def update_cli( self, options ):
+        self.src_dir    = os.path.normpath( options.src )
+        self.build_dir  = os.path.normpath( options.build )
+        self.prefix_dir = os.path.normpath( options.prefix )
+
+        ## special case if src == build: add build subdir
+        if os.path.abspath( self.src_dir ) == os.path.abspath( self.build_dir ):
+            self.build_dir = os.path.join( self.build_dir, 'build' )
 
 ###############################################################################
-
-## Expand values of iterable object into a decent string representation.
 ##
-def expandValues( obj ):
-    buf = ''
-    for v in obj:
-        buf += ', ' + v
-    return '{ ' + buf[2:] + ' }'
+## abstract action
+##
+## pretext = text which immediately follows 'probe:' output prefix
+## abort   = if true configure will exit on probe fail
+## head    = if true probe session is stripped of all but first line
+## session = output from command, including stderr
+## fail    = true if probe failed
+##
+class Action( object ):
+    actions = []
+
+    def __init__( self, category, pretext='unknown', abort=False, head=False ):
+        if self not in Action.actions:
+            Action.actions.append( self )
+
+        self.category = category
+        self.pretext  = pretext
+        self.abort    = abort
+        self.head     = head
+        self.session  = None
+
+        self.run_done = False
+        self.fail     = True
+        self.msg_fail = 'fail'
+        self.msg_pass = 'pass'
+        self.msg_end  = 'end'
+
+    def _actionBegin( self ):
+        cfg.infof( '%s: %s...', self.category, self.pretext )
+
+    def _actionEnd( self ):
+        if self.fail:
+            cfg.infof( '(%s) %s\n', self.msg_fail, self.msg_end )
+            if self.abort:
+                self._dumpSession( cfg.infof )
+                cfg.errln( 'unable to continue' )
+            self._dumpSession( cfg.verbosef )
+        else:
+            cfg.infof( '(%s) %s\n', self.msg_pass, self.msg_end )
+            self._dumpSession( cfg.verbosef )
 
-###############################################################################
+    def _dumpSession( self, printf ):
+        if self.session and len(self.session):
+            for line in self.session:
+                printf( '  : %s\n', line )
+        else:
+            printf( '  : <NO-OUTPUT>\n' )
+
+    def _parseSession( self ):
+        pass
+
+    def run( self ):
+        if self.run_done:
+            return
+        self.run_done = True
+        self._actionBegin()
+        self._action()
+        if not self.fail:
+            self._parseSession()
+        self._actionEnd()
 
-## Find executable by searching path.
-## On success, returns full pathname of executable.
-## On fail, returns None.
+###############################################################################
+##
+## base probe: anything which runs in shell.
+##
+## pretext = text which immediately follows 'probe:' output prefix
+## command = full command and arguments to pipe
+## abort   = if true configure will exit on probe fail
+## head    = if true probe session is stripped of all but first line
+## session = output from command, including stderr
+## fail    = true if probe failed
 ##
-def findExecutable( name ):
-    if len( os.path.split(name)[0] ):
-        return name if os.access( name, os.X_OK ) else None
+class ShellProbe( Action ):
+    def __init__( self, pretext, command, abort=False, head=False ):
+        super( ShellProbe, self ).__init__( 'probe', pretext, abort, head )
+        self.command = command
 
-    if not os.environ.has_key( 'PATH' ) or os.environ[ 'PATH' ] == '':
-        path = os.defpath
-    else:
-        path = os.environ['PATH']
+    def _action( self ):
+        ## pipe and redirect stderr to stdout; effects communicate result
+        pipe = subprocess.Popen( self.command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
 
-    for dir in path.split( os.pathsep ):
-        f = os.path.join( dir, name )
-        if os.access( f, os.X_OK ):
-            return f
-    return None
+        ## read data into memory buffers, only first element (stdout) data is used
+        data = pipe.communicate()
+        self.fail = pipe.returncode != 0
 
-###############################################################################
+        if data[0]:
+            self.session = data[0].splitlines()
+        else:
+            self.session = []
 
-def computeNumCPU():
-    ## good for darwin9.6.0 and linux
-    try:
-        n = os.sysconf( 'SC_NPROCESSORS_ONLN' )
-        if n < 1:
-            n = 1
-        return n
-    except:
-        pass
-    ## windows
-    try:
-        n = int( os.environ['NUMBER_OF_PROCESSORS'] )
-        if n < 1:
-            n = 1
-        return n
-    except:
-        pass
-    return 1
+        if pipe.returncode:
+            self.msg_end = 'code %d' % (pipe.returncode)
+
+    def _dumpSession( self, printf ):
+        printf( '  + %s\n', self.command )
+        super( ShellProbe, self )._dumpSession( printf )
 
 ###############################################################################
+##
+## GNU host tuple probe: determine canonical platform type
+##
+## example results from various platforms:
+##
+##   i386-apple-darwin9.6.0     (Mac OS X 10.5.6 Intel)
+##   powerpc-apple-darwin9.6.0  (Mac OS X 10.5.6 PPC)
+##   i686-pc-cygwin             (Cygwin, Microsoft Vista)
+##   x86_64-unknown-linux-gnu   (Linux, Fedora 10 x86_64)
+##
+class HostTupleProbe( ShellProbe, list ):
+    GNU_TUPLE_RX = '([^-]+)-([^-]+)-([^0-9-]+)([^-]*)-?([^-]*)'
+
+    def __init__( self ):
+        super( HostTupleProbe, self ).__init__( 'host tuple', '%s/config.guess' % (cfg.dir), abort=True, head=True )
 
-## taken from python2.6 -- we need it
-def relpath(path, start=os.path.curdir):
-    """Return a relative version of a path"""
+    def _parseSession( self ):
+        if len(self.session):
+            self.spec = self.session[0]
+        else:
+            self.spec = ''
 
-    if not path:
-        raise ValueError("no path specified")
+        ## grok GNU host tuples
+        m = re.match( HostTupleProbe.GNU_TUPLE_RX, self.spec )
+        if not m:
+            self.fail = True
+            self.msg_end = 'invalid host tuple: %s' % (self.spec)
+            return
 
-    start_list = os.path.abspath(start).split(os.sep)
-    path_list = os.path.abspath(path).split(os.sep)
+        self.msg_end = self.spec
 
-    # Work out how much of the filepath is shared by start and path.
-    i = len(os.path.commonprefix([start_list, path_list]))
+        ## assign tuple from regex
+        self[:] = m.groups()
 
-    rel_list = [os.pardir] * (len(start_list)-i) + path_list[i:]
-    if not rel_list:
-        return os.path.curdir
-    return os.path.join(*rel_list)
+        ## for clarity
+        self.machine = self[0]
+        self.vendor  = self[1]
+        self.system  = self[2]
+        self.release = self[3]
+        self.extra   = self[4]
 
-###############################################################################
+        ## nice formal name for 'system'
+        self.systemf = platform.system()
 
-# compute project dir which should be 2 dirs below this script
-build_dir = os.curdir
-project_dir = os.path.normpath( sys.argv[0] )
-for i in range( 2 ):
-    project_dir = os.path.dirname( project_dir )
-if len( project_dir ) == 0:
-    project_dir = os.curdir
-initial_project_dir = project_dir
+        if self.match( '*-*-cygwin*' ):
+            self.systemf = self[2][0].upper() + self[2][1:]
+            
+    ## glob-match against spec
+    def match( self, spec ):
+        return fnmatch.fnmatch( self.spec, spec )
 
 ###############################################################################
 
-## model gnu-autotools platform guess
+class BuildAction( Action, list ):
+    def __init__( self ):
+        super( BuildAction, self ).__init__( 'compute', 'build tuple', abort=True )
+
+    def _action( self ):
+        self.spec = arch.mode[arch.mode.mode]
+
+        ## grok GNU host tuples
+        m = re.match( HostTupleProbe.GNU_TUPLE_RX, self.spec )
+        if not m:
+            self.msg_end = 'invalid host tuple: %s' % (self.spec)
+            return
+
+        self.msg_end = self.spec
+
+        ## assign tuple from regex
+        self[:] = m.groups()
+
+        ## for clarity
+        self.machine = self[0]
+        self.vendor  = self[1]
+        self.system  = self[2]
+        self.release = self[3]
+        self.extra   = self[4]
+        self.systemf = host.systemf
+
+        self.fail = False
+
+###############################################################################
 ##
-## native format:
-##   (PROC)-(VENDOR)-(SYSTEM)(RELEASE)-(EXTRA)
+## platform conditional string; if specs do not match host:
 ##
-## examples:
-##   i386-apple-darwin9.6.0    (Mac OS X 10.5.6 Intel)
-##   powerpc-apple-darwin9.6.0 (Mac OS X 10.5.6 PPC)
-##   i686-pc-cygwin            (Cygwin, Microsoft Vista)
-##   x86_64-unknown-linux-gnu  (Linux, Fedora 10 x86_64)
+## - str value is blank
+## - evaluates to False
 ##
-class Guess:
-    def __init__( self ):
-        self.machine = 'unknown'
-        self.vendor  = 'unknown'
-        self.system  = 'unknown'
-        self.systemc = 'Unknown'
-        self.release = '0.0.0'
-        self.extra   = ''
-
-        p_system    = platform.system().lower()
-        p_systemc   = platform.system()
-        p_release   = platform.release().lower()
-        p_processor = platform.processor().lower()
-        p_machine   = platform.machine().lower()
-
-        if re.match( 'cygwin', p_system ):
-            self.machine = p_machine
-            self.vendor  = 'pc'
-            self.system  = 'cygwin'
-            self.systemc = 'Cygwin'
-            self.release = ''
-            self.extra   = ''
-        elif re.match( 'darwin', p_system ):
-            self.machine = p_processor
-            self.vendor  = 'apple'
-            self.system  = p_system
-            self.systemc = p_systemc
-            self.release = p_release
-            self.extra   = ''
-        elif re.match( 'linux', p_system ):
-            self.machine = p_machine
-            self.vendor  = 'unknown'
-            self.system  = p_system
-            self.systemc = p_systemc
-            self.release = ''
-            self.extra   = 'gnu'
-            self.title   = 'Linux %s' % (p_machine)
-        else:
-            errf( 'unrecognized host system: %s', p_system )
-
+class IfHost( object ):
+    def __init__( self, value, *specs ):
+        self.value = ''
+        for spec in specs:
+            if host.match( spec ):
+                self.value = value
+                break
+
+    def __nonzero__( self ):
+        return len(self.value) != 0
+        
     def __str__( self ):
-        if len(self.extra):
-            return '%s-%s-%s%s-%s' % (self.machine,self.vendor,self.system,self.release,self.extra)
-        else:
-            return '%s-%s-%s%s' % (self.machine,self.vendor,self.system,self.release)
+        return self.value
 
-    def match( self, spec ):
-        return fnmatch.fnmatch( str(self), spec )
+###############################################################################
+##
+## platform conditional value; loops through list of tuples comparing
+## to first host match and sets value accordingly; the first value is
+## always default.
+##
+class ForHost( object ):
+    def __init__( self, default, *tuples ):
+        self.value = default
+        for tuple in tuples:
+            if host.match( tuple[1] ):
+                self.value = tuple[0]
+                break
+
+    def __str__( self ):
+        return self.value
 
 ###############################################################################
 
-# a tool represents a command-line tool which may be searched for in PATH
-class Tool:
-    def __init__( self, parent, optional, var, *pool ):
-        self.name     = pool[0]
-        self.optional = optional
-        self.var      = var
-        self.pool     = pool
-        self.found    = None
-        if parent:
-            parent.register( self )
-
-    def addToConfig( self, config ):
-        config.add( self.var, self.found )
-
-    def addToGroup( self, group ):
-        group.add_option( '', '--' + self.name, help='specify %s location' % (self.name), default=None, metavar='EXE' )
-
-    def locate( self, options ):
-        spec = options.__dict__[self.name]
-        pool = self.pool if not spec else [spec]
-        for p in pool:
-            self.found = findExecutable( p )
-            if self.found:
-                outf( 'located %s: %s', self.name, self.found )
-                return
-        if self.optional:
-            outf( 'missing: %s (optional)', self.name )
+class ArchAction( Action ):
+    def __init__( self ):
+        super( ArchAction, self ).__init__( 'compute', 'available architectures', abort=True )
+        self.mode = SelectMode( 'architecture', (host.machine,host.spec) )
+
+    def _action( self ):
+        self.fail = False
+
+        ## some match on system should be made here; otherwise we signal a warning. 
+        if host.match( '*-*-cygwin*' ):
+            pass
+        elif host.match( '*-*-darwin*' ):
+            self.mode['i386']   = 'i386-apple-darwin%s'      % (host.release)
+            self.mode['x86_64'] = 'x86_64-apple-darwin%s'    % (host.release)
+            self.mode['ppc']    = 'powerpc-apple-darwin%s'   % (host.release)
+            self.mode['ppc64']  = 'powerpc64-apple-darwin%s' % (host.release)
+        elif host.match( '*-*-linux*' ):
+            pass
         else:
-            errf( 'unable to locate tool: %s', self.name )
-
-## a select tool picks first found from a list of tools
-class SelectTool( Tool ):
-    def __init__( self, parent, var, name, *pool ):
-        self.var     = var
-        self.name    = name
-        self.pool    = pool
-        self.found   = None
-
-        self.poolMap = {}
-        for p in self.pool:
-            self.poolMap[p.name] = p
-        if parent:
-            parent.register( self )
-
-    def addToConfig( self, config ):
-        config.add( self.var, self.found )
-
-    def addToGroup( self, group ):
-        group.add_option( '', '--' + self.name, help='select %s mode: %s' % (self.name,expandValues(self.poolMap)),
-            default=self.name, metavar='MODE' )
-
-    def locate( self, options ):
-        spec = options.__dict__[self.name]
-        if spec in self.poolMap:
-            self.found = spec
-            return
-        for p in self.pool:
-            if p.found:
-                self.found = p.name
-                outf( 'selected %s: %s', self.name, self.found )
-                return
-        errf( 'require at least one location of: %s', expandValues( self.poolMap ))
+            self.msg_pass = 'WARNING'
+
+        self.msg_end = self.mode.toString()
+
+    ## glob-match against spec
+    def match( self, spec ):
+        return fnmatch.fnmatch( self.spec, spec )
 
 ###############################################################################
 
-class ToolSet:
+class CoreProbe( Action ):
     def __init__( self ):
-        self.items = []
-        Tool( self, False, 'AR.exe',    'ar' )
-        Tool( self, False, 'CP.exe',    'cp' )
-        Tool( self, True,  'CURL.exe',  'curl' )
-        Tool( self, False, 'GCC.gcc',   'gcc', 'gcc-4' )
-        Tool( self, False, 'M4.exe',    'm4' )
-        Tool( self, False, 'MKDIR.exe', 'mkdir' )
-        Tool( self, False, 'PATCH.exe', 'patch' )
-        Tool( self, False, 'RM.exe',    'rm' )
-        Tool( self, False, 'TAR.exe',   'tar' )
-        Tool( self, True,  'WGET.exe',  'wget' )
-
-        SelectTool( self, 'FETCH.select', 'fetch', self.wget, self.curl )
-
-    def register( self, item ):
-        self.__dict__[item.name] = item
-        self.items.append( item )
+        super( CoreProbe, self ).__init__( 'probe', 'number of CPU cores' )
+        self.count = 1
 
-###############################################################################
+    def _action( self ):
+        if self.fail:
+            ## good for darwin9.6.0 and linux
+            try:
+                self.count = os.sysconf( 'SC_NPROCESSORS_ONLN' )
+                if self.count < 1:
+                    self.count = 1
+                self.fail = False
+            except:
+                pass
+
+        if self.fail:
+            ## windows
+            try:
+                self.count = int( os.environ['NUMBER_OF_PROCESSORS'] )
+                if self.count < 1:
+                    self.count = 1
+                self.fail = False
+            except:
+                pass
 
-class OptionMode( list ):
-    def __init__( self, default, *items ):
-        super( OptionMode, self ).__init__( items )
-        self.default = items[default]
-        self.mode = self.default
+        ## clamp
+        if self.count < 1:
+            self.count = 1
+        elif self.count > 32:
+            self.count = 32
 
-    def __str__( self ):
-        s = ''
-        for a in self:
-            if a == self.mode:
-                s += ' *' + a
+        if options.launch:
+            if options.launch_jobs == 0:
+                self.jobs = core.count
             else:
-                s += ' ' + a
-        return s[1:]
-
-    def addToGroup( self, group, option, name ):
-        group.add_option( '', option, help='select %s mode: %s' % (name,self), default=self.mode, metavar='MODE' )
+                self.jobs = options.launch_jobs
+        else:
+            self.jobs = core.count
 
-    def setFromOption( self, name, mode ):
-        if mode not in self:
-            errf( 'invalid %s mode: %s', name, mode )
-        self.mode = mode
+        self.msg_end = str(self.count)
 
 ###############################################################################
 
-## create singletons
-guessHost  = Guess()
-guessBuild = Guess()
-
-makeTool = Tool( None, False, 'CONF.make', 'gmake', 'make' )
-tools = ToolSet()
-
-debugMode    = OptionMode( 0, 'none', 'min', 'std', 'max' )
-optimizeMode = OptionMode( 1, 'none', 'speed', 'size' )
-
-## populate platform-specific architecture modes
-if guessHost.match( 'i386-*-darwin8.*' ):
-    archMode = OptionMode( 0, 'i386', 'ppc' )
-elif guessHost.match( 'powerpc-*-darwin8.*' ):
-    archMode = OptionMode( 1, 'i386', 'ppc' )
-elif guessHost.match( 'i386-*-darwin9.*' ):
-    archMode = OptionMode( 0, 'i386', 'x86_64', 'ppc', 'ppc64' )
-elif guessHost.match( 'powerpc-*-darwin9.*' ):
-    archMode = OptionMode( 2, 'i386', 'x86_64', 'ppc', 'ppc64' )
-else:
-    archMode = OptionMode( 0, guessHost.machine )
-
-if guessHost.match( '*-*-darwin*' ):
-    d_xcode = True
-    d_prefix = '/Applications'
-else: 
-    d_xcode = False
-    d_prefix = '/usr/local'
-
-## create parser
-parser = OptionParser( 'Usage: %prog' )
-
-## add hidden options
-parser.add_option( '', '--conf-method', default='terminal', action='store', help=optparse.SUPPRESS_HELP )
-
-## add install options
-group = OptionGroup( parser, 'Installation Options' )
-group.add_option( '', '--prefix', default=d_prefix, action='store',
-    help='specify destination for final products (%s)' % (d_prefix) )
-parser.add_option_group( group )
-
-group = OptionGroup( parser, 'Feature Options' )
-if d_xcode:
-    group.add_option( '', '--disable-xcode', default=False, action='store_true',
-        help='disable Xcode (Darwin only)' )
-group.add_option( '', '--disable-gtk', default=False, action='store_true',
-    help='disable GTK GUI (Linux only)' )
-parser.add_option_group( group )
-
-## add launch options
-group = OptionGroup( parser, 'Launch Options' )
-group.add_option( '', '--launch', default=False, action='store_true',
-    help='launch build, capture log and wait for completion' )
-group.add_option( '', '--launch-jobs', default=1, action='store', metavar='N',
-    help='allow N jobs at once; 0 to match CPU count (1)' )
-group.add_option( '', '--launch-args', default=None, action='store', metavar='ARGS',
-    help='specify additional ARGS for launch command' )
-group.add_option( '', '--launch-dir', default='build', action='store', metavar='DIR',
-    help='specify scratch DIR to use for build (build)' )
-group.add_option( '', '--launch-force', default=False, action='store_true',
-    help='force use of scratch directory even if exists' )
-group.add_option( '', '--launch-log', default='log.txt', action='store', metavar='FILE',
-    help='specify log FILE (log.txt)' )
-group.add_option( '', '--launch-quiet', default=False, action='store_true',
-    help='do not echo build output' )
-parser.add_option_group( group )
-
-## add compile options
-group = OptionGroup( parser, 'Compiler Options' )
-debugMode.addToGroup( group, '--debug', 'debug' )
-optimizeMode.addToGroup( group, '--optimize', 'optimize' )
-archMode.addToGroup( group, '--arch', 'architecutre' )
-parser.add_option_group( group )
-
-## add tool options
-group = OptionGroup( parser, 'Tool Options' )
-makeTool.addToGroup( group )
-for tool in tools.items:
-    tool.addToGroup( group )
-parser.add_option_group( group )
-
-(options,args) = parser.parse_args()
-
-exports = []
-for arg in args:
-    m = re.match( '([^=]+)=(.*)', arg )
-    if m:
-        exports.append( m.groups() )
-
-## recompute values when launch mode
-if options.launch:
-    options.launch_jobs = int(options.launch_jobs)
-    build_dir = options.launch_dir
-    if os.path.isabs( build_dir ):
-        project_dir = os.getcwd() 
-    else:
-        project_dir = os.path.normpath( relpath( project_dir, build_dir ))
-    if options.launch_jobs == 0:
-        options.launch_jobs = computeNumCPU()
-    if options.launch_jobs < 1:
-        options.launch_jobs = 1
-    elif options.launch_jobs > 8:
-        options.launch_jobs = 8
-
-## make sure configure does not run in source root
-if os.path.abspath( project_dir ) == os.path.abspath( build_dir ):
-    errf( 'scratch (build) directory must not be the same as source root' )
-
-## validate modes
-debugMode.setFromOption( 'debug', options.debug )
-optimizeMode.setFromOption( 'optimize', options.optimize )
-archMode.setFromOption( 'architecture', options.arch )
-
-## update guessBuild as per architecture mode
-if guessHost.match( '*-*-darwin*' ):
-    if archMode.mode == 'i386':
-        guessBuild.machine = 'i386'
-    elif archMode.mode == 'x86_64':
-        guessBuild.machine = 'x86_64'
-    elif archMode.mode == 'ppc':
-        guessBuild.machine = 'powerpc'
-    elif archMode.mode == 'ppc64':
-        guessBuild.machine = 'powerpc64'
-else:
-    guessBuild.machine = archMode.mode
-guessBuild.cross = 0 if archMode.default == archMode.mode else 1
-
-# locate tools
-makeTool.locate( options )
-for tool in tools.items:
-    tool.locate( options )
+class SelectMode( dict ):
+    def __init__( self, descr, *modes, **kwargs ):
+        super( SelectMode, self ).__init__( modes )
+        self.descr    = descr
+        self.modes    = modes
+        self.default  = kwargs.get('default',modes[0][0])
+        self.mode     = self.default
+
+    def cli_add_option( self, parser, option ):
+        parser.add_option( '', option, default=self.mode, metavar='MODE',
+            help='select %s mode: %s' % (self.descr,self.toString()),
+            action='callback', callback=self.cli_callback, type='str' )
+
+    def cli_callback( self, option, opt_str, value, parser, *args, **kwargs ):
+        if value not in self:
+            raise optparse.OptionValueError( 'invalid %s mode: %s (choose from %s)'
+                % (self.descr,value,self.toString( True )) )
+        self.mode = value
+
+    def toString( self, nodefault=False ):
+        keys = self.keys()
+        keys.sort()
+        if len(self) == 1:
+            value = self.mode
+        elif nodefault:
+            value = ' '.join( keys )
+        else:
+            value = '%s [%s]' % (' '.join( keys ), self.mode )
+        return value
 
 ###############################################################################
-
+##
 ## Repository object.
 ## Holds information gleaned from subversion working dir.
 ##
@@ -427,62 +542,48 @@ for tool in tools.items:
 ##  unofficial
 ##      all other builds
 ##
-class Repository:
+class RepoProbe( ShellProbe ):
     def __init__( self ):
+        super( RepoProbe, self ).__init__( 'svn info', 'svn info %s' % (cfg.src_dir) )
+
         self.url       = 'svn://nowhere.com/project/unknown'
         self.root      = 'svn://nowhere.com/project'
         self.branch    = 'unknown'
         self.uuid      = '00000000-0000-0000-0000-000000000000';
         self.rev       = 0
         self.date      = '0000-00-00 00:00:00 -0000'
-        self.wcversion = 'exported'
         self.official  = 0
         self.type      = 'unofficial'
 
-        # parse output: svnversion PROJECT_DIR
-        cmd = 'svnversion ' + initial_project_dir
-        print 'attempting to probe subversion: %s' % (cmd)
-        try:
-            p = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE )
-            p.wait();
-            if p.returncode:
-                sys.exit( 1 )
-            self.wcversion = p.stdout.readline().rstrip()
-        except:
-            pass
+    def _parseSession( self ):
+        for line in self.session:
+            ## grok fields
+            m = re.match( '([^:]+):\\s+(.+)', line )
+            if not m:
+                continue
 
-        # parse output: svn info PROJECT_DIR
-        cmd = 'svn info ' + initial_project_dir
-        print 'attempting to probe subversion: %s' % (cmd)
-        try:
-            p = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE )
-            p.wait();
-            if p.returncode:
-                sys.exit( 1 )
-            for line in p.stdout:
-                (name,value) = re.match( '([^:]+):\\s+(.+)', line.rstrip() ).groups()
-                if name == 'URL':
-                    self.url = value
-                elif name == 'Repository Root':
-                    self.root = value
-                elif name == 'Repository UUID':
-                    self.uuid = value
-                elif name == 'Revision':
-                    self.rev = int( value )
-                elif name == 'Last Changed Date':
-                    # strip chars in parens
-                    if value.find( ' (' ):
-                        self.date = value[0:value.find(' (')]
-                    else:
-                        self.date = value
-        except:
-            pass
+            (name,value) = m.groups()
+            if name == 'URL':
+                self.url = value
+            elif name == 'Repository Root':
+                self.root = value
+            elif name == 'Repository UUID':
+                self.uuid = value
+            elif name == 'Revision':
+                self.rev = int( value )
+            elif name == 'Last Changed Date':
+                # strip chars in parens
+                if value.find( ' (' ):
+                    self.date = value[0:value.find(' (')]
+                else:
+                    self.date = value
 
+        ## grok branch
         i = self.url.rfind( '/' )
         if i != -1 and i < len(self.url)-1:
             self.branch = self.url[i+1:]
 
-        # official UUID behavior
+        # type-classification via repository UUID
         if self.uuid == 'b64f7644-9d1e-0410-96f1-a4d463321fa5':
             self.official = 1
             m = re.match( '([^:]+)://([^/]+)/(.+)', self.url )
@@ -491,14 +592,19 @@ class Repository:
             else:
                 self.type = 'developer'
 
-###############################################################################
+        self.msg_end = self.url
 
-## Project object.
+###############################################################################
+##
+## project object.
+##
 ## Contains manually updated version numbers consistent with HB releases
 ## and other project metadata.
 ##
-class Project:
+class Project( Action ):
     def __init__( self ):
+        super( Project, self ).__init__( 'compute', 'project data' )
+
         self.name          = 'HandBrake'
         self.acro_lower    = 'hb'
         self.acro_upper    = 'HB'
@@ -513,6 +619,7 @@ class Project:
         self.vminor = 9
         self.vpoint = 4
 
+    def _action( self ):
         appcastfmt = 'http://handbrake.fr/appcast%s.xml'
 
         if repo.type == 'release':
@@ -527,48 +634,164 @@ class Project:
             self.title = '%s svn%d (%s)' % (self.name,repo.rev,self.build)
         else:
             self.version = 'svn%d' % (repo.rev)
-            self.version = '%d.%d.%d' % (self.vmajor,self.vminor,self.vpoint)
             self.url_appcast = appcastfmt % ('_unofficial')
             self.build = time.strftime('%Y%m%d') + '99'
             self.title = 'Unofficial svn%d (%s)' % (repo.rev,self.build)
 
+        self.msg_end = '%s (%s)' % (self.name,repo.type)
+        self.fail = False
+
 ###############################################################################
 
-## Config object used to output gnu-make or gnu-m4 output.
+class ToolProbe( Action ):
+    tools = []
+
+    def __init__( self, var, *names, **kwargs ):
+        super( ToolProbe, self ).__init__( 'find', abort=kwargs.get('abort',True) )
+        if not self in ToolProbe.tools:
+            ToolProbe.tools.append( self )
+        self.var    = var
+        self.names  = []
+        self.kwargs = kwargs
+        for name in names:
+            if name:
+                self.names.append( str(name) )
+        self.name = self.names[0]
+        self.pretext = self.name
+        self.pathname = self.names[0]
+
+    def _action( self ):
+        self.session = []
+        for i,name in enumerate(self.names):
+            self.session.append( 'name[%d] = %s' % (i,name) )
+        for name in self.names:
+            f = cfg.findExecutable( name )
+            if f:
+                self.pathname = f
+                self.fail = False
+                self.msg_end = f
+                break
+        if self.fail:
+            self.msg_end = 'not found'
+
+    def cli_add_option( self, parser ):
+        parser.add_option( '', '--'+self.name, metavar='PROG',
+            help='[%s]' % (self.pathname),
+            action='callback', callback=self.cli_callback, type='str' )
+
+    def cli_callback( self, option, opt_str, value, parser, *args, **kwargs ):
+        self.__init__( self.var, value, **self.kwargs )
+        self.run()
+
+    def doc_add( self, doc ):
+        doc.add( self.var, self.pathname )
+
+###############################################################################
+
+class SelectTool( Action ):
+    selects = []
+
+    def __init__( self, var, name, *pool, **kwargs ):
+        super( SelectTool, self ).__init__( 'select', abort=kwargs.get('abort',True) )
+        self.pretext = name
+        if not self in SelectTool.selects:
+            SelectTool.selects.append( self )
+        self.var      = var
+        self.name     = name
+        self.pool     = pool
+        self.kwargs   = kwargs
+
+    def _action( self ):
+        self.session = []
+        for i,(name,tool) in enumerate(self.pool):
+            self.session.append( 'tool[%d] = %s (%s)' % (i,name,tool.pathname) )
+        for (name,tool) in self.pool:
+            if not tool.fail:
+                self.selected = name
+                self.fail = False
+                self.msg_end = '%s (%s)' % (name,tool.pathname)
+                break
+        if self.fail:
+            self.msg_end = 'not found'
+
+    def cli_add_option( self, parser ):
+        parser.add_option( '', '--'+self.name, metavar='MODE',
+            help='select %s mode: %s' % (self.name,self.toString()),
+            action='callback', callback=self.cli_callback, type='str' )
+
+    def cli_callback( self, option, opt_str, value, parser, *args, **kwargs ):
+        found = False
+        for (name,tool) in self.pool:
+            if name == value:
+                found = True
+                self.__init__( self.var, self.name, [name,tool], **kwargs )
+                self.run()
+                break
+        if not found:
+            raise optparse.OptionValueError( 'invalid %s mode: %s (choose from %s)'
+                % (self.name,value,self.toString( True )) )
+
+    def doc_add( self, doc ):
+        doc.add( self.var, self.selected )
+
+    def toString( self, nodefault=False ):
+        if len(self.pool) == 1:
+            value = self.pool[0][0]
+        else:
+            s = ''
+            for key,value in self.pool:
+                s += ' ' + key
+            if nodefault:
+                value = s[1:]
+            else:
+                value = '%s [%s]' % (s[1:], self.selected )
+        return value
+
+###############################################################################
 ##
-## Use add() to add NAME/VALUE pairs suitable for both make/m4.
-## Use addBlank() to add a linefeed for both make/m4.
-## Use addMake() to add a make-specific line.
-## Use addM4() to add a m4-specific line.
+## config object used to output gnu-make or gnu-m4 output.
 ##
-class Config:
+## - add() to add NAME/VALUE pairs suitable for both make/m4.
+## - addBlank() to add a linefeed for both make/m4.
+## - addMake() to add a make-specific line.
+## - addM4() to add a m4-specific line.
+##
+class ConfigDocument:
     def __init__( self ):
-        self._items = []
+        self._elements = []
+
+    def _outputMake( self, file, namelen, name, value ):
+        file.write( '%-*s = %s\n' % (namelen, name, value ))
+
+    def _outputM4( self, file, namelen, name, value ):
+        namelen += 7
+        name = '<<__%s>>,' % name.replace( '.', '_' )
+        file.write( 'define(%-*s  <<%s>>)dnl\n' % (namelen, name, value ))
 
     def add( self, name, value ):
-        self._items.append( (name,value) )
+        self._elements.append( (name,value) )
 
     def addBlank( self ):
-        self._items.append( None )
+        self._elements.append( None )
 
     def addComment( self, format, *args ):
         self.addMake( '## ' + format % args )
         self.addM4( 'dnl ' + format % args )
 
     def addMake( self, line ):
-        self._items.append( ('?make',line) )
+        self._elements.append( ('?make',line) )
 
     def addM4( self, line ):
-        self._items.append( ('?m4',line) )
+        self._elements.append( ('?m4',line) )
 
     def output( self, file, type ):
         namelen = 0
-        for item in self._items:
+        for item in self._elements:
             if item == None or item[0].find( '?' ) == 0:
                 continue
             if len(item[0]) > namelen:
                 namelen = len(item[0])
-        for item in self._items:
+        for item in self._elements:
             if item == None:
                 if type == 'm4':
                     file.write( 'dnl\n' )
@@ -585,226 +808,445 @@ class Config:
             else:
                 self._outputMake( file, namelen, item[0], item[1] )
 
-    def _outputMake( self, file, namelen, name, value ):
-        file.write( '%-*s = %s\n' % (namelen, name, value ))
-
-    def _outputM4( self, file, namelen, name, value ):
-        namelen += 7
-        name = '<<__%s>>,' % name.replace( '.', '_' )
-        file.write( 'define(%-*s  <<%s>>)dnl\n' % (namelen, name, value ))
+    def write( self, type ):
+        if type == 'make':
+            fname = 'GNUmakefile'
+        elif type == 'm4':
+            fname = os.path.join( 'project', project.name_lower + '.m4' )
+        else:
+            raise ValueError, 'unknown file type: ' + type
 
-###############################################################################
+        ftmp  = fname + '.tmp'
+        try:
+            try:
+                file = cfg.open( ftmp, 'w' )
+                self.output( file, type )
+            finally:
+                try:
+                    file.close()
+                except:
+                    pass
+        except Exception, x:
+            try:
+                os.remove( ftmp )
+            except Exception, x:
+                pass
+            cfg.errln( 'failed writing to %s\n%s', ftmp, x )
 
-## create configure line, stripping arg --launch, quoting others
-configure = []
-for arg in sys.argv[1:]:
-    if arg == '--launch':
-        continue
-    configure.append( "'%s'" % (arg.replace("'", '%c%c%c%c%c' % (0x27,0x22,0x27,0x22,0x27))) )
-
-## create singletones
-repo = Repository()
-project = Project()
-config  = Config()
-
-config.addComment( 'generated by configure on %s', time.strftime( '%c' ))
-
-config.addBlank()
-config.add( 'CONF.args', ' '.join( configure ))
-
-config.addBlank()
-config.add( 'HB.title',         project.title )
-config.add( 'HB.name',          project.name )
-config.add( 'HB.name.lower',    project.name_lower )
-config.add( 'HB.name.upper',    project.name_upper )
-config.add( 'HB.acro.lower',    project.acro_lower )
-config.add( 'HB.acro.upper',    project.acro_upper )
-
-config.add( 'HB.url.website',   project.url_website )
-config.add( 'HB.url.community', project.url_community )
-config.add( 'HB.url.irc',       project.url_irc )
-config.add( 'HB.url.appcast',   project.url_appcast )
-
-config.add( 'HB.version.major',  project.vmajor )
-config.add( 'HB.version.minor',  project.vminor )
-config.add( 'HB.version.point',  project.vpoint )
-config.add( 'HB.version',        project.version )
-config.add( 'HB.version.hex',    '%04x%02x%02x%08x' % (project.vmajor,project.vminor,project.vpoint,repo.rev) )
-
-config.add( 'HB.build', project.build )
-
-config.add( 'HB.repo.url',       repo.url )
-config.add( 'HB.repo.root',      repo.root )
-config.add( 'HB.repo.branch',    repo.branch )
-config.add( 'HB.repo.uuid',      repo.uuid )
-config.add( 'HB.repo.rev',       repo.rev )
-config.add( 'HB.repo.date',      repo.date )
-config.add( 'HB.repo.wcversion', repo.wcversion )
-config.add( 'HB.repo.official',  repo.official )
-config.add( 'HB.repo.type',      repo.type )
-
-config.addBlank()
-config.add( 'HOST.spec',    guessHost )
-config.add( 'HOST.machine', guessHost.machine )
-config.add( 'HOST.vendor',  guessHost.vendor )
-config.add( 'HOST.system',  guessHost.system )
-config.add( 'HOST.systemc', guessHost.systemc )
-config.add( 'HOST.release', guessHost.release )
-config.add( 'HOST.title',   '%s %s' % (guessHost.systemc,archMode.default) )
-config.add( 'HOST.extra',   guessHost.extra )
-config.add( 'HOST.ncpu',    computeNumCPU() )
-
-config.addBlank()
-config.add( 'BUILD.spec',    guessBuild )
-config.add( 'BUILD.machine', guessBuild.machine )
-config.add( 'BUILD.vendor',  guessBuild.vendor )
-config.add( 'BUILD.system',  guessBuild.system )
-config.add( 'BUILD.systemc', guessBuild.systemc )
-config.add( 'BUILD.release', guessBuild.release )
-config.add( 'BUILD.title',   '%s %s' % (guessBuild.systemc,archMode.mode) )
-config.add( 'BUILD.extra',   guessBuild.extra )
-config.add( 'BUILD.method',  'terminal' )
-config.add( 'BUILD.cross',   guessBuild.cross )
-config.add( 'BUILD.date',    time.strftime('%c') )
-config.add( 'BUILD.arch',    archMode.mode )
-config.add( 'BUILD.jobs',    computeNumCPU() )
-
-config.addBlank()
-config.add( 'CONF.method', options.conf_method )
-
-config.addBlank()
-config.add( 'BUILD/',   os.curdir + os.sep )
-config.add( 'PROJECT/', project_dir + os.sep )
-
-config.addBlank()
-config.add( 'INSTALL.prefix', options.prefix )
-config.add( 'INSTALL.prefix/', '$(INSTALL.prefix)/' )
-
-config.addBlank()
-config.add( 'FEATURE.xcode', 0 if not hasattr(options, 'disable_xcode') or options.disable_xcode else 1 )
-config.add( 'FEATURE.gtk',   0 if options.disable_gtk   else 1 )
-
-config.addMake( '' )
-config.addMake( '## include main definitions' )
-config.addMake( 'include $(PROJECT/)make/include/main.defs' )
-
-config.addBlank()
-for tool in tools.items:
-    tool.addToConfig( config )
-
-config.addBlank()
-config.add( 'GCC.archs', archMode.mode if guessBuild.cross else '' )
-config.add( 'GCC.g', options.debug )
-config.add( 'GCC.O', options.optimize )
-
-if len(exports):
-    config.addBlank()
-    for nv in exports:
-        config.add( nv[0], nv[1] )
-
-config.addMake( '' )
-config.addMake( '## include (optional) customization file' )
-config.addMake( '-include $(BUID/)GNUmakefile.custom' )
-
-config.addMake( '' )
-config.addMake( '## include main rules' )
-config.addMake( 'include $(PROJECT/)make/include/main.rules' )
+        try:
+            os.rename( ftmp, fname )
+        except Exception, x:
+            cfg.errln( 'failed writing to %s\n%s', fname, x )
 
 ###############################################################################
+##
+## create cli parser
+##
+def createCLI():
+    cli = OptionParser( 'usage: %prog [OPTIONS...] [TARGETS...]' )
+
+    cli.description = ''
+    cli.description += 'Configure %s build system.' % (project.name)
+
+    ## add hidden options
+    cli.add_option( '', '--conf-method', default='terminal', action='store', help=optparse.SUPPRESS_HELP )
+    cli.add_option( '', '--force', default=False, action='store_true', help='overwrite existing build config' )
+    cli.add_option( '', '--verbose', default=False, action='store_true', help='increase verbosity' )
+
+    ## add install options
+    grp = OptionGroup( cli, 'Directory Locations' )
+    grp.add_option( '', '--src', default=cfg.src_dir, action='store', metavar='DIR',
+        help='specify top-level source dir [%s]' % (cfg.src_dir) )
+    grp.add_option( '', '--build', default=cfg.build_dir, action='store', metavar='DIR',
+        help='specify build scratch/output dir [%s]' % (cfg.build_dir) )
+    grp.add_option( '', '--prefix', default=cfg.prefix_dir, action='store', metavar='DIR',
+        help='specify install dir for products [%s]' % (cfg.prefix_dir) )
+    cli.add_option_group( grp )
+
+    ## add feature options
+    grp = OptionGroup( cli, 'Feature Options' )
+    h = ForHost( optparse.SUPPRESS_HELP, ['disable Xcode (Darwin only)','*-*-darwin*'] ).value
+    grp.add_option( '', '--disable-xcode', default=False, action='store_true', help=h )
+    h = ForHost( optparse.SUPPRESS_HELP, ['disable GTK GUI (Linux only)','*-*-linux*'] ).value
+    grp.add_option( '', '--disable-gtk', default=False, action='store_true', help=h )
+    cli.add_option_group( grp )
+
+    ## add launch options
+    grp = OptionGroup( cli, 'Launch Options' )
+    grp.add_option( '', '--launch', default=False, action='store_true',
+        help='launch build, capture log and wait for completion' )
+    grp.add_option( '', '--launch-jobs', default=1, action='store', metavar='N', type='int',
+        help='allow N jobs at once; 0 to match CPU count [1]' )
+    grp.add_option( '', '--launch-args', default=None, action='store', metavar='ARGS',
+        help='specify additional ARGS for launch command' )
+    grp.add_option( '', '--launch-quiet', default=False, action='store_true',
+        help='do not echo build output' )
+    cli.add_option_group( grp )
+
+    ## add compile options
+    grp = OptionGroup( cli, 'Compiler Options' )
+    debugMode.cli_add_option( grp, '--debug' )
+    optimizeMode.cli_add_option( grp, '--optimize' )
+    arch.mode.cli_add_option( grp, '--arch' )
+    cli.add_option_group( grp )
+
+    ## add tool locations
+    grp = OptionGroup( cli, 'Tool Basenames and Locations' )
+    for tool in ToolProbe.tools:
+        tool.cli_add_option( grp )
+    cli.add_option_group( grp )
+
+    ## add tool modes
+    grp = OptionGroup( cli, 'Tool Options' )
+    for select in SelectTool.selects:
+        select.cli_add_option( grp )
+    cli.add_option_group( grp )
+    return cli
 
-# generate make or m4 file
-def generate( type ):
-    if type == 'make':
-        fname = 'GNUmakefile'
-    elif type == 'm4':
-        fname = os.path.join( 'project', project.name_lower + '.m4' )
-    else:
-        raise ValueError, 'unknown file type: ' + type
-
-    ftmp  = fname + '.tmp'
-
-    pdir = os.path.dirname( fname )
-    if pdir:
-        if not os.path.exists( pdir ):
-            os.makedirs( pdir )
+###############################################################################
+##
+## launcher - used for QuickStart method; launch; build and capture log.
+##
+class Launcher:
+    def __init__( self, targets ):
+        # open build logfile
+        self._file = cfg.open( 'log/build.txt', 'w' )
+
+        cmd = '%s -j%d' % (Tools.gmake.pathname,core.jobs)
+        if options.launch_args:
+            cmd += ' ' + options.launch_args
+        if len(targets):
+            cmd += ' ' + ' '.join(targets)
+
+        ## record begin
+        timeBegin = time.time()
+        self.infof( 'time begin: %s\n', time.asctime() )
+        self.infof( 'launch: %s\n', cmd )
+        if options.launch_quiet:
+            stdout.write( 'building to %s ...\n' % (os.path.abspath( cfg.build_final )))
+        else:
+            stdout.write( '%s\n' % ('-' * 79) )
 
-    try:
+        ## launch/pipe
         try:
-            outf( 'generating %s', fname )
-            file = open( ftmp, 'w' )
-            config.output( file, type )
-        finally:
-            try:
-                file.close()
-            except:
-                pass
-    except Exception, x:
-        try:
-            os.remove( ftmp )
+            pipe = subprocess.Popen( cmd, shell=True, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
         except Exception, x:
-            pass
-        errf( 'failed writing to %s\n%s', ftmp, x )
+            cfg.errln( 'launch failure: %s', x )
+        for line in pipe.stdout:
+            self.echof( '%s', line )
+        pipe.wait()
 
-    try:
-        os.rename( ftmp, fname )
-    except Exception, x:
-        errf( 'failed writing to %s\n%s', fname, x )
+        ## record end
+        timeEnd = time.time()
+        elapsed = timeEnd - timeBegin
 
-###############################################################################
+        if pipe.returncode:
+            result = 'FAILURE (code %d)' % pipe.returncode
+        else:
+            result = 'SUCCESS'
+
+        ## present duration in decent format
+        seconds = elapsed
+        hours = int(seconds / 3600)
+        seconds -= hours * 3600
+        minutes = int(seconds / 60)
+        seconds -= minutes * 60
+
+        segs = []
+        duration = ''
+
+        if hours == 1:
+            segs.append( '%d hour' % hours )
+        elif hours > 1:
+            segs.append( '%d hours' % hours )
+
+        if len(segs) or minutes == 1:
+            segs.append( '%d minute' % minutes )
+        elif len(segs) or  minutes > 1:
+            segs.append( '%d minutes' % minutes )
+
+        if seconds == 1:
+            segs.append( '%d second' % seconds )
+        else:
+            segs.append( '%d seconds' % seconds )
 
-if not options.launch:
-    generate( 'make' )
-    generate( 'm4' )
-    sys.exit( 0 )
+        if not options.launch_quiet:
+            stdout.write( '%s\n' % ('-' * 79) )
+        self.infof( 'time end: %s\n', time.asctime() )
+        self.infof( 'duration: %s (%.2fs)\n', ', '.join(segs), elapsed )
+        self.infof( 'result: %s\n', result )
 
-###############################################################################
+        ## cleanup
+        self._file.close()
 
-if os.path.exists( options.launch_dir ):
-    if not options.launch_force:
-        errf( 'scratch directory already exists: %s', options.launch_dir )
-else:
-    outf( 'creating %s', options.launch_dir )
-    os.makedirs( options.launch_dir )    
+    def echof( self, format, *args ):
+        line = format % args
+        self._file.write( line )
+        if not options.launch_quiet:
+            stdout.write( '  : %s' % line )
+            stdout.flush()
 
-outf( 'chdir %s', options.launch_dir )
-os.chdir( options.launch_dir )
-generate( 'make' )
-generate( 'm4' )
+    def infof( self, format, *args ):
+        line = format % args
+        self._file.write( line )
+        cfg.infof( '%s', line )
 
-outf( 'opening %s', options.launch_log )
+###############################################################################
+##
+## main program
+##
 try:
-    log = open( options.launch_log, 'w' )
-except Exception, x:
-    errf( 'open failure: %s', x )
+    ## we need to pre-check argv for -h or --help or --verbose to deal with
+    ## initializing Configure correctly.
+    verbose = Configure.OUT_INFO
+    for arg in sys.argv:
+        if arg == '-h' or arg == '--help':
+            verbose = Configure.OUT_QUIET
+            break
+        if arg == '--verbose':
+            verbose = Configure.OUT_VERBOSE
+
+    ## create main objects; actions/probes run() is delayed.
+    ## if any actions must be run earlier (eg: for configure --help purposes)
+    ## then run() must be invoked earlier. subequent run() invocations
+    ## are ignored.
+    cfg   = Configure( verbose )
+    host  = HostTupleProbe(); host.run()
+
+    cfg.prefix_dir = ForHost( '/usr/local', ['/Applications','*-*-darwin*'] ).value
+
+    build = BuildAction()
+    arch  = ArchAction(); arch.run()
+
+    ## create remaining main objects
+    core    = CoreProbe()
+    repo    = RepoProbe()
+    project = Project()
+
+    ## create tools in a scope
+    class Tools:
+        ar    = ToolProbe( 'AR.exe',    'ar' )
+        cp    = ToolProbe( 'CP.exe',    'cp' )
+        curl  = ToolProbe( 'CURL.exe',  'curl', abort=False )
+        gcc   = ToolProbe( 'GCC.gcc',   'gcc', IfHost('gcc-4','*-*-cygwin*') )
+
+        if host.match( '*-*-darwin*' ):
+            gmake = ToolProbe( 'GMAKE.exe', 'make', 'gmake' )
+        else:
+            gmake = ToolProbe( 'GMAKE.exe', 'gmake', 'make' )
+
+        m4    = ToolProbe( 'M4.exe',    'm4' )
+        mkdir = ToolProbe( 'MKDIR.exe', 'mkdir' )
+        patch = ToolProbe( 'PATCH.exe', 'gpatch', 'patch' )
+        rm    = ToolProbe( 'RM.exe',    'rm' )
+        tar   = ToolProbe( 'TAR.exe',   'gtar', 'tar' )
+        wget  = ToolProbe( 'WGET.exe',  'wget', abort=False )
+
+        xcodebuild = ToolProbe( 'XCODEBUILD.exe', 'xcodebuild', abort=False )
+        lipo       = ToolProbe( 'LIPO.exe',       'lipo', abort=False )
+
+        fetch = SelectTool( 'FETCH.select', 'fetch', ['wget',wget], ['curl',curl] )
+
+    ## run tool probes
+    for tool in ToolProbe.tools:
+        tool.run()
+    for select in SelectTool.selects:
+        select.run()
+
+    debugMode = SelectMode( 'debug', ('none','none'), ('min','min'), ('std','std'), ('max','max') )
+    optimizeMode = SelectMode( 'optimize', ('none','none'), ('speed','speed'), ('size','size'), default='speed' )
+
+    ## create CLI and parse
+    cli = createCLI()
+    (options,args) = cli.parse_args()
+
+    ## update cfg with cli directory locations
+    cfg.update_cli( options )
+
+    ## prepare list of targets and NAME=VALUE args to pass to make
+    targets = []
+    exports = []
+    rx_exports = re.compile( '([^=]+)=(.*)' )
+    for arg in args:
+        m = rx_exports.match( arg )
+        if m:
+            exports.append( m.groups() )
+        else:
+            targets.append( arg )
+
+    ## run delayed actions
+    for action in Action.actions:
+        action.run()
+
+    ## cfg hook before doc prep
+    cfg.doc_ready()
+
+    ## create document object
+    doc = ConfigDocument()
+    doc.addComment( 'generated by configure on %s', time.strftime( '%c' ))
+
+    ## add configure line for reconfigure purposes
+    doc.addBlank()
+    args = []
+    for arg in sys.argv[1:]:
+        if arg == '--launch':
+            continue
+        args.append( "'%s'" % (arg.replace("'", '%c%c%c%c%c' % (0x27,0x22,0x27,0x22,0x27))) )
+    doc.add( 'CONF.args', ' '.join( args ))
+
+    doc.addBlank()
+    doc.add( 'HB.title',         project.title )
+    doc.add( 'HB.name',          project.name )
+    doc.add( 'HB.name.lower',    project.name_lower )
+    doc.add( 'HB.name.upper',    project.name_upper )
+    doc.add( 'HB.acro.lower',    project.acro_lower )
+    doc.add( 'HB.acro.upper',    project.acro_upper )
+
+    doc.add( 'HB.url.website',   project.url_website )
+    doc.add( 'HB.url.community', project.url_community )
+    doc.add( 'HB.url.irc',       project.url_irc )
+    doc.add( 'HB.url.appcast',   project.url_appcast )
+
+    doc.add( 'HB.version.major',  project.vmajor )
+    doc.add( 'HB.version.minor',  project.vminor )
+    doc.add( 'HB.version.point',  project.vpoint )
+    doc.add( 'HB.version',        project.version )
+    doc.add( 'HB.version.hex',    '%04x%02x%02x%08x' % (project.vmajor,project.vminor,project.vpoint,repo.rev) )
+
+    doc.add( 'HB.build', project.build )
+
+    doc.add( 'HB.repo.url',       repo.url )
+    doc.add( 'HB.repo.root',      repo.root )
+    doc.add( 'HB.repo.branch',    repo.branch )
+    doc.add( 'HB.repo.uuid',      repo.uuid )
+    doc.add( 'HB.repo.rev',       repo.rev )
+    doc.add( 'HB.repo.date',      repo.date )
+    doc.add( 'HB.repo.official',  repo.official )
+    doc.add( 'HB.repo.type',      repo.type )
+
+    doc.addBlank()
+    doc.add( 'HOST.spec',    host.spec )
+    doc.add( 'HOST.machine', host.machine )
+    doc.add( 'HOST.vendor',  host.vendor )
+    doc.add( 'HOST.system',  host.system )
+    doc.add( 'HOST.systemf', host.systemf )
+    doc.add( 'HOST.release', host.release )
+    doc.add( 'HOST.extra',   host.extra )
+    doc.add( 'HOST.title',   '%s %s' % (host.systemf,arch.mode.default) )
+    doc.add( 'HOST.ncpu',    core.count )
+
+    doc.addBlank()
+    doc.add( 'BUILD.spec',    build.spec )
+    doc.add( 'BUILD.machine', build.machine )
+    doc.add( 'BUILD.vendor',  build.vendor )
+    doc.add( 'BUILD.system',  build.system )
+    doc.add( 'BUILD.systemf', build.systemf )
+    doc.add( 'BUILD.release', build.release )
+    doc.add( 'BUILD.extra',   build.extra )
+    doc.add( 'BUILD.title',   '%s %s' % (build.systemf,arch.mode.mode) )
+    doc.add( 'BUILD.ncpu',    core.count )
+    doc.add( 'BUILD.jobs',    core.jobs )
+
+    doc.add( 'BUILD.cross',   int(arch.mode.mode != arch.mode.default) )
+    doc.add( 'BUILD.method',  'terminal' )
+    doc.add( 'BUILD.date',    time.strftime('%c') )
+    doc.add( 'BUILD.arch',    arch.mode.mode )
+
+    doc.addBlank()
+    doc.add( 'CONF.method', options.conf_method )
+
+    doc.addBlank()
+    doc.add( 'SRC',     cfg.src_final )
+    doc.add( 'SRC/',    cfg.src_final + os.sep )
+    doc.add( 'BUILD',   cfg.build_final )
+    doc.add( 'BUILD/',  cfg.build_final + os.sep )
+    doc.add( 'PREFIX',  cfg.prefix_final )
+    doc.add( 'PREFIX/', cfg.prefix_final + os.sep )
+    
+    doc.addBlank()
+    doc.add( 'FEATURE.xcode', int( not (Tools.xcodebuild.fail or options.disable_xcode) ))
+    doc.add( 'FEATURE.gtk',   int( not options.disable_gtk ))
+
+    if not Tools.xcodebuild.fail and not options.disable_xcode:
+        doc.addBlank()
+        doc.add( 'XCODE.external.src',    cfg.xcode_x_src )
+        doc.add( 'XCODE.external.build',  cfg.xcode_x_build )
+        doc.add( 'XCODE.external.prefix', cfg.xcode_x_prefix )
+
+    doc.addMake( '' )
+    doc.addMake( '## include definitions' )
+    doc.addMake( 'include $(SRC/)make/include/main.defs' )
+
+    doc.addBlank()
+    for tool in ToolProbe.tools:
+        tool.doc_add( doc )
+
+    doc.addBlank()
+    for select in SelectTool.selects:
+        select.doc_add( doc )
+
+    doc.addBlank()
+    if arch.mode.mode != arch.mode.default:
+        doc.add( 'GCC.archs', arch.mode.mode )
+    else:
+        doc.add( 'GCC.archs', '' )
+    doc.add( 'GCC.g', debugMode.mode )
+    doc.add( 'GCC.O', optimizeMode.mode )
+
+    ## add exports to make
+    if len(exports):
+        doc.addBlank()
+        doc.addComment( 'overrides via VARIABLE=VALUE on command-line' )
+        for nv in exports:
+            doc.add( nv[0], nv[1] )
+
+    doc.addMake( '' )
+    doc.addMake( '## include custom definitions' )
+    doc.addMake( '-include $(SRC/)custom.defs' )
+    doc.addMake( '-include $(BUILD/)GNUmakefile.custom.defs' )
+
+    doc.addMake( '' )
+    doc.addMake( '## include rules' )
+    doc.addMake( 'include $(SRC/)make/include/main.rules' )
+    doc.addMake( '-include $(SRC/)custom.rules' )
+    doc.addMake( '-include $(BUILD/)GNUmakefile.custom.rules' )
+
+    ## chdir
+    cfg.chdir()
+
+    ## perform
+    doc.write( 'make' )
+    doc.write( 'm4' )
+    if options.launch:
+        Launcher( targets )
+
+    cfg.record_log()
+
+    if os.path.normpath( cfg.build_dir ) == os.curdir:
+        nocd = True
+    else:
+        nocd = False
 
-cmd = '%s -j%d' % (makeTool.found,options.launch_jobs)
-if options.launch_args:
-    cmd += ' ' + options.launch_args
+    stdout.write( '%s\n' % ('-' * 79) )
+    if options.launch:
+        stdout.write( 'Build is finished!\n' )
+        if nocd:
+            stdout.write( 'You may now examine the output.\n' )
+        else:
+            stdout.write( 'You may now cd into %s and examine the output.\n' % (cfg.build_dir) )
+    else:
+        stdout.write( 'Build is configured!\n' )
+        if nocd:
+            stdout.write( 'You may now run make (%s).\n' % (Tools.gmake.pathname) )
+        else:
+            stdout.write( 'You may now cd into %s and run make (%s).\n' % (cfg.build_dir,Tools.gmake.pathname) )
 
-## record begin
-timeBegin = time.time()
-s = '###\n### TIME: %s\n### launch: %s\n###\n' % (time.asctime(),cmd)
-stdout.write( s ); stdout.flush()
-log.write( s ); log.flush()
+except AbortError, x:
+    stderr.write( 'ERROR: %s\n' % (x) )
+    try:
+        cfg.record_log()
+    except:
+        pass        
+    sys.exit( 1 )    
 
-## launch/pipe
-try:
-    pipe = subprocess.Popen( cmd, shell=True, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
-except Exception, x:
-    errf( 'launch failure: %s', x )
-for line in pipe.stdout:
-    if not options.launch_quiet:
-        stdout.write( line ); stdout.flush()
-    log.write( line ); log.flush()
-pipe.wait()
-
-## record end
-timeEnd = time.time()
-elapsed = timeEnd - timeBegin
-result = '%s (exit code %d)' % ('success' if pipe.returncode == 0 else 'failed',pipe.returncode)
-s = '###\n### TIME: %s\n### finished: %.2f seconds\n### %s\n###\n' % (time.asctime(),elapsed,result)
-stdout.write( s ); stdout.flush()
-log.write( s ); log.flush()
-
-log.close()
 sys.exit( 0 )
index 3cd8030..5f1f9e5 100644 (file)
@@ -1,5 +1,5 @@
 CONTRIB.build/    = $(BUILD/)contrib/
-CONTRIB.download/ = $(PROJECT/)download/
+CONTRIB.download/ = $(SRC/)download/
 CONTRIB.host      = $(if $(filter 1,$(BUILD.cross)),$(BUILD.spec))
 
 ###############################################################################
@@ -17,7 +17,7 @@ define import.CONTRIB.defs
     ##
     ## common values useful across targets
     ##
-    $(1).src/   = $$(PROJECT/)contrib/$($(1).name)/
+    $(1).src/   = $$(SRC/)contrib/$($(1).name)/
     $(1).build/ = $$(CONTRIB.build/)$($(1).name)/
     $(1).deps   = $$(foreach n,$($(1).prerequisites),$$($$n.INSTALL.target))
 
@@ -209,7 +209,7 @@ $($(1).name).extract.touch:
        $$(TOUCH.exe) $$($(1).EXTRACT.target)
 
 $($(1).name).extract.untouch:
-       $$(RM.exe) $$($(1).EXTRACT.target)
+       $$(RM.exe) -f $$($(1).EXTRACT.target)
 
 ##
 ## target: patch
@@ -224,7 +224,7 @@ $($(1).name).patch.touch:
        $$(TOUCH.exe) $$($(1).PATCH.target)
 
 $($(1).name).patch.untouch:
-       $$(RM.exe) $$($(1).PATCH.target)
+       $$(RM.exe) -f $$($(1).PATCH.target)
 
 ##
 ## target: configure
@@ -240,7 +240,7 @@ $($(1).name).configure.touch:
        $$(TOUCH.exe) $$($(1).CONFIGURE.target)
 
 $($(1).name).configure.untouch:
-       $$(RM.exe) $$($(1).CONFIGURE.target)
+       $$(RM.exe) -f $$($(1).CONFIGURE.target)
 
 ##
 ## target: build
@@ -256,7 +256,7 @@ $($(1).name).build.touch:
        $$(TOUCH.exe) $$($(1).BUILD.target)
 
 $($(1).name).build.untouch:
-       $$(RM.exe) $$($(1).BUILD.target)
+       $$(RM.exe) -f $$($(1).BUILD.target)
 
 ##
 ## target: install
@@ -271,7 +271,7 @@ $($(1).name).install.touch:
        $$(TOUCH.exe) $$($(1).INSTALL.target)
 
 $($(1).name).install.untouch:
-       $$(RM.exe) $$($(1).INSTALL.target)
+       $$(RM.exe) -f $$($(1).INSTALL.target)
 
 ##
 ## target: uninstall
index 93271a3..f07678b 100644 (file)
@@ -1,10 +1,10 @@
-include $(PROJECT/)make/include/base.defs
-include $(PROJECT/)make/include/contrib.defs
-include $(PROJECT/)make/include/function.defs
-include $(PROJECT/)make/include/gcc.defs
-include $(PROJECT/)make/include/select.defs
-include $(PROJECT/)make/include/target.defs
-include $(PROJECT/)make/include/tool.defs
+include $(SRC/)make/include/base.defs
+include $(SRC/)make/include/contrib.defs
+include $(SRC/)make/include/function.defs
+include $(SRC/)make/include/gcc.defs
+include $(SRC/)make/include/select.defs
+include $(SRC/)make/include/target.defs
+include $(SRC/)make/include/tool.defs
 
 ###############################################################################
 
@@ -62,6 +62,6 @@ MODULES += doc
 
 ###############################################################################
 
-include $(MODULES:%=$(PROJECT/)%/module.defs)
-include $(PROJECT/)make/variant/$(HOST.system).defs
--include $(PROJECT/)make/variant/$(HOST.system).$(BUILD.machine).defs
+include $(MODULES:%=$(SRC/)%/module.defs)
+include $(SRC/)make/variant/$(HOST.system).defs
+-include $(SRC/)make/variant/$(HOST.system).$(BUILD.machine).defs
index 4625ae9..51460a3 100644 (file)
@@ -5,12 +5,12 @@
 
 ## file-wide conditional to use xcode rules if xcode=1 method=terminal
 ifeq ($(FEATURE.xcode):$(BUILD.method),1:terminal)
-    include $(PROJECT/)macosx/module.xcode
+    include $(SRC/)macosx/module.xcode
 else
 
 ## only included using special report targets
 ifneq (,$(REPORT))
-    include $(PROJECT/)make/include/report.defs
+    include $(SRC/)make/include/report.defs
 endif
 
 ###############################################################################
@@ -30,22 +30,22 @@ mrproper: xclean
 
 ###############################################################################
 
-include $(PROJECT/)make/include/base.rules
+include $(SRC/)make/include/base.rules
 
-include $(MODULES:%=$(PROJECT/)%/module.rules)
--include $(PROJECT/)make/variant/$(HOST.system).rules
--include $(PROJECT/)make/variant/$(HOST.system).$(BUILD.machine).rules
+include $(MODULES:%=$(SRC/)%/module.rules)
+-include $(SRC/)make/variant/$(HOST.system).rules
+-include $(SRC/)make/variant/$(HOST.system).$(BUILD.machine).rules
 
 ###############################################################################
 
 ## target which causes re-configure if project-root is svn update'd
-$(BUILD/)GNUmakefile: $(wildcard $(PROJECT/).svn/entries)
-       $(PROJECT/)configure $(CONF.args)
+$(BUILD/)GNUmakefile: $(wildcard $(SRC/).svn/entries)
+       $(SRC/)configure $(CONF.args)
 
 ## target useful to force reconfigure; only helpful for build-system development
 .PHONY: reconfigure
 reconfigure:
-       $(PROJECT/)configure $(CONF.args)
+       $(SRC/)configure $(CONF.args)
 
 ###############################################################################
 
index 6f8f672..baffda5 100644 (file)
@@ -1,40 +1,9 @@
-## UB build support
-##
-## PROCEDURE:
-##
-##  1. Perform a build (let us call it arch-X).
-##  2. cd into arch-X's build/ driectory.
-##  3. Launch builds of the remaining architectures.
-##     We compute $(UB.archs.other) to be the remaining archs to build.
-##     The entire list is defined $(UB.archs) .
-##  4. Combine other architectures into arch-X's binaries.
-##
-## EXAMPLE: serial method, archs: i386,x86_64,ppc,ppc64
-##
-##  ./configure --launch
-##  cd build/
-##  make ub.build.serial
-##  make ub.combine
-##
-## EXAMPLE: parallel method, archs: i386,x86_64,ppc,ppc64
-##
-##  ./configure --launch
-##  cd build/
-##  make ub.build.parallel
-##  make ub.combine
-##
-## EXAMPLE: serial, archs: i386,x86_64 (assuming i386 is native)
-##
-##  ./configure --launch
-##  cd build/
-##  make ub.build.parallel UB.archs="i386 x86_64"
-##  make ub.combine UB.archs="i386 x86_64"
-##
-UB.archs       = i386 x86_64 ppc ppc64
-UB.archs.other = $(filter-out $(BUILD.arch),$(UB.archs))
-UB.builds      = $(wildcard $(foreach n,$(UB.archs.other),$(PROJECT/)build.$n))
+UB.archs  = i386 x86_64 ppc ppc64
+UB.builds = $(wildcard $(foreach n,$(UB.archs),$(SRC/)build.$n))
+UB.first  = $(word 1,$(UB.archs))
+UB.other  = $(wordlist 2,999,$(UB.archs))
 
-UB.BUILD = $(PROJECT/)configure --launch --launch-dir=ub.$(1) --arch=$(1)
+UB.BUILD = $(SRC/)configure --build=ub.$(1) --arch=$(1) --launch --launch-quiet
 
 ## linefeed is important
 define UB.BUILD.item
@@ -43,19 +12,21 @@ define UB.BUILD.item
 endef
 
 define UB.BUILD.SERIAL
-       $(foreach n,$(UB.archs.other),$(call UB.BUILD.item,$n))
+       $(foreach n,$(UB.archs),$(call UB.BUILD.item,$n))
 endef
 
 define UB.BUILD.PARALLEL
-       $(call UB.BUILD,$(1)) 2>&1 > ub.$(1).log
+       $(call UB.BUILD,$(1)) >/dev/null 2>&1
 endef
 
 define UB.COMBINE
        $(RM.exe) -fr ub.combine
        $(MKDIR.exe) -p ub.combine
-       $(CP.exe) -R HandBrake.app ub.combine/.
-       lipo $(1) $(foreach n,$(UB.archs.other),ub.$n/$(1)) -create -output ub.combine/$(1)
+       $(CP.exe) -R ub.$(UB.first)/HandBrake.app ub.combine/.
+       $(LIPO.exe) $(foreach n,$(UB.archs),ub.$n/$(1)) -create -output ub.combine/$(1)
+       @lipo -info ub.combine/$(1)
+       @sync
        @echo ""
-       @sync; lipo -info ub.combine/$(1)
-       @du -sh ub.combine/$(1)
+       @echo "$@: { $(UB.archs) } combined -> ub.combine/HandBrake.app"
+       @echo "$@: UB executable size: `du -sh ub.combine/$(1) | awk '{ print $$1 }'`"
 endef
index c4f4f97..d59a222 100644 (file)
@@ -5,7 +5,7 @@ ub.build.serial:
 
 ub.build.parallel:
        @set -e; \
-       for arch in $(UB.archs.other); do \
+       for arch in $(UB.archs); do \
            $(call UB.BUILD.PARALLEL,$$arch) & \
            children="$$children $$!"; \
            echo "pid $$!: $(call UB.BUILD.PARALLEL,$$arch)"; \
index c58706b..9a807b8 100644 (file)
@@ -2,3 +2,8 @@ TARGET.dylib.ext = .so
 
 GCC.args.dylib = -shared
 GCC.args.pic   = 1
+
+GCC.args.g.none    = -g0
+GCC.args.g.min     = -g1
+GCC.args.g.default = -g2
+GCC.args.g.max     = -g3
index a75cd3e..fde684c 100755 (executable)
@@ -12,8 +12,6 @@ set -e
 MAKEFLAGS=
 MFLAGS=
 
-cd $EXTERNAL_BUILD
-
 ## re/configure if not configured by Xcode or if missing top-makefile
 if [ $EXTERNAL_METHOD != 'xcode' -o ! -f $EXTERNAL_BUILD/GNUmakefile ]; then
     ## compute --arch value based on Xcode configuration naming convention
@@ -36,7 +34,7 @@ if [ $EXTERNAL_METHOD != 'xcode' -o ! -f $EXTERNAL_BUILD/GNUmakefile ]; then
     esac
 
     ## invoke configure with (hidden) option which indicates conf performed by xcode
-    $EXTERNAL_PROJECT/configure PATH=$PATH --conf-method=xcode $args
+    $EXTERNAL_SRC/configure --force --build=$EXTERNAL_BUILD --conf-method=xcode PATH=$PATH $args
 fi
 
 ## safeguard against passing blank value which would result in unlimited jobs
index af42f13..234cb1d 100644 (file)
@@ -1,11 +1,11 @@
 $(eval $(call import.MODULE.defs,TEST,test,LIBHB))
 $(eval $(call import.GCC,TEST))
 
-TEST.src/   = $(PROJECT/)test/
+TEST.src/   = $(SRC/)test/
 TEST.build/ = $(BUILD/)test/
 
 TEST.c   = $(wildcard $(TEST.src/)*.c)
-TEST.c.o = $(patsubst $(PROJECT/)%.c,$(BUILD/)%.o,$(TEST.c))
+TEST.c.o = $(patsubst $(SRC/)%.c,$(BUILD/)%.o,$(TEST.c))
 
 TEST.exe = $(BUILD/)$(call TARGET.exe,$(HB.name)CLI)
 
@@ -14,7 +14,7 @@ TEST.libs = $(LIBHB.a) $(foreach n, \
         ogg samplerate swscale theora vorbis vorbisenc x264 xvidcore, \
         $(CONTRIB.build/)lib/lib$(n).a )
 
-TEST.install.exe = $(INSTALL.prefix/)bin/$(notdir $(TEST.exe))
+TEST.install.exe = $(PREFIX/)bin/$(notdir $(TEST.exe))
 
 ## add libs from optional modules
 ifeq (1,$(BZIP2.enabled))
index 9a47aa1..c510689 100644 (file)
@@ -8,7 +8,7 @@ $(TEST.exe): $(TEST.c.o)
 
 $(TEST.c.o): $(LIBHB.a)
 $(TEST.c.o): | $(dir $(TEST.c.o))
-$(TEST.c.o): $(BUILD/)%.o: $(PROJECT/)%.c
+$(TEST.c.o): $(BUILD/)%.o: $(SRC/)%.c
        $(call TEST.GCC.C_O,$@,$<)
 
 test.clean: