[libalien-base-perl] 01/02: Import original source of Alien-Base 0.028

C.J. Collier cjcollier at linuxfoundation.org
Sun Jun 5 22:46:08 UTC 2016


This is an automated email from the git hooks/post-receive script.

cjadamscollier-guest pushed a commit to branch master
in repository libalien-base-perl.

commit 853d31b034b5abaca31ac87a02a9dbeb098c27ad
Author: C.J. Collier <cjcollier at linuxfoundation.org>
Date:   Sun Jun 5 15:42:18 2016 -0700

    Import original source of Alien-Base 0.028
---
 .appveyor.yml                                      |   32 +
 Build.PL                                           |   76 ++
 Changes                                            |  412 ++++++
 LICENSE                                            |  379 ++++++
 MANIFEST                                           |   98 ++
 META.json                                          |  123 ++
 META.yml                                           |   84 ++
 README                                             |   42 +
 TODO                                               |    2 +
 lib/Alien/Base.pm                                  |  734 +++++++++++
 lib/Alien/Base/Authoring.pod                       |  159 +++
 lib/Alien/Base/FAQ.pod                             |  413 ++++++
 lib/Alien/Base/ModuleBuild.pm                      | 1381 ++++++++++++++++++++
 lib/Alien/Base/ModuleBuild/API.pod                 |  470 +++++++
 lib/Alien/Base/ModuleBuild/Cabinet.pm              |   46 +
 lib/Alien/Base/ModuleBuild/File.pm                 |   73 ++
 lib/Alien/Base/ModuleBuild/Repository.pm           |   96 ++
 lib/Alien/Base/ModuleBuild/Repository/FTP.pm       |   60 +
 lib/Alien/Base/ModuleBuild/Repository/HTTP.pm      |  172 +++
 lib/Alien/Base/ModuleBuild/Repository/Local.pm     |   57 +
 lib/Alien/Base/ModuleBuild/Utils.pm                |   56 +
 lib/Alien/Base/PkgConfig.pm                        |  156 +++
 t/00_diag.t                                        |   46 +
 t/RepositoryTest.pm                                |   73 ++
 t/alien_base.t                                     |  122 ++
 t/alien_base/ab_share/lib/Alien/Bar2.pm            |    7 +
 t/alien_base/ab_share/share/alien_builder.json     |    1 +
 t/alien_base/ab_share/share/include/bar2.h         |    0
 t/alien_base/ab_sys/lib/Alien/Bar1.pm              |    7 +
 t/alien_base/ab_sys/share/alien_builder.json       |    1 +
 t/alien_base/mb_share/lib/Alien/Foo2.pm            |    7 +
 t/alien_base/mb_share/lib/Alien/Foo2/ConfigData.pm |  123 ++
 t/alien_base/mb_share/share/README                 |    0
 .../share/lib/libfoo2-3.2.1/include/foo2.h         |    0
 t/alien_base/mb_sys/lib/Alien/Foo1.pm              |    7 +
 t/alien_base/mb_sys/lib/Alien/Foo1/ConfigData.pm   |   91 ++
 t/alien_base/pkgconfig/libbar1.pc                  |   11 +
 t/alien_base/pkgconfig/libfoo1.pc                  |   11 +
 t/build_flags.t                                    |   27 +
 t/builder.t                                        |  460 +++++++
 t/builder/bin/privateapp                           |    3 +
 t/builder/bin/privateapp.bat                       |    3 +
 t/cabinet.t                                        |   16 +
 t/file.t                                           |   10 +
 t/find_lib.t                                       |  127 ++
 t/find_lib/dynamic/include/mylib.h                 |    0
 t/find_lib/dynamic/include/otherlib.h              |    0
 t/find_lib/dynamic/lib/libmylib.so.0               |    0
 t/find_lib/dynamic/lib/mylib.dll                   |    0
 t/find_lib/dynamic/lib/onlypostdot.so.0            |    0
 t/find_lib/dynamic/lib/prepostdot.0.so.0           |    0
 t/find_lib/mixed/dynamic/libmylib.so.1.2.3         |    0
 t/find_lib/mixed/dynamic/mylib.dll                 |    0
 t/find_lib/mixed/dynamic/otherlib.dll              |    0
 t/find_lib/mixed/include/mylib.h                   |    0
 t/find_lib/mixed/include/otherlib.h                |    0
 t/find_lib/mixed/lib/mylib.lib                     |    0
 t/find_lib/mixed/lib/otherlib.lib                  |    0
 t/find_lib/static/include/mylib.h                  |    0
 t/find_lib/static/include/otherlib.h               |    0
 t/find_lib/static/lib/mylib.lib                    |    0
 t/find_lib/static/lib/otherlib.lib                 |    0
 t/http.t                                           |  172 +++
 t/http_uri.t                                       |   57 +
 t/inline.t                                         |   33 +
 t/inline_cpp.t                                     |   37 +
 t/install_destination.t                            |   30 +
 t/interpolate.t                                    |  105 ++
 t/local_repo.t                                     |   28 +
 t/pkgconfig.t                                      |   70 +
 t/pkgconfig/gsl.pc                                 |   11 +
 t/pkgconfig/test.pc                                |    8 +
 t/repository.t                                     |  120 ++
 t/repository_content_disposition.t                 |   47 +
 t/system_installed/MANIFEST                        |    2 +
 t/system_installed/lib/MyTest.pm                   |    9 +
 t/test_http/index.html                             |    9 +
 t/utils.t                                          |   24 +
 t/validation.t                                     |   33 +
 t/version.t                                        |   39 +
 t/yy-system_installed.t                            |   86 ++
 xt/release/pod.t                                   |   11 +
 82 files changed, 7205 insertions(+)

diff --git a/.appveyor.yml b/.appveyor.yml
new file mode 100644
index 0000000..7bee4ec
--- /dev/null
+++ b/.appveyor.yml
@@ -0,0 +1,32 @@
+---
+
+install:
+  - choco install strawberryperl
+  - SET PATH=C:\Perl5\bin;C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;%PATH%
+  - perl -v
+  - if not exist C:\Perl5 mkdir C:\Perl5
+  - SET PERL5LIB=C:/Perl5/lib/perl5
+  - SET PERL_LOCAL_LIB_ROOT=C:/Perl5
+  - SET PERL_MB_OPT=--install_base C:/Perl5
+  - SET PERL_MM_OPT=INSTALL_BASE=C:/Perl5
+  - cpanm -n --installdeps .
+  - cpanm -n Inline::C Inline::CPP
+  - cpanm -n FFI::Platypus
+  - cpanm -n Test::CChecker
+  - cpanm -n Test::Alien
+
+build: off
+
+test_script:
+  - perl Build.PL
+  - Build
+  - prove -bv t
+  - Build install
+  - cpanm -v Acme::Alien::DontPanic
+  - cpanm -v Acme::Ford::Prefect
+  - cpanm -v Acme::Ford::Prefect::FFI
+
+cache:
+  - C:\Perl5
+
+shallow_clone: true
diff --git a/Build.PL b/Build.PL
new file mode 100644
index 0000000..c6caadf
--- /dev/null
+++ b/Build.PL
@@ -0,0 +1,76 @@
+use strict;
+use warnings;
+use Config;
+use Module::Build;
+
+my %build_args = (
+  module_name => 'Alien::Base',
+  dist_name => 'Alien-Base',
+  dist_abstract => 'A base class for Alien:: modules',
+  dist_author => [
+    'Graham Ollis <plicease at cpan.org>',
+    'Joel A. Berger <joel.a.berger at gmail.com>',
+  ],
+  license  => 'perl',
+  configure_requires => {
+    'Module::Build' => 0.36,
+  },
+  requires => {
+    'perl'             => '5.8.1',
+    'parent'           => 0,
+    'Module::Build'    => 0.36,
+    'Capture::Tiny'    => 0.17,
+    'File::chdir'      => 0.1005,
+    'Sort::Versions'   => 0,
+    'List::MoreUtils'  => 0,
+    'Perl::OSType'     => 0,
+    'URI'              => 0,
+    'File::ShareDir'   => 0,
+    'Archive::Extract' => 0,
+    'HTTP::Tiny'       => '0.044',
+    'Text::ParseWords' => '3.26',
+    'Shell::Guess'     => 0,
+    'Shell::Config::Generate' => 0,
+    'FFI::CheckLib'    => 0.11,
+    'JSON::PP'          => 0,
+  },
+  test_requires => {
+    'Test::More'       => 0.94,
+    'Cwd'              => 0,
+    'FindBin'          => 0,
+    'File::Spec'       => 0,
+    'File::Temp'       => 0,
+  },
+  recommends => {
+    'HTML::LinkExtor' => 0,
+  },
+  meta_merge => {
+    resources  => {
+      repository => "http://github.com/Perl5-Alien/Alien-Base",
+      bugtracker => "http://github.com/Perl5-Alien/Alien-Base/issues",
+      x_MailingList => 'https://groups.google.com/forum/#!forum/perl5-alien',
+      x_IRC => "irc://irc.perl.org/#native",
+    },
+    no_index => {
+      file      => [ 'README.pod' ],
+      directory => [ 't' ],
+    },
+  },
+);
+
+unless (`pkg-config --version` && $? == 0) {
+  $build_args{'requires'}->{'PkgConfig'} = '0.07520';
+}
+
+# For now we prefer PkgConfig.pm over pkg-config on
+# Solaris 64 bit Perls.  We may need to do this on
+# other platforms, in which case this logic should
+# be abstracted so that it can be shared here and
+# in lib/Alien/Base.pm#pkg_config_command
+if($^O eq 'solaris' && $Config{ptrsize} == 8) {
+  $build_args{'requires'}->{'PkgConfig'} = '0.08826';
+}
+
+my $builder = Module::Build->new(%build_args);
+$builder->add_to_cleanup( '_Inline', 'Alien-Base-*' );
+$builder->create_build_script;
diff --git a/Changes b/Changes
new file mode 100644
index 0000000..22c94cb
--- /dev/null
+++ b/Changes
@@ -0,0 +1,412 @@
+Revision history for Perl module Alien::Base.
+
+0.028  Mon Mar 14, 2016
+  - Production release identical to 0.027_03 release
+
+0.027_03  Wed Mar 9, 2016
+  - Updated documentation to recommend the use of Alien::Base::ModuleBuild
+    as a configure_requires.  PLEASE UPDATE YOUR Build.PL FILES!
+  - Fixed bug where missing trailing slash when used with exact_filename
+    would cause a failure (plicease gh#161, gh162)
+  - Documentation fix in FAQ (plicease gh#159,gh#160)
+  - Added compatability for Alien::Builder (pliceasee gh#158, see also gh#157)
+
+0.027_02  Sat Feb 27, 2016
+  - Fix bug where default ffi_name was incorrectly computed
+
+0.027_01  Fri Feb 19, 2016
+  - Deprecate %p
+  - Require Alien::CMake 0.07 as a minimum when used as alien_bin_requires
+    for Alien::Base compatability
+
+0.027  Thu Feb 4, 2016
+  - Production release identical to 0.026_02 release
+
+0.026_02  Mon Feb 1, 2016
+  - Fix test bug introduced in 0.026_01 where t/builder.t
+    would fail on Windows if Alien::MSYS was not installed.
+
+0.026_01  Mon Feb 1, 2016
+  - Added alien_env property to Alien::Base::ModuleBuild
+  - require HTTP::Tiny 0.044 for correct calculation of
+    relative URLs on may websites.
+
+0.026  Fri Jan 22, 2016
+  - For http, use base URL from index request when downloading
+    files (plicease gh#150, gh#151)
+
+0.025  Wed Jan 20, 2016
+  - Production release identical to 0.024_02 release
+
+0.024_02  Mon Jan 18, 2016
+  - Silenced warnings that can happen when multiple .pc files are included
+    with a package (salva++ gh#148)
+  - Fixed bug where verbose diagnostic could cause false positives
+    and false negatives for system libraries (salva++ gh#147, plicease gh#149)
+
+0.024_01  Tue Jan 12, 2016
+  - Use URI internally for improved support for GitHub as a source
+    (among others) (salva++ gh#144)
+
+0.024  Thu Jan 7, 2015
+  - Production release identical to 0.023_01 release
+
+0.023_01  Sat Jan 2, 2015
+  - Fixed a usually harmless but frequently annoying isssue where the
+    alien_install_commands were executed on every invocation of './Build',
+    './Build test', and './Build install' instead of just once as is
+    needed.  (plicease gh#141)
+  - Archive extraction can now be overridden with the alien_extract_archive
+    method in Alien::Base::ModuleBuild. (salva++ gh#142)
+  - Fixed bug with windows where using \ instead of / broke relocatable
+    installs.  (plicease gh#139)
+  - Promoted _env_do_system a public method named alien_do_system
+    (salva++ gh#143)
+
+0.023  Mon Sep 14, 2015
+  - Fixed typo in FAQ
+  - Updated FAQ Alien::gmake example to require Alien::gmake 0.11
+  - Otherwise a production release identical to the 0.22_01 release
+
+0.022_01  Fri Jul 31, 2015
+  - Add support for ALIEN_INSTALL_TYPE environment variable
+
+0.022  Mon Jul 20, 2015
+  - Correction for the section "How do I specify a minumum or exact version
+    requirement for packages that use pkg-config?" in the FAQ.
+
+0.021_01  Wed Jul 15, 2015
+  - Added a default %{pkg_config} helper
+  - Fixed bug introduced in 0.016_01 where using --destdir or $ENV{DESTDIR}
+    would break the "./Build install" command.
+
+0.021  Wed Jul 15, 2015
+  - Fixed bug where upgrading to 0.020 could break Alien modules installed
+    before the upgrade.  You do not need to re-install your Alien modules,
+    just upgrade to Alien::Base 0.021.
+
+0.020  Mon Jul 13, 2015
+  - Production release identical to 0.019_02 release
+
+0.019_02  Wed Jul 8, 2015
+  - Fixed bug where alien_provides_* options were not being honored when the
+    system provided the library (plicease gh#131)
+
+0.019_01  Mon Jul  6, 2015
+  - Improved documentation: added a FAQ at Alien::Base::FAQ
+  - Added helpers for source code builds see 
+    Alien::Base#alien_helper
+    and
+    Alien::Base::ModuleBuild::API#alien_helper
+    for details
+
+0.019  Fri Jun  5, 2015
+  - Production release identical to 0.018_02 release
+
+0.018_02  Wed Jun  3, 2015
+  - Fix test suite for Cygwin
+
+0.018_01  Tue May 26, 2015
+  - Added alien_arch option for non-homogeneous environments with shared @INC
+    (for example AFS) (plicease gh#119)
+
+0.018  Tue May 26, 2015
+  - alien_stage_install is now on by default
+    (first production release for this to be the case)
+
+0.017  Fri Apr 24, 2015
+  - Identical to 0.016_02 release, except alien_stage_install is
+    OFF by default (it was turned on for dev release 0.016_01,
+    and will be turned back on or after May 25).
+
+0.016_02  Fri Apr 24, 2015
+  - Fix bug where ConfigData.pm was not updated after install to blib
+    (plicease gh#121)
+
+0.016_01  Tue Apr 22, 2015
+  - alien_stage_install is now on by default
+
+0.016  Tue Apr 22, 2015
+  - Production release identical to 0.015_03 release
+
+0.015_03  Mon Apr 20, 2015
+  - Fixed bug related to absolute URL (polettix++ gh#116)
+
+0.015_02  Fri Apr 17, 2015
+  - On OS X use install_name_tool to more reliably relocate dynamic libraries
+    on that platform (plicease gh#115)
+
+0.015_01  Fri Apr 17, 2015
+  - Add alien_stage_install option for Alien::Base::ModuleBuild
+    see Alien::Base::ModuleBuild::API for details (plicease gh#114)
+  - alien_stage_install is default for PPM builds
+
+0.015  Tue Mar 17, 2015
+  - Production release identical to 0.014_01 release
+
+0.014_01  Fri Mar 13, 2015
+  - Generate config.site for autoconfigure source installs (plicease gh#113)
+
+0.014  Feb 25, 2015
+  - Production release identical to 0.012_01 release
+
+0.012_01  Feb 24, 2015
+  - Prefer and require PkgConfig.pm over pkg-config on 64 solaris
+    If pkg-config is used it will likely be giving flags for 32 bit libs
+    (plicease gh#110)
+  - Allow for relocation of Alien-Base based dists.
+    (plicease gh#111)
+
+0.012  Feb 22, 2015
+  - Fix bug introduced in 0.011 where bin_dir dies when install_type=system
+
+0.011  Feb 22, 2015
+  - Production release identical to 0.010_01 release
+
+0.010_01  Feb 21, 2015
+  - When installed from source (install_type=share) if the share directory is
+    missing it is now a fatal exception.  (plicease gh#108)
+
+0.010  Feb 17, 2015
+  - Production release identical to 0.009_04 release
+
+0.009_04  Feb 16, 2015
+  - Test fix for Microsoft Visual C++
+
+0.009_03  Feb 15, 2015
+  - Improved FFI support
+
+0.009_02  Feb 4, 2015
+  - Added diagnostics for Alien authors to help in diagnosing common configuration problems.
+
+0.009_01  Jan 27, 2015
+  - Added './Build alien_fakebuild' command which shows you what would be executed without actually doing it (plicease gh#102)
+
+0.009  Jan 27, 2015
+  - Production release identical to 0.008_01 release
+
+0.008_01  Jan 26, 2015
+  - Allow multiple argument system calls for alien_build_commands and alien_install_commands (plicease gh#103)
+
+0.008  Jan 16, 2015
+  - Production release identical to 0.007_01 release
+
+0.007_01  Jan 12, 2015
+  - Add support for https repositories (zmughal++ gh#98)
+
+0.007  Jan 8, 2015
+  - Production release identical to 0.006_03 release
+
+0.006_03  Jan 8, 2015
+  - (optional) inline tests now require Acme::Alien::DontPanic 0.010
+    older versions do not do a link test, and we want that type of failure reported there, not here
+
+0.006_02  Jan 7, 2015
+  - alien_bin_requires only become build_requires if Alien::Base::ModuleBuild determines
+    a source build is necessary (plicease gh#96)
+  - On MSWin32, Alien::MSYS is only injected a prereq if Alien::Base::ModuleBuild determines
+    a source build is necessary and autoconf is detected (plicease gh#96)
+
+0.006_01  Nov 14, 2014
+  - Add support for Alien::Base dynamic_libs method for system installs
+    (previously only share install was supported)
+    This adds FFI::CheckLib as a prereq.
+
+0.006  Oct 14, 2014
+  - Production release identical to 0.005_07 release
+
+0.005_07  Oct 13, 2014
+  - commands are printed as they are executed for easier debugging (plicease gh#91)
+  - c_compiler_required repository option (default on)
+
+0.005_06  Sep 30, 2014
+  - ExtUtils::Depends integration (plicease gh#85, gh#87)
+  - added alien_check_built_version method to Alien::Base::ModuleBuild (plicease gh#83, gh#89)
+
+0.005_05  Sep 29, 2014
+  - fix regression in test on MSWin32 introduced in 0.005_04
+
+0.005_04  Sep 28, 2014
+  - added alien_bin_requires property to Alien::Base::ModuleBuild (plicease gh#84, gh#88)
+  - added alien_msys property to Alien::Base::ModuleBuild (plicease gh#86)
+
+0.005_03  Sep 23, 2014
+  - Inline tests requires Inline 0.56 (skip elsewise)
+  - Document Inline 0.56 or better required for Inline integration
+
+0.005_02  Sep 23, 2014
+  - silence Archive::Extract deprecation warning
+    (we explicitly specify it as a prereq)
+  - remove accidental undeclared dependency on YAML introduced in 0.005_01
+  - fixed test failures introduced in 0.005_01
+
+0.005_01  Sep 22, 2014
+  - fixes with static library detection when pkg-config is not available (plicease gh#79, gh#75)
+  - support for Inline 'with' (plicease gh#71, gh#77, gh#78)
+  - fix prereqs for Text::ParseWords and PkgConfig (plicease gh#73, gh#70)
+
+0.005  Sep 11, 2014
+  - improved documentation coverage
+
+0.004_05  Sep 09, 2014
+  - additional use / instead of \ on MSWin32 (plicease gh#68)
+
+0.004_04  Sep 09, 2014
+  - fixed test error introduced in 0.004_03 expressed on cygwin (plicease gh#67)
+
+0.004_03  Sep 09, 2014
+  - added support for destdir (plicease gh#65, gh#39)
+  - no longer attempt to dl_load static libraries, which aside from being
+    wrong was triggering a dialog warning in windows (plicease gh#64)
+  - use / instead of \ on MSWin32 (plicease gh#64)
+
+0.004_02  Sep 04, 2014
+  - fixed MSWin32 specific bug introduced in 0.004_01 (plicease gh#59)
+  - use pure perl PkgConfig as an alternative to pkg-config if the latter
+    is not provided by operating system (plicease gh#61)
+  - support SHA-1/256 sum checks for downloads (vikasnkumar++ gh#33, gh#60)
+
+0.004_01  Sep 04, 2014
+  - Libraries in the share directory are preferred over the system library
+    if that is what was used during install of the Alien module (plicease++ gh#22)
+  - Better handling of paths on Windows (zmughal++ gh#41)
+  - Fix test failure when pkg-config is not available (mohawk2++ gh#44)
+  - Support for autotools on Windows (MSWin32, but not cygwin) (plicease++ gh#46)
+  - Alien::MSYS will be injected as a build_requires on Windows if autotools is detected
+  - "%c" can now be used as a platform independent way of running autotool based
+    "configure" script
+  - The new default for build uses "%c" instead of "%pconfigure"
+  - Added property alien_isolate_dynamic which allows an Alien author to
+    avoid using dynamic libraries when building XS modules (plicease gh#51)
+  - Added dynamic_libs which returns a list of dynamic libraries (.dll, .so or
+    .dylib depending on platform) which can be used for FFI modules (see FFI::Raw)
+    (plicease gh#51)
+  - Added support for LWP as an alternative to HTTP::Tiny (preaction++ gh#24)
+  - Added support for content-disposition HTTP header to determine correct filename
+    and determine format from that (rsimoes++ gh#27)
+  - By default run autotools style configure scripts with --with-pic and add
+    alien_autoconf_with_pic property to allow disabling that (plicease gh#47)
+
+0.004  Mar 5, 2014
+  - Added version token to the interpolator (MidLifeXis++)
+  - Fixed broken test (MidLifeXis++)
+
+0.003  Mar 3, 2013
+	- Added 'blib scheme' detection logic
+		- Improves Mac/CPANtesters compatibility
+		- Controlled by ALIEN_BLIB env var
+	- ACTION_alien is now ACTION_alien_code
+	- Added ACTION_alien_install
+	- Fix manual .pc file bug
+	- Unbuffer STDOUT during ACTION_alien_*
+
+0.002  Jan 27, 2013
+	- Added exact_filename key (giatorta++)
+	- Various bugfixes
+
+0.001_003  Nov 29, 2012
+	- Improved pkg-config handling
+	- Added support for pkg-config key ${pcfiledir}
+	- Note: released from "experimental" branch
+
+0.001_002  Nov 5, 2012
+	- Fixed some false positives in library detection
+	- Initialize temporary directories later
+	- Note: released from "experimental" branch
+
+0.001_001  Nov 4, 2012
+	- Improved library detection
+	- Library files are added to packlist
+	- Note: released from "packlist" branch
+
+0.001  Oct 9, 2012
+	- First Beta release!
+	- Documentation updated
+	- Better autogeneration of pkgconfig information (run4flat++)
+
+0.000_022  Oct 8, 2012
+	- Major refactoring
+		- separate alien_{x}_commands where x = build, test, install
+		- removed mac specific code
+		- no longer test provisioning (it never worked anyway)
+		- directly allow library to install to final share_dir destination
+	- Moved Alien::DontPanic and Ford::Prefect to CPAN under Acme:: namespaces
+
+0.000_021  Jul 25, 2012
+	- Some fixes for Mac, not sure its working yet
+
+0.000_020  Jun 22, 2012
+	- Windows now passes the test suite (another cleanup error trapped)
+	- Begin overloading copy_if_modified for relocalizing dylibs on mac 
+            (this is not working yet, this release is for windows testers)
+
+0.000_019  Jun 21, 2012
+	- REALLY return to EU::LibBuilder (sorry for the noise)
+
+0.000_018  Jun 21, 2012
+	- return to EU::LibBuilder
+
+0.000_017  May 6, 2012
+	- typo **faceplant**
+
+0.000_016  May 6, 2012
+	- remove dependence on EU::LibBuilder (Mac Bundle)
+	- t/zz-example.t shouldn't die on failure to cleanup
+	- Capture::Tiny needs some min version, using newest but perhaps less is ok
+
+0.000_015  May 2, 2012
+	- interpolation %x is current Perl interpreter ($^X)
+	- platform specific bugfixes
+
+0.000_014  May 1, 2012
+	- bugfix on dontpanic build chain (t/zz-example.t)
+
+0.000_013  Apr 30, 2012
+	- libdontpanic build chain should be more x-plat. Uses EU::LibBuilder
+
+0.000_012  Apr 29, 2012
+	- Simplified capture mechanism, this should prevent warnings from being suppressed
+	- Check the return status of alien_build, die if necessary
+
+0.000_011  Apr 25, 2012
+	- I'm starting to believe the bug is in the dontpanic library build chain
+	- Die on more warnings in that build chain. This won't fix anything,
+		but may show where the true problem lies
+
+0.000_010  Apr 24, 2012
+	- Prevent build process from cwd-ing from underneath us (hopefully)
+
+0.000_009  Apr 24, 2012
+	- Note: Released from 'dlopen' branch
+	- Uses new dynamic loading mechanism via DynaLoader
+
+0.000_008  Apr 11, 2012
+	- Prevent do_system from changing wd globally
+
+0.000_007  Apr 4, 2012
+	- Don't rebuild library on repeated M::B::dispatch
+	- More bugfixes
+
+0.000_006  Apr 3, 2012
+	- Yet anther bugfix(?) release 
+
+0.000_005  Apr 2, 2012
+	- Bugfix: A::B::PkgConfig _manual key shouldn't emit undef values
+
+0.000_004  Apr 2, 2012
+	- Don't mangle LD_RUN_PATH if system installed
+	- Bugfix related to dreaded '"Can't call method "keyword" on an undefined value' error
+	- Made t/yy-system_installed.t smarter on picking a library for testing
+
+0.000_003  Mar 18, 2012
+	- Require safer File::chdir
+	- Fixed "Bad File Descriptor" bug calling pkg-config
+
+0.000_002  Mar 18, 2012
+	- More documentation
+	- Smarter in handling user-provided pkg-config data
+	- Generates pkg-config data from file structure if not defined
+
+0.000_001  Mar 15, 2012
+	- Initial pre-alpha release, mostly to see CPANtesters results
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..6f264d5
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,379 @@
+This software is copyright (c) 2012-2015 by Joel Berger
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+Terms of the Perl programming language system itself
+
+a) the GNU General Public License as published by the Free
+   Software Foundation; either version 1, or (at your option) any
+   later version, or
+b) the "Artistic License"
+
+--- The GNU General Public License, Version 1, February 1989 ---
+
+This software is Copyright (c) 2012-2015 by Joel Berger.
+
+This is free software, licensed under:
+
+  The GNU General Public License, Version 1, February 1989
+
+                    GNU GENERAL PUBLIC LICENSE
+                     Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The license agreements of most software companies try to keep users
+at the mercy of those companies.  By contrast, our General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, that you receive source code or can get it if you want it,
+that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of a such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must tell them their rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any program or other work which
+contains a notice placed by the copyright holder saying it may be
+distributed under the terms of this General Public License.  The
+"Program", below, refers to any such program or work, and a "work based
+on the Program" means either the Program or any work containing the
+Program or a portion of it, either verbatim or with modifications.  Each
+licensee is addressed as "you".
+
+  1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program.  You may charge a fee for the physical act of
+transferring a copy.
+
+  2. You may modify your copy or copies of the Program or any portion of
+it, and copy and distribute such modifications under the terms of Paragraph
+1 above, provided that you also do the following:
+
+    a) cause the modified files to carry prominent notices stating that
+    you changed the files and the date of any change; and
+
+    b) cause the whole of any work that you distribute or publish, that
+    in whole or in part contains the Program or any part thereof, either
+    with or without modifications, to be licensed at no charge to all
+    third parties under the terms of this General Public License (except
+    that you may choose to grant warranty protection to some or all
+    third parties, at your option).
+
+    c) If the modified program normally reads commands interactively when
+    run, you must cause it, when started running for such interactive use
+    in the simplest and most usual way, to print or display an
+    announcement including an appropriate copyright notice and a notice
+    that there is no warranty (or else, saying that you provide a
+    warranty) and that users may redistribute the program under these
+    conditions, and telling the user how to view a copy of this General
+    Public License.
+
+    d) You may charge a fee for the physical act of transferring a
+    copy, and you may at your option offer warranty protection in
+    exchange for a fee.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
+
+  3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 1 and 2 above provided that you also do one of the following:
+
+    a) accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    b) accompany it with a written offer, valid for at least three
+    years, to give any third party free (except for a nominal charge
+    for the cost of distribution) a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    c) accompany it with the information you received as to where the
+    corresponding source code may be obtained.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it.  For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+  4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License.  However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+  5. By copying, distributing or modifying the Program (or any work based
+on the Program) you indicate your acceptance of this license to do so,
+and all its terms and conditions.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these
+terms and conditions.  You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein.
+
+  7. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of the license which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+the license, you may choose any version ever published by the Free Software
+Foundation.
+
+  8. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+        Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to humanity, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+  To do so, attach the following notices to the program.  It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 1, or (at your option)
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19xx name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License.  Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  program `Gnomovision' (a program to direct compilers to make passes
+  at assemblers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+--- The Artistic License 1.0 ---
+
+This software is Copyright (c) 2012-2015 by Joel Berger.
+
+This is free software, licensed under:
+
+  The Artistic License 1.0
+
+The Artistic License
+
+Preamble
+
+The intent of this document is to state the conditions under which a Package
+may be copied, such that the Copyright Holder maintains some semblance of
+artistic control over the development of the package, while giving the users of
+the package the right to use and distribute the Package in a more-or-less
+customary fashion, plus the right to make reasonable modifications.
+
+Definitions:
+
+  - "Package" refers to the collection of files distributed by the Copyright
+    Holder, and derivatives of that collection of files created through
+    textual modification. 
+  - "Standard Version" refers to such a Package if it has not been modified,
+    or has been modified in accordance with the wishes of the Copyright
+    Holder. 
+  - "Copyright Holder" is whoever is named in the copyright or copyrights for
+    the package. 
+  - "You" is you, if you're thinking about copying or distributing this Package.
+  - "Reasonable copying fee" is whatever you can justify on the basis of media
+    cost, duplication charges, time of people involved, and so on. (You will
+    not be required to justify it to the Copyright Holder, but only to the
+    computing community at large as a market that must bear the fee.) 
+  - "Freely Available" means that no fee is charged for the item itself, though
+    there may be fees involved in handling the item. It also means that
+    recipients of the item may redistribute it under the same conditions they
+    received it. 
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications derived
+from the Public Domain or from the Copyright Holder. A Package modified in such
+a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided that
+you insert a prominent notice in each changed file stating how and when you
+changed that file, and provided that you do at least ONE of the following:
+
+  a) place your modifications in the Public Domain or otherwise make them
+     Freely Available, such as by posting said modifications to Usenet or an
+     equivalent medium, or placing the modifications on a major archive site
+     such as ftp.uu.net, or by allowing the Copyright Holder to include your
+     modifications in the Standard Version of the Package.
+
+  b) use the modified Package only within your corporation or organization.
+
+  c) rename any non-standard executables so the names do not conflict with
+     standard executables, which must also be provided, and provide a separate
+     manual page for each non-standard executable that clearly documents how it
+     differs from the Standard Version.
+
+  d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or executable
+form, provided that you do at least ONE of the following:
+
+  a) distribute a Standard Version of the executables and library files,
+     together with instructions (in the manual page or equivalent) on where to
+     get the Standard Version.
+
+  b) accompany the distribution with the machine-readable source of the Package
+     with your modifications.
+
+  c) accompany any non-standard executables with their corresponding Standard
+     Version executables, giving the non-standard executables non-standard
+     names, and clearly documenting the differences in manual pages (or
+     equivalent), together with instructions on where to get the Standard
+     Version.
+
+  d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package.  You may charge any fee you choose for support of this Package. You
+may not charge a fee for this Package itself. However, you may distribute this
+Package in aggregate with other (possibly commercial) programs as part of a
+larger (possibly commercial) software distribution provided that you do not
+advertise this Package as a product of your own.
+
+6. The scripts and library files supplied as input to or produced as output
+from the programs of this Package do not automatically fall under the copyright
+of this Package, but belong to whomever generated them, and may be sold
+commercially, and may be aggregated with this Package.
+
+7. C or perl subroutines supplied by you and linked into this Package shall not
+be considered part of this Package.
+
+8. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+The End
+
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..923cf1c
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,98 @@
+.appveyor.yml
+Build.PL
+Changes
+lib/Alien/Base.pm
+lib/Alien/Base/Authoring.pod
+lib/Alien/Base/FAQ.pod
+lib/Alien/Base/ModuleBuild.pm
+lib/Alien/Base/ModuleBuild/API.pod
+lib/Alien/Base/ModuleBuild/Cabinet.pm
+lib/Alien/Base/ModuleBuild/File.pm
+lib/Alien/Base/ModuleBuild/Repository.pm
+lib/Alien/Base/ModuleBuild/Repository/FTP.pm
+lib/Alien/Base/ModuleBuild/Repository/HTTP.pm
+lib/Alien/Base/ModuleBuild/Repository/Local.pm
+lib/Alien/Base/ModuleBuild/Utils.pm
+lib/Alien/Base/PkgConfig.pm
+LICENSE
+MANIFEST			This list of files
+META.json
+META.yml
+README
+t/00_diag.t
+t/alien_base.t
+t/alien_base/ab_share/lib/Alien/Bar2.pm
+t/alien_base/ab_share/share/alien_builder.json
+t/alien_base/ab_share/share/include/bar2.h
+t/alien_base/ab_share/share/lib/libbar2.a
+t/alien_base/ab_sys/lib/Alien/Bar1.pm
+t/alien_base/ab_sys/share/alien_builder.json
+t/alien_base/mb_share/lib/Alien/Foo2.pm
+t/alien_base/mb_share/lib/Alien/Foo2/ConfigData.pm
+t/alien_base/mb_share/share/lib/libfoo2-3.2.1/include/foo2.h
+t/alien_base/mb_share/share/lib/libfoo2.a
+t/alien_base/mb_share/share/README
+t/alien_base/mb_sys/lib/Alien/Foo1.pm
+t/alien_base/mb_sys/lib/Alien/Foo1/ConfigData.pm
+t/alien_base/pkgconfig/libbar1.pc
+t/alien_base/pkgconfig/libfoo1.pc
+t/build_flags.t
+t/builder.t
+t/builder/bin/privateapp
+t/builder/bin/privateapp.bat
+t/cabinet.t
+t/file.t
+t/find_lib.t
+t/find_lib/dynamic/include/mylib.h
+t/find_lib/dynamic/include/otherlib.h
+t/find_lib/dynamic/lib/dirlikelib.so/dontfindthis
+t/find_lib/dynamic/lib/libmylib.0.so
+t/find_lib/dynamic/lib/libmylib.so
+t/find_lib/dynamic/lib/libmylib.so.0
+t/find_lib/dynamic/lib/libotherlib.so
+t/find_lib/dynamic/lib/mylib.dll
+t/find_lib/dynamic/lib/onlypostdot.so.0
+t/find_lib/dynamic/lib/onlypredot.0.so
+t/find_lib/dynamic/lib/prepostdot.0.so.0
+t/find_lib/mixed/dynamic/libmylib.so.1.2.3
+t/find_lib/mixed/dynamic/libotherlib.so
+t/find_lib/mixed/dynamic/mylib.dll
+t/find_lib/mixed/dynamic/otherlib.dll
+t/find_lib/mixed/include/mylib.h
+t/find_lib/mixed/include/otherlib.h
+t/find_lib/mixed/lib/dirlikelib.a/dontfindthis
+t/find_lib/mixed/lib/dirlikelib.so/dontfindthis
+t/find_lib/mixed/lib/libmylib.a
+t/find_lib/mixed/lib/libotherlib.a
+t/find_lib/mixed/lib/mylib.lib
+t/find_lib/mixed/lib/otherlib.lib
+t/find_lib/static/include/mylib.h
+t/find_lib/static/include/otherlib.h
+t/find_lib/static/lib/dirlikelib.a/dontfindthis
+t/find_lib/static/lib/dirlikelib.so/dontfindthis
+t/find_lib/static/lib/libmylib.a
+t/find_lib/static/lib/libotherlib.a
+t/find_lib/static/lib/mylib.lib
+t/find_lib/static/lib/otherlib.lib
+t/http.t
+t/http_uri.t
+t/inline.t
+t/inline_cpp.t
+t/install_destination.t
+t/interpolate.t
+t/local_repo.t
+t/pkgconfig.t
+t/pkgconfig/gsl.pc
+t/pkgconfig/test.pc
+t/repository.t
+t/repository_content_disposition.t
+t/RepositoryTest.pm
+t/system_installed/lib/MyTest.pm
+t/system_installed/MANIFEST
+t/test_http/index.html
+t/utils.t
+t/validation.t
+t/version.t
+t/yy-system_installed.t
+TODO
+xt/release/pod.t
diff --git a/META.json b/META.json
new file mode 100644
index 0000000..a685bde
--- /dev/null
+++ b/META.json
@@ -0,0 +1,123 @@
+{
+   "abstract" : "A base class for Alien:: modules",
+   "author" : [
+      "Graham Ollis <plicease at cpan.org>",
+      "Joel A. Berger <joel.a.berger at gmail.com>"
+   ],
+   "dynamic_config" : 1,
+   "generated_by" : "Module::Build version 0.4216",
+   "license" : [
+      "perl_5"
+   ],
+   "meta-spec" : {
+      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+      "version" : "2"
+   },
+   "name" : "Alien-Base",
+   "no_index" : {
+      "directory" : [
+         "t"
+      ],
+      "file" : [
+         "README.pod"
+      ]
+   },
+   "prereqs" : {
+      "configure" : {
+         "requires" : {
+            "Module::Build" : "0.36"
+         }
+      },
+      "runtime" : {
+         "recommends" : {
+            "HTML::LinkExtor" : "0"
+         },
+         "requires" : {
+            "Archive::Extract" : "0",
+            "Capture::Tiny" : "0.17",
+            "FFI::CheckLib" : "0.11",
+            "File::ShareDir" : "0",
+            "File::chdir" : "0.1005",
+            "HTTP::Tiny" : "0.044",
+            "JSON::PP" : "0",
+            "List::MoreUtils" : "0",
+            "Module::Build" : "0.36",
+            "Perl::OSType" : "0",
+            "Shell::Config::Generate" : "0",
+            "Shell::Guess" : "0",
+            "Sort::Versions" : "0",
+            "Text::ParseWords" : "3.26",
+            "URI" : "0",
+            "parent" : "0",
+            "perl" : "v5.8.1"
+         }
+      },
+      "test" : {
+         "requires" : {
+            "Cwd" : "0",
+            "File::Spec" : "0",
+            "File::Temp" : "0",
+            "FindBin" : "0",
+            "Test::More" : "0.94"
+         }
+      }
+   },
+   "provides" : {
+      "Alien::Base" : {
+         "file" : "lib/Alien/Base.pm",
+         "version" : "0.028"
+      },
+      "Alien::Base::ModuleBuild" : {
+         "file" : "lib/Alien/Base/ModuleBuild.pm",
+         "version" : "0.028"
+      },
+      "Alien::Base::ModuleBuild::Cabinet" : {
+         "file" : "lib/Alien/Base/ModuleBuild/Cabinet.pm",
+         "version" : "0.028"
+      },
+      "Alien::Base::ModuleBuild::File" : {
+         "file" : "lib/Alien/Base/ModuleBuild/File.pm",
+         "version" : "0.028"
+      },
+      "Alien::Base::ModuleBuild::Repository" : {
+         "file" : "lib/Alien/Base/ModuleBuild/Repository.pm",
+         "version" : "0.028"
+      },
+      "Alien::Base::ModuleBuild::Repository::FTP" : {
+         "file" : "lib/Alien/Base/ModuleBuild/Repository/FTP.pm",
+         "version" : "0.028"
+      },
+      "Alien::Base::ModuleBuild::Repository::HTTP" : {
+         "file" : "lib/Alien/Base/ModuleBuild/Repository/HTTP.pm",
+         "version" : "0.028"
+      },
+      "Alien::Base::ModuleBuild::Repository::Local" : {
+         "file" : "lib/Alien/Base/ModuleBuild/Repository/Local.pm",
+         "version" : "0.028"
+      },
+      "Alien::Base::ModuleBuild::Utils" : {
+         "file" : "lib/Alien/Base/ModuleBuild/Utils.pm",
+         "version" : "0.028"
+      },
+      "Alien::Base::PkgConfig" : {
+         "file" : "lib/Alien/Base/PkgConfig.pm",
+         "version" : "0.028"
+      }
+   },
+   "release_status" : "stable",
+   "resources" : {
+      "bugtracker" : {
+         "web" : "http://github.com/Perl5-Alien/Alien-Base/issues"
+      },
+      "license" : [
+         "http://dev.perl.org/licenses/"
+      ],
+      "repository" : {
+         "url" : "http://github.com/Perl5-Alien/Alien-Base"
+      },
+      "x_IRC" : "irc://irc.perl.org/#native",
+      "x_MailingList" : "https://groups.google.com/forum/#!forum/perl5-alien"
+   },
+   "version" : "0.028",
+   "x_serialization_backend" : "JSON::PP version 2.27300"
+}
diff --git a/META.yml b/META.yml
new file mode 100644
index 0000000..a93fae5
--- /dev/null
+++ b/META.yml
@@ -0,0 +1,84 @@
+---
+abstract: 'A base class for Alien:: modules'
+author:
+  - 'Graham Ollis <plicease at cpan.org>'
+  - 'Joel A. Berger <joel.a.berger at gmail.com>'
+build_requires:
+  Cwd: '0'
+  File::Spec: '0'
+  File::Temp: '0'
+  FindBin: '0'
+  Test::More: '0.94'
+configure_requires:
+  Module::Build: '0.36'
+dynamic_config: 1
+generated_by: 'Module::Build version 0.4216, CPAN::Meta::Converter version 2.150005'
+license: perl
+meta-spec:
+  url: http://module-build.sourceforge.net/META-spec-v1.4.html
+  version: '1.4'
+name: Alien-Base
+no_index:
+  directory:
+    - t
+  file:
+    - README.pod
+provides:
+  Alien::Base:
+    file: lib/Alien/Base.pm
+    version: '0.028'
+  Alien::Base::ModuleBuild:
+    file: lib/Alien/Base/ModuleBuild.pm
+    version: '0.028'
+  Alien::Base::ModuleBuild::Cabinet:
+    file: lib/Alien/Base/ModuleBuild/Cabinet.pm
+    version: '0.028'
+  Alien::Base::ModuleBuild::File:
+    file: lib/Alien/Base/ModuleBuild/File.pm
+    version: '0.028'
+  Alien::Base::ModuleBuild::Repository:
+    file: lib/Alien/Base/ModuleBuild/Repository.pm
+    version: '0.028'
+  Alien::Base::ModuleBuild::Repository::FTP:
+    file: lib/Alien/Base/ModuleBuild/Repository/FTP.pm
+    version: '0.028'
+  Alien::Base::ModuleBuild::Repository::HTTP:
+    file: lib/Alien/Base/ModuleBuild/Repository/HTTP.pm
+    version: '0.028'
+  Alien::Base::ModuleBuild::Repository::Local:
+    file: lib/Alien/Base/ModuleBuild/Repository/Local.pm
+    version: '0.028'
+  Alien::Base::ModuleBuild::Utils:
+    file: lib/Alien/Base/ModuleBuild/Utils.pm
+    version: '0.028'
+  Alien::Base::PkgConfig:
+    file: lib/Alien/Base/PkgConfig.pm
+    version: '0.028'
+recommends:
+  HTML::LinkExtor: '0'
+requires:
+  Archive::Extract: '0'
+  Capture::Tiny: '0.17'
+  FFI::CheckLib: '0.11'
+  File::ShareDir: '0'
+  File::chdir: '0.1005'
+  HTTP::Tiny: '0.044'
+  JSON::PP: '0'
+  List::MoreUtils: '0'
+  Module::Build: '0.36'
+  Perl::OSType: '0'
+  Shell::Config::Generate: '0'
+  Shell::Guess: '0'
+  Sort::Versions: '0'
+  Text::ParseWords: '3.26'
+  URI: '0'
+  parent: '0'
+  perl: v5.8.1
+resources:
+  IRC: irc://irc.perl.org/#native
+  MailingList: https://groups.google.com/forum/#!forum/perl5-alien
+  bugtracker: http://github.com/Perl5-Alien/Alien-Base/issues
+  license: http://dev.perl.org/licenses/
+  repository: http://github.com/Perl5-Alien/Alien-Base
+version: '0.028'
+x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff --git a/README b/README
new file mode 100644
index 0000000..2547219
--- /dev/null
+++ b/README
@@ -0,0 +1,42 @@
+Alien::Base is a base class and framework for creating Alien 
+distributions.  The goal of the project is to make things as simple and 
+easy as possible for both developers and users of Alien modules.
+
+Alien is a Perl namespace for defining dependencies in CPAN for 
+libraries and tools which are not "native" to CPAN.  Alien modules will 
+typically use the system libraries if they are available, or download 
+the latest version from the internet and build them from source code. 
+These libraries can then be used by other Perl modules, usually modules 
+that are implemented with XS or FFI.
+
+To install Alien::Base, use cpanminus:
+
+ cpanm Alien::Base
+ 
+Once installed you can read the project documentation using the perldoc 
+command, or via the metacpan.org website.  If you are an Alien 
+developer, see the authoring documentation:
+
+ perldoc Alien::Base::Authoring
+ http://metacpan.org/pod/Alien::Base::Authoring
+
+The FAQ also contains hints on dealing with specific challenges, like 
+dealing with specific tools:
+
+ perldoc Alien::Base::FAQ
+ http://metacpan.org/pod/Alien::Base::FAQ
+
+If you are a user of an Alien module, you will likely be more interested 
+in the Alien::Base interface itself:
+
+ perldoc Alien::Base
+ http://metacpan.org/pod/Alien::Base
+
+For questions that aren't answered in the documentation, please feel 
+free to contact the Alien::Base team:
+
+ * IRC: #native on irc.perl.org
+ * mailing list at https://groups.google.com/forum/#!forum/perl5-alien
+ * GitHub issue tracker at https://github.com/Perl5-Alien/Alien-Base/issues
+
+
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..cd6e7e2
--- /dev/null
+++ b/TODO
@@ -0,0 +1,2 @@
+* Cabinet: file selection: more generics and overrides
+* Test for prebuilt library?
diff --git a/lib/Alien/Base.pm b/lib/Alien/Base.pm
new file mode 100644
index 0000000..fdbe225
--- /dev/null
+++ b/lib/Alien/Base.pm
@@ -0,0 +1,734 @@
+package Alien::Base;
+
+use strict;
+use warnings;
+
+use Alien::Base::PkgConfig;
+
+our $VERSION = '0.028';
+$VERSION = eval $VERSION;
+
+use Carp;
+use DynaLoader ();
+
+use File::ShareDir ();
+use File::Spec;
+use Scalar::Util qw/blessed/;
+use Capture::Tiny 0.17 qw/capture_merged/;
+use Text::ParseWords qw/shellwords/;
+use Perl::OSType qw/os_type/;
+
+=encoding UTF-8
+
+=head1 NAME
+
+Alien::Base - Base classes for Alien:: modules
+
+=head1 SYNOPSIS
+
+ package Alien::MyLibrary;
+
+ use strict;
+ use warnings;
+
+ use parent 'Alien::Base';
+
+ 1;
+
+(For a synopsis of the C<Build.PL> that comes with your
+C<Alien::MyLibrary> see L<Alien::Base::ModuleBuild>)
+
+Then a C<MyLibrary::XS> can use C<Alien::MyLibrary> in its C<Build.PL>:
+
+ use Alien::MyLibrary;
+ use Module::Build 0.28; # need at least 0.28
+ 
+ my $builder = Module::Build->new(
+   ...
+   extra_compiler_flags => Alien::MyLibrary->cflags,
+   extra_linker_flags   => Alien::MyLibrary->libs,
+   ...
+ );
+ 
+ $builder->create_build_script;
+
+Or if you prefer L<ExtUtils::MakeMaker>, in its C<Makefile.PL>:
+
+ use Alien::MyLibrary
+ use ExtUtils::MakeMaker;
+ 
+ WriteMakefile(
+   ...
+   CFLAGS => Alien::MyLibrary->cflags,
+   LIBS   => ALien::MyLibrary->libs,
+   ...
+ );
+
+Or if you are using L<ExtUtils::Depends>:
+
+ use ExtUtils::MakeMaker;
+ use ExtUtils::Depends;
+ my $eud = ExtUtils::Depends->new(qw( MyLibrary::XS Alien::MyLibrary ));
+ WriteMakefile(
+   ...
+   $eud->get_makefile_vars
+ );
+
+In your C<MyLibrary::XS> module, you may need to use L<Alien::MyLibrary> if
+dynamic libraries are used:
+
+ package MyLibrary::XS;
+ 
+ use Alien::MyLibrary;
+ 
+ ...
+
+Or you can use it from an FFI module:
+
+ package MyLibrary::FFI;
+ 
+ use Alien::MyLibrary;
+ use FFI::Platypus;
+ 
+ my $ffi = FFI::Platypus->new;
+ $ffi->lib(Alien::MyLibrary->dynamic_libs);
+ 
+ $ffi->attach( 'my_library_function' => [] => 'void' );
+
+You can even use it with L<Inline> (C and C++ languages are supported):
+
+ package MyLibrary::Inline;
+ 
+ use Alien::MyLibrary;
+ # Inline 0.56 or better is required
+ use Inline 0.56 with => 'Alien::MyLibrary';
+ ...
+
+=head1 DESCRIPTION
+
+L<Alien::Base> comprises base classes to help in the construction of C<Alien::> modules. Modules in the L<Alien> namespace are used to locate and install (if necessary) external libraries needed by other Perl modules.
+
+This is the documentation for the L<Alien::Base> module itself. To learn more about the system as a whole please see L<Alien::Base::Authoring>.
+
+=cut
+
+sub import {
+  my $class = shift;
+
+  return if $class->install_type('system');
+
+  # Sanity check in order to ensure that dist_dir can be found.
+  # This will throw an exception otherwise.  
+  $class->dist_dir;
+
+  # get a reference to %Alien::MyLibrary::AlienLoaded
+  # which contains names of already loaded libraries
+  # this logic may be replaced by investigating the DynaLoader arrays
+  my $loaded = do {
+    no strict 'refs';
+    no warnings 'once';
+    \%{ $class . "::AlienLoaded" };
+  };
+
+  my @libs = $class->split_flags( $class->libs );
+
+  my @L = grep { s/^-L// } @libs;
+  my @l = grep { /^-l/ } @libs;
+
+  unshift @DynaLoader::dl_library_path, @L;
+
+  my @libpaths;
+  foreach my $l (@l) {
+    next if $loaded->{$l};
+
+    my $path = DynaLoader::dl_findfile( $l );
+    unless ($path) {
+      carp "Could not resolve $l";
+      next;
+    }
+
+    push @libpaths, $path;
+    $loaded->{$l} = $path;
+  }
+
+  push @DynaLoader::dl_resolve_using, @libpaths;
+
+  my @librefs = map { DynaLoader::dl_load_file( $_, 0x01 ) } grep !/\.(a|lib)$/, @libpaths;
+  push @DynaLoader::dl_librefs, @librefs;
+
+}
+
+=head1 METHODS
+
+In the example snippets here, C<Alien::MyLibrary> represents any
+subclass of L<Alien::Base>.
+
+=head2 dist_dir
+
+ my $dir = Alien::MyLibrary->dist_dir;
+
+Returns the directory that contains the install root for
+the packaged software, if it was built from install (i.e., if
+C<install_type> is C<share>).
+
+=cut
+
+sub dist_dir {
+  my $class = shift;
+
+  my $dist = blessed $class || $class;
+  $dist =~ s/::/-/g;
+
+
+  my $dist_dir = 
+    $class->config('finished_installing') 
+      ? File::ShareDir::dist_dir($dist) 
+      : $class->config('working_directory');
+
+  croak "Failed to find share dir for dist '$dist'"
+    unless defined $dist_dir && -d $dist_dir;
+
+  return $dist_dir;
+}
+
+sub new { return bless {}, $_[0] }
+
+=head2 cflags
+
+ my $cflags = Alien::MyLibrary->cflags;
+
+ use Text::ParseWords qw( shellwords );
+ my @cflags = shellwords( Alien::MyLibrary->cflags );
+
+Returns the C compiler flags necessary to compile an XS
+module using the alien software.  If you need this in list
+form (for example if you are calling system with a list
+argument) you can pass this value into C<shellwords> from
+the Perl core L<Text::ParseWords> module.
+
+=cut
+
+sub cflags {
+  my $self = shift;
+  return $self->_keyword('Cflags', @_);
+}
+
+=head2 libs
+
+ my $libs = Alien::MyLibrary->libs;
+
+ use Text::ParseWords qw( shellwords );
+ my @cflags = shellwords( Alien::MyLibrary->libs );
+
+Returns the library linker flags necessary to link an XS
+module against the alien software.  If you need this in list
+form (for example if you are calling system with a list
+argument) you can pass this value into C<shellwords> from
+the Perl core L<Text::ParseWords> module.
+
+=cut
+
+sub libs {
+  my $self = shift;
+  return $self->_keyword('Libs', @_);
+}
+
+=head2 install_type
+
+ my $install_type = Alien::MyLibrary->install_type;
+
+Returns the install type that was used when C<Alien::MyLibrary> was
+installed.  Types include:
+
+=over 4
+
+=item system
+
+The library was provided by the operating system
+
+=item share
+
+The library was not available when C<Alien::MyLibrary> was installed, so
+it was built from source code, either downloaded from the Internet
+or bundled with C<Alien::MyLibrary>.
+
+=back
+
+=cut
+
+sub install_type {
+  my $self = shift;
+  my $type = $self->config('install_type');
+  return @_ ? $type eq $_[0] : $type;
+}
+
+sub _keyword {
+  my $self = shift;
+  my $keyword = shift;
+
+  # use pkg-config if installed system-wide
+  if ($self->install_type('system')) {
+    my $name = $self->config('name');
+    my $command = Alien::Base::PkgConfig->pkg_config_command . " --\L$keyword\E $name";
+
+    $! = 0;
+    chomp ( my $pcdata = capture_merged { system( $command ) } );
+
+    # if pkg-config fails for whatever reason, then we try to
+    # fallback on alien_provides_*
+    $pcdata = '' if $! || $?;
+
+    $pcdata =~ s/\s*$//;
+
+    if($self->config('system_provides')) {
+      if(my $system_provides = $self->config('system_provides')->{$keyword}) {
+        $pcdata = length $pcdata ? "$pcdata $system_provides" : $system_provides;
+      }
+    }
+
+    return $pcdata;
+  }
+
+  # use parsed info from build .pc file
+  my $dist_dir = $self->dist_dir;
+  my @pc = $self->pkgconfig(@_);
+  my @strings =
+    grep defined,
+    map { $_->keyword($keyword, 
+      #{ pcfiledir => $dist_dir }
+    ) }
+    @pc;
+
+  if(defined $self->config('original_prefix') && $self->config('original_prefix') ne $self->dist_dir)
+  {
+    my $dist_dir = $self->dist_dir;
+    $dist_dir =~ s{\\}{/}g if $^O eq 'MSWin32';
+    my $old = quotemeta $self->config('original_prefix');
+    @strings = map {
+      s{^(-I|-L|-LIBPATH:)?($old)}{$1.$dist_dir}e;
+      s/(\s)/\\$1/g;
+      $_;
+    } map { $self->split_flags($_) } @strings;
+  }
+
+  return join( ' ', @strings );
+}
+
+sub pkgconfig {
+  my $self = shift;
+  my %all = %{ $self->config('pkgconfig') };
+
+  # merge in found pc files
+  require File::Find;
+  my $wanted = sub {
+    return if ( -d or not /\.pc$/ );
+    my $pkg = Alien::Base::PkgConfig->new($_);
+    $all{$pkg->{package}} = $pkg;
+  };
+  File::Find::find( $wanted, $self->dist_dir );
+    
+  croak "No Alien::Base::PkgConfig objects are stored!"
+    unless keys %all;
+  
+  # Run through all pkgconfig objects and ensure that their modules are loaded:
+  for my $pkg_obj (values %all) {
+    my $perl_module_name = blessed $pkg_obj;
+    eval "require $perl_module_name"; 
+  }
+
+  return @all{@_} if @_;
+
+  my $manual = delete $all{_manual};
+
+  if (keys %all) {
+    return values %all;
+  } else {
+    return $manual;
+  }
+}
+
+=head2 config
+
+ my $value = Alien::MyLibrary->config($key);
+
+Returns the configuration data as determined during the install
+of L<Alien::MyLibrary>.  For the appropriate config keys, see 
+L<Alien::Base::ModuleBuild::API#CONFIG-DATA>.
+
+=cut
+
+# helper method to call Alien::MyLib::ConfigData->config(@_)
+sub config {
+  my $class = shift;
+  $class = blessed $class || $class;
+
+  if(my $alien_builder_data = $class->_alien_builder_data)
+  {
+    return $alien_builder_data->{config}->{$_[0]};
+  }
+  
+  my $config = $class . '::ConfigData';
+  eval "require $config";
+  warn $@ if $@;
+
+  return $config->config(@_);
+}
+
+sub Alien::Base::_alien_builder_data
+{
+  my($class) = @_;
+  
+  my $dist = $class;
+  $dist =~ s/::/-/g;
+  my $dir = eval { File::ShareDir::dist_dir($dist) };
+  return unless defined $dir && -d $dir;
+  my $filename = File::Spec->catfile($dir, 'alien_builder.json');
+  return unless -r $filename;
+
+  require JSON::PP;
+  open my $fh, '<', $filename;    
+  my $config = JSON::PP->new
+    ->filter_json_object(sub {
+      my($object) = @_;
+      my $class = delete $object->{'__CLASS__'};
+      return unless $class;
+      bless $object, $class;
+    })->decode(do { local $/; <$fh> });
+  close $fh;
+
+  # avoid re-reading on next call
+  if($class ne 'Alien::Base')
+  {
+    my $method = join '::', $class, '_alien_builder_data';
+    no strict 'refs';
+    *{$method} = sub { $config };
+  }
+
+  $config;
+}
+
+# helper method to split flags based on the OS
+sub split_flags {
+  my ($class, $line) = @_;
+  my $os = os_type();
+  if( $os eq 'Windows' ) {
+    $class->split_flags_windows($line);
+  } else {
+    # $os eq 'Unix'
+    $class->split_flags_unix($line);
+  }
+}
+
+sub split_flags_unix {
+  my ($class, $line) = @_;
+  shellwords($line);
+}
+
+sub split_flags_windows {
+  # NOTE a better approach would be to write a function that understands cmd.exe metacharacters.
+  my ($class, $line) = @_;
+
+  # Double the backslashes so that when they are unescaped by shellwords(),
+  # they become a single backslash. This should be fine on Windows since
+  # backslashes are not used to escape metacharacters in cmd.exe.
+  $line =~ s,\\,\\\\,g;
+  shellwords($line);
+}
+
+=head2 dynamic_libs
+
+ my @dlls = Alien::MyLibrary->dynamic_libs;
+ my($dll) = Alien::MyLibrary->dynamic_libs;
+
+Returns a list of the dynamic library or shared object files for the
+alien software.  Currently this only works for when C<install_type> is
+C<share> and C<alien_isolate_dynamic> is used (See
+L<Alien::Base::ModuleBuild::API#CONSTRUCTOR> for all build arguments).
+
+=cut
+
+sub dynamic_libs {
+  my ($class) = @_;
+  
+  require FFI::CheckLib;
+  
+  if($class->install_type('system')) {
+
+    my $name = $class->config('ffi_name');
+    unless(defined $name) {
+      $name = $class->config('name');
+      # strip leading lib from things like libarchive or libffi
+      $name =~ s/^lib//;
+      # strip trailing version numbers
+      $name =~ s/-[0-9\.]+$//;
+    }
+    
+    return FFI::CheckLib::find_lib(lib => $name);
+  
+  } else {
+  
+    my $dir = $class->dist_dir;
+    my $dynamic = File::Spec->catfile($class->dist_dir, 'dynamic');
+    
+    if(-d $dynamic)
+    {
+      return FFI::CheckLib::find_lib(
+        lib        => '*',
+        libpath    => $dynamic,
+        systempath => [],
+      );
+    }
+
+    return FFI::CheckLib::find_lib(
+      lib        => '*',
+      libpath    => $dir,
+      systempath => [],
+      recursive  => 1,
+    );
+  }
+}
+
+=head2 bin_dir
+
+ my(@dir) = Alien::MyLibrary->bin_dir
+
+Returns a list of directories with executables in them.  For a C<system>
+install this will be an empty list.  For a C<share> install this will be
+a directory under C<dist_dir> named C<bin> if it exists.  You may wish
+to override the default behavior if you have executables or scripts that
+get installed into non-standard locations.
+
+=cut
+
+sub bin_dir {
+  my ($class) = @_;
+  return unless $class->install_type('share');
+  my $dir = File::Spec->catfile($class->dist_dir, 'bin');
+  -d $dir ? ($dir) : ();
+}
+
+=head2 alien_helper
+
+ my $helpers = Alien::MyLibrary->alien_helper;
+
+Returns a hash reference of helpers provided by the Alien module.
+The keys are helper names and the values are code references.  The
+code references will be executed at command time and the return value
+will be interpolated into the command before execution.  The default
+implementation returns an empty hash reference, and you are expected
+to override the method to create your own helpers.
+
+For compatability with the C<Alien::Base::ModuleBuild> attribute C<alien_helper>,
+helpers may also be specified as Perl strings that will be evaluated
+and executed at command time.  This is necessary because of limitations
+with C<Module::Build>, and you are strongly encouraged to use code
+references when defining helpers from an Alien module.
+
+Helpers allow users of your Alien module to use platform or environment 
+determined logic to compute command names or arguments in 
+C<alien_build_commands> or C<alien_install_commands> in their C<Build.PL>.
+Helpers allow you to do this without making your Alien module a requirement
+when a build from source code is not necessary.
+
+As a concrete example, consider L<Alien::gmake>, which provides the 
+helper C<gmake>:
+
+ package Alien::gmake;
+ 
+ ...
+ 
+ sub alien_helper {
+   my($class) = @_;
+   return {
+     gmake => sub {
+       # return the executable name for GNU make,
+       # usually either make or gmake depending on
+       # the platform and environment
+       $class->exe;
+     }
+   },
+ }
+
+Now consider L<Alien::nasm>.  C<nasm> requires GNU Make to build from 
+source code, but if the system C<nasm> package is installed we don't 
+need it.  From the C<Build.PL> of C<Alien::nasm>:
+
+ # Alien::nasm Build.PL
+ 
+ ...
+ 
+ Alien::Build::ModuleBuild->new(
+   ...
+   alien_bin_requires => {
+     'Alien::gmake' => '0.05',  # helper introduced in 0.05
+   },
+   alien_build_commands => [
+     '%c --prefix=%s',
+     '%{gmake}',
+   ],
+   alien_install_commands => [
+     '%{gmake} install',
+   ],
+   ...
+
+=cut
+
+sub alien_helper {
+  {};
+}
+
+=head2 inline_auto_include
+
+ my(@headers) = Alien::MyLibrary->inline_auto_include;
+
+List of header files to automatically include in inline C and C++
+code when using L<Inline::C> or L<Inline::CPP>.  This is provided
+as a public interface primarily so that it can be overidden at run
+time.  This can also be specified in your C<Build.PL> with 
+L<Alien::Base::ModuleBuild> using the C<alien_inline_auto_include>
+property.
+
+=cut
+
+sub inline_auto_include {
+  my ($class) = @_;
+  return [] unless $class->config('inline_auto_include');
+  $class->config('inline_auto_include')
+}
+
+sub Inline {
+  my ($class, $language) = @_;
+  return if $language !~ /^(C|CPP)$/;
+  my $config = {
+    CCFLAGSEX    => $class->cflags,
+    LIBS         => $class->libs,
+  };
+  
+  if (@{ $class->inline_auto_include } > 0) {
+    $config->{AUTO_INCLUDE} = join "\n", map { "#include \"$_\"" } @{ $class->inline_auto_include };
+  }
+  
+  $config;
+}
+
+1;
+
+__END__
+__POD__
+
+=head1 SUPPORT AND CONTRIBUTING
+
+First check the L<Alien::Base::FAQ> for questions that have already been answered.
+
+IRC: #native on irc.perl.org
+
+L<(click for instant chatroom login)|http://chat.mibbit.com/#native@irc.perl.org> 
+
+If you find a bug, please report it on the projects issue tracker on GitHub:
+
+=over 4
+
+=item L<https://github.com/Perl5-Alien/Alien-Base/issues>
+
+=back
+
+Development is discussed on the projects google groups.  This is also
+a reasonable place to post a question if you don't want to open an issue
+in GitHub.
+
+=over 4
+
+=item L<https://groups.google.com/forum/#!forum/perl5-alien>
+
+=back
+
+If you have implemented a new feature or fixed a bug, please open a pull 
+request.
+
+=over 4
+
+=item L<https://github.com/Perl5-Alien/Alien-Base/pulls>
+
+=back
+
+=head1 SEE ALSO
+
+=over 
+
+=item * 
+
+L<Module::Build>
+
+=item *
+
+L<Alien>
+
+=item *
+
+L<Alien::Base::FAQ>
+
+=back
+
+=head1 AUTHOR
+
+Original author: Joel Berger, E<lt>joel.a.berger at gmail.comE<gt>
+
+Current maintainer: Graham Ollis E<lt>plicease at cpan.orgE<gt> and the L<Alien::Base> team
+
+=head1 CONTRIBUTORS
+
+=over 
+
+=item David Mertens (run4flat)
+
+=item Mark Nunberg (mordy, mnunberg)
+
+=item Christian Walde (Mithaldu)
+
+=item Brian Wightman (MidLifeXis)
+
+=item Graham Ollis (plicease)
+
+=item Zaki Mughal (zmughal)
+
+=item mohawk2
+
+=item Vikas N Kumar (vikasnkumar)
+
+=item Flavio Poletti (polettix)
+
+=item Salvador Fandiño (salva)
+
+=back
+
+Thanks also to
+
+=over
+
+=item Christian Walde (Mithaldu)
+
+For productive conversations about component interoperablility.
+
+=item kmx
+
+For writing Alien::Tidyp from which I drew many of my initial ideas.
+
+=item David Mertens (run4flat)
+
+For productive conversations about implementation.
+
+=item Mark Nunberg (mordy, mnunberg)
+
+For graciously teaching me about rpath and dynamic loading,
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2012-2015 by Joel Berger
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
diff --git a/lib/Alien/Base/Authoring.pod b/lib/Alien/Base/Authoring.pod
new file mode 100644
index 0000000..3cd69ce
--- /dev/null
+++ b/lib/Alien/Base/Authoring.pod
@@ -0,0 +1,159 @@
+=head1 NAME
+
+Alien::Base::Authoring - Authoring an C<Alien::> module
+
+=head1 DESCRIPTION
+
+Congratulations! You have made the decision to help the Perl community by providing a C library via CPAN. The L<Alien> namespace has been instrumental in providing C libraries for many years, but authoring those modules has been a commitment that most authors weren't willing to take on. L<Alien::Base> tries to ease that pain by providing most of the needed functionality; usually authors should only need a little boilerplate and configuration!
+
+=head1 STATUS
+
+L<Alien::Base> is under active development.  The API is relatively 
+stable, although breaking changes may be introduced if the rewards are 
+deemed greater than the pains that they produce.
+
+=head1 ECOSYSTEM
+
+The L<Alien::Base> ecosystem is made up of several elements. Some of these elements are the base classes in the distribution itself. Of course, no ecosystem is complete without inhabitants, therefore, it is also important to consider the users of these base classes. This documentation will assume that you are writing C<Alien::MyLibrary> which provides F<libmylibrary.so>. Further it will assume that you or someone else is going to use this module/library to write C<Some::Module::MyLibrary [...]
+
+=head2 Alien::Base::ModuleBuild
+
+L<Alien::Base::ModuleBuild> provides a base class, utility methods and configuration handling for the build/install phase of the library. It is itself a subclass of L<Module::Build>, which is what supports the building and installing of the surrouning C<Alien::> module. C<Alien::MyLibrary>'s F<Build.PL> file will use L<Alien::Base::ModuleBuild> to create its builder object.
+
+ # file: Alien-MyLibrary/Build.PL
+ use Alien::Base::ModuleBuild;
+ my $builder = Alien::Base::ModuleBuild->new(...);
+ $builder->create_build_script;
+
+This is just like you would do for L<Module::Build>, except that there will be a few additional configuration parameters (see L<Alien::Base::ModuleBuild::API>).
+
+L<Alien::Base::ModuleBuild> adds the additional build actions C<alien_code> and C<alien_install>. These actions need never be run directly, the usual C<build> action (usually seen as C<./Build>) and C<install> (C<./Build install>) will call them for you. The C<alien_code> action is responsible for finding, downloading, extracting and building the external libary (the commands specified in builder parameter C<alien_build_commands>). The C<alien_install> action is responsible for installin [...]
+
+The C<./Build test> command will invoke any library tests specified in C<alien_test_commands>, though none are defined by default. Finally C<./Build install> will invoke whatever C<alien_install_commands> were specified.
+
+=head2 Alien::Base
+
+L<Alien::Base> is the base class of C<Alien::MyLibrary>. In this context, L<Alien::Base> has two distinct uses. First it is used by C<Alien::MyLibrary> to provide the build information/flags for building C<Some::Module::MyLibrary>. Secondly it is used (again through C<Alien::MyLibrary>) to provide run-time access to F<libmylibrary.so> to C<Some::Module::MyLibrary>.
+
+=head3 Alien::Base for Building
+
+C<Alien::MyLibrary> is called by C<Some::Library::MyLibrary>'s build script, either F<Build.PL> or F<Makefile.PL>. Most of the functionality can be utilized through class method calls, though creating an object can save a few keystrokes.
+
+ # file: Some-Module-MyLibrary/Build.PL
+ use Module::Build;
+ use Alien::MyLibrary;
+
+ my $alien = Alien::MyLibrary->new;
+ my $builder = Module::Build->new(
+   ...
+   extra_compiler_flags => $alien->cflags(),
+   extra_linker_flags   => $alien->libs(),
+ );
+ $builder->create_build_script;
+
+Additional information can be gotten from the C<config> method.
+
+=head3 Alien::Base for Run-Time Provision
+
+C<Alien::MyLibrary> must be a subclass of L<Alien::Base>. This provides the C<import> method, which does the run-time provisioning so that when the XS file is loaded, it can find F<libmylibrary.so>. The C<import> method does this by pre-loading the library via C<DynaLoader::dl_load_file> which is a platform-independent wrapper for C<dlopen> or your system's equivalent. It no longer appends to C<$ENV{LD_RUN_PATH}>.
+
+ # file: Alien-MyLibrary/lib/Alien/MyLibrary.pm
+ package Alien::MyLibrary;
+
+ use parent 'Alien::Base';
+
+ 1;
+
+Finally, C<Alien::MyLibrary> must also be called by C<Some::Library::MyLibrary> before C<DynaLoader::bootstrap> or C<XSLoader::load>. The C<use> directive is recommended, however if you must use C<require> then be sure to call the C<import> method too. Without this C<import> call, the loader doesn't know where to find F<libmylibrary.so>.
+
+ # file: Some-Module-MyLibrary/lib/Some/Module/MyLibrary.pm
+ package Some::Module::MyLibrary;
+
+ use Alien::MyLibrary;
+ our $VERSION = '0.54';
+
+ require XSLoader;
+ XSLoader::load('Some::Module::MyLibrary', $VERSION);
+
+ # your code
+
+=head1 EXAMPLES
+
+The example code that was housed in this distribution during alpha phase has been moved to two different CPAN distributions. Those are:
+
+=over
+
+=item *
+
+L<Acme::Alien::DontPanic> -- An example C<Alien::> module which provides F<libdontpanic.so>. It provides the C function C<answer> which is simply:
+
+ int answer () { return 42 }
+
+=item *
+
+L<Acme::Ford::Prefect> -- An XS module which provides the Perl-level access to C<answer>. It relies on F<libdontpanic.so> and uses L<Acme::Alien::DontPanic> to locate/load it.
+
+=back
+
+Additionally, there exist in-production C<Alien::> distributions that serve as de-facto tests of L<Alien::Base>'s networking components:
+
+=over
+
+=item *
+
+L<Alien::LibYAML> -- Builds and installs F<libyaml>, acquiring the library archive from its hosted location via C<Alien::Base::Repository::HTTP>.
+
+=item *
+
+L<Alien::GSL> -- Builds and installs F<libgsl>, aquiring the library source archive via C<Alien::Base::Repository::FTP>.
+
+=item *
+
+L<Alien::gmake> -- Builds and installs GNU make.  Rather than being a library, this is a tool used to build other tools and libraries.  It is useful for other Alien modules that require the GNU version of make.  It also demonstrates the use of L<Alien::Base> for providing tools rather than libraries.
+
+=back
+
+=head1 AUTHOR
+
+Joel Berger <joel.a.berger at gmail.com>
+
+=head1 SEE ALSO
+
+=over
+
+=item * 
+
+L<Module::Build>
+
+=item *
+
+L<Alien>
+
+=item *
+
+L<Alien::Base>
+
+=item *
+
+L<Alien::Base::FAQ>
+
+=back
+
+=head1 SOURCE REPOSITORY
+
+L<http://github.com/Perl5-Alien/Alien-Base>
+
+=head1 AUTHOR
+
+Original author: Joel Berger, E<lt>joel.a.berger at gmail.comE<gt>
+
+Current maintainer: Graham Ollis E<lt>plicease at cpan.orgE<gt> and the L<Alien::Base> team
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2012-2015 by Joel Berger
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
diff --git a/lib/Alien/Base/FAQ.pod b/lib/Alien/Base/FAQ.pod
new file mode 100644
index 0000000..a59805b
--- /dev/null
+++ b/lib/Alien/Base/FAQ.pod
@@ -0,0 +1,413 @@
+=head1 NAME
+
+Alien::Base::FAQ - Frequently Asked Questions about Alien::Base
+
+=head1 SYNOPSIS
+
+ perldoc Alien::Base::FAQ
+
+=head1 DESCRIPTION
+
+This document serves to answer the most frequently asked questions made by L<Alien::Base> authors.
+
+=head2 What is Alien and Alien::Base?
+
+Alien is a Perl namespace for defining dependencies in CPAN for libraries and tools which are not "native"
+to CPAN.  For a manifesto style description of the Why, and How see L<Alien>.  L<Alien::Base> is a base
+class and framework for creating Alien distributions.  The idea is to address as many of the common challenges
+to developing Alien modules in the base class to simplify the process.
+
+=head2 How do I specify a minimum or exact version requirement for packages that use pkg-config?
+
+The C<alien_version_check> attribute to L<Alien::Base::ModuleBuild> will be executed to determine if
+the library is provided by the operating system.  The default for this is C<%{pkg_config} --modversion %n>
+which simply checks to see if any version of that package is available, and prints the version
+number.  You can use the C<--atleast-version>, C<--exact-version> options to require a specific range of versions,
+but these flags do not work with the C<--modversion> flag, so be sure to invoke separately.
+
+ use Alien::Base::ModuleBuild;
+ Alien::Base::ModuleBuild->new(
+   dist_name           => 'Alien::Foo',
+   alien_name          => 'foo',
+   configure_requires  => { 'Alien::Base::ModuleBuild' => '0.022' }, # required for %{pkg_config}
+   alien_version_check => '%{pkg_config} --atleast-version 1.2.3 %n && %{pkg_config} --modversion %n',
+   ...
+ )->create_build_script;
+
+It is better to use the built in C<%{pkg_config}> helper as it will use the system provided pkg-config
+if it is available and fallback on the pure perl L<PkgConfig> if not.
+
+You can also use C<--exact-version> to specify an exact version.
+
+=head2 How to create an Alien module for packages that do not support pkg-config?
+
+Although L<Alien::Base> and L<Alien::Base::ModuleBuild> assume packages come with a C<pkg-config>
+C<.pc> file to determine compiler and linker flags by default, you can implement an Alien module
+for packages that do use C<pkg-config> by following these tasks:
+
+=over 4
+
+=item subclass L<Alien::Base::ModuleBuild> and implement C<alien_check_installed_version>
+
+Create a subclass of L<Alien::Base::ModuleBuild> and put it in the C<inc> directory of your distribution so
+that it can be used during install but won't I<be installed>.
+
+ # inc/My/ModuleBuild.pm
+ package My::ModuleBuild;
+ 
+ use parent 'Alien::Base::ModuleBuild';
+ 
+ sub alien_check_installed_version {
+   my($class) = @_;
+   
+   # determine if your library is already provided by the system
+   my $version = ...;
+   
+   # return false if the library is NOT provided by the system
+   return unless defined $version;
+   
+   # otherwise return the version detected
+   # (if you cannot determine the version it
+   #  is usually sufficient to return a true value)
+   return $version;
+ }
+
+There are number of methods you can use to determine if the system provides your library.  From Perl
+methods include L<Devel::CheckLib>, L<ExtUtils::CBuilder>, L<ExtUtls::CChecker>, L<Config::AutoConf>,
+L<FFI::CheckLib> among others.  It is also frequently possible to determine if a library is installed
+using a C<-config> suffixed program.  For example C<libxml2> comes with xml2-config which provides the
+existence, compiler and linker flags it needs.  In my experience, however, most packages that provide a
+C<-config> suffixed program also provide a C<pkg-config> interface as well.
+
+=item implement C<alien_check_built_version> in your L<Alien::Base::ModuleBuild> subclass
+
+You should also implement C<alien_check_build_version> which will be executed from the package build
+root once the package is successfully built.
+
+ # inc/My/ModuleBuild.pm
+ package My::ModuleBuild;
+ 
+ ...
+ 
+ sub alien_check_built_version {
+   my($self) = @_;
+   
+   my $version = ...
+   
+   # (Again, if you cannot determine the version,
+   #  it is usually sufficent to return a true value)
+   return $version;
+ }
+
+=item set C<alien_provides_cflags> and C<alien_provides_libs> in C<Build.PL>.
+
+Add something like this to your C<Build.PL>:
+
+ # Build.PL
+ use lib 'inc';
+ use My::ModuleBuild;
+ 
+ My::ModuleBuild->new(
+   ...
+   alien_provides_cflags => '-I/usr/include/foo',
+   alien_provides_libs   => '-L/usr/lib/foo -lfoo',
+   ...
+ );
+
+Note that it is frequently sufficient to provide C<alien_provides_libs> and the appropriate C<-l> flag.
+These flags will be used in the event that the system package can be found.  It is a good idea to verify
+that these flags do indeed work in C<alien_check_installed_version> above.
+
+=back
+
+For a fully implemented example, see L<Alien::Libbz2>.
+
+=head2 How do I test my package once it is built (before it is installed)?
+
+There are many ways to test Alien modules before (or after) they are installed, but instead
+of rolling your own, consider using L<Test::Alien> which is light on dependencies and will
+test your module very closely to the way that it will actaully be used.  That is to say by
+building a mini XS or FFI extension and using it.  It even has tests for tool oriented Alien
+distributions (like L<Alien::gmake> and L<Alien::patch>).  Here is a short example, there
+are many others included with the L<Test::Alien> documentation:
+
+ use Test::Stream -V1;
+ use Test::Alien;
+ use Alien::Editline;
+ 
+ alien_ok 'Alien::Editline';
+ my $xs = do { local $/; <DATA> };
+ xs_ok $xs, with_subtest {
+   my($module) = @_;
+   ok $module->version;
+ };
+ 
+ __DATA__
+ 
+ #include "EXTERN.h"
+ #include "perl.h"
+ #include "XSUB.h"
+ #include <editline/readline.h>
+ 
+ /* having a string parameter that we ignore
+    allows us to call this as a class method */
+ const char *
+ version(const char *class)
+ {
+   return rl_library_version;
+ }
+ 
+ MODULE = TA_MODULE PACKAGE = TA_MODULE
+ 
+ const char *version(class);
+     const char *class;
+
+=head2 How do I patch packages that need minor (or major) alterations?
+
+One approach is to create a unified diff for patches that you want to apply and simply run patch on them.  The
+L<Alien::patch> and the C<%{patch}> helper can be used like this:
+
+ # Build.PL
+ use Alien::Base::ModuleBuild;
+ 
+ Alien::Base::ModuleBuild->new(
+   ...
+   alien_bin_requires => {
+     'Alien::patch' => 0.06, # needed for %{patch} helper
+   },
+   alien_build_commands => [
+     '%{patch} -p1 < ../../patch/mypackage.patch',
+     ...
+   ],
+   ...
+ )->create_build_script;
+
+Create a folder in your distribution root called C<patch> and place the C<mypackage.patch> file in there.  Since 
+the C<patch> command will be executed in the package root instead of the distribution root, you need to use a 
+relative path prefixed by C<../..>.  Here we use L<Alien::patch> to provide patch even in environments where it
+is not provided.
+
+A more powerful approach to patching is to write a perl subroutine to modify the source after it has been 
+extracted.  One way to do this is to create a module in your distribution's inc directory that does the 
+patching (modules in inc can be used during build/test but won't be installed):
+
+ # inc/My/AlienPatch.pm
+ package My::AlienPatch;
+ 
+ # add this sub to the main namespace
+ # so we don't need to quote or escape
+ # anything below
+ sub main::alien_patch {
+   # is executed in the package root,
+   # make what ever changes you need to
+   # to the source here.
+ }
+ 
+ 1;
+
+ # Build.PL
+ use Alien::Base::ModuleBuild;
+ 
+ Alien::Base::ModuleBuild->new(
+   ...
+   alien_build_commands => [
+     # %x will be replaced by path for calling Perl
+     # from the command line
+     "%x -I../../inc -MMy::AlienPatch -e alien_patch",
+     ...
+   ],
+   ...
+ )->create_build_script;
+
+=head2 How do I build a package that uses I<build system>?
+
+=head3 autoconf
+
+By default L<Alien::Base::ModuleBuild> assumes a package with an autoconf style C<configure> script.  The 
+default is
+ 
+ # Build.PL
+ use Alien::Base::ModuleBuild;
+ Alien::Base::ModuleBuild->new(
+   ...
+   alien_build_commands => [
+     '%c --prefix=%s',
+     'make',
+   ],
+   alien_install_commands => [
+     'make install',
+   ],
+   ...
+ )->create_build_script;
+
+There are a couple of short cuts here, C<%c> indicates the platform independent method for executing the 
+C<configure> script, plus any normal autoconf flags that are appropriate for Perl Alien libraries. The C<%c> 
+also tells L<Alien::Base::ModuleBuild> to use L<Alien::MSYS> on Windows platforms and to add that as a 
+dependency.  The C<%s> is a placeholder for the location to which the package will be installed.  This is 
+normally in a share directory specific to your distribution.
+
+=head3 autoconf-like
+
+If you see an error like this:
+
+ Unknown option "--with-pic".
+
+It may be because your package provides a C<configure> script that provides an autoconf-style interface, but is 
+not actually autoconf.  L<Alien::Base::ModuleBuild> is aggressive in using the C<--with-pic> option because when 
+supported by autoconf it produces position independent code (important for reliably building XS extensions), and 
+when not supported autoconf simply ignores the option. Unfortunately some autoconf-style C<configure> scripts 
+consider it an error when they see options that they do not recognize.  You can tell L<Alien::Base::ModuleBuild> 
+to not use the C<--with-pic> option via the C<alien_autoconf_with_pic> property:
+
+ # Build.PL
+ use Alien::Base::ModuleBuild;
+ Alien::Base::ModuleBuild->new(
+   ...
+   alien_autoconf_with_pic => 0,
+   ...
+ )->create_build_script;
+
+=head3 CMAKE
+
+You probably cannot count on CMake being available on most platforms.  Fortunately, there is an alien 
+distribution L<Alien::CMake> which will either use the CMake provided by the operating system, or download and 
+install it for you.  You can use this from your C<Build.PL> with the C<alien_bin_requires> property:
+
+ # Build.PL
+ use Alien::Base::ModuleBuild;
+ use Config;
+ Alien::Base::ModuleBuild->new(
+   ...
+   alien_bin_requires => {
+     'Alien::CMake' => 0.07,
+   },
+   alien_build_commands => [
+     # acutal required arguments may vary
+     "cmake -G 'Unix Makefiles' -DCMAKE_MAKE_PROGRAM=$Config{make} -DCMAKE_INSTALL_PREFIX:PATH=%s",
+     "$Config{make}",
+   ],
+   alien_install_commands => [
+     "$Config{make} install",
+   ],
+   ...
+ )->create_build_script;
+
+
+=head3 vanilla Makefiles?
+
+If you want to use the same C<make> as Perl, you can use L<Config>:
+
+ # Build.PL
+ use Alien::Base::ModuleBuild;
+ use Config;
+ Alien::Base::ModuleBuild->new(
+   ...
+   alien_build_commands => [
+     "$Config{make}",
+   ],
+   alien_install_commands => [
+     "$Config{make} install",
+   ],
+   ...
+ )->create_build_script;
+
+=head3 Gnu Makefiles?
+
+Some packages require GNU Make's unique syntax.  Perl's L<Config> provides an entry for C<gmake>, but it is 
+frequently wrong.  Do not depend on it.  Instead you can ues L<Alien::gmake> to provide a real GNU Make (either 
+from the operating system, or built from source):
+
+ # Build.PL
+ use Alien::Base::ModuleBuild;
+ 
+ Alien::Base::ModuleBuild->new(
+   ...
+   alien_bin_requires => {
+     'Alien::gmake' => 0.11, # needed for %{gmake} helper
+   },
+   alien_build_commands => [
+     "%{gmake}",
+   ],
+   alien_install_commands => [
+     "%{gmake} install",
+   ],
+   ...
+ )->create_build_script;
+
+=head2 When debugging my package build, I get different results!
+
+If you get results from running the commands in your shell different to what happens when your C<Alien::> 
+distribution attempts to build, it may be because your environment is different than the one that your 
+distribution is using.  For example, if you use L<Alien::CMake> or L<Alien::gmake> to build with specific tools 
+that are provided by your operating system, L<Alien::Build::ModuleBuild> will adjust the path before executing 
+build and install commands.
+
+In the alien build directory (usually C<_alien>) you will find environment files that you can source
+into your shell (C<env.csh> for tcsh and C<env.sh> for bourne based shells), which should provide the 
+identical environment used by the build process in order to troubleshoot the build manually.
+
+ % source _alien/env.sh
+
+=head2 How do I use C<Alien::Base> from C<Dist::Zilla>
+
+For creating L<Alien::Base> based dists from L<Dist::Zilla> you can use the plugin 
+L<Dist::Zilla::Plugin::Alien>.
+
+=head2 I have question not listed here!
+
+There are a number of forums available to people working on L<Alien> and L<Alien::Base> modules:
+
+=over 4
+
+=item C<#native> on irc.perl.org
+
+This is intended for native interfaces in general and so is a good place for questions about L<Alien>
+generally or L<Alien::Base> specifically.
+
+=item mailing list
+
+The C<perl5-alien> google group is intended for L<Alien> issues generally, including L<Alien::Base>.
+
+L<https://groups.google.com/forum/#!forum/perl5-alien>
+
+=item Open a support ticket
+
+If you have an issue with L<Alie::Base> itself, then please open a support ticket on the
+project's GitHub issue tracker.
+
+L<https://github.com/Perl5-Alien/Alien-Base/issues>
+
+=back
+ 
+=head1 SEE ALSO
+
+=over
+
+=item * 
+
+L<Alien::Base>
+
+=item *
+
+L<Alien::Base::ModuleBuild>
+
+=item *
+
+L<Alien::Base::ModuleBuild::API>
+
+=back
+
+=head1 AUTHOR
+
+Original author: Joel Berger, E<lt>joel.a.berger at gmail.comE<gt>
+
+Current maintainer: Graham Ollis E<lt>plicease at cpan.orgE<gt> and the L<Alien::Base> team
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2012-2015 by Joel Berger
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
diff --git a/lib/Alien/Base/ModuleBuild.pm b/lib/Alien/Base/ModuleBuild.pm
new file mode 100644
index 0000000..9786143
--- /dev/null
+++ b/lib/Alien/Base/ModuleBuild.pm
@@ -0,0 +1,1381 @@
+package Alien::Base::ModuleBuild;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.028';
+$VERSION = eval $VERSION;
+
+use parent 'Module::Build';
+
+use Capture::Tiny 0.17 qw/capture tee/;
+use File::chdir;
+use File::Spec;
+use File::Basename qw/fileparse/;
+use Carp;
+no warnings;
+use Archive::Extract;
+use warnings;
+use Sort::Versions;
+use List::MoreUtils qw/uniq first_index/;
+use ExtUtils::Installed;
+use File::Copy qw/move/;
+use Env qw( @PATH );
+use Shell::Guess;
+use Shell::Config::Generate;
+use File::Path qw/mkpath/;
+use Config;
+use Text::ParseWords qw( shellwords );
+
+use Alien::Base::PkgConfig;
+use Alien::Base::ModuleBuild::Cabinet;
+use Alien::Base::ModuleBuild::Repository;
+
+use Alien::Base::ModuleBuild::Repository::HTTP;
+use Alien::Base::ModuleBuild::Repository::FTP;
+use Alien::Base::ModuleBuild::Repository::Local;
+
+# setup protocol specific classes
+# Alien:: author can override these defaults using alien_repository_class property
+my %default_repository_class = (
+  default => 'Alien::Base::ModuleBuild::Repository',
+  http    => 'Alien::Base::ModuleBuild::Repository::HTTP',
+  https   => 'Alien::Base::ModuleBuild::Repository::HTTP',
+  ftp     => 'Alien::Base::ModuleBuild::Repository::FTP',
+  local   => 'Alien::Base::ModuleBuild::Repository::Local',
+);
+
+our $Verbose;
+$Verbose = $ENV{ALIEN_VERBOSE} if defined $ENV{ALIEN_VERBOSE};
+
+our $Force;
+$Force = $ENV{ALIEN_FORCE} if defined $ENV{ALIEN_FORCE};
+$Force = 1 if defined $ENV{ALIEN_INSTALL_TYPE} && $ENV{ALIEN_INSTALL_TYPE} eq 'share';
+
+our $ForceSystem;
+$ForceSystem = 1 if defined $ENV{ALIEN_INSTALL_TYPE} && $ENV{ALIEN_INSTALL_TYPE} eq 'system';
+
+################
+#  Parameters  #
+################
+
+## Extra parameters in A::B::MB objects (all (toplevel) should start with 'alien_')
+
+# alien_name: name of library (pkg-config)
+__PACKAGE__->add_property('alien_name');
+
+# alien_ffi_name: name of library (the "foo" in libfoo)
+__PACKAGE__->add_property('alien_ffi_name');
+
+# alien_temp_dir: folder name for download/build
+__PACKAGE__->add_property( alien_temp_dir => '_alien' );
+
+# alien_share_dir: folder name for the "install" of the library
+# this is added (unshifted) to the @{share_dir->{dist}}  
+# N.B. is reset during constructor to be full folder name 
+__PACKAGE__->add_property('alien_share_dir' => '_share' );
+
+# alien_selection_method: name of method for selecting file: (todo: newest, manual)
+#   default is specified later, when this is undef (see alien_check_installed_version)
+__PACKAGE__->add_property( alien_selection_method => 'newest' );
+
+# alien_build_commands: arrayref of commands for building
+__PACKAGE__->add_property( 
+  alien_build_commands => 
+  default => [ '%c --prefix=%s', 'make' ],
+);
+
+# alien_test_commands: arrayref of commands for testing the library
+# note that this might be better tacked onto the build-time commands
+__PACKAGE__->add_property( 
+  alien_test_commands => 
+  default => [ ],
+);
+
+# alien_build_commands: arrayref of commands for installing the library
+__PACKAGE__->add_property( 
+  alien_install_commands => 
+  default => [ 'make install' ],
+);
+
+# alien_version_check: command to execute to check if install/version
+__PACKAGE__->add_property( alien_version_check => '%{pkg_config} --modversion %n' );
+
+# pkgconfig-esque info, author provides these by hand for now, will parse .pc file eventually
+__PACKAGE__->add_property( 'alien_provides_cflags' );
+__PACKAGE__->add_property( 'alien_provides_libs' );
+
+# alien_repository: hash (or arrayref of hashes) of information about source repo on ftp
+#   |-- protocol: ftp or http
+#   |-- protocol_class: holder for class type (defaults to 'Net::FTP' or 'HTTP::Tiny')
+#   |-- host: ftp server for source
+#   |-- location: ftp folder containing source, http addr to page with links
+#   |-- pattern: qr regex matching acceptable files, if has capture group those are version numbers
+#   |-- platform: src or platform, matching os_type M::B method
+#   |
+#   |-- (non-api) connection: holder for Net::FTP-like object (needs cwd, ls, and get methods)
+__PACKAGE__->add_property( 'alien_repository'         => [] );
+__PACKAGE__->add_property( 'alien_repository_default' => {} );
+__PACKAGE__->add_property( 'alien_repository_class'   => {} );
+
+# alien_isolate_dynamic
+__PACKAGE__->add_property( 'alien_isolate_dynamic' => 0 );
+__PACKAGE__->add_property( 'alien_autoconf_with_pic' => 1 );
+
+# alien_inline_auto_include
+__PACKAGE__->add_property( 'alien_inline_auto_include' => [] );
+
+# use MSYS even if %c isn't found
+__PACKAGE__->add_property( 'alien_msys' => 0 );
+
+# Alien packages that provide build dependencies
+__PACKAGE__->add_property( 'alien_bin_requires' => {} );
+
+# Do a staged install to blib instead of trying to install to the final location.
+__PACKAGE__->add_property( 'alien_stage_install' => 1 );
+
+# Should modules be installed into arch specific directory?
+# Most alien dists will have arch specific files in their share so it makes sense to install
+# the module in the arch specific location.  If you are alienizing something that isn't arch
+# specific, like javascript source or java byte code, then you'd want to set this to 0.
+# For now this will default to off.  See gh#119 for a discussion.
+__PACKAGE__->add_property( 'alien_arch' => defined $ENV{ALIEN_ARCH} ? $ENV{ALIEN_ARCH} : 0 );
+
+__PACKAGE__->add_property( 'alien_helper' => {} );
+
+__PACKAGE__->add_property( 'alien_env' => {} );
+
+################
+#  ConfigData  #
+################
+
+# working_directory: full path to the extracted source or binary of the library
+# pkgconfig: hashref of A::B::PkgConfig objects created from .pc file found in working_directory
+# install_type: either system or share
+# version: version number installed or available
+# Cflags: holder for cflags if manually specified
+# Libs:   same but libs
+# name: holder for name as needed by pkg-config
+# finished_installing: set to true once ACTION_install is finished, this helps testing now and real checks later
+
+############################
+#  Initialization Methods  #
+############################
+
+sub new {
+  my $class = shift;
+  my %args = @_;
+
+  # merge default and user-defined repository classes
+  $args{alien_repository_class}{$_} ||= $default_repository_class{$_} 
+    for keys %default_repository_class;
+
+  my $self = $class->SUPER::new(%args);
+
+  $self->alien_helper->{pkg_config} = 'Alien::Base::PkgConfig->pkg_config_command'
+    unless defined $self->alien_helper->{pkg_config};
+
+  # setup additional temporary directories, and yes we have to add File::ShareDir manually
+  $self->_add_prereq( 'requires', 'File::ShareDir', '1.00' );
+
+  # this just gets passed from the Build.PL to the config so that it can
+  # be used by the auto_include method
+  $self->config_data( 'inline_auto_include' => $self->alien_inline_auto_include );
+
+  if($Force || !$self->alien_check_installed_version) {
+    if (grep /(?<!\%)\%c/, map { ref($_) ? @{$_} : $_ } @{ $self->alien_build_commands }) {
+      $self->config_data( 'autoconf' => 1 );
+    }
+
+    if ($^O eq 'MSWin32' && ($self->config_data( 'autoconf') || $self->alien_msys)) {
+      $self->_add_prereq( 'build_requires', 'Alien::MSYS', '0' );
+      $self->config_data( 'msys' => 1 );
+    } else {
+      $self->config_data( 'msys' => 0 );
+    }
+  
+    foreach my $tool (keys %{ $self->alien_bin_requires  }) {
+      my $version = $self->alien_bin_requires->{$tool};
+      if($tool eq 'Alien::CMake' && $version < 0.07) {
+        $version = '0.07';
+      }
+      $self->_add_prereq( 'build_requires', $tool, $version );
+    }
+  }
+
+
+  # force newest for all automated testing 
+  #TODO (this probably should be checked for "input needed" rather than blindly assigned)
+  if ($ENV{AUTOMATED_TESTING}) {
+    $self->alien_selection_method('newest');
+  }
+
+  $self->config_data( 'finished_installing' => 0 );
+
+  if(grep /(?<!\%)\%p/, map { ref($_) ? @{$_} : $_ } @{ $self->alien_build_commands }) {
+    carp "%p is deprecated, See https://metacpan.org/pod/distribution/Alien-Base/lib/Alien/Base/ModuleBuild/API.pod#p";
+  }
+
+  return $self;
+}
+
+sub alien_init_temp_dir {
+  my $self = shift;
+  my $temp_dir = $self->alien_temp_dir;
+  my $share_dir = $self->alien_share_dir;
+
+  # make sure we are in base_dir
+  local $CWD = $self->base_dir;
+
+  unless ( -d $temp_dir ) {
+    mkdir $temp_dir or croak "Could not create temporary directory $temp_dir";
+  }
+  $self->add_to_cleanup( $temp_dir );
+
+  unless ( -d $share_dir ) {
+    mkdir $share_dir or croak "Could not create temporary directory $share_dir";
+  }
+  $self->add_to_cleanup( $share_dir );
+
+  # add share dir to share dir list
+  my $share_dirs = $self->share_dir;
+  unshift @{ $share_dirs->{dist} }, $share_dir;
+  $self->share_dir( $share_dirs );
+  {
+    local $CWD = $share_dir;
+    open my $fh, '>', 'README' or die "Could not open README for writing (in directory $share_dir)\n";
+    print $fh <<'END';
+This README file is autogenerated by Alien::Base. 
+
+Currently it exists for testing purposes, but it might eventually contain information about the file(s) installed.
+END
+  }
+}
+
+####################
+#  ACTION methods  #
+####################
+
+sub ACTION_alien_fakebuild {
+  my $self = shift;
+
+  # needed for any helpers provided by alien_bin_requires
+  $self->_alien_bin_require($_) for keys %{ $self->alien_bin_requires };
+
+  print "# Build\n";
+  foreach my $cmd (@{ $self->alien_build_commands })
+  {
+    my @cmd = map { $self->alien_interpolate($_) } ref($cmd) ? @$cmd : ($cmd);
+    print "+ @cmd\n";
+  }
+  print "# Build install\n";
+  foreach my $cmd (@{ $self->alien_install_commands })
+  {
+    my @cmd = map { $self->alien_interpolate($_) } ref($cmd) ? @$cmd : ($cmd);
+    print "+ @cmd\n";
+  }
+}
+
+sub ACTION_code {
+  my $self = shift;
+  $self->notes( 'alien_blib_scheme' => $self->alien_detect_blib_scheme );
+
+  # PLEASE NOTE, BOTH BRANCHES CALL SUPER::ACTION_code !!!!!!!
+  if ( $self->notes('ACTION_alien_completed') ) {
+
+    $self->SUPER::ACTION_code;
+
+  } else {
+
+    $self->depends_on('alien_code');
+    $self->SUPER::ACTION_code;
+  }
+  
+  my $module = $self->module_name;
+  my $file   = File::Spec->catfile($self->blib, 'lib', split /::/, "$module\::Install::Files.pm");
+  unless (-e $file) {
+    mkpath(File::Spec->catdir($self->blib, 'lib', split /::/, "$module\::Install"), { verbose => 0 });
+    open my $fh, '>', $file;
+    print $fh <<EOF;
+package $module\::Install::Files;
+require $module;
+sub Inline { shift; $module->Inline(\@_) }
+1;
+
+=begin Pod::Coverage
+
+  Inline
+
+=end Pod::Coverage
+
+=cut
+EOF
+    close $fh;
+  }
+  
+  if($self->alien_arch) {
+    my @parts = split /::/, $module;
+    my $arch_dir = File::Spec->catdir($self->blib, 'arch', 'auto', @parts);
+    File::Path::mkpath($arch_dir, 0, oct(777)) unless -d $arch_dir;
+    open my $fh, '>', File::Spec->catfile($arch_dir, $parts[-1].".txt");
+    print $fh "Alien based distribution with architecture specific file in share\n";
+    close $fh;
+  }
+
+  $self->depends_on('alien_install') if $self->alien_stage_install;
+}
+
+sub process_share_dir_files {
+  my $self = shift;
+  $self->SUPER::process_share_dir_files(@_);
+  
+  # copy the compiled files into blib if running under blib scheme
+  $self->depends_on('alien_install') if $self->notes('alien_blib_scheme') || $self->alien_stage_install;
+}
+
+sub alien_extract_archive {
+  my ($self, $archive) = @_;
+  print "Extracting Archive ... ";
+  my $ae = Archive::Extract->new( archive => $archive );
+  $ae->extract or croak "Archive extraction failed!";
+  print "Done\n";
+  return $ae->extract_path;
+}
+
+sub ACTION_alien_code {
+  my $self = shift;
+  local $| = 1; # don't buffer stdout
+
+  $self->alien_init_temp_dir;
+
+  $self->config_data( name => $self->alien_name );
+  $self->config_data( ffi_name => $self->alien_ffi_name );
+
+  my $version;
+  $version = $self->alien_check_installed_version
+    unless $Force;
+
+  if ($version) {
+    $self->config_data( install_type => 'system' );
+    $self->config_data( version => $version );
+    my %system_provides;
+    $system_provides{Cflags} = $self->alien_provides_cflags
+      if defined $self->alien_provides_cflags;
+    $system_provides{Libs}   = $self->alien_provides_libs
+      if defined $self->alien_provides_libs;
+    $self->config_data( system_provides => \%system_provides );
+    return;
+  }
+  
+  if ($ForceSystem) {
+    die "Requested system install, but system package not detected."
+  }
+
+  my @repos = $self->alien_create_repositories;
+
+  my $cabinet = Alien::Base::ModuleBuild::Cabinet->new;
+
+  foreach my $repo (@repos) {
+    $cabinet->add_files( $repo->probe() );
+  }
+
+  $cabinet->sort_files;
+
+  {
+    local $CWD = $self->alien_temp_dir;
+
+    my $file = $cabinet->files->[0];
+    $version = $file->version;
+    $self->config_data( alien_version => $version ); # Temporary setting, may be overridden later
+
+    print "Downloading File: " . $file->filename . " ... ";
+    my $filename = $file->get;
+    croak "Error downloading file" unless $filename;
+    print "Done\n";
+
+    my $extract_path = _catdir(File::Spec->rel2abs($self->alien_extract_archive($filename)));
+
+    $self->config_data( working_directory => $extract_path );
+    $CWD = $extract_path;
+
+    if ( $file->platform eq 'src' ) {
+      print "Building library ... ";
+      unless ($self->alien_do_commands('build')) {
+        print "Failed\n";
+        croak "Build not completed";
+      }
+    }
+
+    print "Done\n";
+
+  }
+
+  $self->config_data( install_type => 'share' );
+  $self->config_data( original_prefix => $self->alien_library_destination );
+
+  my $pc = $self->alien_load_pkgconfig;
+  my $pc_version = (
+    $pc->{$self->alien_name} || $pc->{_manual}
+  )->keyword('Version');
+
+  unless (defined $version) {
+    local $CWD = $self->config_data( 'working_directory' );
+    $version = $self->alien_check_built_version
+  }
+
+  if (! $version and ! $pc_version) {
+    print STDERR "If you are the author of this Alien dist, you may need to provide a an\n";
+    print STDERR "alien_check_built_version method for your Alien::Base::ModuleBuild\n";
+    print STDERR "class.  See:\n";
+    print STDERR "https://metacpan.org/pod/Alien::Base::ModuleBuild#alien_check_built_version\n";
+    carp "Library looks like it installed, but no version was determined";
+    $self->config_data( version => 0 );    
+    return
+  }
+
+  if ( $version and $pc_version and versioncmp($version, $pc_version)) {
+    carp "Version information extracted from the file name and pkgconfig data disagree";
+  } 
+
+  $self->config_data( version => $pc_version || $version );
+
+  # prevent building multiple times (on M::B::dispatch)
+  $self->notes( 'ACTION_alien_completed' => 1 );
+
+  return;
+}
+
+sub ACTION_test {
+  my $self = shift;
+  $self->SUPER::ACTION_test;
+
+  print "Testing library (if applicable) ... ";
+  if ($self->config_data( 'install_type' ) eq 'share') {
+    if (defined (my $wdir = $self->config_data( 'working_directory' ))) {
+      local $CWD = $wdir;
+      $self->alien_do_commands('test') or die "Failed\n";
+    }
+  }
+  print "Done\n";
+}
+
+sub ACTION_install {
+  my $self = shift;
+  $self->SUPER::ACTION_install;
+  if($self->alien_stage_install) {
+    $self->alien_relocation_fixup;
+  } else {
+    $self->depends_on('alien_install');
+  }
+}
+
+sub ACTION_alien_install {
+  my $self = shift;
+
+  local $| = 1; # don't buffer stdout
+
+  return if $self->config_data( 'install_type' ) eq 'system';
+
+  my $destdir = $self->destdir;
+  my $target = $self->alien_library_destination;
+  
+  if(defined $destdir && !$self->alien_stage_install)
+  {
+    # Note: no longer necessary when doing a staged install
+    # prefix the target directory with $destdir so that package builds
+    # can install into a fake root
+    $target = File::Spec->catdir($destdir, $target);
+  }
+
+  {
+    local $CWD = $target;
+
+    # The only form of introspection that exists is to see that the README file
+    # which was placed in the share_dir (default _share) exists where we expect 
+    # after installation.
+    unless ( -e 'README' ) {
+      die "share_dir mismatch detected ($target)\n"
+    }
+  }
+
+  if(!$self->config_data( 'finished_installing' ))
+  {
+    local $CWD = $self->config_data( 'working_directory' );
+    local $ENV{DESTDIR} = $ENV{DESTDIR};
+    $ENV{DESTDIR} = $destdir if defined $destdir && !$self->alien_stage_install;
+    print "Installing library to $CWD ... ";
+    $self->alien_do_commands('install') or die "Failed\n";
+    print "Done\n";
+  }
+  
+  if ( $self->alien_isolate_dynamic ) {
+    local $CWD = $target;
+    print "Isolating dynamic libraries ... ";
+    mkdir 'dynamic' unless -d 'dynamic';
+    foreach my $dir (qw( bin lib )) {
+      next unless -d $dir;
+      opendir(my $dh, $dir);
+      my @dlls = grep { /\.so/ || /\.(dylib|bundle|la|dll|dll\.a)$/ } grep !/^\./, readdir $dh;
+      closedir $dh;
+      foreach my $dll (@dlls) {
+        my $from = File::Spec->catfile($dir, $dll);
+        my $to   = File::Spec->catfile('dynamic', $dll);
+        unlink $to if -e $to;
+        move($from, $to);
+      }
+    }
+    print "Done\n";
+  }
+
+  # refresh metadata after library installation
+  $self->alien_refresh_manual_pkgconfig( $self->alien_library_destination );
+  $self->config_data( 'finished_installing' => 1 );
+
+  if ( $self->notes( 'alien_blib_scheme') || $self->alien_stage_install) {
+  
+    ### TODO: empty if should be claned up before 0.017.
+    ### we used to call process_files_by_extension('pm')
+    ### here, but with gh#121 it is unecessary
+    ## reinstall config_data to blib
+    #$self->process_files_by_extension('pm');
+
+  } else {
+
+    # to refresh config_data
+    $self->SUPER::ACTION_config_data;
+
+    # reinstall config_data
+    $self->SUPER::ACTION_install;
+
+    # refresh the packlist
+    $self->alien_refresh_packlist( $self->alien_library_destination );
+  }
+}
+
+#######################
+#  Pre-build Methods  #
+#######################
+
+sub alien_check_installed_version {
+  my $self = shift;
+  my $command = $self->alien_version_check;
+
+  my %result = $self->do_system($command, {verbose => 0});
+  my $version = ($result{success} && $result{stdout}) || 0;
+
+  return $version;
+}
+
+sub alien_create_repositories {
+  my $self = shift;
+
+  ## get repository specs
+  my $repo_default = $self->alien_repository_default;
+  my $repo_specs = $self->alien_repository;
+
+  # upconvert to arrayref if a single hashref is passed
+  if (ref $repo_specs eq 'HASH') {
+    $repo_specs = [ $repo_specs ];
+  }
+  
+  unless(@$repo_specs)
+  {
+    print STDERR "If you are the author of this Alien dist, you need to provide at least\n";
+    print STDERR "one repository in your Build.PL.  See:\n";
+    print STDERR "https://metacpan.org/pod/distribution/Alien-Base/lib/Alien/Base/ModuleBuild/API.pod#alien_repository\n";
+    croak "No repositories specified.";
+  }
+
+  my @repos;
+  foreach my $repo ( @$repo_specs ) {
+    #merge defaults into spec
+    foreach my $key ( keys %$repo_default ) {
+      next if defined $repo->{$key};
+      $repo->{$key} = $repo_default->{$key};
+    }
+
+    $repo->{platform} = 'src' unless defined $repo->{platform};
+    my $protocol = $repo->{protocol} || 'default';
+
+    push @repos, $self->alien_repository_class($protocol)->new( $repo );
+  }
+
+  # check validation, including c compiler for src type
+  @repos = 
+    grep { $self->alien_validate_repo($_) }
+    @repos;
+
+  unless (@repos) {
+    croak "No valid repositories available";
+  }
+
+  return @repos;
+
+}
+
+sub alien_validate_repo {
+  my $self = shift;
+  my ($repo) = @_;
+  my $platform = $repo->{platform};
+
+  # return true if platform is undefined
+  return 1 unless defined $platform;
+
+  # if $valid is src, check for c compiler
+  if ($platform eq 'src') {
+    return !$repo->{c_compiler_required} || $self->have_c_compiler;
+  }
+
+  # $valid is a string (OS) to match against
+  return $self->os_type eq $platform;
+}
+
+sub alien_library_destination {
+  my $self = shift;
+
+  # send the library into the blib if running under the blib scheme
+  my $lib_dir = 
+    $self->notes('alien_blib_scheme') || $self->alien_stage_install
+    ? File::Spec->catdir( $self->base_dir, $self->blib, 'lib' )
+    : $self->install_destination($self->alien_arch ? 'arch' : 'lib');
+
+  my $dist_name = $self->dist_name;
+  my $dest = _catdir( $lib_dir, qw/auto share dist/, $dist_name );
+  return $dest;
+}
+
+# CPAN testers often run tests without installing modules, but rather add
+# blib dirs to @INC, this is a problem, so here we try to deal with it
+sub alien_detect_blib_scheme {
+  my $self = shift;
+
+  return 0 if $self->alien_stage_install;
+  return $ENV{ALIEN_BLIB} if defined $ENV{ALIEN_BLIB};
+
+  # check to see if Alien::Base::ModuleBuild is running from blib.
+  # if so it is likely that this is the blib scheme
+
+  (undef, my $dir, undef) = File::Spec->splitpath( __FILE__ );
+  my @dirs = File::Spec->splitdir($dir);
+
+  my $index = first_index { $_ eq 'blib' } @dirs;
+  return 0 if $index == -1;
+
+  if ( $dirs[$index+1] eq 'lib' ) {
+    print qq{'blib' scheme is detected. Setting ALIEN_BLIB=1. If this has been done in error, please set ALIEN_BLIB and restart build process to disambiguate.\n};
+    return 1;
+  }
+
+  carp q{'blib' scheme is suspected, but uncertain. Please set ALIEN_BLIB and restart build process to disambiguate. Setting ALIEN_BLIB=1 for now.};
+  return 1;
+}
+
+###################
+#  Build Methods  #
+###################
+
+sub _shell_config_generate
+{
+  my $scg = Shell::Config::Generate->new;
+  $scg->comment(
+    'this script sets the environment needed to build this package.',
+    'generated by: ' . __FILE__,
+  );
+  $scg;
+}
+
+sub _filter_defines
+{
+  join ' ', grep !/^-D/, shellwords($_[0]);
+}
+
+sub _alien_bin_require {
+  my($self, $mod) = @_;
+  
+  my $version = $self->alien_bin_requires->{$mod};
+
+  eval qq{ use $mod $version () }; # should also work for version = 0
+  die $@ if $@;
+  
+  if($mod->can('alien_helper')) {
+    my $helpers = $mod->alien_helper;
+    while(my($k,$v) = each %$helpers) {
+      next if defined $self->alien_helper->{$k};
+      $self->alien_helper->{$k} = $v;
+    }
+  }
+}
+
+sub alien_do_system {
+  my $self = shift;
+  my $command = shift;
+  
+  local %ENV = %ENV;
+  
+  if ($self->config_data( 'msys' )) {
+    $self->alien_bin_requires->{'Alien::MSYS'} ||= 0
+  }
+  
+  my $config;
+  
+  foreach my $mod (keys %{ $self->alien_bin_requires }) {
+    $self->_alien_bin_require($mod);
+    
+    my %path;
+    
+    if ($mod eq 'Alien::MSYS') {
+      $path{Alien::MSYS->msys_path} = 1;
+    } elsif ($mod eq 'Alien::TinyCC') {
+      $path{Alien::TinyCC->path_to_tcc} = 1;
+    } elsif ($mod eq 'Alien::Autotools') {
+      $path{$_} = 1 for map { Alien::Autotools->$_ } qw( autoconf_dir automake_dir libtool_dir );
+    } elsif (eval { $mod->can('bin_dir') }) {
+      $path{$_} = 1 for $mod->bin_dir;
+    }
+    
+    # remove anything already in PATH
+    delete $path{$_} for @PATH;
+    # add anything else to start of PATH
+    unshift @PATH, sort keys %path;
+
+    $config ||= _shell_config_generate();
+    $config->prepend_path( PATH => sort keys %path );
+  }
+
+  # If we are using autoconf, then create a site.config file
+  # that specifies the same compiler and compiler linker flags
+  # as were used for building Perl.  This is helpful for
+  # mixed 32/64bit platforms where 32bit is the default but
+  # Perl is 64bit.
+  if($self->config_data('autoconf') && !defined $ENV{CONFIG_SITE}) {
+  
+    local $CWD;
+    pop @CWD;
+    
+    my $ldflags = $Config{ldflags};
+    $ldflags .= " -Wl,-headerpad_max_install_names"
+      if $^O eq 'darwin';
+    
+    open my $fh, '>', 'config.site';
+    print $fh "CC='$Config{cc}'\n";
+    # -D define flags should be stripped because they are Perl
+    # specific.
+    print $fh "CFLAGS='", _filter_defines($Config{ccflags}), "'\n";
+    print $fh "CPPFLAGS='", _filter_defines($Config{cppflags}), "'\n";
+    print $fh "CXXFLAGS='", _filter_defines($Config{ccflags}), "'\n";
+    print $fh "LDFLAGS='$ldflags'\n";
+    close $fh;
+  
+    my $config ||= _shell_config_generate();
+    my $config_site = File::Spec->catfile($CWD, 'config.site');
+    $config_site =~ s{\\}{/}g if $^O eq 'MSWin32';
+    $config->set( CONFIG_SITE => $config_site );
+    $ENV{CONFIG_SITE} = $config_site;
+  }
+  
+  foreach my $key (sort keys %{ $self->alien_env })
+  {
+    my $value = $self->alien_interpolate($self->alien_env->{$key});
+    defined $value ? $ENV{$key} = $value : delete $ENV{$key};
+    $config ||= _shell_config_generate();
+    $config->set( $key => $value );
+  }
+
+  if($config) {  
+    if($^O eq 'MSWin32') {
+      local $CWD;
+      pop @CWD;
+      $config->generate_file( Shell::Guess->command_shell, 'env.bat' );
+      $config->generate_file( Shell::Guess->cmd_shell,     'env.cmd' );
+      $config->generate_file( Shell::Guess->power_shell,   'env.ps1' );
+    } else {
+      local $CWD;
+      pop @CWD;
+      $config->generate_file( Shell::Guess->bourne_shell,  'env.sh'  );
+      $config->generate_file( Shell::Guess->c_shell,       'env.csh' );
+    }
+  }
+
+  $self->do_system( ref($command) ? @$command : $command );
+}
+
+# alias for backwards compatibility
+*_env_do_system = \&alien_do_system;
+
+sub alien_check_built_version {
+  return;
+}
+
+sub alien_do_commands {
+  my $self = shift;
+  my $phase = shift;
+
+  my $attr = "alien_${phase}_commands";
+  my $commands = $self->$attr();
+
+  print "\n+ cd $CWD\n";
+
+  foreach my $command (@$commands) {
+
+    my %result = $self->alien_do_system( $command );
+    unless ($result{success}) {
+      carp "External command ($result{command}) failed! Error: $?\n";
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+# wrapper for M::B::do_system which interpolates alien_ vars first
+# futher it either captures or tees depending on the value of $Verbose
+sub do_system {
+  my $self = shift;
+  my $opts = ref $_[-1] ? pop : { verbose => 1 };
+
+  my $verbose = $Verbose || $opts->{verbose};
+
+  # prevent build process from cwd-ing from underneath us
+  local $CWD;
+  my $initial_cwd = $CWD;
+
+  my @args = map { $self->alien_interpolate($_) } @_;
+
+  print "+ @args\n";
+
+  my $old_super_verbose = $self->verbose;
+  $self->verbose(0);
+  my ($out, $err, $success) = 
+    $verbose
+    ? tee     { $self->SUPER::do_system(@args) }
+    : capture { $self->SUPER::do_system(@args) }
+  ;
+  $self->verbose($old_super_verbose);
+
+  my %return = (
+    stdout => $out,
+    stderr => $err,
+    success => $success,
+    command => join(' ', @args),
+  );
+
+  # restore wd
+  $CWD = $initial_cwd;
+
+  return wantarray ? %return : $return{success};
+}
+
+sub _alien_execute_helper {
+  my($self, $helper) = @_;
+  my $code = $self->alien_helper->{$helper};
+  die "no such helper: $helper" unless defined $code;
+
+  if(ref($code) ne 'CODE') {
+    my $perl = $code;
+    $code = sub {
+      my $value = eval $perl;
+      die $@ if $@;
+      $value;
+    };
+  }
+
+  $code->();
+}
+
+sub alien_interpolate {
+  my $self = shift;
+  my ($string) = @_;
+
+  my $prefix = $self->alien_exec_prefix;
+  my $configure = $self->alien_configure;
+  my $share  = $self->alien_library_destination;
+  my $name   = $self->alien_name || '';
+
+  # substitute:
+  #   install location share_dir (placeholder: %s)
+  $string =~ s/(?<!\%)\%s/$share/g;
+  #   local exec prefix (ph: %p)
+  $string =~ s/(?<!\%)\%p/$prefix/g;
+  #   correct incantation for configure on platform
+  $string =~ s/(?<!\%)\%c/$configure/g;
+  #   library name (ph: %n)
+  $string =~ s/(?<!\%)\%n/$name/g;
+  #   current interpreter ($^X) (ph: %x)
+  my $perl = $self->perl;
+  $string =~ s/(?<!\%)\%x/$perl/g;
+  $perl =~ s{\\}{/}g if $^O eq 'MSWin32';
+  $string =~ s/(?<!\%)\%X/$perl/g;
+
+  # Version, but only if needed.  Complain if needed and not yet
+  # stored.
+  if ($string =~ /(?<!\%)\%v/) {
+    my $version = $self->config_data( 'alien_version' );
+    if ( ! defined( $version ) ) {
+      carp "Version substution requested but unable to identify";
+    } else {
+      $string =~ s/(?<!\%)\%v/$version/g;
+    }
+  }
+
+  $string =~ s/(?<!\%)\%\{([a-zA-Z_][a-zA-Z_0-9]+)\}/$self->_alien_execute_helper($1)/eg;
+
+  #remove escapes (%%)
+  $string =~ s/\%(?=\%)//g;
+
+  return $string;
+}
+
+sub alien_exec_prefix {
+  my $self = shift;
+  if ( $self->is_windowsish ) {
+    return '';
+  } else {
+    return './';
+  }
+}
+
+sub alien_configure {
+  my $self = shift;
+  my $configure;
+  if ($self->config_data( 'msys' )) {
+    $configure = 'sh configure';
+  } else {
+    $configure = './configure';
+  }
+  if ($self->alien_autoconf_with_pic) {
+    $configure .= ' --with-pic';
+  }
+  $configure;
+}
+
+########################
+#  Post-Build Methods  #
+########################
+
+sub alien_load_pkgconfig {
+  my $self = shift;
+
+  my $dir = _catdir($self->config_data( 'working_directory' ));
+  my $pc_files = $self->rscan_dir( $dir, qr/\.pc$/ );
+
+  my %pc_objects = map { 
+    my $pc = Alien::Base::PkgConfig->new($_);
+    $pc->make_abstract( pcfiledir => $dir );
+    ($pc->{package}, $pc)
+  } @$pc_files;
+
+  $pc_objects{_manual} = $self->alien_generate_manual_pkgconfig($dir)
+    or croak "Could not autogenerate pkgconfig information";
+
+  $self->config_data( pkgconfig => \%pc_objects );
+  return \%pc_objects;
+}
+
+sub alien_refresh_manual_pkgconfig {
+  my $self = shift;
+  my ($dir) = @_;
+
+  my $pc_objects = $self->config_data( 'pkgconfig' );
+  $pc_objects->{_manual} = $self->alien_generate_manual_pkgconfig($dir)
+    or croak "Could not autogenerate pkgconfig information";
+  
+  $self->config_data( pkgconfig => $pc_objects );
+
+  return 1;
+}
+
+sub alien_generate_manual_pkgconfig {
+  my $self = shift;
+  my ($dir) = _catdir(shift);
+
+  my $paths = $self->alien_find_lib_paths($dir);
+
+  my @L = 
+    map { "-L$_" }
+    map { _catdir( '${pcfiledir}', $_ ) }
+    @{$paths->{lib}};
+
+  my $provides_libs = $self->alien_provides_libs;
+
+  #if no provides_libs then generate -l list from found files
+  unless ($provides_libs) {
+    my @files = map { "-l$_" } @{$paths->{lib_files}};
+    $provides_libs = join( ' ', @files );
+  } 
+
+  my $libs = join( ' ', @L, $provides_libs );
+
+  my @I = 
+    map { "-I$_" }
+    map { _catdir( '${pcfiledir}', $_ ) }
+    @{$paths->{inc}};
+
+  my $provides_cflags = $self->alien_provides_cflags;
+  push @I, $provides_cflags if $provides_cflags;
+  my $cflags = join( ' ', @I );
+
+  my $manual_pc = Alien::Base::PkgConfig->new({
+    package  => $self->alien_name,
+    vars     => {
+      pcfiledir => $dir,
+    },
+    keywords => {
+      Cflags  => $cflags || '',
+      Libs    => $libs || '',
+      Version => '',
+    },
+  });
+
+  return $manual_pc;
+}
+
+sub _alien_file_pattern_dynamic {
+  my $self = shift;
+  my $ext = $self->config('so'); #platform specific .so extension
+  return qr/\.[\d.]*(?<=\.)$ext[\d.]*(?<!\.)|(\.h|$ext)$/;
+};
+
+sub _alien_file_pattern_static {
+  my $self = shift;
+  my $ext = quotemeta $self->config('lib_ext');
+  return qr/(\.h|$ext)$/;
+}
+
+sub alien_find_lib_paths {
+  my $self = shift;
+  my ($dir) = @_;
+
+  my $libs = $self->alien_provides_libs;
+  my @libs;
+  @libs = grep { s/^-l// } split /\s+/, $libs if $libs;
+
+  my (@lib_files, @lib_paths, @inc_paths);
+
+  foreach my $file_pattern ($self->_alien_file_pattern_static, $self->_alien_file_pattern_dynamic) {
+
+    my @files =     
+      map { File::Spec->abs2rel( $_, $dir ) }  # make relative to $dir
+      grep { ! -d }
+      @{ $self->_rscan_destdir( $dir, $file_pattern ) };
+
+    for (@files) {
+
+      my ($file, $path, $ext) = fileparse( $_, $file_pattern );
+      next unless $ext; # just in case
+
+      $path = File::Spec->catdir($path); # remove trailing /
+
+      if ($ext eq '.h') {
+        push @inc_paths, $path;
+        next;
+      }
+
+      $file =~ s/^lib//;
+      
+      if (@libs) {
+        next unless grep { $file eq $_ } @libs;
+      }
+      
+      next if grep { $file eq $_ } @lib_files;
+
+      push @lib_files, $file;
+      push @lib_paths, $path;
+    }
+  }
+
+  @lib_files = uniq @lib_files;
+  @lib_files = sort @lib_files;
+
+  @lib_paths = uniq @lib_paths;
+  @inc_paths = uniq @inc_paths;
+
+  return { lib => \@lib_paths, inc => \@inc_paths, lib_files => \@lib_files };
+}
+
+sub alien_refresh_packlist {
+  my $self = shift;
+  my $dir = shift || croak "Must specify a directory to include in packlist";
+
+  return unless $self->create_packlist;
+
+  my %installed_args;
+  $installed_args{extra_libs} = [map { File::Spec->catdir($self->destdir, $_) } @INC]
+    if defined $self->destdir;
+
+  my $inst = ExtUtils::Installed->new( %installed_args );
+  my $packlist = $inst->packlist( $self->module_name );
+  print "Using " .  $packlist->packlist_file . "\n";
+
+  my $changed = 0;
+  my $files = $self->_rscan_destdir($dir);
+  # This is kind of strange, but MB puts the destdir paths in the
+  # packfile, when arguably it should not.  Usually you will want 
+  # to turn off packlists when you you are building an rpm anyway,
+  # but for the sake of maximum compat with MB we add the destdir
+  # back in after _rscan_destdir has stripped it out.
+  $files = [ map { File::Spec->catdir($self->destdir, $_) } @$files ]
+    if defined $self->destdir;
+  for my $file (@$files) {
+    next if $packlist->{$file};
+    print "Adding $file to packlist\n"; 
+    $changed++;
+    $packlist->{$file}++;
+  };
+
+  $packlist->write if $changed;
+}
+
+sub alien_relocation_fixup {
+  my($self) = @_;
+  
+  # so far relocation fixup is only needed on OS X
+  return unless $^O eq 'darwin';
+
+  my $dist_name = $self->dist_name;  
+  my $share = _catdir( $self->install_destination($self->alien_arch ? 'arch' : 'lib'), qw/auto share dist/, $dist_name );
+  
+  require File::Find;
+  File::Find::find(sub {
+    if(/\.dylib$/)
+    {
+      # save the original mode and make it writable
+      my $mode = (stat $File::Find::name)[2];
+      chmod 0755, $File::Find::name unless -w $File::Find::name;
+      
+      my @cmd = (
+        'install_name_tool',
+        '-id' => $File::Find::name,
+        $File::Find::name,
+      );
+      print "+ @cmd\n";
+      system @cmd;
+      
+      # restore the original permission mode
+      chmod $mode, $File::Find::name;
+    }
+  }, $share);
+}
+
+sub _rscan_destdir {
+  my($self, $dir, $pattern) = @_;
+  my $destdir = $self->destdir;
+  $dir = _catdir($destdir, $dir) if defined $destdir;
+  my $files = $self->rscan_dir($dir, $pattern);
+  $files = [ map { s/^$destdir//; $_ } @$files ] if defined $destdir;
+  $files;
+}
+
+# File::Spec uses \ as the file separator on MSWin32, which makes sense
+# since it is the default "native" file separator, but in practice / is
+# supported everywhere that matters and is significantly less problematic
+# in a number of common use cases (e.g. shell quoting).  This is a short
+# cut _catdir for this rather common pattern where you want catdir with
+# / as the file separator on Windows.
+sub _catdir {
+  my $dir = File::Spec->catdir(@_);
+  $dir =~ s{\\}{/}g if $^O eq 'MSWin32';
+  $dir;
+}
+
+1;
+
+__END__
+__POD__
+
+=head1 NAME
+
+Alien::Base::ModuleBuild - A Module::Build subclass for building Alien:: modules and their libraries
+
+=head1 SYNOPSIS
+
+In your Build.PL:
+
+ use Alien::Base::ModuleBuild;
+ 
+ my $builder = Alien::Base::ModuleBuild->new(
+   module_name => 'Alien::MyLibrary',
+   
+   configure_requires => {
+     'Alien::Base::ModuleBuild' => '0.005',
+     'Module::Build' => '0.28'
+   },
+   requires => {
+     'Alien::Base' => '0.005',
+   },
+   
+   alien_name => 'mylibrary', # the pkg-config name if you want
+                              # to use pkg-config to discover
+                              # system version of the mylibrary
+   
+   alien_repository => {
+     protocol => 'http',
+     host     => 'myhost.org',
+     location => '/path/to/tarballs',
+     pattern  => qr{^mylibrary-([0-9\.]+)\.tar\.gz$},
+   },
+   
+   # this is the default:
+   alien_build_commands => [
+     "%c --prefix=%s", # %c is a platform independent version of ./configure
+     "make",
+   ],
+   
+   # this is the default for install:
+   alien_install_commands => [
+     "make install",
+   ],
+   
+   alien_isolate_dynamic => 1,
+ );
+
+=head1 DESCRIPTION
+
+This is a subclass of L<Module::Build>, that with L<Alien::Base> allows
+for easy creation of Alien distributions.  This module is used during the
+build step of your distribution.  When properly configured it will
+
+=over 4
+
+=item use pkg-config to find and use the system version of the library
+
+=item download, build and install the library if the system does not provide it
+
+=back
+
+=head1 METHODS
+
+=head2 alien_check_installed_version
+
+ my $version = $abmb->alien_check_installed_version;
+
+This function determines if the library is already installed as part of
+the operating system, and returns the version as a string.  If it can't
+be detected then it should return empty list.
+
+The default implementation relies on C<pkg-config>, but you will probably
+want to override this with your own implementation if the package you are
+building does not use C<pkg-config>.
+
+=head2 alien_check_built_version
+
+ my $version = $amb->alien_check_built_version;
+
+This function determines the version of the library after it has been
+built from source.  This function only gets called if the operating
+system version can not be found and the package is successfully built.
+
+The default implementation relies on C<pkg-config>, and other heuristics,
+but you will probably want to override this with your own implementation
+if the package you are building does not use C<pkg-config>.
+
+When this method is called, the current working directory will be the
+build root.
+
+If you see an error message like this:
+
+ Library looks like it installed, but no version was determined
+
+After the package is built from source code then you probably need to
+provide an implementation for this method.
+
+=head2 alien_extract_archive
+
+  my $dir = $amb->alien_extract_archive($filename);
+
+This function unpacks the given archive and returns the directory
+containing the unpacked files.
+
+The default implementation relies on L<Archive::Extract> that is able
+to handle most common formats. In order to handle other formats or
+archives requiring some special treatment you may want to override
+this method.
+
+=head2 alien_do_system
+
+  my %result = $amb->alien_do_system($cmd)
+
+Similar to L<Module::Build::do_system>, also sets the path and several
+environment variables in accordance to the object configuration
+(i.e. C<alien_bin_requires>) and performs the interpolation of the
+patterns described in L<Alien::Base::ModuleBuild::API/COMMAND
+INTERPOLATION>.
+
+Returns a set of key value pairs including C<stdout>, C<stderr>,
+C<success> and C<command>.
+
+=head1 GUIDE TO DOCUMENTATION
+
+The documentation for C<Module::Build> is broken up into sections:
+ 
+=over
+
+=item General Usage (L<Module::Build>)
+ 
+This is the landing document for L<Alien::Base::ModuleBuild>'s parent class.
+It describes basic usage and background information.
+Its main purpose is to assist the user who wants to learn how to invoke 
+and control C<Module::Build> scripts at the command line.
+
+It also lists the extra documentation for its use. Users and authors of Alien:: 
+modules should familiarize themselves with these documents. L<Module::Build::API>
+is of particular importance to authors. 
+ 
+=item Alien-Specific Usage (L<Alien::Base::ModuleBuild>)
+ 
+This is the document you are currently reading.
+ 
+=item Authoring Reference (L<Alien::Base::Authoring>)
+ 
+This document describes the structure and organization of 
+C<Alien::Base> based projects, beyond that contained in
+C<Module::Build::Authoring>, and the relevant concepts needed by authors who are
+writing F<Build.PL> scripts for a distribution or controlling
+C<Alien::Base::ModuleBuild> processes programmatically.
+
+Note that as it contains information both for the build and use phases of 
+L<Alien::Base> projects, it is located in the upper namespace.
+ 
+=item API Reference (L<Alien::Base::ModuleBuild::API>)
+ 
+This is a reference to the C<Alien::Base::ModuleBuild> API beyond that contained
+in C<Module::Build::API>.
+ 
+=back
+
+=head1 SEE ALSO
+
+=over
+
+=item * 
+
+L<Module::Build>
+
+=item *
+
+L<Alien>
+
+=item *
+
+L<Alien::Base>
+
+=back
+
+=head1 SOURCE REPOSITORY
+
+L<http://github.com/Perl5-Alien/Alien-Base>
+
+=head1 AUTHOR
+
+Original author: Joel Berger, E<lt>joel.a.berger at gmail.comE<gt>
+
+Current maintainer: Graham Ollis E<lt>plicease at cpan.orgE<gt> and the L<Alien::Base> team
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2012-2015 by Joel Berger
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
diff --git a/lib/Alien/Base/ModuleBuild/API.pod b/lib/Alien/Base/ModuleBuild/API.pod
new file mode 100644
index 0000000..4d6b672
--- /dev/null
+++ b/lib/Alien/Base/ModuleBuild/API.pod
@@ -0,0 +1,470 @@
+=head1 NAME
+ 
+Alien::Base::ModuleBuild::API - API Reference for Alien:: Authors
+ 
+=head1 DESCRIPTION
+
+A list of extra properties and methods provided by 
+L<Alien::Base::ModuleBuild> beyond those contained in L<Module::Build::API>.
+Note that all property and method names are prefixed with C<alien_> to prevent future 
+collisions L<Module::Build> builtins.
+
+=head2 CONSTRUCTOR
+
+L<Alien::Base::ModuleBuild> adds several parameters to the L<new|Module::Build::API/CONSTRUCTORS> constructor in L<Module::Build>. Unless otherwise specified all of the parameters listed in L<Module::Build::API> are available and behave identically to the description contained therein.
+
+=over
+
+=item alien_arch
+
+[version 0.019]
+
+Install module into an architecture specific directory.  This is off by default, unless $ENV{ALIEN_ARCH} is true.  Most Alien distributions will be installing binary code.  If you are an integrator where the C<@INC> path is shared by multiple Perls in a non-homogeneous environment you can set $ENV{ALIEN_ARCH} to 1 and Alien modules will be installed in architecture specific directories.
+
+=item alien_autoconf_with_pic
+
+[version 0.005]
+
+Add C<--with-pic> option to autoconf style C<configure> script when called.  This is the default, and normally a good practice.  Normally autoconf will ignore this and any other options that it does not recognize, but some non-autoconf C<configure> scripts may complain.
+
+=item alien_bin_requires
+
+[version 0.006]
+
+Hash reference of modules (keys) and versions (values) that specifies C<Alien> modules that provide binary tools that are required to build.  Any L<Alien::Base> module that includes binaries should work.  Also supported are L<Alien::MSYS>, L<Alien::CMake>, L<Alien::TinyCC> and L<Alien::Autotools>.
+
+[version 0.007]
+
+These only become required for building if L<Alien::Base::ModuleBuild> determines that a source code build is required.
+
+=item alien_build_commands
+
+[version 0.001]
+
+An arrayref of commands used to build the library in the directory specified in C<alien_temp_dir>. Each command is first passed through the L<command interpolation engine|/"COMMAND INTERPOLATION">, so those variables may be used. The default is tailored to the GNU toolchain, i.e. AutoConf and Make; it is C<[ '%c --prefix=%s', 'make' ]>.
+
+[version 0.009]
+
+Each command may be either a string or an array reference.  If the array reference form is used then the multiple argument form of C<system> is used.  Prior to version 0.009, only the string form was supported.
+
+=item alien_env
+
+[version 0.027]
+
+Environment overrides.  Allows you to set environment variables as a hash
+reference that will override environment variables.  You can use the same
+interpolated escape sequences and helpers that commands use.  Set to undef
+to remove the variable.
+
+ ...
+ Alien::Base::ModuleBuild->new(
+   ...
+   alien_env => {
+     PERL => '%X',     # sets the environment variable PERL to the location
+                       # of the Perl interpreter.
+     PERCENT => '%%',  # evaluates to '%'
+     REMOVE => undef,  # remove the environment variable if it is defined
+   },
+   ...
+ );
+ ...
+
+Please keep in mind that frequently users have a good reason to have set 
+environment variables, and you should not override them without a good 
+reason.  An example of a good justification would be if a project has a 
+Makefile that interacts badly with common environment variables.  This 
+can sometimes be a problem since Makefile variables can be overridden with
+environment variables.
+
+A useful pattern is to use a helper to only override an environment 
+variable if it is not already set.
+
+ ...
+ Alien::Base::ModuleBuild->new(
+   ...
+   alien_helper => {
+     foo => '$ENV{FOO}||"my preferred value if not already set"'
+   },
+   alien_env => {
+     FOO => '%{foo}',
+   },
+   ...
+ );
+ ...
+
+A common pitfall with environment variables is that setting one to the 
+empty string (C<''>) is not portable.  On Unix it works fine as you would
+expect, but in Windows it actually unsets the environment variable, which
+may not be what you intend.
+
+ ...
+ Alien::Base::ModuleBuild->new(
+   ...
+   alien_env => {
+     # is allowed, but may not do what you intend
+     # on some platforms!
+     FOO => '',
+   },
+ );
+ ...
+
+=item alien_ffi_name
+
+[version 0.007]
+
+The name of the shared library for use with FFI.  Provided for situations where the shared library name cannot be determined from the C<pkg-config> name specified with C<alien_name>.
+For example C<libxml2> has a C<pkg-config> of C<libxml-2.0>, but a shared library name of C<xml2>.
+By default alien_name is used with any C<lib> prefix removed.  For example C<libarchive> to be translated into C<archive> which is what you want for that package.
+
+=item alien_helper
+
+[version 0.020]
+
+Provide helpers to generate commands or arguments at build or install time.  This property is a hash 
+reference.  The keys are the helper names and the values are strings containing Perl code that will 
+be evaluated and interpolated into the command before execution.  Because helpers are only needed 
+when building a package from the source code, any dependency may be specified as an 
+C<alien_bin_requires>.  For example:
+
+ ...
+ Alien::Base::ModuleBuild->new(
+   ...
+   alien_bin_requires => {
+     'Alien::foo' => 0,
+   },
+   alien_helper => {
+     'foocommand'  => 'Alien::foo->some_command',
+     'fooargument' => 'Alien::foo->some_argument',
+   },
+   alien_build_commands => [
+     '%{foocommand} %{fooargument}',
+   ],
+   ...
+ );
+
+[version 0.022]
+
+One helper that you get for free is C<%{pkg_config}> which will be the pkg-config implementation
+chosen by L<Alien::Base::ModuleBuild>.  This will either be the real pkg-config provided by the
+operating system (preferred) or L<PkgConfig>, the pure perl implementation found on CPAN.
+
+=item alien_inline_auto_include
+
+[version 0.006]
+
+Array reference containing the list of header files to be used automatically by C<Inline::C> and C<Inline::CPP>.
+
+=item alien_install_commands
+
+[version 0.001]
+
+An arrayref of commands used to install it to the share directory specified by interpolation var C<%s>. Each command is first passed through the L<command interpolation engine|/"COMMAND INTERPOLATION">, so those variables may be used. The default is tailored to the GNU toolchain, i.e. AutoConf and Make; it is C<[ 'make install' ]>.
+
+[version 0.009]
+
+Each command may be either a string or an array reference.  If the array reference form is used then the multiple argument form of C<system> is used.  Prior to version 0.009, only the string form was supported.
+
+=item alien_isolate_dynamic
+
+[version 0.005]
+
+If set to true, then dynamic libraries will be moved from the C<lib> directory to a separate C<dynamic> directory.  This makes them available for FFI modules (see L<FFI::Platypus>, or L<FFI::Raw>), while preferring static libraries when creating XS extensions.
+
+=item alien_msys
+
+[version 0.006]
+
+On windows wrap build and install commands in an C<MSYS> environment using L<Alien::MSYS>.  This option will automatically add L<Alien::MSYS> as a build requirement when building on Windows.
+
+=item alien_name
+
+[version 0.001]
+
+The name of the primary library which will be provided. This should be in the form to be passed to C<pkg-config>. This name is available in the L<command interpolation|/"COMMAND INTERPOLATION"> as C<%n>.
+
+=item alien_provides_cflags
+
+=item alien_provides_libs
+
+[version 0.001]
+
+These parameters, if specified, augment the information found by F<pkg-config>. If no package config data is found, these are used to generate the necessary information. In that case, if these are not specified, they are attempted to be created from found shared-object files and header files. They both are empty by default.
+
+=item alien_repository
+
+[version 0.001]
+
+A hashref or arrayref of hashrefs defining the repositories used to find and fetch library tarballs (or zipballs etc.). These attributes are used to create C<Alien::Base::ModuleBuild::Repository> objects (or more likely, subclasses thereof). Which class is created is governed by the C<protocol> attribute and the C<alien_repository_class> property below. Available attributes are:
+
+=over
+
+=item protocol
+
+One of C<ftp> or C<http> or C<local>. The first two are obvious, C<local> allows packaging a tarball with the Alien:: module.
+
+=item protocol_class
+
+Defines the protocol handler class. Defaults to 'Net::FTP' or 'HTTP::Tiny' as appropriate.
+
+=item host
+
+This is either the root server address for the FTP and HTTP classes (i.e. C<my.server.com>)
+
+=item location
+
+This key is protocol specific. For FTP this contains the name of the folder to search. For HTTP this is the page to be searched for links; this is specified as a path relative to the C<host>. For a local file, this specifies the folder containing the tarball relative to the C<base_dir>.
+
+=item pattern
+
+This is a C<qr> regex matching acceptable files found in the C<location>. If the pattern contains a capture group, the captured string is interpreted as the version number. N.B. if no versions are found, the files are sorted by filename using version semantics, this mechanism is not likely to be as accurate as specifying a capture group.
+
+=item exact_filename
+
+This key may be specified in place of C<pattern> when the filename of the tarball is known, in which case such a file is downloaded from the given C<host> and C<location>. Note that, in general, specifying a C<pattern> gives more flexibility, but there may be cases when you find more convenient to use C<exact_filename>.
+
+=item exact_version
+
+This key may be specified with the C<exact_filename> key when the version of the tarball is known.
+
+=item platform
+
+This attribute is a string telling the repository validator which platform the repository serves. This may be the string C<src> (the default) for platform-independent source files, or a string which matches the L<Module::Build> method C<os_type> (e.g. "Windows", "Unix", "MacOS", "VMS").
+
+=item c_compiler_required
+
+If true (the default), then a C compiler is required to build from source.
+
+=back
+
+=item alien_repository_class
+
+[version 0.001]
+
+As the repositories in C<alien_repository> are converted to objects, this hash controls the type of object that is created. The keys are the relevant protocol. This allows for easy subclassing any or all protocol classes. The defaults are as follows.
+
+ http    => 'Alien::Base::ModuleBuild::Repository::HTTP',
+ ftp     => 'Alien::Base::ModuleBuild::Repository::FTP',
+ local   => 'Alien::Base::ModuleBuild::Repository::Local',
+ default => 'Alien::Base::ModuleBuild::Repository',
+
+Unlike most L<Module::Build> parameters, authors may specify only those keys which are to be overridden. If any of the above keys are not specified, the above defaults will be used.
+
+=item alien_repository_default
+
+[version 0.001]
+
+This property is a shortcut for specifying multiple repositories with similar attributes. If a repository attribute is not defined in its C<alien_repository> hashref, but that attribute is defined here, then this value will be used. This hashref is empty by default.
+
+=item alien_selection_method
+
+[not yet implemented]
+
+This is intended to choose the mechanism for selecting one file from many. The default name is C<newest>.
+
+=item alien_share_dir
+
+[version 0.001]
+
+The name of the folder which will both serve a stub share directory via L<Module::Build>'s C<share_dir>/C<dist_dir> parameter. This directory is added in a smart manner which attempts not to interfere with other author-defined C<share_dir>s. The default name is C<_share>. This folder will hold a README file which is then installed to the target installed share location. It is THAT location that the library will be installed to.
+
+=item alien_stage_install
+
+[version 0.016]
+
+Alien packages are installed directly into the blib directory by the `./Build' command rather than to the final location during the `./Build install` step.
+
+[version 0.017]
+
+As of 0.017 this is the default.
+
+=item alien_temp_dir
+
+[version 0.001]
+
+The name of the temporary folder which will house the library when it is downloaded and built. The default name is C<_alien>.
+
+=item alien_test_commands
+
+[version 0.001]
+
+An arrayref of commands used to test the library.  Each command is first 
+passed through the L<command interpolation engine|/"COMMAND INTERPOLATION">,
+so those variables may be used.  The default is to do no tests.  The most
+common command used by the GNU toolchain is C<[ 'make check' ]>, but beware
+that is not supported by all packages.
+
+[version 0.009]
+
+Each command may be either a string or an array reference.  If the array 
+reference form is used, then the multiple argument form of system is used.
+
+=item alien_version_check
+
+[version 0.001]
+
+A command to run to check the version of the library installed on the system. The default is C<pkg-config --modversion %n>.
+
+=back
+
+=head2 PACKAGE AND ENVIRONMENT VARIABLES
+
+A few global variables are used to set gross behavior. For each pair of variables, if both are set, the environment variable takes precedence.
+
+=over 
+
+=item $ENV{ALIEN_ARCH}
+
+[version 0.017]
+
+Setting this changes the default for alien_arch above.  If the module specifies its own alien_arch in its C<Build.PL> file then it will override this setting.  Typically installing into an architecture specific directory is what you
+want to do, since most L<Alien::Base> based distributions provide architecture specific binary code, so you should consider carefully before installing modules with this environment variable set to 0.  This may be useful for
+integrators creating a single non-architecture specific RPM, .dep or similar package.  In this case the integrator should ensure that the Alien package be installed with a system install_type and use the system package.
+
+=item $ENV{ALIEN_BLIB}
+
+Setting this to true indicates that you don't intend to actually install your Alien::Base subclass, but rather use it from the built F<blib> directory. This behavior is mostly to support automated testing from CPANtesters and should be automagically determined. If by chance you happen to trip the behavior accidentally, setting this environment variable to false (0) before building should prevent problems. 
+
+=item $Alien::Base::ModuleBuild::Force
+
+=item $ENV{ALIEN_FORCE}
+
+Setting either to a true value will cause the builder to ignore a system-wide installation and build a local version of the library.  This is the equivalent to setting $ENV{ALIEN_INSTALL_TYPE} to 'share'.  $ENV{ALIEN_INSTALL_TYPE} takes precedence.
+
+=item $ENV{ALIEN_INSTALL_TYPE}
+
+Setting to C<share> will ignore a system-wide installation and build a local version of the library.  Setting to C<system> will only use a system-wide installation and die if it cannot be found.
+
+=item $Alien::Base::ModuleBuild::Verbose
+
+=item $ENV{ALIEN_VERBOSE}
+
+Setting the either to a true value will output a little more info from within the module itself. At this point L<Alien::Base> is going to be fairly verbose without this enabled. 
+
+=back
+
+=head2 CONFIG DATA
+
+The L<Alien::Base> system needs to store some data to be used in other phases of the build and eventual use. This is done via the mechanism provided by L<Module::Build::ConfigData>. During the build-phase this information is mutable and is available through the C<Module::Build::config_data> method. As the build-phase ends the data is serialized and stored as C<Alien::MyModule::ConfigData> (assuming you are authoring C<Alien::MyModule>). Then during the use-phase, the C<Alien::MyModule::C [...]
+
+Config keys of interest are:
+
+=over
+
+=item name
+
+Holder for C<alien_name> as needed by pkg-config.
+
+=item install_type
+
+Remembers if the library was found system-wide (value: C<system>) or was installed during build (value: C<share>).
+
+=item pkgconfig
+
+A hashref of Alien::Base::PkgConfig objects created from F<.pc> files found in C<working_directory>. One extra object (whose key is C<_manual> is created from the C<alien_provides_*> information.
+
+=item version
+
+The version number installed or available.
+
+=item working_directory
+
+Holder for the full path to the extracted source of the library. This is used to munge the pkg-config data later on.
+
+=back
+
+=head2 COMMAND INTERPOLATION
+
+Before L<Alien::Base::ModuleBuild> executes system commands, it replaces a few special escape sequences with useful data. This is needed especially for referencing the full path to the C<alien_share_dir> before this path is known. The availble sequences are:
+
+=over
+
+=item %{I<helper>}
+
+[version 0.020]
+
+Call the given helper, either provided by the C<alien_helper> or C<alien_bin_requires> property.  See L<Alien::Base#alien_helper>.
+
+=item %c
+
+Platform independent incantation for running autoconf C<configure> script.  On *nix systems this is C<./configure>, on Windows this is C<sh configure>.  On windows L<Alien::MSYS> is injected as a dependency and all commands are executed in an C<MSYS> environment.
+
+=item %n
+
+Shortcut for the name stored in C<alien_name>
+
+ pkg-config --modversion %n
+
+=item %p
+
+B<deprecated>
+
+Platform independent "local command prefix". On *nix systems this is C<./>, on Windows it is an empty string.
+
+ %pconfigure
+
+Please note that this only works to run scripts on Unix, and does not work on Windows.  It is thus, not fit for purpose and should not be used.  As an alternative:
+
+=over 4
+
+=item autoconf "configure"
+
+If you are trying to invoke the autoconf configure script, use C<%c> instead.  This will use the correct incantation on either Unix like systems and on Windows.
+
+=item Some other script
+
+Invoke the interpreter directly.  For example, if you have a python script use "python foo.py", if you have a Perl script use "%X foo.pl", if you have an sh script use "sh foo.sh".  These are all portable.
+For sh, be sure to set the C<alien_msys> property so that it will work on Windows.
+
+=back
+
+=item %s
+
+The full path to the final installed location of the share directory (builder method C<alien_library_destination>). This is where the library should install itself; for autoconf style installs this will look like 
+
+ --prefix=%s
+
+=item %v
+
+Captured version of the original archive.
+
+=item %x
+
+The current Perl interpreter (aka $^X)
+
+=item %X
+
+[version 0.027]
+
+The current Perl interpreter using the Unix style path separator C</>
+instead of the native Windows C<\>.
+
+=item %%
+
+A literal C<%>.
+
+=back
+
+=head1 AUTHOR
+
+Original author: Joel Berger, E<lt>joel.a.berger at gmail.comE<gt>
+
+Current maintainer: Graham Ollis E<lt>plicease at cpan.orgE<gt> and the L<Alien::Base> team
+
+=head1 SEE ALSO
+
+=over
+
+=item * 
+
+L<Module::Build::API>
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2012-2015 by Joel Berger
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
diff --git a/lib/Alien/Base/ModuleBuild/Cabinet.pm b/lib/Alien/Base/ModuleBuild/Cabinet.pm
new file mode 100644
index 0000000..43f2ece
--- /dev/null
+++ b/lib/Alien/Base/ModuleBuild/Cabinet.pm
@@ -0,0 +1,46 @@
+package Alien::Base::ModuleBuild::Cabinet;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.028';
+$VERSION = eval $VERSION;
+
+use Sort::Versions;
+use List::MoreUtils qw/part/;
+
+sub new {
+  my $class = shift;
+  my $self = ref $_[0] ? shift : { @_ };
+
+  bless $self, $class;
+
+  return $self;
+}
+
+sub files { shift->{files} }
+
+sub add_files {
+  my $self = shift;
+  push @{ $self->{files} }, @_;
+  return $self->files;
+}
+
+sub sort_files {
+  my $self = shift;
+
+  # split files which have versions and those which don't (sorted on filename)
+  my ($name, $version) = part { $_->has_version } @{ $self->{files} };
+
+  # store the sorted lists of versioned, then non-versioned
+  my @sorted;
+  push @sorted, sort { versioncmp( $b->version,  $a->version  ) } @$version if $version;
+  push @sorted, sort { versioncmp( $b->filename, $a->filename ) } @$name    if $name;
+
+  $self->{files} = \@sorted;
+
+  return;
+}
+
+1;
+
diff --git a/lib/Alien/Base/ModuleBuild/File.pm b/lib/Alien/Base/ModuleBuild/File.pm
new file mode 100644
index 0000000..4d2c3fa
--- /dev/null
+++ b/lib/Alien/Base/ModuleBuild/File.pm
@@ -0,0 +1,73 @@
+package Alien::Base::ModuleBuild::File;
+
+use strict;
+use warnings;
+use Carp;
+
+our $VERSION = '0.028';
+$VERSION = eval $VERSION;
+
+sub new {
+  my $class = shift;
+  my $self = ref $_[0] ? shift : { @_ };
+
+  bless $self, $class;
+
+  return $self;
+}
+
+sub has_version {
+  my $self = shift;
+  return defined $self->version;
+}
+
+sub get {
+  my $self = shift;
+  my $repo = $self->repository;
+
+  my $filename = $repo->get_file($self->filename);
+  if ( my $new_filename = $repo->{new_filename} ) {
+    $filename = $new_filename;
+  }
+
+  ## whatever happened, record the new filename
+  $self->{filename} = $filename;
+
+  if (defined $self->{sha1} || defined $self->{sha256}) {
+    unless (eval 'require Digest::SHA') {
+      warn "sha1 or sha256 sums are specified but cannot be checked since Digest::SHA is not installed";
+      return $filename;
+    }
+
+    eval 'require Digest::SHA' or return $filename;
+    ## verify that the SHA-1 and/or SHA-256 sums match if provided
+    if (defined $self->{sha1}) {
+      my $sha = Digest::SHA->new(1);
+      $sha->addfile($filename);
+      unless ($sha->hexdigest eq $self->{sha1}) {
+          carp "SHA-1 of downloaded $filename is ", $sha->hexdigest,
+          " Expected: ", $self->{sha1};
+          return undef;
+      }
+    }
+    if (defined $self->{sha256}) {
+      my $sha = Digest::SHA->new(256);
+      $sha->addfile($filename);
+      unless ($sha->hexdigest eq $self->{sha256}) {
+          carp "SHA-256 of downloaded $filename is ", $sha->hexdigest,
+          " Expected: ", $self->{sha256};
+          return undef;
+      }
+    }
+  }
+
+  return $filename;
+}
+
+sub platform   { shift->{platform}   }
+sub repository { shift->{repository} }
+sub version    { shift->{version}    }
+sub filename   { shift->{filename}   }
+
+1;
+
diff --git a/lib/Alien/Base/ModuleBuild/Repository.pm b/lib/Alien/Base/ModuleBuild/Repository.pm
new file mode 100644
index 0000000..9733655
--- /dev/null
+++ b/lib/Alien/Base/ModuleBuild/Repository.pm
@@ -0,0 +1,96 @@
+package Alien::Base::ModuleBuild::Repository;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.028';
+$VERSION = eval $VERSION;
+
+use Carp;
+
+use Alien::Base::ModuleBuild::File;
+use Alien::Base::ModuleBuild::Utils qw/pattern_has_capture_groups/;
+
+sub new {
+  my $class = shift;
+  my (%self) = ref $_[0] ? %{ shift() } : @_;
+
+  my $obj = bless \%self, $class;
+
+  $obj->{c_compiler_required} = 1
+    unless defined $obj->{c_compiler_required};
+
+  if($obj->{exact_filename} && $obj->{location} !~ m{/$}) {
+    $obj->{location} .= '/'
+  }
+
+  return $obj;
+}
+
+sub protocol { return shift->{protocol} }
+
+sub host {
+  my $self = shift;
+  $self->{host} = shift if @_;
+  return $self->{host};
+}
+
+sub location {
+  my $self = shift;
+  $self->{location} = shift if @_;
+  return $self->{location};
+}
+
+sub probe {
+  my $self = shift;
+
+  my $pattern = $self->{pattern};
+
+  my @files;
+
+  if ($self->{exact_filename}) {
+    # if filename provided, use that specific file
+    @files = ($self->{exact_filename});    
+  } else {
+    @files = $self->list_files();
+
+    if ($pattern) {
+      @files = grep { $_ =~ $pattern } @files;
+    }
+
+    carp "Could not find any matching files" unless @files;
+  }
+
+  @files = map { +{ 
+    repository => $self,
+    platform   => $self->{platform},
+    filename   => $_,
+  } } @files;
+
+  if ($self->{exact_filename} and $self->{exact_version}) {
+    # if filename and version provided, use a specific version
+    $files[0]->{version} = $self->{exact_version};
+    $files[0]->{sha1} = $self->{sha1} if defined $self->{sha1};
+    $files[0]->{sha256} = $self->{sha256} if defined $self->{sha256};
+  } elsif ($pattern and pattern_has_capture_groups($pattern)) {
+    foreach my $file (@files) {
+      $file->{version} = $1 
+        if $file->{filename} =~ $pattern;
+    }
+  }
+
+  @files = 
+    map { Alien::Base::ModuleBuild::File->new($_) }
+    @files;
+
+  return @files;
+}
+
+# subclasses are expected to provide 
+sub connection { croak "$_[0] doesn't provide 'connection' method" }
+sub list_files { croak "$_[0] doesn't provide 'list_files' method" }
+# get_file must return filename actually used
+sub get_file  { croak "$_[0] doesn't provide 'get_files' method"  }
+
+1;
+
diff --git a/lib/Alien/Base/ModuleBuild/Repository/FTP.pm b/lib/Alien/Base/ModuleBuild/Repository/FTP.pm
new file mode 100644
index 0000000..7695435
--- /dev/null
+++ b/lib/Alien/Base/ModuleBuild/Repository/FTP.pm
@@ -0,0 +1,60 @@
+package Alien::Base::ModuleBuild::Repository::FTP;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.028';
+$VERSION = eval $VERSION;
+
+use parent 'Alien::Base::ModuleBuild::Repository';
+
+use Carp;
+use Net::FTP;
+
+sub connection {
+  my $self = shift;
+
+  return $self->{connection}
+    if $self->{connection};
+
+  # allow easy use of Net::FTP subclass
+  $self->{protocol_class} ||= 'Net::FTP';
+
+  my $server = $self->{host} 
+    or croak "Must specify a host for FTP service";
+
+  my $ftp = $self->{protocol_class}->new($server, Debug => 0)
+    or croak "Cannot connect to $server: $@";
+
+  $ftp->login() 
+    or croak "Cannot login ", $ftp->message;
+
+  if (defined $self->location) {
+    $ftp->cwd($self->location) 
+      or croak "Cannot change working directory ", $ftp->message;
+  }
+
+  $ftp->binary();
+  $self->{connection} = $ftp;
+
+  return $ftp;
+}
+
+sub get_file {
+  my $self = shift;
+  my $file = shift || croak "Must specify file to download";
+
+  my $ftp = $self->connection();
+
+  $ftp->get( $file ) or croak "Download failed: " . $ftp->message();
+
+  return $file;
+}
+
+sub list_files {
+  my $self = shift;
+  return $self->connection->ls();
+}
+
+1;
+
diff --git a/lib/Alien/Base/ModuleBuild/Repository/HTTP.pm b/lib/Alien/Base/ModuleBuild/Repository/HTTP.pm
new file mode 100644
index 0000000..04902ce
--- /dev/null
+++ b/lib/Alien/Base/ModuleBuild/Repository/HTTP.pm
@@ -0,0 +1,172 @@
+package Alien::Base::ModuleBuild::Repository::HTTP;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.028';
+$VERSION = eval $VERSION;
+
+use Carp;
+
+use HTTP::Tiny;
+use Scalar::Util qw( blessed );
+use URI;
+
+use Alien::Base::ModuleBuild::Utils;
+
+use parent 'Alien::Base::ModuleBuild::Repository';
+
+our $Has_HTML_Parser = eval { require HTML::LinkExtor; 1 };
+
+sub connection {
+
+  my $self = shift;
+
+  return $self->{connection}
+    if $self->{connection};
+
+  # allow easy use of HTTP::Tiny subclass
+  $self->{protocol_class} ||= 'HTTP::Tiny';
+  my $module = $self->{protocol_class};
+  $module =~ s{::}{/}g;
+  $module .= '.pm';
+  eval { require $module; 1 }
+    or croak "Could not load protocol_class '$self->{protocol_class}': $@";
+
+  my $http = $self->{protocol_class}->new();
+
+  $self->{connection} = $http;
+
+  return $http;
+
+}
+
+sub get_file {
+  my $self = shift;
+  my $file = shift || croak "Must specify file to download";
+
+  my $protocol = $self->protocol;
+  my $host = $self->{host};
+  my $from = $self->location;
+
+  my $uri = $self->build_uri($protocol, $host, $from, $file);
+  $file = ($uri->path_segments())[-1];
+  my $res = $self->connection->mirror($uri, $file);
+  my ( $is_error, $content, $headers ) = $self->check_http_response( $res );
+  croak "Download failed: " . $content if $is_error;
+
+  my $disposition = $headers->{"content-disposition"};
+  if ( defined($disposition) && ($disposition =~ /filename="([^"]+)"/ || $disposition =~ /filename=([^\s]+)/)) {
+    my $new_filename = $1;
+    rename $file, $new_filename;
+    $self->{new_filename} = $new_filename;
+  }
+
+  return $file;
+}
+
+sub list_files {
+  my $self = shift;
+
+  my $protocol = $self->protocol;
+  my $host = $self->host;
+  my $location = $self->location;
+  my $uri = $self->build_uri($protocol, $host, $location);
+
+  my $res = $self->connection->get($uri);
+
+  my ( $is_error, $content, undef, $base_url ) = $self->check_http_response( $res );
+  if ( $is_error ) {
+    carp $content;
+    return ();
+  }
+  
+  $self->{base_url} = $base_url;
+
+  my @links = $self->find_links($content);
+
+  return @links;  
+}
+
+sub find_links {
+  my $self = shift;
+  my ($html) = @_;
+
+  my @links;
+  if ($Has_HTML_Parser) {
+    push @links, $self->find_links_preferred($html) 
+  } else {
+    push @links, $self->find_links_textbalanced($html)
+  }
+
+  return @links;
+}
+
+sub find_links_preferred {
+  my $self = shift;
+  my ($html) = @_;
+
+  my @links;
+
+  my $extor = HTML::LinkExtor->new(
+    sub { 
+      my ($tag, %attrs) = @_;
+      return unless $tag eq 'a';
+      return unless defined $attrs{href};
+      push @links, $attrs{href};
+    },
+  );
+
+  $extor->parse($html);
+
+  return @links;
+}
+
+sub find_links_textbalanced {
+  my $self = shift;
+  my ($html) = @_;
+  return Alien::Base::ModuleBuild::Utils::find_anchor_targets($html);
+}
+
+sub build_uri {
+  my $self = shift;
+  my ($protocol, $host, $path, $target) = @_;
+
+  my $uri;
+  if (defined $host) {
+    my $base = $self->{base_url};
+    unless($base)
+    {
+      $base = URI->new($host);
+      unless (defined $base->scheme) {
+        $base = URI->new(($protocol || 'http') ."://$host");
+      }
+      $base->path($path) if defined $path;
+    }
+    $uri = URI->new_abs($target, $base);
+  }
+  else {
+    $uri = URI->new($target);
+  }
+  return $uri->canonical;
+}
+
+sub check_http_response {
+  my ( $self, $res ) = @_;
+  if ( blessed $res && $res->isa( 'HTTP::Response' ) ) {
+    my %headers = map { lc $_ => $res->header($_) } $res->header_field_names;
+    if ( !$res->is_success ) {
+      return ( 1, $res->status_line . " " . $res->decoded_content, \%headers, $res->request->uri );
+    }
+    return ( 0, $res->decoded_content, \%headers, $res->request->uri );
+  }
+  else {
+    if ( !$res->{success} ) {
+      return ( 1, $res->{reason}, $res->{headers}, $res->{url} );
+    }
+    return ( 0, $res->{content}, $res->{headers}, $res->{url} );
+  }
+}
+
+1;
+
diff --git a/lib/Alien/Base/ModuleBuild/Repository/Local.pm b/lib/Alien/Base/ModuleBuild/Repository/Local.pm
new file mode 100644
index 0000000..187ceb3
--- /dev/null
+++ b/lib/Alien/Base/ModuleBuild/Repository/Local.pm
@@ -0,0 +1,57 @@
+package Alien::Base::ModuleBuild::Repository::Local;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.028';
+$VERSION = eval $VERSION;
+
+use Carp;
+use File::chdir;
+use File::Copy qw/copy/;
+use File::Spec;
+
+use parent 'Alien::Base::ModuleBuild::Repository';
+
+sub new {
+  my $class = shift;
+
+  my $self = $class->SUPER::new(@_);
+
+  # make location absolute
+  local $CWD = $self->location;
+  $self->location("$CWD");
+
+  return $self;
+}
+
+sub list_files { 
+  my $self = shift;
+
+  local $CWD = $self->location;
+
+  opendir( my $dh, $CWD);
+  my @files = 
+    grep { ! /^\./ }
+    readdir $dh;
+
+  return @files;
+}
+
+sub get_file  { 
+  my $self = shift;
+  my $file = shift || croak "Must specify file to copy";
+  
+  my $full_file = do {
+    local $CWD = $self->location;
+    croak "Cannot find file: $file" unless -e $file;
+    File::Spec->rel2abs($file);
+  };
+
+  copy $full_file, $CWD;
+
+  return $file;
+}
+
+1;
+
diff --git a/lib/Alien/Base/ModuleBuild/Utils.pm b/lib/Alien/Base/ModuleBuild/Utils.pm
new file mode 100644
index 0000000..8ae7693
--- /dev/null
+++ b/lib/Alien/Base/ModuleBuild/Utils.pm
@@ -0,0 +1,56 @@
+package Alien::Base::ModuleBuild::Utils;
+# some useful functions for A::B::MB code
+
+use strict;
+use warnings;
+
+our $VERSION = '0.028';
+$VERSION = eval $VERSION;
+
+use Text::Balanced qw/extract_bracketed extract_delimited extract_multiple/;
+
+use parent 'Exporter';
+our @EXPORT_OK = qw/find_anchor_targets pattern_has_capture_groups/;
+
+sub find_anchor_targets {
+  my $html = shift;
+
+  my @tags = extract_multiple( 
+    $html, 
+    [ sub { extract_bracketed($_[0], '<>') } ],
+    undef, 1
+  );
+
+  @tags = 
+    map { extract_href($_) }  # find related href=
+    grep { /^<a/i }            # only anchor begin tags
+    @tags;
+
+  return @tags;
+}
+
+sub extract_href {
+  my $tag = shift;
+  if($tag =~ /href=(?='|")/gci) {
+    my $text = scalar extract_delimited( $tag, q{'"} );
+    my $delim = substr $text, 0, 1;
+    $text =~ s/^$delim//;
+    $text =~ s/$delim$//;
+    return $text;
+  } elsif ($tag =~ /href=(.*?)(?:\s|\n|>)/i) {
+    return $1;
+  } else {
+    return ();
+  }
+}
+
+sub pattern_has_capture_groups {
+  my $re = shift;
+  "" =~ /|$re/;
+  return $#+;
+}
+
+
+1;
+
+
diff --git a/lib/Alien/Base/PkgConfig.pm b/lib/Alien/Base/PkgConfig.pm
new file mode 100644
index 0000000..e3a7ef2
--- /dev/null
+++ b/lib/Alien/Base/PkgConfig.pm
@@ -0,0 +1,156 @@
+package Alien::Base::PkgConfig;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.028';
+$VERSION = eval $VERSION;
+
+use Carp;
+use Config;
+use File::Basename qw/fileparse/;
+use File::Spec;
+use Capture::Tiny qw( capture_stderr );
+
+sub new {
+  my $class   = shift;
+
+  # allow creation of an object from a full spec.
+  if (ref $_[0] eq 'HASH') {
+    return bless $_[0], $class;
+  }
+
+  my ($path) = @_;
+  croak "Must specify a file" unless defined $path;
+
+  $path = File::Spec->rel2abs( $path );
+
+  my ($name, $dir) = fileparse $path, '.pc';
+
+  $dir = File::Spec->catdir( $dir );  # remove trailing slash
+  $dir =~ s{\\}{/}g;
+
+  my $self = {
+    package  => $name,
+    vars     => { pcfiledir => $dir },
+    keywords => {},
+  };
+
+  bless $self, $class;
+
+  $self->read($path);
+
+  return $self;
+}
+
+sub read {
+  my $self = shift;
+  my ($path) = @_;
+
+  open my $fh, '<', $path
+    or croak "Cannot open .pc file $path: $!";
+
+  while (<$fh>) {
+    if (/(.*?)=([^\n\r]*)/) {
+      $self->{vars}{$1} = $2;
+    } elsif (/^(.*?):\s*([^\n\r]*)/) {
+      $self->{keywords}{$1} = $2;
+    }
+  }
+}
+
+# getter/setter for vars
+sub var {
+  my $self = shift;
+  my ($var, $newval) = @_;
+  if (defined $newval) {
+    $self->{vars}{$var} = $newval;
+  }
+  return $self->{vars}{$var};
+}
+
+# abstract keywords and other vars in terms of "pure" vars
+sub make_abstract {
+  my $self = shift;
+  die "make_abstract needs a key (and possibly a value)" unless @_;
+  my ($var, $value) = @_;
+
+  $value = defined $value ? $value : $self->{vars}{$var};
+    
+  # convert other vars
+  foreach my $key (keys %{ $self->{vars} }) {
+    next if $key eq $var; # don't overwrite the current var
+    $self->{vars}{$key} =~ s/\Q$value\E/\$\{$var\}/g;
+  }
+
+  # convert keywords
+  foreach my $key (keys %{ $self->{keywords} }) {
+    $self->{keywords}{$key} =~ s/\Q$value\E/\$\{$var\}/g;
+  }
+
+}
+
+sub _interpolate_vars {
+  my $self = shift;
+  my ($string, $override) = @_;
+
+  $override ||= {};
+
+  foreach my $key (keys %$override) {
+    carp "Overriden pkg-config variable $key, contains no data" 
+      unless $override->{$key};
+  }
+
+  if (defined $string) {
+    1 while $string =~ s/\$\{(.*?)\}/$override->{$1} || $self->{vars}{$1}/e;
+  }
+  return $string;
+}
+
+sub keyword {
+  my $self = shift;
+  my ($keyword, $override) = @_;
+  
+  {
+    no warnings 'uninitialized';
+    croak "overrides passed to 'keyword' must be a hashref"
+      if defined $override and ref $override ne 'HASH';
+  }
+
+  return $self->_interpolate_vars( $self->{keywords}{$keyword}, $override );
+}
+
+my $pkg_config_command;
+
+sub pkg_config_command {
+  unless (defined $pkg_config_command) {
+    capture_stderr {
+    
+      # For now we prefer PkgConfig.pm over pkg-config on
+      # Solaris 64 bit Perls.  We may need to do this on
+      # other platforms, in which case this logic should
+      # be abstracted so that it can be shared here and
+      # in Build.PL
+
+      if (`pkg-config --version` && $? == 0 && !($^O eq 'solaris' && $Config{ptrsize} == 8)) {
+        $pkg_config_command = 'pkg-config';
+      } else {
+        require PkgConfig;
+        $pkg_config_command = "$^X $INC{'PkgConfig.pm'}";
+      }
+    }
+  }
+  
+  $pkg_config_command;
+}
+
+sub TO_JSON
+{
+  my($self) = @_;
+  my %hash = %$self;
+  $hash{'__CLASS__'} = ref($self);
+  \%hash;
+}
+
+1;
+
diff --git a/t/00_diag.t b/t/00_diag.t
new file mode 100644
index 0000000..9fc22e0
--- /dev/null
+++ b/t/00_diag.t
@@ -0,0 +1,46 @@
+use strict;
+use warnings;
+use Test::More tests => 1;
+
+# please keep in alpha order
+my @mods = qw(
+  Acme::Alien::DontPanic
+  Acme::Ford::Prefect
+  Acme::Ford::Prefect::FFI
+  Archive::Extract
+  Capture::Tiny
+  Cwd
+  File::ShareDir
+  File::Spec
+  File::Temp
+  File::chdir
+  FindBin
+  HTML::LinkExtor
+  HTTP::Tiny
+  Inline
+  Inline::C
+  Inline::CPP
+  List::MoreUtils
+  Module::Build
+  Perl::OSType
+  Shell::Config::Generate
+  Shell::Guess
+  Sort::Versions
+  Test::Alien
+  Test::CChecker
+  Test::More
+  Text::ParseWords
+  URI
+  parent
+);
+
+pass 'okay';
+
+diag '';
+diag sprintf "%25s %s", 'perl', $];
+
+foreach my $mod (@mods) {
+  my $version = eval qq{ no warnings; require $mod; \$$mod\::VERSION };
+  $version = 'undefined' unless defined $version;
+  diag sprintf "%25s %s", $mod, $version;
+}
diff --git a/t/RepositoryTest.pm b/t/RepositoryTest.pm
new file mode 100644
index 0000000..e7538bc
--- /dev/null
+++ b/t/RepositoryTest.pm
@@ -0,0 +1,73 @@
+package Alien::Base::ModuleBuild::Repository::Test;
+
+use strict;
+use warnings;
+
+use parent 'Alien::Base::ModuleBuild::Repository';
+
+sub list_files {
+  my $self = shift;
+  #files from GNU GSL FTP server, fetched 1/24/2012
+  my @files = ( qw/
+    gsl-1.0-gsl-1.1.patch.gz
+    gsl-1.0.tar.gz
+    gsl-1.1-gsl-1.1.1.patch.gz
+    gsl-1.1.1-gsl-1.2.patch.gz
+    gsl-1.1.1.tar.gz
+    gsl-1.1.tar.gz
+    gsl-1.10-1.11.patch.gz
+    gsl-1.10-1.11.patch.gz.sig
+    gsl-1.10.tar.gz
+    gsl-1.10.tar.gz.sig
+    gsl-1.11-1.12.patch.gz
+    gsl-1.11-1.12.patch.gz.sig
+    gsl-1.11.tar.gz
+    gsl-1.11.tar.gz.sig
+    gsl-1.12-1.13.patch.gz
+    gsl-1.12-1.13.patch.gz.sig
+    gsl-1.12.tar.gz
+    gsl-1.12.tar.gz.sig
+    gsl-1.13-1.14.patch.gz
+    gsl-1.13-1.14.patch.gz.sig
+    gsl-1.13.tar.gz
+    gsl-1.13.tar.gz.sig
+    gsl-1.14.tar.gz
+    gsl-1.14.tar.gz.sig
+    gsl-1.15.tar.gz
+    gsl-1.15.tar.gz.sig
+    gsl-1.2-gsl-1.3.patch.gz
+    gsl-1.2.tar.gz
+    gsl-1.3-gsl-1.4.patch.gz
+    gsl-1.3-gsl-1.4.patch.gz.asc
+    gsl-1.3.tar.gz
+    gsl-1.4-gsl-1.5.patch.gz
+    gsl-1.4-gsl-1.5.patch.gz.sig
+    gsl-1.4.tar.gz
+    gsl-1.4.tar.gz.asc
+    gsl-1.5-gsl-1.6.patch.gz
+    gsl-1.5-gsl-1.6.patch.gz.sig
+    gsl-1.5.tar.gz
+    gsl-1.5.tar.gz.sig
+    gsl-1.6-gsl-1.7.patch.gz
+    gsl-1.6-gsl-1.7.patch.gz.sig
+    gsl-1.6.tar.gz
+    gsl-1.6.tar.gz.sig
+    gsl-1.7-1.8.patch.gz
+    gsl-1.7-1.8.patch.gz.sig
+    gsl-1.7.tar.gz
+    gsl-1.7.tar.gz.sig
+    gsl-1.8-1.9.patch.gz
+    gsl-1.8-1.9.patch.gz.sig
+    gsl-1.8.tar.gz
+    gsl-1.8.tar.gz.sig
+    gsl-1.9-1.10.patch.gz
+    gsl-1.9-1.10.patch.gz.sig
+    gsl-1.9.tar.gz
+    gsl-1.9.tar.gz.sig
+  / );
+
+  return @files;
+}
+
+1;
+
diff --git a/t/alien_base.t b/t/alien_base.t
new file mode 100644
index 0000000..9bf36e1
--- /dev/null
+++ b/t/alien_base.t
@@ -0,0 +1,122 @@
+use strict;
+use warnings;
+use lib 't/alien_base/ab_share/lib';
+use lib 't/alien_base/ab_sys/lib';
+use lib 't/alien_base/mb_share/lib';
+use lib 't/alien_base/mb_sys/lib';
+use Test::More;
+use Env qw( @PKG_CONFIG_PATH );
+use File::Spec;
+
+unshift @PKG_CONFIG_PATH, File::Spec->rel2abs(File::Spec->catdir( qw( t alien_base pkgconfig )));
+
+subtest 'AB::MB sys install' => sub {
+
+  require_ok 'Alien::Foo1';
+
+  my $cflags = Alien::Foo1->cflags;
+  my $libs   = Alien::Foo1->libs;
+
+  is $cflags, '-DFOO=stuff', "cflags: $cflags";
+  is $libs,   '-lfoo1', "libs: $libs";
+};
+
+subtest 'AB::MB share install' => sub {
+
+  require_ok 'Alien::Foo2';
+
+  my $cflags = Alien::Foo2->cflags;
+  my $libs   = Alien::Foo2->libs;
+    
+  ok $cflags, "cflags: $cflags";
+  ok $libs,   "libs:   $libs";
+
+  if($cflags =~ /-I(.*)$/)
+  {
+    ok -f "$1/foo2.h", "include path: $1";
+  }
+  else
+  {
+    fail "include path: ?";
+  }
+  
+  if($libs =~ /-L([^ ]*)/)
+  {
+    ok -f "$1/libfoo2.a", "lib path: $1";
+  }
+  else
+  {
+    fail "lib path: ?";
+  }
+
+};
+
+subtest 'A::Builder sys install' => sub {
+
+  require_ok 'Alien::Bar1';
+
+  my $cflags = Alien::Bar1->cflags;
+  my $libs   = Alien::Bar1->libs;
+
+  is $cflags, '-DFOO=stuff', "cflags: $cflags";
+  is $libs,   '-lbar1', "libs: $libs";
+};
+
+subtest 'A::Builder share install' => sub {
+
+  require_ok 'Alien::Bar2';
+
+  my $cflags = Alien::Bar2->cflags;
+  my $libs   = Alien::Bar2->libs;
+
+  ok $cflags, "cflags: $cflags";
+  ok $libs,   "libs:   $libs";
+
+  if($cflags =~ /-I(.*)$/)
+  {
+    ok -f "$1/bar2.h", "include path: $1";
+  }
+  else
+  {
+    fail "include path: ?";
+  }
+  
+  if($libs =~ /-L([^ ]*)/)
+  {
+    ok -f "$1/libbar2.a", "lib path: $1";
+  }
+  else
+  {
+    fail "lib path: ?";
+  }
+};
+
+done_testing;
+
+package
+  File::ShareDir;
+
+BEGIN { $INC{'File/ShareDir.pm'} = __FILE__ }
+
+use File::Spec;
+
+sub dist_dir
+{
+  my($dist) = @_;
+  if($dist eq 'Alien-Foo2')
+  {
+    return File::Spec->rel2abs('t/alien_base/mb_share/share');
+  }
+  elsif($dist eq 'Alien-Bar1')
+  {
+    return File::Spec->rel2abs('t/alien_base/ab_sys/share');
+  }
+  elsif($dist eq 'Alien-Bar2')
+  {
+    return File::Spec->rel2abs('t/alien_base/ab_share/share');
+  }
+  else
+  {
+    die "no such share dir for $dist";
+  }
+}
diff --git a/t/alien_base/ab_share/lib/Alien/Bar2.pm b/t/alien_base/ab_share/lib/Alien/Bar2.pm
new file mode 100644
index 0000000..ecb1faf
--- /dev/null
+++ b/t/alien_base/ab_share/lib/Alien/Bar2.pm
@@ -0,0 +1,7 @@
+package Alien::Bar2;
+
+use strict;
+use warnings;
+use parent qw( Alien::Base );
+
+1;
diff --git a/t/alien_base/ab_share/share/alien_builder.json b/t/alien_base/ab_share/share/alien_builder.json
new file mode 100644
index 0000000..7d0ea60
--- /dev/null
+++ b/t/alien_base/ab_share/share/alien_builder.json
@@ -0,0 +1 @@
+{"class":"Alien::Builder::MM","init":{"extractor":null,"ffi_name":"bar2","provides_cflags":null,"msys":null,"install_commands":["make install"],"build_commands":["%c --prefix=%s --disable-https","make"],"autoconf_with_pic":null,"env":null,"retriever_spec":[{"pattern":"^libbar2-(([0-9]+\\.)*[0-9]+)\\.tar\\.gz$"}],"retriever_start":"http://ftp.gnu.org/gnu/libbar2","retriever":null,"version_check":null,"isolate_dynamic":0,"test_commands":null,"bin_requires":null,"interpolator":null,"dest_di [...]
diff --git a/t/alien_base/ab_share/share/include/bar2.h b/t/alien_base/ab_share/share/include/bar2.h
new file mode 100644
index 0000000..e69de29
diff --git a/t/alien_base/ab_sys/lib/Alien/Bar1.pm b/t/alien_base/ab_sys/lib/Alien/Bar1.pm
new file mode 100644
index 0000000..55dbb48
--- /dev/null
+++ b/t/alien_base/ab_sys/lib/Alien/Bar1.pm
@@ -0,0 +1,7 @@
+package Alien::Bar1;
+
+use strict;
+use warnings;
+use parent 'Alien::Base';
+
+1;
diff --git a/t/alien_base/ab_sys/share/alien_builder.json b/t/alien_base/ab_sys/share/alien_builder.json
new file mode 100644
index 0000000..62b2a57
--- /dev/null
+++ b/t/alien_base/ab_sys/share/alien_builder.json
@@ -0,0 +1 @@
+{"alien":null,"init":{"name":"libbar1","msys":null,"build_commands":["%c --prefix=%s --disable-https","make"],"prefix":"/home/user/dev/Alien-libbar1/Alien-libbar1-0.01/blib/lib/auto/share/dist/Alien-libbar1","arch":null,"extractor":null,"isolate_dynamic":0,"install_type":null,"helper":null,"provides_libs":null,"retriever":null,"env":null,"retriever_start":"http://ftp.gnu.org/gnu/libbar1","dest_dir":null,"install_commands":["make install"],"inline_auto_include":null,"autoconf_with_pic":nu [...]
diff --git a/t/alien_base/mb_share/lib/Alien/Foo2.pm b/t/alien_base/mb_share/lib/Alien/Foo2.pm
new file mode 100644
index 0000000..898a1db
--- /dev/null
+++ b/t/alien_base/mb_share/lib/Alien/Foo2.pm
@@ -0,0 +1,7 @@
+package Alien::Foo2;
+
+use strict;
+use warnings;
+use parent qw( Alien::Base );
+
+1;
diff --git a/t/alien_base/mb_share/lib/Alien/Foo2/ConfigData.pm b/t/alien_base/mb_share/lib/Alien/Foo2/ConfigData.pm
new file mode 100644
index 0000000..dbed0a2
--- /dev/null
+++ b/t/alien_base/mb_share/lib/Alien/Foo2/ConfigData.pm
@@ -0,0 +1,123 @@
+package Alien::Foo2::ConfigData;
+use strict;
+my $arrayref = eval do {local $/; <DATA>}
+  or die "Couldn't load ConfigData data: $@";
+close DATA;
+my ($config, $features, $auto_features) = @$arrayref;
+
+sub config { $config->{$_[1]} }
+
+sub set_config { $config->{$_[1]} = $_[2] }
+sub set_feature { $features->{$_[1]} = 0+!!$_[2] }  # Constrain to 1 or 0
+
+sub auto_feature_names { grep !exists $features->{$_}, keys %$auto_features }
+
+sub feature_names {
+  my @features = (keys %$features, auto_feature_names());
+  @features;
+}
+
+sub config_names  { keys %$config }
+
+sub write {
+  my $me = __FILE__;
+
+  # Can't use Module::Build::Dumper here because M::B is only a
+  # build-time prereq of this module
+  require Data::Dumper;
+
+  my $mode_orig = (stat $me)[2] & 07777;
+  chmod($mode_orig | 0222, $me); # Make it writeable
+  open(my $fh, '+<', $me) or die "Can't rewrite $me: $!";
+  seek($fh, 0, 0);
+  while (<$fh>) {
+    last if /^__DATA__$/;
+  }
+  die "Couldn't find __DATA__ token in $me" if eof($fh);
+
+  seek($fh, tell($fh), 0);
+  my $data = [$config, $features, $auto_features];
+  print($fh 'do{ my '
+	      . Data::Dumper->new([$data],['x'])->Purity(1)->Dump()
+	      . '$x; }' );
+  truncate($fh, tell($fh));
+  close $fh;
+
+  chmod($mode_orig, $me)
+    or warn "Couldn't restore permissions on $me: $!";
+}
+
+sub feature {
+  my ($package, $key) = @_;
+  return $features->{$key} if exists $features->{$key};
+
+  my $info = $auto_features->{$key} or return 0;
+
+  # Under perl 5.005, each(%$foo) isn't working correctly when $foo
+  # was reanimated with Data::Dumper and eval().  Not sure why, but
+  # copying to a new hash seems to solve it.
+  my %info = %$info;
+
+  require Module::Build;  # XXX should get rid of this
+  while (my ($type, $prereqs) = each %info) {
+    next if $type eq 'description' || $type eq 'recommends';
+
+    my %p = %$prereqs;  # Ditto here.
+    while (my ($modname, $spec) = each %p) {
+      my $status = Module::Build->check_installed_status($modname, $spec);
+      if ((!$status->{ok}) xor ($type =~ /conflicts$/)) { return 0; }
+      if ( ! eval "require $modname; 1" ) { return 0; }
+    }
+  }
+  return 1;
+}
+
+__DATA__
+do{ my $x = [
+       {
+         'alien_version' => undef,
+         'ffi_name' => undef,
+         'finished_installing' => 1,
+         'inline_auto_include' => [],
+         'install_type' => 'share',
+         'msys' => 0,
+         'name' => 'libfoo2',
+         'original_prefix' => '/home/user/.cpanm/work/1456299506.4021/Alien-Foo2-0.12/blib/lib/auto/share/dist/Alien-Foo2',
+         'pkgconfig' => {
+                          '_manual' => bless( {
+                                                'keywords' => {
+                                                                'Cflags' => '-I${pcfiledir}/lib/libfoo2-3.2.1/include',
+                                                                'Libs' => '-L${pcfiledir}/lib -lfoo2',
+                                                                'Version' => ''
+                                                              },
+                                                'package' => 'libfoo2',
+                                                'vars' => {
+                                                            'pcfiledir' => '/home/user/.cpanm/work/1456299506.4021/Alien-Foo2-0.12/blib/lib/auto/share/dist/Alien-Foo2'
+                                                          }
+                                              }, 'Alien::Base::PkgConfig' ),
+                          'libfoo2' => bless( {
+                                               'keywords' => {
+                                                               'Cflags' => '-I${includedir}',
+                                                               'Description' => 'Library supporting Foreign Function Interfaces',
+                                                               'Libs' => '-L${toolexeclibdir} -lfoo2',
+                                                               'Name' => 'libfoo2',
+                                                               'Version' => '3.2.1'
+                                                             },
+                                               'package' => 'libfoo2',
+                                               'vars' => {
+                                                           'exec_prefix' => '${prefix}',
+                                                           'includedir' => '${libdir}/libfoo2-3.2.1/include',
+                                                           'libdir' => '${exec_prefix}/lib',
+                                                           'pcfiledir' => '/home/user/.cpanm/work/1456299506.4021/Alien-Foo2-0.12/_alien/libfoo2-3.2.1',
+                                                           'prefix' => '/home/user/.cpanm/work/1456299506.4021/Alien-Foo2-0.12/blib/lib/auto/share/dist/Alien-Foo2',
+                                                           'toolexeclibdir' => '${exec_prefix}/lib/../lib'
+                                                         }
+                                             }, 'Alien::Base::PkgConfig' )
+                        },
+         'version' => '3.2.1',
+         'working_directory' => '/home/user/.cpanm/work/1456299506.4021/Alien-Foo2-0.12/_alien/libfoo2-3.2.1'
+       },
+       {},
+       {}
+     ];
+$x; }
diff --git a/t/alien_base/mb_share/share/README b/t/alien_base/mb_share/share/README
new file mode 100644
index 0000000..e69de29
diff --git a/t/alien_base/mb_share/share/lib/libfoo2-3.2.1/include/foo2.h b/t/alien_base/mb_share/share/lib/libfoo2-3.2.1/include/foo2.h
new file mode 100644
index 0000000..e69de29
diff --git a/t/alien_base/mb_sys/lib/Alien/Foo1.pm b/t/alien_base/mb_sys/lib/Alien/Foo1.pm
new file mode 100644
index 0000000..d5a7cfd
--- /dev/null
+++ b/t/alien_base/mb_sys/lib/Alien/Foo1.pm
@@ -0,0 +1,7 @@
+package Alien::Foo1;
+
+use strict;
+use warnings;
+use parent qw( Alien::Base );
+
+1;
diff --git a/t/alien_base/mb_sys/lib/Alien/Foo1/ConfigData.pm b/t/alien_base/mb_sys/lib/Alien/Foo1/ConfigData.pm
new file mode 100644
index 0000000..6961db3
--- /dev/null
+++ b/t/alien_base/mb_sys/lib/Alien/Foo1/ConfigData.pm
@@ -0,0 +1,91 @@
+package Alien::Foo1::ConfigData;
+use strict;
+my $arrayref = eval do {local $/; <DATA>}
+  or die "Couldn't load ConfigData data: $@";
+close DATA;
+my ($config, $features, $auto_features) = @$arrayref;
+
+sub config { $config->{$_[1]} }
+
+sub set_config { $config->{$_[1]} = $_[2] }
+sub set_feature { $features->{$_[1]} = 0+!!$_[2] }  # Constrain to 1 or 0
+
+sub auto_feature_names { grep !exists $features->{$_}, keys %$auto_features }
+
+sub feature_names {
+  my @features = (keys %$features, auto_feature_names());
+  @features;
+}
+
+sub config_names  { keys %$config }
+
+sub write {
+  my $me = __FILE__;
+
+  # Can't use Module::Build::Dumper here because M::B is only a
+  # build-time prereq of this module
+  require Data::Dumper;
+
+  my $mode_orig = (stat $me)[2] & 07777;
+  chmod($mode_orig | 0222, $me); # Make it writeable
+  open(my $fh, '+<', $me) or die "Can't rewrite $me: $!";
+  seek($fh, 0, 0);
+  while (<$fh>) {
+    last if /^__DATA__$/;
+  }
+  die "Couldn't find __DATA__ token in $me" if eof($fh);
+
+  seek($fh, tell($fh), 0);
+  my $data = [$config, $features, $auto_features];
+  print($fh 'do{ my '
+	      . Data::Dumper->new([$data],['x'])->Purity(1)->Dump()
+	      . '$x; }' );
+  truncate($fh, tell($fh));
+  close $fh;
+
+  chmod($mode_orig, $me)
+    or warn "Couldn't restore permissions on $me: $!";
+}
+
+sub feature {
+  my ($package, $key) = @_;
+  return $features->{$key} if exists $features->{$key};
+
+  my $info = $auto_features->{$key} or return 0;
+
+  # Under perl 5.005, each(%$foo) isn't working correctly when $foo
+  # was reanimated with Data::Dumper and eval().  Not sure why, but
+  # copying to a new hash seems to solve it.
+  my %info = %$info;
+
+  require Module::Build;  # XXX should get rid of this
+  while (my ($type, $prereqs) = each %info) {
+    next if $type eq 'description' || $type eq 'recommends';
+
+    my %p = %$prereqs;  # Ditto here.
+    while (my ($modname, $spec) = each %p) {
+      my $status = Module::Build->check_installed_status($modname, $spec);
+      if ((!$status->{ok}) xor ($type =~ /conflicts$/)) { return 0; }
+      if ( ! eval "require $modname; 1" ) { return 0; }
+    }
+  }
+  return 1;
+}
+
+
+__DATA__
+do{ my $x = [
+       {
+         'ffi_name' => undef,
+         'finished_installing' => 0,
+         'inline_auto_include' => [],
+         'install_type' => 'system',
+         'name' => 'libfoo1',
+         'system_provides' => {},
+         'version' => '3.99999
+'
+       },
+       {},
+       {}
+     ];
+$x; }
diff --git a/t/alien_base/pkgconfig/libbar1.pc b/t/alien_base/pkgconfig/libbar1.pc
new file mode 100644
index 0000000..fbed132
--- /dev/null
+++ b/t/alien_base/pkgconfig/libbar1.pc
@@ -0,0 +1,11 @@
+prefix=/home/user/opt/libfoo1/git-06747d318761884e70dfa433a9548219fd779d7d
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+toolexeclibdir=${exec_prefix}/lib/../lib
+includedir=${libdir}/libfoo1-3.99999/include
+
+Name: libfoo1
+Description: Library supporting Foreign Function Interfaces
+Version: 3.99999
+Libs: -lbar1
+Cflags: -DFOO=stuff
diff --git a/t/alien_base/pkgconfig/libfoo1.pc b/t/alien_base/pkgconfig/libfoo1.pc
new file mode 100644
index 0000000..f215c77
--- /dev/null
+++ b/t/alien_base/pkgconfig/libfoo1.pc
@@ -0,0 +1,11 @@
+prefix=/home/user/opt/libfoo1/git-06747d318761884e70dfa433a9548219fd779d7d
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+toolexeclibdir=${exec_prefix}/lib/../lib
+includedir=${libdir}/libfoo1-3.99999/include
+
+Name: libfoo1
+Description: Library supporting Foreign Function Interfaces
+Version: 3.99999
+Libs: -lfoo1
+Cflags: -DFOO=stuff
diff --git a/t/build_flags.t b/t/build_flags.t
new file mode 100644
index 0000000..33ce5aa
--- /dev/null
+++ b/t/build_flags.t
@@ -0,0 +1,27 @@
+use Test::More;
+
+use Alien::Base ();
+
+my %unix_flags = (
+  q{ -L/a/b/c -lz -L/a/b/c } => [ "-L/a/b/c", "-lz", "-L/a/b/c" ],
+);
+
+my %win_flags = (
+  q{ -L/a/b/c -lz -L/a/b/c } => [ "-L/a/b/c", "-lz", "-L/a/b/c" ],
+  q{ -LC:/a/b/c -lz -L"C:/a/b c/d" } => [ "-LC:/a/b/c", "-lz", "-LC:/a/b c/d" ],
+  q{ -LC:\a\b\c -lz } => [ q{-LC:\a\b\c}, "-lz" ],
+);
+
+subtest 'unix' => sub {
+  while ( my ($flag, $split) = each %unix_flags ) {
+    is_deeply( [ Alien::Base->split_flags_unix( $flag ) ], $split );
+  }
+};
+
+subtest 'windows' => sub {
+  while ( my ($flag, $split) = each %win_flags ) {
+    is_deeply( [ Alien::Base->split_flags_windows( $flag ) ], $split );
+  }
+};
+
+done_testing;
diff --git a/t/builder.t b/t/builder.t
new file mode 100644
index 0000000..bd9638c
--- /dev/null
+++ b/t/builder.t
@@ -0,0 +1,460 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+BEGIN { delete $ENV{ACTIVESTATE_PPM_BUILD} }
+
+use Alien::Base::ModuleBuild;
+use File::chdir;
+use File::Temp ();
+use File::Path qw( rmtree mkpath );
+use Capture::Tiny qw( capture );
+use FindBin ();
+
+my $dir = File::Temp->newdir;
+local $CWD = "$dir";
+
+my %basic = (
+  module_name  => 'My::Test',
+  dist_version => '0.01',
+  dist_author  => 'Joel Berger',
+);
+
+sub output_to_note (&) {
+  my $sub = shift;
+  my($out, $err) = capture { $sub->() };
+  note "[out]\n$out" if $out;
+  note "[err]\n$err" if $err;
+}
+
+our $mb_class = 'Alien::Base::ModuleBuild';
+
+sub builder {
+  my @args = @_;
+  my $builder;
+  output_to_note { $builder = $mb_class->new( %basic, @args ) };
+  $builder;
+}
+
+###########################
+#  Temporary Directories  #
+###########################
+
+subtest 'default temp and share' => sub {
+  rmtree [qw/_alien _share/], 0, 1;
+
+  my $builder = builder;
+
+  # test the builder function
+  isa_ok($builder, 'Alien::Base::ModuleBuild');
+  isa_ok($builder, 'Module::Build');
+
+  $builder->alien_init_temp_dir;
+  ok( -d '_alien', "Creates _alien dir");
+  ok( -d '_share', "Creates _share dir");
+
+  output_to_note { $builder->depends_on('clean') };
+  ok( ! -d '_alien', "Removes _alien dir");
+  ok( ! -d '_share', "Removes _share dir");
+
+  rmtree [qw/_alien _share/], 0, 1;
+};
+
+subtest 'override temp and share' => sub {
+  rmtree [qw/_test_temp _test_share/], 0, 1;
+
+  my $builder = builder(
+    alien_temp_dir => '_test_temp',
+    alien_share_dir => '_test_share',
+  );
+
+  $builder->alien_init_temp_dir;
+  ok( -d '_test_temp', "Creates _test_temp dir");
+  ok( -d '_test_share', "Creates _test_temp dir");
+
+  output_to_note { $builder->depends_on('clean') };
+  ok( ! -d '_test_temp', "Removes _test_temp dir");
+  ok( ! -d '_test_share', "Removes _test_share dir");
+
+  rmtree [qw/_test_temp _test_share/], 0, 1;
+};
+
+subtest 'destdir' => sub {
+  plan skip_all => 'TODO on MSWin32' if $^O eq 'MSWin32';
+
+  open my $fh, '>', 'build.pl';
+  print $fh <<'EOF';
+use strict;
+use warnings;
+use File::Copy qw( copy );
+
+my $cmd = shift;
+ at ARGV = map { s/DESTDIR/$ENV{DESTDIR}/g; $_ } @ARGV;
+print "% $cmd @ARGV\n";
+if($cmd eq 'mkdir')    { mkdir shift } 
+elsif($cmd eq 'touch') { open my $fh, '>', shift; close $fh; }
+elsif($cmd eq 'copy')  { copy shift, shift }
+EOF
+  close $fh;
+
+  my $destdir = File::Temp->newdir;
+  
+  mkdir 'src';
+  open $fh, '>', 'src/foo.tar.gz';
+  binmode $fh;
+  print $fh unpack("u", 
+              q{M'XL(`%)-#E0``TO+S]=GH#$P,#`P-S55`-*&YJ8&R#0<*!@:F1 at 8FYB8F1J:} .
+              q{M*A@`.>:&#`JFM'88")06ER06`9V2GY.369R.6QTA>:@_X/00`6G`^-=+K<@L} .
+              q{L+BFFF1W`\#`S,2$E_HW-S<T9%`QHYB(D,,+C?Q2, at E$P<@$`7EO"E``(````}
+            );
+  close $fh;
+  
+  my $builder = builder(
+    alien_name => 'foobarbazfakething',
+    alien_build_commands => [
+      [ $^X, "$CWD/build.pl", 'mkdir', 'bin' ],
+      [ $^X, "$CWD/build.pl", 'touch', 'bin/foo' ],
+    ],
+    alien_install_commands => [
+      [ $^X, "$CWD/build.pl", 'mkdir', 'DESTDIR%s/bin' ],
+      [ $^X, "$CWD/build.pl", 'copy',  'bin/foo', 'DESTDIR%s/bin/foo' ],
+    ],
+    alien_repository => {
+      protocol => 'local',
+      location => 'src',
+      c_compiler_required => 0,
+    },
+    alien_stage_install => 0,
+  );
+
+  my $share = $builder->alien_library_destination;
+  
+  output_to_note { $builder->depends_on('build') };
+
+  $builder->destdir($destdir);  
+  is $builder->destdir, $destdir, "destdir accessor";
+  
+  output_to_note { $builder->depends_on('install') };
+
+  my $foo_script = File::Spec->catfile($destdir, $share, 'bin', 'foo');
+  ok -e $foo_script, "script installed in destdir $foo_script";
+    
+  unlink 'build.pl';
+  rmtree [qw/ _alien  _share  blib  src /], 0, 0;
+};
+
+subtest 'alien_bin_requires' => sub {
+
+  my $bin = File::Spec->catdir($FindBin::Bin, 'builder', 'bin');
+  note "bin = $bin";
+
+  eval q{
+    package Alien::Libfoo;
+
+    our $VERSION = '1.00';
+    
+    $INC{'Alien/Libfoo.pm'} = __FILE__;
+
+    package Alien::ToolFoo;
+
+    our $VERSION = '0.37';
+    
+    $INC{'Alien/ToolFoo.pm'} = __FILE__;
+    
+    sub bin_dir {
+      ($bin)
+    }
+  };
+
+  my $builder = builder(
+    alien_name => 'foobarbazfakething',
+    build_requires => {
+      'Alien::Libfoo' => '1.00',
+    },
+    alien_bin_requires => {
+      'Alien::ToolFoo' => '0.37',
+    },
+    alien_build_commands => [
+      '/bin/true',
+    ],
+  );
+
+  is $builder->build_requires->{"Alien::MSYS"},     undef, 'no Alien::MSYS';
+  is $builder->build_requires->{"Alien::Libfoo"},  '1.00', 'normal build requires';
+  is $builder->build_requires->{"Alien::ToolFoo"}, '0.37', 'alien_bin_requires implies a build requires';
+
+  my %status;
+  output_to_note { 
+    local $CWD;
+    my $dir = File::Spec->catdir(qw( _alien buildroot ));
+    mkpath($dir, { verbose => 0 });
+    $CWD = $dir;
+    %status = $builder->alien_do_system('privateapp');
+  };
+  ok $status{success}, 'found privateapp in path';
+  if($^O eq 'MSWin32') {
+    ok -e File::Spec->catfile(qw( _alien env.cmd )), 'cmd shell helper';
+    ok -e File::Spec->catfile(qw( _alien env.bat )), 'bat shell helper';
+    ok -e File::Spec->catfile(qw( _alien env.ps1 )), 'power shell helper';
+  } else {
+    ok -e File::Spec->catfile(qw( _alien env.sh )), 'bourne shell helper';
+    ok -e File::Spec->catfile(qw( _alien env.csh )), 'c shell helper';
+  }
+
+  rmtree [qw/ _alien /], 0, 0;
+};
+
+subtest 'alien_check_built_version' => sub {
+
+  open my $fh, '>', 'build.pl';
+  print $fh <<'EOF';
+exit 0;
+EOF
+  close $fh;
+
+  mkdir 'src';
+  open $fh, '>', 'src/foo.tar.gz';
+  binmode $fh;
+  print $fh unpack("u", 
+    q{M'XL(`)"=)%0``^W1P0K",`P&X)Y]BCQ!36K2GGP8#YL,AH6UBH]OA#%DH)ZJ} .
+    q{MB/DNH;30O_W[G+>N,41,(J"3DN#C7``%)A4C$:`N)#F0UL'NSJ4>)HV2QW$H} .
+    q{MQ^?GWNW/[UCFC^BU_TLWE2&??+W6)G?H?T3F%_V'=?\<DSC`)FE6_KS_N7O8} .
+    q{50_`[SYMOYS'&&/,9-ZR`#EH`"@``}
+  );
+  close $fh;
+
+  eval q{
+    package My::ModuleBuild1;
+    
+    use base qw( Alien::Base::ModuleBuild );
+    
+    sub alien_check_built_version {
+      open my $fh, '<', 'version.txt';
+      my $txt = <$fh>;
+      close $fh;
+      $txt =~ /version = ([0-9.]+)/ ? $1 : ();
+    }
+  };
+  die $@ if $@;
+
+  local $mb_class = 'My::ModuleBuild1';
+  
+  my $builder = builder(
+    alien_name => 'foobarbazfakething',
+    alien_build_commands => [
+      [ $^X, "$CWD/build.pl" ],
+    ],
+    alien_install_commands => [
+      [ $^X, "$CWD/build.pl" ],
+    ],
+    alien_repository => {
+      protocol => 'local',
+      location => 'src',
+      c_compiler_required => 0,
+    },
+  );
+  
+  output_to_note { $builder->depends_on('build') };
+
+  is $builder->config_data( 'version' ), '2.3.4', 'version is set correctly';
+
+  unlink 'build.pl';
+  rmtree [qw/ _alien  _share  blib  src /], 0, 0;
+};
+
+subtest 'multi arg do_system' => sub {
+
+  open my $fh, '>', 'build.pl';
+  print $fh <<'EOF';
+exit($ARGV[0] =~ /^(build|install) it$/ ? 0 : 2);
+EOF
+  close $fh;
+
+  mkdir 'src';
+  open $fh, '>', 'src/foo.tar.gz';
+  binmode $fh;
+  print $fh unpack("u", 
+    q{M'XL(`)"=)%0``^W1P0K",`P&X)Y]BCQ!36K2GGP8#YL,AH6UBH]OA#%DH)ZJ} .
+    q{MB/DNH;30O_W[G+>N,41,(J"3DN#C7``%)A4C$:`N)#F0UL'NSJ4>)HV2QW$H} .
+    q{MQ^?GWNW/[UCFC^BU_TLWE2&??+W6)G?H?T3F%_V'=?\<DSC`)FE6_KS_N7O8} .
+    q{50_`[SYMOYS'&&/,9-ZR`#EH`"@``}
+  );
+  close $fh;
+
+  eval q{
+    package My::ModuleBuild2;
+    
+    use base qw( Alien::Base::ModuleBuild );
+    
+    sub alien_check_built_version {
+      open my $fh, '<', 'version.txt';
+      my $txt = <$fh>;
+      close $fh;
+      $txt =~ /version = ([0-9.]+)/ ? $1 : ();
+    }
+  };
+  die $@ if $@;
+
+  local $mb_class = 'My::ModuleBuild2';
+  
+  my $builder = builder(
+    alien_name => 'foobarbazfakething',
+    alien_build_commands => [
+      [ "%x", "$CWD/build.pl", "build it" ],
+    ],
+    alien_install_commands => [
+      [ "%x", "$CWD/build.pl", "install it" ],
+    ],
+    alien_repository => {
+      protocol => 'local',
+      location => 'src',
+      c_compiler_required => 0,
+    },
+  );
+  
+  output_to_note { $builder->depends_on('build') };
+
+  is $builder->config_data( 'version' ), '2.3.4', 'version is set correctly';
+
+  unlink 'build.pl';
+  rmtree [qw/ _alien  _share  blib  src /], 0, 0;
+};
+
+subtest 'source build requires' => sub {
+
+  local $mb_class = do {
+    package My::MBBuildRequiresExample1;
+
+    use base qw( Alien::Base::ModuleBuild );
+
+    sub alien_check_installed_version
+    {
+      return;
+    }
+
+    __PACKAGE__;
+  };
+
+  subtest 'not installed, not forced' => sub {
+    local $Alien::Base::ModuleBuild::Force = 0;
+    my $builder = builder( alien_bin_requires => { 'Foo::Bar' => '1.1' } );
+    is $builder->build_requires->{"Foo::Bar"}, '1.1', 'Foo::Bar = 1.1';
+  };
+
+  subtest 'not installed, forced' => sub {
+    local $Alien::Base::ModuleBuild::Force = 1;
+    my $builder = builder( alien_bin_requires => { 'Foo::Bar' => '1.1' } );
+    is $builder->build_requires->{"Foo::Bar"}, '1.1', 'Foo::Bar = 1.1';
+  };
+
+  local $mb_class = do {
+    package My::MBBuildRequiresExample2;
+
+    use base qw( Alien::Base::ModuleBuild );
+
+    sub alien_check_installed_version
+    {
+      return '1.2';
+    }
+
+    __PACKAGE__;
+  };
+
+  subtest 'installed, not forced' => sub {
+    local $Alien::Base::ModuleBuild::Force = 0;
+    my $builder = builder( alien_bin_requires => { 'Foo::Bar' => '1.1' } );
+    is $builder->build_requires->{"Foo::Bar"}, undef, 'Foo::Bar = undef';
+  };
+
+  subtest 'installed, forced' => sub {
+    local $Alien::Base::ModuleBuild::Force = 1;
+    my $builder = builder( alien_bin_requires => { 'Foo::Bar' => '1.1' } );
+    is $builder->build_requires->{"Foo::Bar"}, '1.1', 'Foo::Bar = 1.1';
+  };
+
+  rmtree [qw/ _alien  _share  blib  src /], 0, 0;
+};
+
+subtest 'system provides' => sub {
+
+  local $mb_class = do {
+    package My::MBBuildSystemProvidesExample;
+
+    use base qw( Alien::Base::ModuleBuild );
+
+    sub alien_check_installed_version {
+      return '1.0';
+    }
+
+    __PACKAGE__;
+  };
+
+  subtest 'not installed, not forced' => sub {
+    local $Alien::Base::ModuleBuild::Force = 0;
+    my $builder = builder( alien_provides_cflags => '-DMY_CFLAGS', alien_provides_libs => '-L/my/libs -lmylib' );
+    $builder->depends_on('code');
+    is $builder->config_data('system_provides')->{Cflags}, '-DMY_CFLAGS',          'cflags';
+    is $builder->config_data('system_provides')->{Libs},   '-L/my/libs -lmylib', 'libs';
+  };
+
+  rmtree [qw/ _alien  _share  blib  src /], 0, 0;
+};
+
+subtest 'alien_env' => sub {
+
+  local $ENV{BAZ} = 'baz';
+
+  my $builder = builder(
+    alien_helper => {
+      myhelper => '"my helper text"',
+    },
+    alien_env => {
+      FOO => 'foo1',
+      BAR => '%{myhelper}',
+      BAZ => undef,
+    },
+    alien_build_commands => [],
+  );
+  
+  isa_ok $builder, 'Alien::Base::ModuleBuild';
+  my($out, $err, %status) = capture { $builder->alien_do_system([$^X, -e => 'print $ENV{FOO}']) };
+  is $status{stdout}, 'foo1', 'env FOO passed to process';
+  ($out, $err, %status) = capture { $builder->alien_do_system([$^X, -e => 'print $ENV{BAR}']) };
+  is $status{stdout}, 'my helper text', 'alien_env works with helpers';
+  ($out, $err, %status) = capture { $builder->alien_do_system([$^X, -e => 'print $ENV{BAZ}||"undef"']) };
+  is $status{stdout}, 'undef', 'alien_env works with helpers';
+  
+  
+  rmtree [qw/ _alien  _share  blib  src /], 0, 0;
+};
+
+subtest 'cmake' => sub {
+
+  subtest 'default' => sub {
+
+    my $builder = builder(
+      alien_bin_requires => { 'Alien::CMake' => 0 },
+      alien_build_commands => [],
+    );
+
+    isa_ok $builder, 'Alien::Base::ModuleBuild';
+    is $builder->build_requires->{"Alien::CMake"}, '0.07', 'require at least 0.07';
+    rmtree [qw/ _alien  _share  blib  src /], 0, 0;  
+  };
+
+  subtest 'more recent' => sub {
+
+    my $builder = builder(
+      alien_bin_requires => { 'Alien::CMake' => '0.10' },
+      alien_build_commands => [],
+    );
+
+    isa_ok $builder, 'Alien::Base::ModuleBuild';
+    is $builder->build_requires->{"Alien::CMake"}, '0.10', 'keep 0.10';
+    rmtree [qw/ _alien  _share  blib  src /], 0, 0;  
+  };
+  
+};
+
+done_testing;
diff --git a/t/builder/bin/privateapp b/t/builder/bin/privateapp
new file mode 100755
index 0000000..16132b2
--- /dev/null
+++ b/t/builder/bin/privateapp
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo 'seems okay';
diff --git a/t/builder/bin/privateapp.bat b/t/builder/bin/privateapp.bat
new file mode 100644
index 0000000..cf42524
--- /dev/null
+++ b/t/builder/bin/privateapp.bat
@@ -0,0 +1,3 @@
+ at echo off
+
+echo "seems okay";
diff --git a/t/cabinet.t b/t/cabinet.t
new file mode 100644
index 0000000..e45e9a1
--- /dev/null
+++ b/t/cabinet.t
@@ -0,0 +1,16 @@
+use strict;
+use warnings;
+
+use Test::More tests => 4;
+
+use_ok('Alien::Base::ModuleBuild::Cabinet');
+
+my $cab = Alien::Base::ModuleBuild::Cabinet->new();
+isa_ok( $cab, 'Alien::Base::ModuleBuild::Cabinet');
+
+# make some fake file objects
+my @fake_files = map { bless {}, 'Alien::Base::ModuleBuild::File' } (1..3);
+
+is_deeply( $cab->add_files( @fake_files ), \@fake_files, "add_files the files" );
+is_deeply( $cab->files, \@fake_files, "add_files, well ... adds files");
+
diff --git a/t/file.t b/t/file.t
new file mode 100644
index 0000000..b2fcace
--- /dev/null
+++ b/t/file.t
@@ -0,0 +1,10 @@
+use strict;
+use warnings;
+
+use Test::More tests => 2;
+
+use_ok('Alien::Base::ModuleBuild::File');
+
+my $file = Alien::Base::ModuleBuild::File->new();
+isa_ok( $file, 'Alien::Base::ModuleBuild::File');
+
diff --git a/t/find_lib.t b/t/find_lib.t
new file mode 100644
index 0000000..cb4ffe1
--- /dev/null
+++ b/t/find_lib.t
@@ -0,0 +1,127 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Alien::Base::ModuleBuild;
+use File::chdir;
+
+my $expected = { 
+  lib       => [ 'lib' ], 
+  inc       => [ 'include' ],
+  lib_files => [ 'mylib' ],
+};
+
+my $dir = do {
+  local $CWD;
+  push @CWD, qw/ t find_lib dynamic /;
+  $CWD;
+};
+
+my $builder = Alien::Base::ModuleBuild->new( 
+  module_name => 'My::Test', 
+  dist_version => 0.01,
+  alien_name => 'test',
+);
+
+$builder->config( so => 'so' );
+$builder->config( ext_lib => '.a' );
+
+subtest 'Find from file structure' => sub {
+  local $expected->{lib_files} = [sort qw/mylib onlypostdot onlypredot otherlib prepostdot/];
+  my $paths = $builder->alien_find_lib_paths($dir);
+  is_deeply( $paths, $expected, "found paths from extensions only" ); 
+
+  my $pc = $builder->alien_generate_manual_pkgconfig($dir);
+  isa_ok($pc, 'Alien::Base::PkgConfig');
+
+  my $libs = $pc->keyword('Libs');
+  note "libs = $libs";
+
+  like( $libs, qr/-lmylib/, "->keyword('Libs') returns mylib" );
+
+  my ($L) = $libs =~ /-L(\S*)/g;
+  ok( -d $L,  "->keyword('Libs') finds mylib directory");
+  opendir(my $dh, $L);
+  my @files = grep { /mylib/ } readdir $dh;
+  ok( @files, "->keyword('Libs') finds mylib" );
+};
+
+subtest 'Find using alien_provides_libs' => sub {
+  $builder->alien_provides_libs('-lmylib');
+  my $paths = $builder->alien_find_lib_paths($dir);
+  is_deeply( $paths, $expected, "found paths from provides" ); 
+
+  my $pc = $builder->alien_generate_manual_pkgconfig($dir);
+  isa_ok($pc, 'Alien::Base::PkgConfig');
+
+  my $libs = $pc->keyword('Libs');
+  note "libs = $libs";
+
+  like( $libs, qr/-lmylib/, "->keyword('Libs') returns mylib" );
+
+  my ($L) = $libs =~ /-L(\S*)/g;
+  ok( -d $L,  "->keyword('Libs') finds mylib directory");
+  opendir(my $dh, $L);
+  my @files = grep { /mylib/ } readdir $dh;
+  ok( @files, "->keyword('Libs') finds mylib" );
+};
+
+$dir = do {
+  local $CWD;
+  push @CWD, qw/ t find_lib static /;
+  $CWD;
+};
+
+subtest 'Find with static libs only' => sub {
+  $builder->alien_provides_libs(undef);
+  local $expected->{lib_files} = [sort qw/mylib otherlib/];
+
+  my $paths = $builder->alien_find_lib_paths($dir);
+  is_deeply( $paths, $expected, "found paths from extensions only" );
+
+
+  my $pc = $builder->alien_generate_manual_pkgconfig($dir);
+  isa_ok($pc, 'Alien::Base::PkgConfig');
+
+  my $libs = $pc->keyword('Libs');
+  note "libs = $libs";
+
+  like( $libs, qr/-lmylib/, "->keyword('Libs') returns mylib" );
+
+  my ($L) = $libs =~ /-L(\S*)/g;
+  ok( -d $L,  "->keyword('Libs') finds mylib directory");
+  opendir(my $dh, $L);
+  my @files = grep { /mylib/ } readdir $dh;
+  ok( @files, "->keyword('Libs') finds mylib" );
+};
+
+$dir = do {
+  local $CWD;
+  push @CWD, qw/ t find_lib mixed /;
+  $CWD;
+};
+
+subtest 'Find with static libs and dynamic dir' => sub {
+  local $expected->{lib_files} = [sort qw/mylib otherlib/];
+
+  my $paths = $builder->alien_find_lib_paths($dir);
+  is_deeply( $paths, $expected, "found paths from extensions only" );
+  
+  my $pc = $builder->alien_generate_manual_pkgconfig($dir);
+  isa_ok($pc, 'Alien::Base::PkgConfig');
+
+  my $libs = $pc->keyword('Libs');
+  note "libs = $libs";
+
+  like( $libs, qr/-lmylib/, "->keyword('Libs') returns mylib" );
+
+  my ($L) = $libs =~ /-L(\S*)/g;
+  ok( -d $L,  "->keyword('Libs') finds mylib directory");
+  opendir(my $dh, $L);
+  my @files = grep { /mylib/ } readdir $dh;
+  ok( @files, "->keyword('Libs') finds mylib" );
+
+};
+
+done_testing;
+
diff --git a/t/find_lib/dynamic/include/mylib.h b/t/find_lib/dynamic/include/mylib.h
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/dynamic/include/otherlib.h b/t/find_lib/dynamic/include/otherlib.h
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/dynamic/lib/libmylib.so.0 b/t/find_lib/dynamic/lib/libmylib.so.0
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/dynamic/lib/mylib.dll b/t/find_lib/dynamic/lib/mylib.dll
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/dynamic/lib/onlypostdot.so.0 b/t/find_lib/dynamic/lib/onlypostdot.so.0
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/dynamic/lib/prepostdot.0.so.0 b/t/find_lib/dynamic/lib/prepostdot.0.so.0
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/mixed/dynamic/libmylib.so.1.2.3 b/t/find_lib/mixed/dynamic/libmylib.so.1.2.3
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/mixed/dynamic/mylib.dll b/t/find_lib/mixed/dynamic/mylib.dll
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/mixed/dynamic/otherlib.dll b/t/find_lib/mixed/dynamic/otherlib.dll
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/mixed/include/mylib.h b/t/find_lib/mixed/include/mylib.h
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/mixed/include/otherlib.h b/t/find_lib/mixed/include/otherlib.h
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/mixed/lib/mylib.lib b/t/find_lib/mixed/lib/mylib.lib
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/mixed/lib/otherlib.lib b/t/find_lib/mixed/lib/otherlib.lib
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/static/include/mylib.h b/t/find_lib/static/include/mylib.h
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/static/include/otherlib.h b/t/find_lib/static/include/otherlib.h
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/static/lib/mylib.lib b/t/find_lib/static/lib/mylib.lib
new file mode 100644
index 0000000..e69de29
diff --git a/t/find_lib/static/lib/otherlib.lib b/t/find_lib/static/lib/otherlib.lib
new file mode 100644
index 0000000..e69de29
diff --git a/t/http.t b/t/http.t
new file mode 100644
index 0000000..eecdb66
--- /dev/null
+++ b/t/http.t
@@ -0,0 +1,172 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Cwd qw( abs_path );
+use File::chdir;
+use FindBin;
+use File::Spec;
+use File::Temp;
+use URI::file;
+
+my $FILE_HOST = File::Spec->catdir( abs_path( $FindBin::Bin ), 'test_http' );
+my $INDEX_PATH = File::Spec->catfile( $FILE_HOST, 'index.html' );
+{
+  package Test::Alien::Base::HTTP;
+
+  sub new {
+    return bless {}, __PACKAGE__;
+  }
+
+  sub get {
+    local $/ = undef;
+    open my $fh, '<', $INDEX_PATH or die "Could not open $INDEX_PATH: $!";
+    return {
+      success => 1,
+      content => <$fh>,
+    };
+  }
+
+  sub mirror {
+    return {
+      success => 1,
+    };
+  }
+}
+$INC{'Test/Alien/Base/HTTP.pm'} = __FILE__;
+
+use_ok('Alien::Base::ModuleBuild::Repository::HTTP');
+
+my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new;
+
+# replicated in utils.t
+my $html = q#Some <a href=link>link text</a> stuff. And a little <A HREF="link2">different link text</a>. AN ALL CAPS TAG <A HREF="link3">ALL CAPS</A> <A HREF=link4>ALL CAPS NO QUOTES</A>. <!--  <a href="dont_follow.html">you can't see me!</a> -->#;
+my $correct = [qw/link link2 link3 link4/];
+
+SKIP: {
+  no warnings 'once';
+  skip "HTML::LinkExtor not detected", 2 
+    unless $Alien::Base::ModuleBuild::Repository::HTTP::Has_HTML_Parser; 
+
+  my @targets = $repo->find_links_preferred($html);
+  is_deeply( \@targets, $correct, "parse HTML for anchor targets (HTML::LinkExtor)");
+
+  my @disp_targets = $repo->find_links($html);
+  is_deeply( \@disp_targets, $correct, "parse HTML for anchor targets (HTML::LinkExtor, dispatched)");
+}
+
+{
+  my @targets = $repo->find_links_textbalanced($html);
+  is_deeply( \@targets, $correct, "parse HTML for anchor targets (Text::Balanced)");
+
+  # force Text::Balanced in dispatcher
+  $Alien::Base::ModuleBuild::Repository::HTTP::Has_HTML_Parser = 0;
+  my @disp_targets = $repo->find_links($html);
+  is_deeply( \@disp_targets, $correct, "parse HTML for anchor targets (Text::Balanced, dispatched)");
+}
+
+subtest 'connection() and protocol_class' => sub {
+  subtest 'HTTP::Tiny' => sub {
+    my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new(
+      protocol_class => 'HTTP::Tiny',
+    );
+    isa_ok $repo->connection, 'HTTP::Tiny', 'default HTTP class';
+  };
+
+  subtest 'LWP::UserAgent' => sub {
+    plan skip_all => 'No LWP::UserAgent detected'
+      unless eval { require LWP::UserAgent; 1 };
+    my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new(
+      protocol_class => 'LWP::UserAgent',
+    );
+    isa_ok $repo->connection, 'LWP::UserAgent';
+  };
+
+  subtest 'default' => sub {
+    my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new;
+    isa_ok $repo->connection, 'HTTP::Tiny', 'default HTTP class';
+  };
+
+  subtest 'invalid class' => sub {
+    my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new(
+      protocol_class => 'THISCOULDNEVERBEAPROTOCOLCLASSWHATAREYOUTHINKING',
+    );
+    eval { $repo->connection };
+    like $@, qr{Could not load protocol_class};
+  };
+};
+
+subtest 'list_files()' => sub {
+  subtest 'mock client' => sub {
+    my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new(
+      protocol_class => 'Test::Alien::Base::HTTP',
+      host => 'http://example.com',
+      location => '/index.html',
+    );
+    is_deeply [ $repo->list_files ], [ 'relativepackage.txt' ];
+  };
+  subtest 'LWP::UserAgent' => sub {
+    plan skip_all => 'No LWP::UserAgent' unless eval { require LWP::UserAgent; 1 };
+    my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new(
+      protocol_class => 'LWP::UserAgent',
+      host => URI::file->new($INDEX_PATH)->as_string,
+      # location doesn't work for file:// URLs
+    );
+    is_deeply [ $repo->list_files ], [ 'relativepackage.txt' ];
+  };
+};
+
+subtest 'get_file()' => sub {
+  subtest 'mock client' => sub {
+    my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new(
+      protocol_class => 'Test::Alien::Base::HTTP',
+    );
+    my $file = $repo->get_file( 'http://example.com/test.tar.gz' );
+    is $file, 'test.tar.gz';
+  };
+  subtest 'LWP::UserAgent' => sub {
+    plan skip_all => 'No LWP::UserAgent' unless eval { require LWP::UserAgent; 1 };
+    my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new(
+      protocol_class => 'LWP::UserAgent',
+    );
+    # Change to a tempdir so our file gets automatically cleaned up
+    my $tmp = File::Temp->newdir;
+    local $CWD = $tmp->dirname;
+
+    my $file = $repo->get_file( URI::file->new($INDEX_PATH)->as_string );
+    is $file, 'index.html';
+  };
+};
+
+subtest 'get()' => sub {
+  subtest 'mock client' => sub {
+    my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new(
+      protocol_class => 'Test::Alien::Base::HTTP',
+    );
+    my $file = Alien::Base::ModuleBuild::File->new(
+      repository => $repo,
+      filename => 'http://example.com/test.tar.gz',
+    );
+    my $filename = $file->get();
+    is $filename, 'test.tar.gz';
+  };
+  subtest 'LWP::UserAgent' => sub {
+    plan skip_all => 'No LWP::UserAgent' unless eval { require LWP::UserAgent; 1 };
+    my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new(
+      protocol_class => 'LWP::UserAgent',
+    );
+    # Change to a tempdir so our file gets automatically cleaned up
+    my $tmp = File::Temp->newdir;
+    local $CWD = $tmp->dirname;
+
+    my $file = Alien::Base::ModuleBuild::File->new(
+      repository => $repo,
+      filename => URI::file->new($INDEX_PATH)->as_string,
+    );
+    my $filename = $file->get();
+    is $filename, 'index.html';
+  };
+};
+
+done_testing;
+
diff --git a/t/http_uri.t b/t/http_uri.t
new file mode 100644
index 0000000..746ff60
--- /dev/null
+++ b/t/http_uri.t
@@ -0,0 +1,57 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use_ok('Alien::Base::ModuleBuild::Repository::HTTP');
+
+my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new;
+
+{
+  my $uri = $repo->build_uri('http','host.com', 'path');
+  is $uri, 'http://host.com/path', 'simplest case';
+}
+
+{
+  my $uri = $repo->build_uri('https','host.com', 'path');
+  is $uri, 'https://host.com/path', 'simplest case with the HTTPS protocol';
+}
+
+{
+  my $uri = $repo->build_uri('http','host.com', 'my path');
+  is $uri, 'http://host.com/my%20path', 'path with spaces';
+}
+
+{
+  my $uri = $repo->build_uri('http','host.com', 'deeper/', 'my path');
+  is $uri, 'http://host.com/deeper/my%20path', 'extended path with spaces';
+}
+
+{
+  my $uri = $repo->build_uri('http','host.com/', '/path');
+  is $uri, 'http://host.com/path', 'remove repeated /';
+}
+
+{
+  my $uri = $repo->build_uri('http','host.com/', '/path/', 'file.ext');
+  is $uri, 'http://host.com/path/file.ext', 'file with path';
+}
+
+{
+  my $uri = $repo->build_uri('http','host.com/', '/path/', 'http://host.com/other/file.ext');
+  is $uri, 'http://host.com/other/file.ext', 'absolute URI found in link';
+}
+
+{
+  my $uri = $repo->build_uri('http','host.com/', '/path/', 'http://example.org/other/file.ext');
+  is $uri, 'http://example.org/other/file.ext', 'absolute URI on different host';
+}
+
+{
+  my $uri = $repo->build_uri('https', 'github.com', '/libssh2/libssh2/releases/',
+                             '/libssh2/libssh2/releases/download/libssh2-1.6.0/libssh2-1.6.0.tar.gz');
+  is $uri, 'https://github.com/libssh2/libssh2/releases/download/libssh2-1.6.0/libssh2-1.6.0.tar.gz';
+}
+
+done_testing;
+
diff --git a/t/inline.t b/t/inline.t
new file mode 100644
index 0000000..a638960
--- /dev/null
+++ b/t/inline.t
@@ -0,0 +1,33 @@
+use strict;
+use warnings;
+use Test::More;
+
+BEGIN {
+  eval q{ use Inline 0.56 (); require Inline::C; } || plan skip_all => 'test requires Inline 0.56 and Inline::C';
+  eval q{ use Acme::Alien::DontPanic 0.010; 1 } || plan skip_all => 'test requires Acme::Alien::DontPanic 0.010 :' . $@;
+  plan skip_all => 'test requires that Acme::Alien::DontPanic was build with Alien::Base 0.006'
+    unless defined Acme::Alien::DontPanic->Inline("C")->{AUTO_INCLUDE};
+}
+
+use Acme::Alien::DontPanic;
+use Inline 0.56 with => 'Acme::Alien::DontPanic';
+use Inline C => 'DATA', ENABLE => 'AUTOWRAP';
+
+is string_answer(), "the answer to life the universe and everything is 42", "indirect call";
+is answer(), 42, "direct call";
+
+done_testing;
+
+__DATA__
+__C__
+
+#include <stdio.h>
+
+char *string_answer()
+{
+  static char buffer[1024];
+  sprintf(buffer, "the answer to life the universe and everything is %d", answer());
+  return buffer;
+}
+
+extern int answer();
diff --git a/t/inline_cpp.t b/t/inline_cpp.t
new file mode 100644
index 0000000..8c2a853
--- /dev/null
+++ b/t/inline_cpp.t
@@ -0,0 +1,37 @@
+use strict;
+use warnings;
+use Test::More;
+
+BEGIN {
+  eval q{ use Inline 0.56 (); require Inline::CPP; } || plan skip_all => 'test requires Inline 0.56 and Inline::CPP';
+  eval q{ use Acme::Alien::DontPanic 0.010; 1 } || plan skip_all => 'test requires Acme::Alien::DontPanic 0.010 :' . $@;
+  plan skip_all => 'test requires that Acme::Alien::DontPanic was build with Alien::Base 0.006'
+    unless defined Acme::Alien::DontPanic->Inline("CPP")->{AUTO_INCLUDE};
+}
+
+
+use Acme::Alien::DontPanic;
+use Inline 0.56 with => 'Acme::Alien::DontPanic';
+use Inline CPP => 'DATA', ENABLE => 'AUTOWRAP';
+
+is Foo->new->string_answer, "the answer to life the universe and everything is 42", 'indirect';
+is answer(), 42, "direct";
+
+done_testing;
+
+__DATA__
+__CPP__
+
+#include <stdio.h>
+
+class Foo {
+public:
+  char *string_answer()
+  {
+    static char buffer[1024];
+    sprintf(buffer, "the answer to life the universe and everything is %d", answer());
+    return buffer;
+  }
+};
+
+extern int answer();
diff --git a/t/install_destination.t b/t/install_destination.t
new file mode 100644
index 0000000..3cdf4b3
--- /dev/null
+++ b/t/install_destination.t
@@ -0,0 +1,30 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use Alien::Base::ModuleBuild;
+use File::chdir;
+use File::Temp ();
+use File::Spec;
+
+my $dir = File::Temp->newdir;
+local $CWD = "$dir";
+
+my %basic = (
+  module_name  => 'My::Test',
+  dist_version => '0.01',
+  dist_author  => 'Joel Berger',
+);
+
+my $builder = Alien::Base::ModuleBuild->new( %basic );
+my $path = $builder->alien_library_destination;
+
+# this is not good enough, I really wish I could introspect File::ShareDir, then again, I wouldn't need this test!
+my $path_to_share = File::Spec->catdir( qw/auto share dist My-Test/ );
+$path_to_share =~ s{\\}{/}g if $^O eq 'MSWin32';
+like $path, qr/\Q$path_to_share\E/, 'path looks good';
+
+
+done_testing;
+
diff --git a/t/interpolate.t b/t/interpolate.t
new file mode 100644
index 0000000..e74461a
--- /dev/null
+++ b/t/interpolate.t
@@ -0,0 +1,105 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Alien::Base::ModuleBuild;
+
+my $builder = Alien::Base::ModuleBuild->new( 
+  module_name => 'My::Test', 
+  dist_version => 0.01,
+  alien_name => 'test',
+  alien_helper => {
+    foo => ' "bar" . "baz" ',
+    exception => ' die "abcd" ',
+    double => '"1";',
+    argument_count1 => 'scalar @_',
+  },
+  alien_bin_requires => {
+    'Alien::foopatcher' => 0,
+  },
+); 
+
+is( $builder->alien_interpolate('%phello'), $builder->alien_exec_prefix . 'hello', 'prefix interpolation');
+is( $builder->alien_interpolate('%%phello'), '%phello', 'no prefix interpolation with escape');
+
+my $path = $builder->alien_library_destination;
+is( $builder->alien_interpolate('thing other=%s'), "thing other=$path", 'share_dir interpolation');
+is( $builder->alien_interpolate('thing other=%%s'), 'thing other=%s', 'no share_dir interpolation with escape');
+
+my $perl = $builder->perl;
+is( $builder->alien_interpolate('%x'), $perl, '%x is current interpreter' );
+unlike( $builder->alien_interpolate('%X'), qr{\\}, 'no backslash in %X' );
+
+# Prior to loading the version information
+{
+  my @warn             = ();
+  local $SIG{__WARN__} = sub { push @warn, @_ };
+
+  is  ( $builder->alien_interpolate('version=%v'), 'version=%v', 'version prior to setting it' );
+  isnt( join( "\n", @warn ),                       '',           'version warning prior to setting it' );
+}
+
+# After loading the version information
+#
+# The guard used below is needed so that the configuration data
+# modified as part of the test is rolled back at the end of the test.
+#
+{
+  my @warn             = ();
+  local $SIG{__WARN__} = sub { push @warn, @_ };
+
+  my $current_version = $builder->config_data( 'alien_version' ) ;
+  my $guard = MyGuard->new(
+      sub {
+	  my $self = shift;
+	  $builder->config_data( 'alien_version', $current_version );
+      },
+      );
+
+  my $test_version = time;
+  $builder->config_data( 'alien_version', $test_version );
+
+  is( $builder->alien_interpolate('version=%v'), "version=$test_version", 'version after setting it' );
+  is( join( "\n", @warn ),                       '',                      'version warning after setting it' );
+}
+
+is( $builder->alien_interpolate("|%{foo}|"), "|barbaz|", "helper" );
+is( $builder->alien_interpolate("|%{foo}|%{foo}|"), "|barbaz|barbaz|", "helper x 2" );
+eval { $builder->alien_interpolate("%{exception}") };
+like $@, qr{abcd}, "exception gets thrown";
+
+$builder->_alien_bin_require('Alien::foopatcher');
+is( $builder->alien_interpolate("|%{patch1}|"), "|patch1 --binary|", "helper from independent Alien module");
+is( $builder->alien_interpolate("|%{patch2}|"), "|patch2 --binary|", "helper from independent Alien module with code ref");
+
+eval { $builder->alien_interpolate("%{bogus}") };
+like $@, qr{no such helper: bogus}, "exception thrown with bogus helper";
+
+is( $builder->alien_interpolate('%{double}'), "1", "MB helper overrides AB helper");
+
+is( $builder->alien_interpolate('%{argument_count1}'), "0", "argument count is zero (string helper)");
+is( $builder->alien_interpolate('%{argument_count2}'), "0", "argument count is zero (code helper)");
+
+is( $builder->alien_interpolate('%{pkg_config}'), Alien::Base::PkgConfig->pkg_config_command, "support for %{pkg_config}");
+
+done_testing;
+
+package
+    MyGuard;  # Hide from PAUSE
+
+sub new     { bless { ondie => $_[1] }, $_[0] }
+sub DESTROY { $_[0]{ondie}->() if ( $_[0]{ondie} ) }
+
+package
+    Alien::foopatcher;
+
+BEGIN { $INC{'Alien/foopatcher.pm'} = __FILE__; our $VERSION = '0.01' }
+
+sub alien_helper {
+    return {
+      patch1 => 'join " ", qw(patch1 --binary)',
+      patch2 => sub { 'patch2 --binary' },
+      double => sub { 2 },
+      argument_count2 => sub { scalar @_ },
+    },
+}
diff --git a/t/local_repo.t b/t/local_repo.t
new file mode 100644
index 0000000..4b8887e
--- /dev/null
+++ b/t/local_repo.t
@@ -0,0 +1,28 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use File::Basename qw/fileparse/;
+use File::Temp;
+use File::chdir;
+
+use Alien::Base::ModuleBuild::Repository::Local;
+
+my $repo = Alien::Base::ModuleBuild::Repository::Local->new({ location => 't' });
+
+my @files = $repo->list_files;
+my $this_file = fileparse __FILE__;
+
+ok( grep { $_ eq $this_file } @files, "found this file" );
+
+{
+  my $tempdir = File::Temp->newdir;
+  local $CWD = "$tempdir";
+
+  $repo->get_file($this_file);
+  ok( -e $this_file, "copied this file to temp dir" );
+}
+
+done_testing;
+
diff --git a/t/pkgconfig.t b/t/pkgconfig.t
new file mode 100644
index 0000000..8939b36
--- /dev/null
+++ b/t/pkgconfig.t
@@ -0,0 +1,70 @@
+use strict;
+use warnings;
+
+use File::Spec;
+
+use Test::More;
+
+use_ok('Alien::Base::PkgConfig');
+
+my $file = File::Spec->catfile( qw/t pkgconfig test.pc/ );
+ok( -e $file, "Test file found" );
+
+my $pc = Alien::Base::PkgConfig->new($file);
+isa_ok( $pc, 'Alien::Base::PkgConfig' );
+
+# read tests
+my $pcfiledir = delete $pc->{vars}{pcfiledir};
+ok( -d $pcfiledir, 'pcfiledir is a directory' );
+ok( -e File::Spec->catfile($pcfiledir, 'test.pc'), 'pcfiledir contains test.pc' );
+
+is_deeply( 
+  $pc->{vars}, 
+  {
+    'INTERNAL_VARIABLE' => '-lotherlib',
+    'prefix' => '/home/test/path',
+  },
+  "read vars"
+);
+
+is_deeply(
+  $pc->{keywords},
+  {
+    'Version' => '1.01',
+    'Libs' => '-L/home/test/path/lib -lsomelib ${INTERNAL_VARIABLE} -lm -lm',
+    'Cflags' => '-I/home/test/path/deeper/include',
+    'Description' => 'My TEST Library',
+    'Name' => 'TEST',
+  },
+  "read keywords"
+);
+
+is( $pc->{package}, 'test', "understands package name from file path" );
+
+# vars getter/setter
+is( $pc->var('prefix'), '/home/test/path', "var getter" );
+is( $pc->var(deeper => '/home/test/path/deeper'), '/home/test/path/deeper', "var setter" );
+
+# abstract vars
+$pc->make_abstract('prefix');
+
+is( $pc->{vars}{deeper}, '${prefix}/deeper', "abstract vars in terms of each other" );
+is( (split qr/\s+/, $pc->{keywords}{Libs})[0], '-L${prefix}/lib', "abstract simple" );
+
+$pc->make_abstract('deeper');
+is( $pc->{keywords}{Cflags}, '-I${deeper}/include', "abstract abstract 'nested'" );
+
+# interpolate vars into keywords
+is( $pc->keyword('Version'), '1.01', "Simple keyword getter" );
+is( (split qr/\s+/, $pc->keyword('Libs'))[0], '-L/home/test/path/lib', "single interpolation keyword" );
+is( $pc->keyword('Cflags'), '-I/home/test/path/deeper/include', "multiple interpolation keyword" );
+
+# interpolate with overrides
+is( 
+  $pc->keyword( 'Cflags', {prefix => '/some/other/path'}), 
+  '-I/some/other/path/deeper/include', 
+  "multiple interpolation keyword with override"
+);
+
+done_testing;
+
diff --git a/t/pkgconfig/gsl.pc b/t/pkgconfig/gsl.pc
new file mode 100644
index 0000000..6f37267
--- /dev/null
+++ b/t/pkgconfig/gsl.pc
@@ -0,0 +1,11 @@
+prefix=/home/joel/Programs/Dist/Alien-Base/examples/Alien-GSL/_install
+exec_prefix=/home/joel/Programs/Dist/Alien-Base/examples/Alien-GSL/_install
+libdir=/home/joel/Programs/Dist/Alien-Base/examples/Alien-GSL/_install/lib
+includedir=/home/joel/Programs/Dist/Alien-Base/examples/Alien-GSL/_install/include
+GSL_CBLAS_LIB=-lgslcblas
+
+Name: GSL
+Description: GNU Scientific Library
+Version: 1.15
+Libs: -L/home/joel/Programs/Dist/Alien-Base/examples/Alien-GSL/_install/lib -lgsl ${GSL_CBLAS_LIB} -lm -lm 
+Cflags: -I/home/joel/Programs/Dist/Alien-Base/examples/Alien-GSL/_install/include
diff --git a/t/pkgconfig/test.pc b/t/pkgconfig/test.pc
new file mode 100644
index 0000000..96dee49
--- /dev/null
+++ b/t/pkgconfig/test.pc
@@ -0,0 +1,8 @@
+prefix=/home/test/path
+INTERNAL_VARIABLE=-lotherlib
+
+Name: TEST
+Description: My TEST Library
+Version: 1.01
+Libs: -L/home/test/path/lib -lsomelib ${INTERNAL_VARIABLE} -lm -lm
+Cflags: -I/home/test/path/deeper/include
diff --git a/t/repository.t b/t/repository.t
new file mode 100644
index 0000000..6cfb139
--- /dev/null
+++ b/t/repository.t
@@ -0,0 +1,120 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use File::chdir;
+local $CWD = 't';
+
+require RepositoryTest;
+
+my $default = { 
+  protocol => 'test',
+  host     => 'ftp.gnu.org',
+  location => '/gnu/gsl',
+};
+
+{
+  my $repo = Alien::Base::ModuleBuild::Repository::Test->new($default);
+
+  my @filenames = $repo->list_files;
+
+  my @files = $repo->probe();
+
+  is( scalar @files, scalar @filenames, 'without pattern, probe returns an object for each file');
+  isa_ok( $files[0], 'Alien::Base::ModuleBuild::File' );
+}
+
+{
+  my $pattern = qr/^gsl-[\d\.]+\.tar\.gz$/;
+  local $default->{pattern} = $pattern;
+  my $repo = Alien::Base::ModuleBuild::Repository::Test->new($default);
+
+  my @filenames = grep { $_ =~ $pattern } $repo->list_files;
+
+  my @files = $repo->probe();
+
+  is( scalar @files, scalar @filenames, 'with pattern, probe returns an object for each matching file');
+  isa_ok( $files[0], 'Alien::Base::ModuleBuild::File' );
+  ok( ! defined $files[0]->version, 'without capture, no version information is available');
+}
+
+{
+  my $pattern = qr/^gsl-([\d\.]+)\.tar\.gz$/;
+  local $default->{pattern} = $pattern;
+  my $repo = Alien::Base::ModuleBuild::Repository::Test->new($default);
+
+  my @filenames = grep { $_ =~ $pattern } $repo->list_files;
+
+  my @files = $repo->probe();
+
+  is( scalar @files, scalar @filenames, 'with pattern, probe returns an object for each matching file');
+  isa_ok( $files[0], 'Alien::Base::ModuleBuild::File' );
+  ok( defined $files[0]->version, 'with capture, version information is available');
+}
+
+{
+  my $filename = 'gsl-1.9.tar.gz.sig';
+  local $default->{exact_filename} = $filename;
+  my $repo = Alien::Base::ModuleBuild::Repository::Test->new($default);
+
+  my @files = $repo->probe();
+
+  is( scalar @files, 1, 'with exact filename, probe returns one object');
+  isa_ok( $files[0], 'Alien::Base::ModuleBuild::File' );
+  is( $files[0]->{filename}, $filename, 'the name of the object is the given filename');
+  ok( ! defined $files[0]->version, 'without exact version, no version information is available');
+}
+
+{
+  my $filename = 'gsl-1.9.tar.gz.sig';
+  local $default->{exact_filename} = $filename;
+  local $default->{exact_version} = '1.9';
+  my $sha1 = '17f8ce6a621da79d8343a934100dfd4278b2a5e9';
+  local $default->{sha1} = $sha1;
+  my $sha256 = 'eb154b23cc82c5c0ae0a7fb5f0b80261e88283227a8bdd830eea29bade534c58';
+  local $default->{sha256} = $sha256;
+  my $repo = Alien::Base::ModuleBuild::Repository::Test->new($default);
+
+  my @files = $repo->probe();
+
+  is( scalar @files, 1, 'with exact filename, probe returns one object');
+  isa_ok( $files[0], 'Alien::Base::ModuleBuild::File' );
+  is( $files[0]->{filename}, $filename, 'the name of the object is the given filename');
+  is( $files[0]->version, '1.9', 'with exact version, the version of the object if the given version');
+  if (eval 'require Digest::SHA') {
+      is( $files[0]->{sha1}, $sha1, 'the SHA-1 hash of the given filename');
+      is( $files[0]->{sha256}, $sha256, 'the SHA-256 hash of the given filename');
+  }
+}
+
+subtest 'exact_filename trailing slash' => sub {
+
+  my $repo = Alien::Base::ModuleBuild::Repository->new(
+    protocol       => 'https',
+    host           => 'github.com',
+    location       => 'hunspell/hunspell/archive',
+    exact_filename => 'v1.3.4.tar.gz',
+  );
+  is $repo->location, 'hunspell/hunspell/archive/', 'exact filename implies trailing /';
+
+  $repo = Alien::Base::ModuleBuild::Repository->new(
+    protocol       => 'https',
+    host           => 'github.com',
+    location       => 'hunspell/hunspell/archive/',
+    exact_filename => 'v1.3.4.tar.gz',
+  );
+  is $repo->location, 'hunspell/hunspell/archive/', 'exact filename with trailing slash already there';
+
+  $repo = Alien::Base::ModuleBuild::Repository->new(
+    protocol       => 'https',
+    host           => 'github.com',
+    location       => 'hunspell/hunspell/archive',
+    pattern        => '^v([0-9\.]+).tar.gz$',
+  );
+  is $repo->location, 'hunspell/hunspell/archive', 'no exact filename does not imply trailing /';
+
+};
+
+done_testing;
+
diff --git a/t/repository_content_disposition.t b/t/repository_content_disposition.t
new file mode 100644
index 0000000..7942773
--- /dev/null
+++ b/t/repository_content_disposition.t
@@ -0,0 +1,47 @@
+use strict;
+use warnings;
+use Test::More tests => 7;
+
+my $content_disposition;
+
+eval q{
+  package HTTP::Tiny;
+
+  sub new {
+    bless {}, 'HTTP::Tiny';
+  }
+  
+  sub mirror {
+    my $response = { success => 1 };
+    $response->{headers}->{'content-disposition'} = $content_disposition
+      if defined $content_disposition;
+    $response;
+  }
+  
+  $INC{'HTTP/Tiny.pm'} = __FILE__;
+};
+
+use_ok 'Alien::Base::ModuleBuild::Repository::HTTP';
+use_ok 'Alien::Base::ModuleBuild::File';
+
+my $repo = Alien::Base::ModuleBuild::Repository::HTTP->new(
+  host => 'foo.bar.com',
+);
+
+is Alien::Base::ModuleBuild::File->new( repository => $repo, filename => 'bogus' )->get, 'bogus', 'no content disposition';
+
+$content_disposition = 'attachment; filename=foo.txt';
+
+is Alien::Base::ModuleBuild::File->new( repository => $repo, filename => 'bogus' )->get, 'foo.txt', 'filename = foo.txt (bare)';
+
+$content_disposition = 'attachment; filename="foo.txt"';
+
+is Alien::Base::ModuleBuild::File->new( repository => $repo, filename => 'bogus' )->get, 'foo.txt', 'filename = foo.txt (double quotes)';
+
+$content_disposition = 'attachment; filename="foo with space.txt" and some other stuff';
+
+is Alien::Base::ModuleBuild::File->new( repository => $repo, filename => 'bogus' )->get, 'foo with space.txt', 'filename = foo with space.txt (double quotes with space)';
+
+$content_disposition = 'attachment; filename=foo.txt and some other stuff';
+
+is Alien::Base::ModuleBuild::File->new( repository => $repo, filename => 'bogus' )->get, 'foo.txt', 'filename = foo.txt (space terminated)';
diff --git a/t/system_installed/MANIFEST b/t/system_installed/MANIFEST
new file mode 100644
index 0000000..ef29c90
--- /dev/null
+++ b/t/system_installed/MANIFEST
@@ -0,0 +1,2 @@
+lib/MyTest.pm
+MANIFEST			This list of files
diff --git a/t/system_installed/lib/MyTest.pm b/t/system_installed/lib/MyTest.pm
new file mode 100644
index 0000000..12803ec
--- /dev/null
+++ b/t/system_installed/lib/MyTest.pm
@@ -0,0 +1,9 @@
+package MyTest;
+
+use strict;
+use warnings;
+
+use parent 'Alien::Base';
+
+1;
+
diff --git a/t/test_http/index.html b/t/test_http/index.html
new file mode 100644
index 0000000..31a54ac
--- /dev/null
+++ b/t/test_http/index.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>This is a test repository page</title>
+  </head>
+  <body>
+    <a href="relativepackage.txt">This is the package you want to download</a>
+  </body>
+</html>
diff --git a/t/utils.t b/t/utils.t
new file mode 100644
index 0000000..0f177fd
--- /dev/null
+++ b/t/utils.t
@@ -0,0 +1,24 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use_ok('Alien::Base::ModuleBuild::Utils', 'find_anchor_targets', 'pattern_has_capture_groups');
+
+# replicated in http.t
+my $html = q#Some <a href=link>link text</a> stuff. And a little <A HREF="link2">different link text</a>. <!--  <a href="dont_follow.html">you can't see me!</a> -->#;
+
+my @targets = find_anchor_targets($html);
+
+is_deeply( \@targets, [qw/link link2/], "parse HTML for anchor targets");
+
+my $pattern_zero = qr/[a-z]/;
+my $pattern_one = qr/[a-z](.)/;
+my $pattern_two = qr/[a-z](.)(.)/;
+
+is( pattern_has_capture_groups($pattern_zero), 0, "No capture groups");
+is( pattern_has_capture_groups($pattern_one), 1, "One capture group");
+is( pattern_has_capture_groups($pattern_two), 2, "Two capture group");
+
+done_testing;
+
diff --git a/t/validation.t b/t/validation.t
new file mode 100644
index 0000000..fb36582
--- /dev/null
+++ b/t/validation.t
@@ -0,0 +1,33 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use_ok('Alien::Base::ModuleBuild');
+
+my $builder = Alien::Base::ModuleBuild->new(
+  module_name  => 'My::Test::Module',
+  dist_version => '1.234.567',
+);
+
+ok( $builder->alien_validate_repo( {platform => undef} ), "undef validates to true");
+
+SKIP: {
+  skip "Windows test", 2 unless $builder->is_windowsish();
+  ok( $builder->alien_validate_repo( {platform => 'Windows'} ), "platform Windows on Windows");
+  ok( ! $builder->alien_validate_repo( {platform => 'Unix'} ), "platform Unix on Windows is false");
+}
+
+SKIP: {
+  skip "Unix test", 2 unless $builder->is_unixish();
+  ok( $builder->alien_validate_repo( {platform => 'Unix'} ), "platform Unix on Unix");
+  ok( ! $builder->alien_validate_repo( {platform => 'Windows'} ), "platform Windows on Unix is false");
+}
+
+SKIP: {
+  skip "Needs c compiler", 1 unless $builder->have_c_compiler();
+  ok( $builder->alien_validate_repo( {platform => 'src'} ), "platform src");
+}
+
+done_testing;
+
diff --git a/t/version.t b/t/version.t
new file mode 100644
index 0000000..f43a4f6
--- /dev/null
+++ b/t/version.t
@@ -0,0 +1,39 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Alien::Base::PkgConfig;
+use_ok('Alien::Base::ModuleBuild');
+
+my $pkg_config = Alien::Base::PkgConfig->pkg_config_command;
+
+my $skip;
+system( "$pkg_config --version" );
+if ( $? ) {
+  $skip = "Cannot use pkg-config: $?";
+}
+
+SKIP: {
+  skip $skip, 2 if $skip;
+
+  my @installed = map { /^(\S+)/ ? $1 : () } `$pkg_config --list-all`;
+  skip "pkg-config returned no packages", 2 unless @installed;
+  my $lib = $installed[0];
+
+  my ($builder_ok, $builder_bad) = map { 
+    Alien::Base::ModuleBuild->new( 
+      module_name => 'My::Test', 
+      dist_version => 0.01,
+      alien_name => $_,
+      share_dir => 't',
+    ); 
+  }
+  ($lib, 'siughspidghsp');
+
+  is( !! $builder_ok->alien_check_installed_version, 1, "Found installed library $lib" );
+  is( $builder_bad->alien_check_installed_version, 0, 'Returns 0 if not found' );
+
+}
+
+done_testing;
+
diff --git a/t/yy-system_installed.t b/t/yy-system_installed.t
new file mode 100644
index 0000000..4c2cef4
--- /dev/null
+++ b/t/yy-system_installed.t
@@ -0,0 +1,86 @@
+use strict;
+use warnings;
+
+use File::chdir;
+use List::Util qw/shuffle/;
+
+BEGIN { $ENV{ALIEN_FORCE} = 0 }
+
+use Test::More;
+use Alien::Base::ModuleBuild;
+use Alien::Base::PkgConfig;
+
+# Since this is not a complete distribution, it complains about missing files/folders
+local $SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /Can't (?:stat)|(?:find)/ };
+
+$ENV{ALIEN_BLIB} = 0;
+
+local $CWD;
+push @CWD, qw/t system_installed/;
+
+my $pkg_config = Alien::Base::PkgConfig->pkg_config_command;
+
+my $skip;
+system( "$pkg_config --version" );
+if ( $? ) {
+  plan skip_all => "Cannot use pkg-config: $?";
+}
+
+my @installed = shuffle map { /^(\S+)/ ? $1 : () } `$pkg_config --list-all`;
+plan skip_all => "Could not find any library for testing" unless @installed;
+
+my ($lib, $cflags, $libs);
+
+my $i = 1;
+
+while (1) {
+
+  $lib = shift @installed;
+
+  chomp( $cflags = `$pkg_config --cflags $lib` );
+  chomp( $libs = `$pkg_config --libs $lib` );
+
+  $cflags =~ s/\s*$//;
+  $libs   =~ s/\s*$//;
+
+  if ($lib and $cflags and $libs) {
+    last;
+  } 
+
+  if ($i++ == 3) {
+    plan skip_all => "Could not find a suitable library for testing";
+    last;
+  }
+
+  $lib    = undef;
+  $cflags = undef;
+  $libs   = undef;
+}
+
+my $builder = Alien::Base::ModuleBuild->new( 
+  module_name => 'MyTest', 
+  dist_version => 0.01,
+  alien_name => $lib,
+  share_dir => 't',
+); 
+
+$builder->depends_on('build');
+
+{
+  local $CWD;
+  push @CWD, qw/blib lib/;
+
+  require MyTest;
+  my $alien = MyTest->new;
+
+  isa_ok($alien, 'MyTest');
+  isa_ok($alien, 'Alien::Base');
+
+  is($alien->cflags, $cflags, "get cflags from system-installed library");
+  is($alien->libs  , $libs  , "get libs from system-installed library"  );
+}
+
+$builder->depends_on('realclean');
+
+done_testing;
+
diff --git a/xt/release/pod.t b/xt/release/pod.t
new file mode 100644
index 0000000..a2fc513
--- /dev/null
+++ b/xt/release/pod.t
@@ -0,0 +1,11 @@
+use strict;
+use warnings;
+use Test::More;
+BEGIN { 
+  plan skip_all => 'test requires Test::Pod' 
+    unless eval q{ use Test::Pod; 1 };
+};
+use Test::Pod;
+
+all_pod_files_ok( grep { -e $_ } qw( bin lib ));
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libalien-base-perl.git



More information about the Pkg-perl-cvs-commits mailing list