Download/build mclinker for Linux/Darwin

1. Download and apply patches
2. Build mclinker once with the default llvm.
   Don't build for windows for now, because mclinker
   isn't mingw-ready yet.

Change-Id: Iacd43b1ad300d15b200fadfa5ae980ebfb81c0d8
diff --git a/build/tools/build-llvm.sh b/build/tools/build-llvm.sh
index 4157d77..e4c19c1 100755
--- a/build/tools/build-llvm.sh
+++ b/build/tools/build-llvm.sh
@@ -241,8 +241,7 @@
     $EXTRA_CONFIG_FLAGS
 fail_panic "Couldn't configure llvm toolchain"
 
-
-# build the toolchain
+# build llvm/clang
 dump "Building : llvm toolchain [this can take a long time]."
 cd $LLVM_BUILD_OUT
 run make -j$NUM_JOBS $MAKE_FLAGS
@@ -263,11 +262,56 @@
 fi
 
 # install the toolchain to its final location
-dump "Install  : llvm toolchain binaries."
+dump "Install  : llvm toolchain binaries"
 cd $LLVM_BUILD_OUT && run make install $MAKE_FLAGS
 fail_panic "Couldn't install llvm toolchain to $TOOLCHAIN_BUILD_PREFIX"
 
-# clean static or shared libraries
+# Build mclinker only against default the LLVM version, once
+# mclinker isn't mingw-ready yet.  ToDo
+if [ "$TOOLCHAIN" = "llvm-$DEFAULT_LLVM_VERSION" -a "$MINGW" != "yes" ] ; then
+    dump "Copy     : mclinker source"
+    MCLINKER_SRC_DIR=$BUILD_OUT/mclinker
+    mkdir -p $MCLINKER_SRC_DIR
+    fail_panic "Couldn't create mclinker source directory: $MCLINKER_SRC_DIR"
+
+    run copy_directory "$SRC_DIR/mclinker" "$MCLINKER_SRC_DIR"
+    fail_panic "Couldn't copy mclinker source: $MCLINKER_SRC_DIR"
+
+    cd $MCLINKER_SRC_DIR && run ./autogen.sh
+    fail_panic "Couldn't run autogen.sh in $MCLINKER_SRC_DIR"
+
+    dump "Configure: mclinker against $TOOLCHAIN"
+    MCLINKER_BUILD_OUT=$MCLINKER_SRC_DIR/build
+    mkdir -p $MCLINKER_BUILD_OUT && cd $MCLINKER_BUILD_OUT
+    fail_panic "Couldn't cd into mclinker build path: $MCLINKER_BUILD_OUT"
+
+    run $MCLINKER_SRC_DIR/configure \
+        --prefix=$TOOLCHAIN_BUILD_PREFIX \
+        --with-llvm-config=$TOOLCHAIN_BUILD_PREFIX/bin/llvm-config \
+        --host=$ABI_CONFIGURE_HOST \
+        --build=$ABI_CONFIGURE_BUILD \
+        --with-bug-report-url=$DEFAULT_ISSUE_TRACKER_URL
+    fail_panic "Couldn't configure mclinker"
+
+    dump "Building : mclinker"
+    cd $MCLINKER_BUILD_OUT
+    run make -j$NUM_JOBS $MAKE_FLAGS
+    fail_panic "Couldn't compile mclinker"
+
+    dump "Install  : mclinker"
+    cd $MCLINKER_BUILD_OUT && run make install $MAKE_FLAGS
+    fail_panic "Couldn't install mclinker to $TOOLCHAIN_BUILD_PREFIX"
+
+    if [ "$CHECK" = "yes" -a "$MINGW" != "yes" -a "$DARWIN" != "yes" ] ; then
+        # run the regression test
+        dump "Running  : mclinker regression test"
+        cd $MCLINKER_BUILD_OUT
+        run make check
+        fail_warning "Couldn't pass all mclinker regression test"  # change to fail_panic later
+    fi
+fi
+
+# remove redundant bits
 rm -rf $TOOLCHAIN_BUILD_PREFIX/docs
 rm -rf $TOOLCHAIN_BUILD_PREFIX/include
 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/*.a
@@ -279,6 +323,7 @@
 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/B*.dylib
 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/LLVMH*.so
 rm -rf $TOOLCHAIN_BUILD_PREFIX/lib/LLVMH*.dylib
+rm -rf $TOOLCHAIN_BUILD_PREFIX/bin/ld.bcc*
 rm -rf $TOOLCHAIN_BUILD_PREFIX/share
 
 UNUSED_LLVM_EXECUTABLES="
diff --git a/build/tools/download-toolchain-sources.sh b/build/tools/download-toolchain-sources.sh
index c1cdd70..bb739a4 100755
--- a/build/tools/download-toolchain-sources.sh
+++ b/build/tools/download-toolchain-sources.sh
@@ -201,6 +201,7 @@
 toolchain_clone python
 toolchain_clone clang
 toolchain_clone llvm
+toolchain_clone mclinker
 
 toolchain_checkout "" $BRANCH build .
 toolchain_checkout "" $BRANCH gmp .
@@ -213,6 +214,7 @@
 toolchain_checkout "" $BRANCH gcc gcc-4.4.3 gcc-4.6 gcc-4.7
 toolchain_checkout "" $BRANCH gdb gdb-6.6 gdb-7.3.x
 toolchain_checkout "" $BRANCH python Python-2.7.3
+toolchain_checkout "" $BRANCH mclinker .
 
 for LLVM_VERSION in $LLVM_VERSION_LIST; do
     LLVM_VERSION_NO_DOT=$(echo $LLVM_VERSION | sed -e 's!\.!!g')
diff --git a/build/tools/toolchain-patches/mclinker/0001-Add-GCC-collect2-compatibility-flags.patch b/build/tools/toolchain-patches/mclinker/0001-Add-GCC-collect2-compatibility-flags.patch
new file mode 100644
index 0000000..ed3f915
--- /dev/null
+++ b/build/tools/toolchain-patches/mclinker/0001-Add-GCC-collect2-compatibility-flags.patch
@@ -0,0 +1,46 @@
+From bd187102557cfff78b1fe929db3466a3c775ebde Mon Sep 17 00:00:00 2001
+From: Andrew Hsieh <andrewhsieh@google.com>
+Date: Fri, 22 Feb 2013 12:30:18 +0800
+Subject: [PATCH 1/2] Add GCC/collect2 compatibility flags
+
+Add -use-gold, -use-mcld, and use-ld passed by GCC/collect2
+both ld.bfd ld.gold ignore
+
+Change-Id: Iaa1cb032c773d99bdc26ebf7335965c76e03a22d
+---
+ tools/llvm-mcld/llvm-mcld.cpp |   19 +++++++++++++++++++
+ 1 files changed, 19 insertions(+), 0 deletions(-)
+
+diff --git a/tools/llvm-mcld/llvm-mcld.cpp b/tools/llvm-mcld/llvm-mcld.cpp
+index 088ba07..e478729 100644
+--- a/tools/llvm-mcld/llvm-mcld.cpp
++++ b/tools/llvm-mcld/llvm-mcld.cpp
+@@ -792,6 +792,25 @@ ArgTextSegAddr("Ttext",
+                cl::init(-1U));
+ 
+ //===----------------------------------------------------------------------===//
++// Ignored GCC Compatibility Options
++//===----------------------------------------------------------------------===//
++static cl::opt<bool>
++ArgLDgold("use-gold",
++          cl::desc("GCC/collect2 compatibility: uses ld.gold.  Ignored"),
++          cl::init(false));
++
++static cl::opt<bool>
++ArgLDmcld("use-mcld",
++          cl::desc("GCC/collect2 compatibility: uses ld.mcld.  Ignored"),
++          cl::init(false));
++
++static cl::opt<bool>
++ArgLDbfd("use-ld",
++          cl::desc("GCC/collect2 compatibility: uses ld.bfd.  Ignored"),
++          cl::init(false));
++
++
++//===----------------------------------------------------------------------===//
+ // non-member functions
+ //===----------------------------------------------------------------------===//
+ /// GetOutputStream - get the output stream.
+-- 
+1.7.7.3
+
diff --git a/build/tools/toolchain-patches/mclinker/0002-Compile-agsint-llvm-3.2.patch b/build/tools/toolchain-patches/mclinker/0002-Compile-agsint-llvm-3.2.patch
new file mode 100644
index 0000000..3a41d64
--- /dev/null
+++ b/build/tools/toolchain-patches/mclinker/0002-Compile-agsint-llvm-3.2.patch
@@ -0,0 +1,92 @@
+From fb2eb10813621ec22963258220abd41e592fc430 Mon Sep 17 00:00:00 2001
+From: Andrew Hsieh <andrewhsieh@google.com>
+Date: Fri, 22 Feb 2013 12:33:36 +0800
+Subject: [PATCH 2/2] Compile agsint llvm 3.2
+
+Current mclinker needs LLVM -r 173175 which contains re-org of
+some headers from since LLVM 3.2.  This patch is to roll back
+so we can build from LLVM 3.2
+
+Change-Id: I634b7b0fa085e5bdb7a0a2861c47d6063bf36d25
+---
+ lib/CodeGen/MCLDTargetMachine.cpp |    2 +-
+ lib/CodeGen/MCLinker.cpp          |    2 +-
+ lib/Target/X86/X86Emulation.cpp   |    3 +--
+ lib/Target/X86/X86LDBackend.cpp   |    3 +--
+ tools/llvm-mcld/llvm-mcld.cpp     |    6 +++---
+ 5 files changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/lib/CodeGen/MCLDTargetMachine.cpp b/lib/CodeGen/MCLDTargetMachine.cpp
+index 785ef1f..8f5d998 100644
+--- a/lib/CodeGen/MCLDTargetMachine.cpp
++++ b/lib/CodeGen/MCLDTargetMachine.cpp
+@@ -26,7 +26,7 @@
+ #include <llvm/CodeGen/MachineModuleInfo.h>
+ #include <llvm/CodeGen/GCStrategy.h>
+ #include <llvm/CodeGen/Passes.h>
+-#include <llvm/IR/DataLayout.h>
++#include <llvm/DataLayout.h>
+ #include <llvm/MC/MCAsmInfo.h>
+ #include <llvm/MC/MCStreamer.h>
+ #include <llvm/MC/MCInstrInfo.h>
+diff --git a/lib/CodeGen/MCLinker.cpp b/lib/CodeGen/MCLinker.cpp
+index 3613a03..909278f 100644
+--- a/lib/CodeGen/MCLinker.cpp
++++ b/lib/CodeGen/MCLinker.cpp
+@@ -28,7 +28,7 @@
+ #include <mcld/Support/raw_ostream.h>
+ #include <mcld/Support/MemoryArea.h>
+ 
+-#include <llvm/IR/Module.h>
++#include <llvm/Module.h>
+ #include <llvm/Support/CommandLine.h>
+ 
+ #include <algorithm>
+diff --git a/lib/Target/X86/X86Emulation.cpp b/lib/Target/X86/X86Emulation.cpp
+index 753d7cc..1e17b03 100644
+--- a/lib/Target/X86/X86Emulation.cpp
++++ b/lib/Target/X86/X86Emulation.cpp
+@@ -23,8 +23,7 @@ static bool MCLDEmulateX86ELF(LinkerConfig& pConfig)
+   unsigned int bitclass;
+   Triple::ArchType arch = pConfig.targets().triple().getArch();
+   assert (arch == Triple::x86 || arch == Triple::x86_64);
+-  if (arch == Triple::x86 ||
+-      pConfig.targets().triple().getEnvironment() == Triple::GNUX32) {
++  if (arch == Triple::x86) {
+     bitclass = 32;
+   }
+   else {
+diff --git a/lib/Target/X86/X86LDBackend.cpp b/lib/Target/X86/X86LDBackend.cpp
+index 85c80a7..2203499 100644
+--- a/lib/Target/X86/X86LDBackend.cpp
++++ b/lib/Target/X86/X86LDBackend.cpp
+@@ -46,8 +46,7 @@ X86GNULDBackend::X86GNULDBackend(const LinkerConfig& pConfig,
+ {
+   Triple::ArchType arch = pConfig.targets().triple().getArch();
+   assert (arch == Triple::x86 || arch == Triple::x86_64);
+-  if (arch == Triple::x86 ||
+-      pConfig.targets().triple().getEnvironment() == Triple::GNUX32) {
++  if (arch == Triple::x86) {
+     m_RelEntrySize = 8;
+     m_RelaEntrySize = 12;
+     if (arch == Triple::x86)
+diff --git a/tools/llvm-mcld/llvm-mcld.cpp b/tools/llvm-mcld/llvm-mcld.cpp
+index e478729..1f77ed1 100644
+--- a/tools/llvm-mcld/llvm-mcld.cpp
++++ b/tools/llvm-mcld/llvm-mcld.cpp
+@@ -24,9 +24,9 @@
+ 
+ #include <llvm/PassManager.h>
+ #include <llvm/Pass.h>
+-#include <llvm/IR/Module.h>
+-#include <llvm/IR/DataLayout.h>
+-#include <llvm/IR/LLVMContext.h>
++#include <llvm/Module.h>
++#include <llvm/DataLayout.h>
++#include <llvm/LLVMContext.h>
+ #include <llvm/ADT/Triple.h>
+ #include <llvm/MC/SubtargetFeature.h>
+ #include <llvm/Support/CommandLine.h>
+-- 
+1.7.7.3
+