These changes are necessary to support the new llvm-config tool. llvm-config
authorReid Spencer <rspencer@reidspencer.com>
Wed, 22 Mar 2006 15:59:55 +0000 (15:59 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Wed, 22 Mar 2006 15:59:55 +0000 (15:59 +0000)
is a handy tool for users of LLVM who want to be able to quickly get
information about LLVM's configuration. It is intended to be used in the
command line of other tools. Documentation will be forthcoming in a
subsequent patch.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26952 91177308-0d34-0410-b5e6-96231b3b80d8

Makefile.rules
autoconf/configure.ac
configure
tools/llvm-config/Makefile
tools/llvm-config/find-cycles.pl [new file with mode: 0755]
tools/llvm-config/llvm-config.in.in [new file with mode: 0644]
utils/llvm-config/Makefile
utils/llvm-config/find-cycles.pl [new file with mode: 0755]
utils/llvm-config/llvm-config.in.in [new file with mode: 0644]

index 6692c73fd8325fa26048ecb46356ef060d4ce848..a066a56fb85befc2355d280d96f9986f00c65a95 100644 (file)
@@ -234,17 +234,17 @@ else
   C.Flags   += -DNDEBUG
 endif
 
-CXX.Flags += $(CXXFLAGS)
-C.Flags   += $(CFLAGS)
-CPP.Flags += $(CPPFLAGS)
-LD.Flags  += $(LDFLAGS)
-AR.Flags  := cru
+CXX.Flags     += $(CXXFLAGS)
+C.Flags       += $(CFLAGS)
+CPP.BaseFlags += $(CPPFLAGS)
+LD.Flags      += $(LDFLAGS)
+AR.Flags      := cru
 LibTool.Flags := --tag=CXX
 
 #Make Floating point ieee complient on alpha
 ifeq ($(ARCH),Alpha)
-  CXX.Flags += -mieee
-  CPP.Flags += -mieee
+  CXX.Flags     += -mieee
+  CPP.BaseFlags += -mieee
 endif
 
 #--------------------------------------------------------------------
@@ -360,13 +360,15 @@ ifeq ($(OS),HP-UX)
   CompileCommonOpts := -D_REENTRANT -D_HPUX_SOURCE
 endif
 
-LD.Flags  += -L$(LibDir) -L$(LLVMLibDir) 
-CPP.Flags += -I$(PROJ_OBJ_DIR) -I$(PROJ_SRC_DIR) \
-            -I$(PROJ_OBJ_ROOT)/include \
-            -I$(PROJ_SRC_ROOT)/include \
-            -I$(LLVM_OBJ_ROOT)/include \
-            -I$(LLVM_SRC_ROOT)/include \
-            -D_GNU_SOURCE -D__STDC_LIMIT_MACROS
+LD.Flags      += -L$(LibDir) -L$(LLVMLibDir) 
+CPP.BaseFlags += -D_GNU_SOURCE -D__STDC_LIMIT_MACROS
+# All -I flags should go here, so that they don't confuse llvm-config.
+CPP.Flags     += -I$(PROJ_OBJ_DIR) -I$(PROJ_SRC_DIR) \
+                -I$(PROJ_OBJ_ROOT)/include \
+                -I$(PROJ_SRC_ROOT)/include \
+                -I$(LLVM_OBJ_ROOT)/include \
+                -I$(LLVM_SRC_ROOT)/include \
+                $(CPP.BaseFlags)
 
 Compile.C     = $(CC) $(CPP.Flags) $(CompileCommonOpts) -c $(C.Flags)
 LTCompile.C   = $(LIBTOOL) $(LibTool.Flags) --mode=compile $(Compile.C)
@@ -386,6 +388,7 @@ Relink        = $(LIBTOOL) $(LibTool.Flags) --mode=link $(CXX) $(CPP.Flags) \
 LTInstall     = $(LIBTOOL) $(LibTool.Flags) --mode=install $(INSTALL) \
                $(Install.Flags)
 ProgInstall   = $(INSTALL) $(Install.StripFlag) -m 0755 
+ScriptInstall = $(INSTALL) -m 0755 
 DataInstall   = $(INSTALL) -m 0644
 Burg          = $(BURG) -I $(PROJ_SRC_DIR)
 TableGen      = $(TBLGEN) -I $(PROJ_SRC_DIR) -I$(PROJ_SRC_ROOT)/include
@@ -635,6 +638,9 @@ endif
 ifeq ($(ARCH),Alpha)
 USEDLIBS :=  $(subst LLVMCore, LLVMCore.a, $(USEDLIBS))
 LLVMLIBS := $(subst LLVMCore, LLVMCore.a, $(LLVMLIBS))
+CORE_IS_ARCHIVE := 1
+else
+CORE_IS_ARCHIVE := 0
 endif
 
 ProjLibsOptions := $(patsubst %.a.o, -l%, $(addsuffix .o, $(USEDLIBS)))
index 531f72b1c554a8acb2a3d8f7b8698d9cd8ac0e71..42d38c8dff391a4cb5ac11f2216c2529b2fdab91 100644 (file)
@@ -659,6 +659,9 @@ AC_CONFIG_FILES([Makefile.config])
 dnl Configure doxygen's configuration file
 AC_CONFIG_FILES([docs/doxygen.cfg])
 
+dnl Do the first stage of configuration for llvm-config.in.
+AC_CONFIG_FILES([utils/llvm-config/llvm-config.in])
+
 dnl Do special configuration of Makefiles
 AC_CONFIG_COMMANDS([setup],,[llvm_src="${srcdir}"])
 AC_CONFIG_MAKEFILE(Makefile)
index ec46bd3db4e7b44189d2ce61b540028efc0ca389..421a5fd37db099bd4986c59322a5078c88c42ee6 100755 (executable)
--- a/configure
+++ b/configure
@@ -8376,7 +8376,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 8380 "configure"
+#line 8379 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10367,7 +10367,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 10371 "configure"' > conftest.$ac_ext
+  echo '#line 10370 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -10852,7 +10852,7 @@ fi
 
 
 # Provide some information about the compiler.
-echo "$as_me:10856:" \
+echo "$as_me:10855:" \
      "checking for Fortran 77 compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
 { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@@ -11909,11 +11909,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11913: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11912: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:11917: \$? = $ac_status" >&5
+   echo "$as_me:11916: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -12152,11 +12152,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:12156: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:12155: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:12160: \$? = $ac_status" >&5
+   echo "$as_me:12159: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -12212,11 +12212,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:12216: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:12215: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:12220: \$? = $ac_status" >&5
+   echo "$as_me:12219: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -14397,7 +14397,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 14401 "configure"
+#line 14400 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -14495,7 +14495,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 14499 "configure"
+#line 14498 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -16688,11 +16688,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16692: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16691: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:16696: \$? = $ac_status" >&5
+   echo "$as_me:16695: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -16748,11 +16748,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16752: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16751: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:16756: \$? = $ac_status" >&5
+   echo "$as_me:16755: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -18109,7 +18109,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 18113 "configure"
+#line 18112 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -18207,7 +18207,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 18211 "configure"
+#line 18210 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -19044,11 +19044,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:19048: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:19047: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:19052: \$? = $ac_status" >&5
+   echo "$as_me:19051: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -19104,11 +19104,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:19108: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:19107: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:19112: \$? = $ac_status" >&5
+   echo "$as_me:19111: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -21143,11 +21143,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:21147: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:21146: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:21151: \$? = $ac_status" >&5
+   echo "$as_me:21150: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -21386,11 +21386,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:21390: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:21389: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:21394: \$? = $ac_status" >&5
+   echo "$as_me:21393: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -21446,11 +21446,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:21450: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:21449: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:21454: \$? = $ac_status" >&5
+   echo "$as_me:21453: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -23631,7 +23631,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 23635 "configure"
+#line 23634 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -23729,7 +23729,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 23733 "configure"
+#line 23732 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -30733,6 +30733,9 @@ _ACEOF
           ac_config_files="$ac_config_files docs/doxygen.cfg"
 
 
+          ac_config_files="$ac_config_files utils/llvm-config/llvm-config.in"
+
+
           ac_config_commands="$ac_config_commands setup"
 
           ac_config_commands="$ac_config_commands Makefile"
@@ -31317,6 +31320,7 @@ do
   # Handling of arguments.
   "Makefile.config" ) CONFIG_FILES="$CONFIG_FILES Makefile.config" ;;
   "docs/doxygen.cfg" ) CONFIG_FILES="$CONFIG_FILES docs/doxygen.cfg" ;;
+  "utils/llvm-config/llvm-config.in" ) CONFIG_FILES="$CONFIG_FILES utils/llvm-config/llvm-config.in" ;;
   "setup" ) CONFIG_COMMANDS="$CONFIG_COMMANDS setup" ;;
   "Makefile" ) CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile" ;;
   "Makefile.common" ) CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile.common" ;;
index 34dfa5542be0ea337a5ac0b0f07659b8b8fb81c1..8a11a279d186af822a08c0eb680da6aa59f16d70 100644 (file)
@@ -1,5 +1,5 @@
 ##===- utils/llvm-config/Makefile --------------------------*- Makefile -*-===##
-# 
+#
 #                     The LLVM Compiler Infrastructure
 #
 # This file was developed by Reid Spencer and Eric Kidd and is distributed under
@@ -12,5 +12,47 @@ LEVEL = ../..
 
 include $(LEVEL)/Makefile.common
 
+# Combine preprocessor flags (except for -I) and CXX flags.
+SUB_CXXFLAGS = ${CPP.BaseFlags} ${CXX.Flags}
+
+# This is blank for now.  We need to be careful about adding stuff here:
+# LDFLAGS tend not to be portable, and we don't currently require the
+# user to use libtool when linking against LLVM.
+SUB_LDFLAGS = 
+
+# MANUAL USE ONLY!  GenLibDeps.pl is very non-portable, so LibDeps.txt
+# should only be re-built manually.  No other rule in this file should
+# depend on LibDeps.txt.
 LibDeps.txt: $(LEVEL)/utils/GenLibDeps.pl $(LibDir)
        $(LEVEL)/utils/GenLibDeps.pl -flat $(LibDir) | sort > LibDeps.txt
+
+# Find all the cyclic dependencies between various LLVM libraries, so we
+# don't have to process them at runtime.
+FinalLibDeps.txt: find-cycles.pl # LibDeps.txt deliberately omitted.
+       $(Echo) "Finding cyclic dependencies between LLVM libraries."
+       $(Verb) $< < $(PROJ_SRC_DIR)/LibDeps.txt > $@
+
+# Rerun our configure substitutions as needed.
+llvm-config.in: llvm-config.in.in $(ConfigStatusScript)
+       $(Verb) cd $(PROJ_OBJ_ROOT) ; \
+               $(ConfigStatusScript) utils/llvm-config/llvm-config.in
+
+# Build our final script.
+llvm-config: llvm-config.in FinalLibDeps.txt
+       $(Echo) "Building llvm-config script."
+       $(Verb) $(ECHO) 's,@LLVM_CXXFLAGS@,$(SUB_CXXFLAGS),' > temp.sed
+       $(Verb) $(ECHO) 's,@LLVM_LDFLAGS@,$(SUB_LDFLAGS),' >> temp.sed
+       $(Verb) $(ECHO) 's,@CORE_IS_ARCHIVE@,$(CORE_IS_ARCHIVE),' >> temp.sed
+       $(Verb) $(SED) -f temp.sed < $< > $@
+       $(Verb) $(RM) temp.sed
+       $(Verb) cat FinalLibDeps.txt >> $@
+       $(Verb) chmod +x llvm-config
+
+# Hook into the standard Makefile rules.
+all-local:: llvm-config
+clean-local::
+       $(Verb) $(RM) -f FinalLibDeps.txt llvm-config llvm-config.in
+install-local:: all-local
+       $(Echo) Installing llvm-config
+       $(Verb) $(MKDIR) $(PROJ_bindir)
+       $(Verb) $(ScriptInstall) llvm-config $(PROJ_bindir)
diff --git a/tools/llvm-config/find-cycles.pl b/tools/llvm-config/find-cycles.pl
new file mode 100755 (executable)
index 0000000..b660955
--- /dev/null
@@ -0,0 +1,162 @@
+#!/usr/bin/perl
+#
+# Program:  find-cycles.pl
+#
+# Synopsis: Given a list of possibly cyclic dependencies, merge all the
+#           cycles.  This makes it possible to topologically sort the
+#           dependencies between different parts of LLVM.
+#
+# Syntax:   find-cycles.pl < LibDeps.txt > FinalLibDeps.txt
+#
+# Input:    cycmem1: cycmem2 dep1 dep2
+#           cycmem2: cycmem1 dep3 dep4
+#           boring: dep4
+#
+# Output:   cycmem1 cycmem2: dep1 dep2 dep3 dep4
+#           boring: dep4
+#
+# This file was written by Eric Kidd, and is placed into the public domain.
+#
+
+use strict;
+use warnings;
+
+my %DEPS;
+my @CYCLES;
+sub find_all_cycles;
+
+# Read our dependency information.
+while (<>) {
+    chomp;
+    my ($module, $dependency_str) = /^([^:]*): ?(.*)$/;
+    die "Malformed data: $_" unless defined $dependency_str;
+    my @dependencies = split(/ /, $dependency_str);
+    $DEPS{$module} = \@dependencies;
+}
+
+# Partition our raw dependencies into sets of cyclically-connected nodes.
+find_all_cycles();
+
+# Print out the finished cycles, with their dependencies.
+my @output;
+foreach my $cycle (@CYCLES) {
+    my @modules = sort keys %{$cycle};
+
+    # Merge the dependencies of all modules in this cycle.
+    my %dependencies;
+    foreach my $module (@modules) {
+        @dependencies{@{$DEPS{$module}}} = 1;
+    }
+
+    # Prune the known cyclic dependencies.
+    foreach my $module (@modules) {
+        delete $dependencies{$module};
+    }
+
+    # Warn about possible linker problems.
+    my @archives = grep(/\.a$/, @modules);
+    if (@archives > 1) {
+        print STDERR "find-cycles.pl: Circular dependency between *.a files:\n";
+        print STDERR "find-cycles.pl:   ", join(' ', @archives), "\n";
+        print STDERR "find-cycles.pl: Some linkers may have problems.\n";
+        push @modules, @archives; # WORKAROUND: Duplicate *.a files. Ick.
+    }
+
+    # Add to our output.  (@modules is already as sorted as we need it to be.)
+    push @output, (join(' ', @modules) . ': ' .
+                   join(' ', sort keys %dependencies) . "\n");
+}
+print sort @output;
+
+
+#==========================================================================
+#  Depedency Cycle Support
+#==========================================================================
+#  For now, we have cycles in our dependency graph.  Ideally, each cycle
+#  would be collapsed down to a single *.a file, saving us all this work.
+#
+#  To understand this code, you'll need a working knowledge of Perl 5,
+#  and possibly some quality time with 'man perlref'.
+
+my %SEEN;
+my %CYCLES;
+sub find_cycles ($@);
+sub found_cycles ($@);
+
+sub find_all_cycles {
+    # Find all multi-item cycles.
+    my @modules = sort keys %DEPS;
+    foreach my $module (@modules) { find_cycles($module); }
+
+    # Build fake one-item "cycles" for the remaining modules, so we can
+    # treat them uniformly.
+    foreach my $module (@modules) {
+        unless (defined $CYCLES{$module}) {
+            my %cycle = ($module, 1);
+            $CYCLES{$module} = \%cycle;
+        }
+    }
+
+    # Find all our unique cycles.  We have to do this the hard way because
+    # we apparently can't store hash references as hash keys without making
+    # 'strict refs' sad.
+    my %seen;
+    foreach my $cycle (values %CYCLES) {
+        unless ($seen{$cycle}) {
+            $seen{$cycle} = 1;
+            push @CYCLES, $cycle;
+        }
+    }
+}
+
+# Walk through our graph depth-first (keeping a trail in @path), and report
+# any cycles we find.
+sub find_cycles ($@) {
+    my ($module, @path) = @_;
+    if (str_in_list($module, @path)) {
+        found_cycle($module, @path);
+    } else {
+        return if defined $SEEN{$module};
+        $SEEN{$module} = 1;
+        foreach my $dep (@{$DEPS{$module}}) {
+            find_cycles($dep, @path, $module);
+        }
+    }
+}
+
+# Give a cycle, attempt to merge it with pre-existing cycle data.
+sub found_cycle ($@) {
+    my ($module, @path) = @_;
+
+    # Pop any modules which aren't part of our cycle.
+    while ($path[0] ne $module) { shift @path; }
+    #print join("->", @path, $module) . "\n";
+
+    # Collect the modules in our cycle into a hash.
+    my %cycle;
+    foreach my $item (@path) {
+        $cycle{$item} = 1;
+        if (defined $CYCLES{$item}) {
+            # Looks like we intersect with an existing cycle, so merge
+            # all those in, too.
+            foreach my $old_item (keys %{$CYCLES{$item}}) {
+                $cycle{$old_item} = 1;
+            }
+        }
+    }
+
+    # Update our global cycle table.
+    my $cycle_ref = \%cycle;
+    foreach my $item (keys %cycle) {
+        $CYCLES{$item} = $cycle_ref;
+    }
+    #print join(":", sort keys %cycle) . "\n";
+}
+
+sub str_in_list ($@) {
+    my ($str, @list) = @_;
+    foreach my $item (@list) {
+        return 1 if ($item eq $str);
+    }
+    return 0;
+}
diff --git a/tools/llvm-config/llvm-config.in.in b/tools/llvm-config/llvm-config.in.in
new file mode 100644 (file)
index 0000000..6f1533c
--- /dev/null
@@ -0,0 +1,364 @@
+#!/usr/bin/perl 
+#
+# Program:  llvm-config
+#
+# Synopsis: Prints out compiler options needed to build against an installed
+#           copy of LLVM.
+#
+# Syntax:   lllvm-config OPTIONS... [COMPONENTS...]
+#
+# This file was written by Eric Kidd, and is placed into the public domain.
+#
+
+use strict;
+use warnings;
+
+#---- begin autoconf values ----
+my $VERSION             = q{@PACKAGE_VERSION@};
+my $PREFIX              = q{@LLVM_PREFIX@};
+my $BINDIR              = q{@LLVM_BINDIR@};
+my $INCLUDEDIR          = q{@LLVM_INCLUDEDIR@};
+my $LIBDIR              = q{@LLVM_LIBDIR@};
+my $ARCH                = lc(q{@ARCH@});
+my @TARGETS_BUILT       = map { lc($_) } qw{@TARGETS_TO_BUILD@};
+#---- end autoconf values ----
+
+#---- begin Makefile values ----
+my $CXXFLAGS            = q{@LLVM_CXXFLAGS@};
+my $LDFLAGS             = q{@LLVM_LDFLAGS@};
+my $CORE_IS_ARCHIVE     = q{@CORE_IS_ARCHIVE@};
+#---- end Makefile values ----
+
+sub usage;
+sub fix_library_names (@);
+sub expand_dependecies (@);
+sub name_map_entries;
+
+# Parse our command-line arguments.
+usage if @ARGV == 0;
+my @components;
+my $has_opt = 0;
+my $want_libs = 0;
+my $want_libnames = 0;
+my $want_components = 0;
+foreach my $arg (@ARGV) {
+    if ($arg =~ /^-/) {
+        if ($arg eq "--version") {
+            $has_opt = 1; print "$VERSION\n";
+        } elsif ($arg eq "--prefix") {
+            $has_opt = 1; print "$PREFIX\n";
+        } elsif ($arg eq "--bindir") {
+            $has_opt = 1; print "$BINDIR\n";
+        } elsif ($arg eq "--includedir") {
+            $has_opt = 1; print "$INCLUDEDIR\n";
+        } elsif ($arg eq "--libdir") {
+            $has_opt = 1; print "$LIBDIR\n";
+        } elsif ($arg eq "--cxxflags") {
+            $has_opt = 1; print "-I$INCLUDEDIR $CXXFLAGS\n";
+        } elsif ($arg eq "--ldflags") {
+            $has_opt = 1; print "-L$LIBDIR $LDFLAGS\n";
+        } elsif ($arg eq "--libs") {
+            $has_opt = 1; $want_libs = 1;
+        } elsif ($arg eq "--libnames") {
+            $has_opt = 1; $want_libnames = 1;
+        } elsif ($arg eq "--components") {
+            $has_opt = 1; print join(' ', name_map_entries), "\n";
+        } elsif ($arg eq "--targets-built") {
+            $has_opt = 1; print join(' ', @TARGETS_BUILT), "\n";
+        } else {
+            usage();
+        }
+    } else {
+        push @components, $arg;
+    }
+}
+
+# If no options were specified, fail.
+usage unless $has_opt;
+
+# If no components were specified, default to 'all'.
+if (@components == 0) {
+    push @components, 'all';
+}
+
+# Handle any arguments which require building our dependency graph.
+if ($want_libs || $want_libnames) {
+    my @libs = expand_dependecies(@components);
+    if ($want_libs) {
+        print join(' ', fix_library_names(@libs)), "\n";
+    }
+    if ($want_libnames) {
+        print join(' ',  @libs), "\n";
+    }
+}
+
+exit 0;
+
+#==========================================================================
+#  Support Routines
+#==========================================================================
+
+sub usage {
+    print STDERR <<__EOD__;
+Usage: llvm-config <OPTION>... [<COMPONENT>...]
+
+Get various configuration information needed to compile programs which use
+LLVM.  Typically called from 'configure' scripts.  Examples:
+  llvm-config --cxxflags
+  llvm-config --ldflags
+  llvm-config --libs jitplus
+
+Options:
+  --version              LLVM version.
+  --prefix               Installation prefix.
+  --bindir               Directory containing LLVM executables.
+  --includedir           Directory containing LLVM headers.
+  --libdir               Directory containing LLVM libraries.
+  --cxxflags             C++ compiler flags for files that include LLVM headers.
+  --ldflags              Linker flags.
+  --libs                 Libraries needed to link against LLVM components.
+  --libnames             Bare library names for in-tree builds.
+  --components           List of all possible components.
+  --targets-built        List of all targets currently built.
+Typical components:
+  all                    All LLVM libraries (default).
+  native                 A native-code backend for this platform, if any.
+  jitplus                All libraries needed to use the LLVM JIT examples.
+__EOD__
+    exit(1);
+}
+
+# Use -lfoo instead of libfoo.a whenever possible, and add directories to
+# files which can't be found using -L.
+sub fix_library_names (@) {
+    my @libs = @_;
+    my @result;
+    foreach my $lib (@libs) {
+        # Transform the bare library name appropriately.
+        my ($basename) = ($lib =~ /^lib([^.]*)\.a/);
+        if (defined $basename) {
+            push @result, "-l$basename";
+        } else {
+            push @result, "$LIBDIR/$lib";
+        }
+    }
+    return @result;
+}
+
+
+#==========================================================================
+#  Library Dependency Analysis
+#==========================================================================
+#  Given a few human-readable library names, find all their dependencies
+#  and sort them into an order which the linker will like.  If we packed
+#  our libraries into fewer archives, we could make the linker do much
+#  of this work for us.
+#
+#  Libraries have two different types of names in this code: Human-friendly
+#  "component" names entered on the command-line, and the raw file names
+#  we use internally (and ultimately pass to the linker).
+#
+#  To understand this code, you'll need a working knowledge of Perl 5,
+#  and possibly some quality time with 'man perlref'.
+
+sub load_dependencies;
+sub build_name_map;
+sub find_native_platform;
+sub expand_names (@);
+sub find_all_required_sets (@);
+sub find_all_required_sets_helper ($$@);
+sub maybe_fix_core (@);
+
+# Each "set" contains one or more libraries which must be included as a
+# group (due to cyclic dependencies).  Sets are represented as a Perl array
+# reference pointing to a list of internal library names.
+my @SETS;
+
+# Various mapping tables.
+my %LIB_TO_SET_MAP; # Maps internal library names to their sets.
+my %SET_DEPS;       # Maps sets to a list of libraries they depend on.
+my %NAME_MAP;       # Maps human-entered names to internal names.
+
+# Have our dependencies been loaded yet?
+my $DEPENDENCIES_LOADED = 0;
+
+# Given a list of human-friendly component names, translate them into a
+# complete set of linker arguments.
+sub expand_dependecies (@) {
+    my @libs = @_;
+    load_dependencies;
+    my @required_sets = find_all_required_sets(expand_names(@libs));
+    my @sorted_sets = topologically_sort_sets(@required_sets);
+
+    # Expand the library sets into libraries, and apply any
+    # platform-specific hackery.
+    my @result;
+    foreach my $set (@sorted_sets) { push @result, @{$set}; }
+    return maybe_fix_core(@result);
+}
+
+# Load in the raw dependency data stored at the end of this file.
+sub load_dependencies {
+    return if $DEPENDENCIES_LOADED;
+    $DEPENDENCIES_LOADED = 1;
+    while (<DATA>) {
+        # Parse our line.
+        my ($libs, $deps) = /^(^[^:]+): ?(.*)$/;
+        die "Malformed dependency data" unless defined $deps;
+        my @libs = split(' ', $libs);
+        my @deps = split(' ', $deps);
+
+        # Record our dependency data.
+        my $set = \@libs;
+        push @SETS, $set;
+        foreach my $lib (@libs) { $LIB_TO_SET_MAP{$lib} = $set; }
+        $SET_DEPS{$set} = \@deps;
+    }
+    build_name_map;
+}
+
+# Build a map converting human-friendly component names into internal
+# library names.
+sub build_name_map {
+    # Add entries for all the actual libraries.
+    foreach my $set (@SETS) {
+        foreach my $lib (sort @$set) {
+            my $short_name = $lib;
+            $short_name =~ s/^(lib)?LLVM([^.]*)\..*$/$2/;
+            $short_name =~ tr/A-Z/a-z/;
+            $NAME_MAP{$short_name} = [$lib];
+        }
+    }
+
+    # Add virtual entries.
+    $NAME_MAP{'native'}  = find_native_platform;
+    $NAME_MAP{'jitplus'} = ['native', 'jit', 'bcreader', 'scalaropts'];
+    $NAME_MAP{'all'}     = [name_map_entries]; # Must be last.
+}
+
+# Figure our what native platform we should use, if any.
+sub find_native_platform {
+    my %BUILT;
+    foreach my $target (@TARGETS_BUILT) { $BUILT{$target} = 1; }
+    if (defined $NAME_MAP{$ARCH} && defined $BUILT{$ARCH}) {
+        return [$ARCH];
+    } else {
+        return [];
+    }
+}
+
+# Get all the human-friendly component names.
+sub name_map_entries {
+    load_dependencies;
+    return sort keys %NAME_MAP;
+}
+
+# Map human-readable names to internal library names.
+sub expand_names (@) {
+    my @names = @_;
+    my @result;
+    foreach my $name (@names) {
+        if (defined $LIB_TO_SET_MAP{$name}) {
+            # We've hit bottom: An actual library name.
+            push @result, $name;
+        } elsif (defined $NAME_MAP{$name}) {
+            # We've found a short name to expand.
+            push @result, expand_names(@{$NAME_MAP{$name}});
+        } else {
+            print STDERR "llvm-config: unknown component name: $name\n";
+            exit(1);
+        }
+    }
+    return @result;
+}
+
+# Given a list of internal library names, return all sets of libraries which
+# will need to be included by the linker (in no particular order).
+sub find_all_required_sets (@) {
+    my @libs = @_;
+    my %sets_added;
+    my @result;
+    find_all_required_sets_helper(\%sets_added, \@result, @libs);
+    return @result;
+}
+
+# Recursive closures are pretty broken in Perl, so we're going to separate
+# this function from find_all_required_sets and pass in the state we need
+# manually, as references.  Yes, this is fairly unpleasant.
+sub find_all_required_sets_helper ($$@) {
+    my ($sets_added, $result, @libs) = @_;
+    foreach my $lib (@libs) {
+        my $set = $LIB_TO_SET_MAP{$lib};
+        next if defined $$sets_added{$set};
+        $$sets_added{$set} = 1;
+        push @$result, $set;
+        find_all_required_sets_helper($sets_added, $result, @{$SET_DEPS{$set}});
+    }
+}
+
+# Print a list of sets, with a label.  Used for debugging.
+sub print_sets ($@) {
+    my ($label, @sets) = @_;
+    my @output;
+    foreach my $set (@sets) { push @output, join(',', @$set); }
+    print "$label: ", join(';', @output), "\n";
+}
+
+# Returns true if $lib is a key in $added.
+sub has_lib_been_added ($$) {
+    my ($added, $lib) = @_;
+    return defined $$added{$LIB_TO_SET_MAP{$lib}};
+}
+
+# Returns true if all the dependencies of $set appear in $added.
+sub have_all_deps_been_added ($$) {
+    my ($added, $set) = @_;
+    #print_sets("  Checking", $set);
+    #print_sets("     Wants", $SET_DEPS{$set});
+    foreach my $lib (@{$SET_DEPS{$set}}) {
+        return 0 unless has_lib_been_added($added, $lib);
+    }
+    return 1;
+}
+
+# Given a list of sets, topologically sort them using dependencies.
+sub topologically_sort_sets (@) {
+    my @sets = @_;
+    my %added;
+    my @result;
+    SCAN: while (@sets) { # We'll delete items from @sets as we go.
+        #print_sets("So far", reverse(@result));
+        #print_sets("Remaining", @sets);
+        for (my $i = 0; $i < @sets; ++$i) {
+            my $set = $sets[$i];
+            if (have_all_deps_been_added(\%added, $set)) {
+                push @result, $set;
+                $added{$set} = 1;
+                #print "Removing $i.\n";
+                splice(@sets, $i, 1);
+                next SCAN; # Restart our scan.
+            }
+        }
+        die "Can't find a library with no dependencies";
+    }
+    return reverse(@result);
+}
+
+# Nasty hack to work around the fact that LLVMCore changes file type on
+# certain platforms.
+sub maybe_fix_core (@) {
+    my @libs = @_;
+    my @result;
+    foreach my $lib (@libs) {
+        if ($lib eq "LLVMCore.o" && $CORE_IS_ARCHIVE) {
+            push @result, "libLLVMCore.a";
+        } else {
+            push @result, $lib;
+        }
+    }
+    return @result;
+}
+
+# Our library dependency data will be added after the '__END__' token, and will
+# be read through the magic <DATA> filehandle.
+__END__
index 34dfa5542be0ea337a5ac0b0f07659b8b8fb81c1..8a11a279d186af822a08c0eb680da6aa59f16d70 100644 (file)
@@ -1,5 +1,5 @@
 ##===- utils/llvm-config/Makefile --------------------------*- Makefile -*-===##
-# 
+#
 #                     The LLVM Compiler Infrastructure
 #
 # This file was developed by Reid Spencer and Eric Kidd and is distributed under
@@ -12,5 +12,47 @@ LEVEL = ../..
 
 include $(LEVEL)/Makefile.common
 
+# Combine preprocessor flags (except for -I) and CXX flags.
+SUB_CXXFLAGS = ${CPP.BaseFlags} ${CXX.Flags}
+
+# This is blank for now.  We need to be careful about adding stuff here:
+# LDFLAGS tend not to be portable, and we don't currently require the
+# user to use libtool when linking against LLVM.
+SUB_LDFLAGS = 
+
+# MANUAL USE ONLY!  GenLibDeps.pl is very non-portable, so LibDeps.txt
+# should only be re-built manually.  No other rule in this file should
+# depend on LibDeps.txt.
 LibDeps.txt: $(LEVEL)/utils/GenLibDeps.pl $(LibDir)
        $(LEVEL)/utils/GenLibDeps.pl -flat $(LibDir) | sort > LibDeps.txt
+
+# Find all the cyclic dependencies between various LLVM libraries, so we
+# don't have to process them at runtime.
+FinalLibDeps.txt: find-cycles.pl # LibDeps.txt deliberately omitted.
+       $(Echo) "Finding cyclic dependencies between LLVM libraries."
+       $(Verb) $< < $(PROJ_SRC_DIR)/LibDeps.txt > $@
+
+# Rerun our configure substitutions as needed.
+llvm-config.in: llvm-config.in.in $(ConfigStatusScript)
+       $(Verb) cd $(PROJ_OBJ_ROOT) ; \
+               $(ConfigStatusScript) utils/llvm-config/llvm-config.in
+
+# Build our final script.
+llvm-config: llvm-config.in FinalLibDeps.txt
+       $(Echo) "Building llvm-config script."
+       $(Verb) $(ECHO) 's,@LLVM_CXXFLAGS@,$(SUB_CXXFLAGS),' > temp.sed
+       $(Verb) $(ECHO) 's,@LLVM_LDFLAGS@,$(SUB_LDFLAGS),' >> temp.sed
+       $(Verb) $(ECHO) 's,@CORE_IS_ARCHIVE@,$(CORE_IS_ARCHIVE),' >> temp.sed
+       $(Verb) $(SED) -f temp.sed < $< > $@
+       $(Verb) $(RM) temp.sed
+       $(Verb) cat FinalLibDeps.txt >> $@
+       $(Verb) chmod +x llvm-config
+
+# Hook into the standard Makefile rules.
+all-local:: llvm-config
+clean-local::
+       $(Verb) $(RM) -f FinalLibDeps.txt llvm-config llvm-config.in
+install-local:: all-local
+       $(Echo) Installing llvm-config
+       $(Verb) $(MKDIR) $(PROJ_bindir)
+       $(Verb) $(ScriptInstall) llvm-config $(PROJ_bindir)
diff --git a/utils/llvm-config/find-cycles.pl b/utils/llvm-config/find-cycles.pl
new file mode 100755 (executable)
index 0000000..b660955
--- /dev/null
@@ -0,0 +1,162 @@
+#!/usr/bin/perl
+#
+# Program:  find-cycles.pl
+#
+# Synopsis: Given a list of possibly cyclic dependencies, merge all the
+#           cycles.  This makes it possible to topologically sort the
+#           dependencies between different parts of LLVM.
+#
+# Syntax:   find-cycles.pl < LibDeps.txt > FinalLibDeps.txt
+#
+# Input:    cycmem1: cycmem2 dep1 dep2
+#           cycmem2: cycmem1 dep3 dep4
+#           boring: dep4
+#
+# Output:   cycmem1 cycmem2: dep1 dep2 dep3 dep4
+#           boring: dep4
+#
+# This file was written by Eric Kidd, and is placed into the public domain.
+#
+
+use strict;
+use warnings;
+
+my %DEPS;
+my @CYCLES;
+sub find_all_cycles;
+
+# Read our dependency information.
+while (<>) {
+    chomp;
+    my ($module, $dependency_str) = /^([^:]*): ?(.*)$/;
+    die "Malformed data: $_" unless defined $dependency_str;
+    my @dependencies = split(/ /, $dependency_str);
+    $DEPS{$module} = \@dependencies;
+}
+
+# Partition our raw dependencies into sets of cyclically-connected nodes.
+find_all_cycles();
+
+# Print out the finished cycles, with their dependencies.
+my @output;
+foreach my $cycle (@CYCLES) {
+    my @modules = sort keys %{$cycle};
+
+    # Merge the dependencies of all modules in this cycle.
+    my %dependencies;
+    foreach my $module (@modules) {
+        @dependencies{@{$DEPS{$module}}} = 1;
+    }
+
+    # Prune the known cyclic dependencies.
+    foreach my $module (@modules) {
+        delete $dependencies{$module};
+    }
+
+    # Warn about possible linker problems.
+    my @archives = grep(/\.a$/, @modules);
+    if (@archives > 1) {
+        print STDERR "find-cycles.pl: Circular dependency between *.a files:\n";
+        print STDERR "find-cycles.pl:   ", join(' ', @archives), "\n";
+        print STDERR "find-cycles.pl: Some linkers may have problems.\n";
+        push @modules, @archives; # WORKAROUND: Duplicate *.a files. Ick.
+    }
+
+    # Add to our output.  (@modules is already as sorted as we need it to be.)
+    push @output, (join(' ', @modules) . ': ' .
+                   join(' ', sort keys %dependencies) . "\n");
+}
+print sort @output;
+
+
+#==========================================================================
+#  Depedency Cycle Support
+#==========================================================================
+#  For now, we have cycles in our dependency graph.  Ideally, each cycle
+#  would be collapsed down to a single *.a file, saving us all this work.
+#
+#  To understand this code, you'll need a working knowledge of Perl 5,
+#  and possibly some quality time with 'man perlref'.
+
+my %SEEN;
+my %CYCLES;
+sub find_cycles ($@);
+sub found_cycles ($@);
+
+sub find_all_cycles {
+    # Find all multi-item cycles.
+    my @modules = sort keys %DEPS;
+    foreach my $module (@modules) { find_cycles($module); }
+
+    # Build fake one-item "cycles" for the remaining modules, so we can
+    # treat them uniformly.
+    foreach my $module (@modules) {
+        unless (defined $CYCLES{$module}) {
+            my %cycle = ($module, 1);
+            $CYCLES{$module} = \%cycle;
+        }
+    }
+
+    # Find all our unique cycles.  We have to do this the hard way because
+    # we apparently can't store hash references as hash keys without making
+    # 'strict refs' sad.
+    my %seen;
+    foreach my $cycle (values %CYCLES) {
+        unless ($seen{$cycle}) {
+            $seen{$cycle} = 1;
+            push @CYCLES, $cycle;
+        }
+    }
+}
+
+# Walk through our graph depth-first (keeping a trail in @path), and report
+# any cycles we find.
+sub find_cycles ($@) {
+    my ($module, @path) = @_;
+    if (str_in_list($module, @path)) {
+        found_cycle($module, @path);
+    } else {
+        return if defined $SEEN{$module};
+        $SEEN{$module} = 1;
+        foreach my $dep (@{$DEPS{$module}}) {
+            find_cycles($dep, @path, $module);
+        }
+    }
+}
+
+# Give a cycle, attempt to merge it with pre-existing cycle data.
+sub found_cycle ($@) {
+    my ($module, @path) = @_;
+
+    # Pop any modules which aren't part of our cycle.
+    while ($path[0] ne $module) { shift @path; }
+    #print join("->", @path, $module) . "\n";
+
+    # Collect the modules in our cycle into a hash.
+    my %cycle;
+    foreach my $item (@path) {
+        $cycle{$item} = 1;
+        if (defined $CYCLES{$item}) {
+            # Looks like we intersect with an existing cycle, so merge
+            # all those in, too.
+            foreach my $old_item (keys %{$CYCLES{$item}}) {
+                $cycle{$old_item} = 1;
+            }
+        }
+    }
+
+    # Update our global cycle table.
+    my $cycle_ref = \%cycle;
+    foreach my $item (keys %cycle) {
+        $CYCLES{$item} = $cycle_ref;
+    }
+    #print join(":", sort keys %cycle) . "\n";
+}
+
+sub str_in_list ($@) {
+    my ($str, @list) = @_;
+    foreach my $item (@list) {
+        return 1 if ($item eq $str);
+    }
+    return 0;
+}
diff --git a/utils/llvm-config/llvm-config.in.in b/utils/llvm-config/llvm-config.in.in
new file mode 100644 (file)
index 0000000..6f1533c
--- /dev/null
@@ -0,0 +1,364 @@
+#!/usr/bin/perl 
+#
+# Program:  llvm-config
+#
+# Synopsis: Prints out compiler options needed to build against an installed
+#           copy of LLVM.
+#
+# Syntax:   lllvm-config OPTIONS... [COMPONENTS...]
+#
+# This file was written by Eric Kidd, and is placed into the public domain.
+#
+
+use strict;
+use warnings;
+
+#---- begin autoconf values ----
+my $VERSION             = q{@PACKAGE_VERSION@};
+my $PREFIX              = q{@LLVM_PREFIX@};
+my $BINDIR              = q{@LLVM_BINDIR@};
+my $INCLUDEDIR          = q{@LLVM_INCLUDEDIR@};
+my $LIBDIR              = q{@LLVM_LIBDIR@};
+my $ARCH                = lc(q{@ARCH@});
+my @TARGETS_BUILT       = map { lc($_) } qw{@TARGETS_TO_BUILD@};
+#---- end autoconf values ----
+
+#---- begin Makefile values ----
+my $CXXFLAGS            = q{@LLVM_CXXFLAGS@};
+my $LDFLAGS             = q{@LLVM_LDFLAGS@};
+my $CORE_IS_ARCHIVE     = q{@CORE_IS_ARCHIVE@};
+#---- end Makefile values ----
+
+sub usage;
+sub fix_library_names (@);
+sub expand_dependecies (@);
+sub name_map_entries;
+
+# Parse our command-line arguments.
+usage if @ARGV == 0;
+my @components;
+my $has_opt = 0;
+my $want_libs = 0;
+my $want_libnames = 0;
+my $want_components = 0;
+foreach my $arg (@ARGV) {
+    if ($arg =~ /^-/) {
+        if ($arg eq "--version") {
+            $has_opt = 1; print "$VERSION\n";
+        } elsif ($arg eq "--prefix") {
+            $has_opt = 1; print "$PREFIX\n";
+        } elsif ($arg eq "--bindir") {
+            $has_opt = 1; print "$BINDIR\n";
+        } elsif ($arg eq "--includedir") {
+            $has_opt = 1; print "$INCLUDEDIR\n";
+        } elsif ($arg eq "--libdir") {
+            $has_opt = 1; print "$LIBDIR\n";
+        } elsif ($arg eq "--cxxflags") {
+            $has_opt = 1; print "-I$INCLUDEDIR $CXXFLAGS\n";
+        } elsif ($arg eq "--ldflags") {
+            $has_opt = 1; print "-L$LIBDIR $LDFLAGS\n";
+        } elsif ($arg eq "--libs") {
+            $has_opt = 1; $want_libs = 1;
+        } elsif ($arg eq "--libnames") {
+            $has_opt = 1; $want_libnames = 1;
+        } elsif ($arg eq "--components") {
+            $has_opt = 1; print join(' ', name_map_entries), "\n";
+        } elsif ($arg eq "--targets-built") {
+            $has_opt = 1; print join(' ', @TARGETS_BUILT), "\n";
+        } else {
+            usage();
+        }
+    } else {
+        push @components, $arg;
+    }
+}
+
+# If no options were specified, fail.
+usage unless $has_opt;
+
+# If no components were specified, default to 'all'.
+if (@components == 0) {
+    push @components, 'all';
+}
+
+# Handle any arguments which require building our dependency graph.
+if ($want_libs || $want_libnames) {
+    my @libs = expand_dependecies(@components);
+    if ($want_libs) {
+        print join(' ', fix_library_names(@libs)), "\n";
+    }
+    if ($want_libnames) {
+        print join(' ',  @libs), "\n";
+    }
+}
+
+exit 0;
+
+#==========================================================================
+#  Support Routines
+#==========================================================================
+
+sub usage {
+    print STDERR <<__EOD__;
+Usage: llvm-config <OPTION>... [<COMPONENT>...]
+
+Get various configuration information needed to compile programs which use
+LLVM.  Typically called from 'configure' scripts.  Examples:
+  llvm-config --cxxflags
+  llvm-config --ldflags
+  llvm-config --libs jitplus
+
+Options:
+  --version              LLVM version.
+  --prefix               Installation prefix.
+  --bindir               Directory containing LLVM executables.
+  --includedir           Directory containing LLVM headers.
+  --libdir               Directory containing LLVM libraries.
+  --cxxflags             C++ compiler flags for files that include LLVM headers.
+  --ldflags              Linker flags.
+  --libs                 Libraries needed to link against LLVM components.
+  --libnames             Bare library names for in-tree builds.
+  --components           List of all possible components.
+  --targets-built        List of all targets currently built.
+Typical components:
+  all                    All LLVM libraries (default).
+  native                 A native-code backend for this platform, if any.
+  jitplus                All libraries needed to use the LLVM JIT examples.
+__EOD__
+    exit(1);
+}
+
+# Use -lfoo instead of libfoo.a whenever possible, and add directories to
+# files which can't be found using -L.
+sub fix_library_names (@) {
+    my @libs = @_;
+    my @result;
+    foreach my $lib (@libs) {
+        # Transform the bare library name appropriately.
+        my ($basename) = ($lib =~ /^lib([^.]*)\.a/);
+        if (defined $basename) {
+            push @result, "-l$basename";
+        } else {
+            push @result, "$LIBDIR/$lib";
+        }
+    }
+    return @result;
+}
+
+
+#==========================================================================
+#  Library Dependency Analysis
+#==========================================================================
+#  Given a few human-readable library names, find all their dependencies
+#  and sort them into an order which the linker will like.  If we packed
+#  our libraries into fewer archives, we could make the linker do much
+#  of this work for us.
+#
+#  Libraries have two different types of names in this code: Human-friendly
+#  "component" names entered on the command-line, and the raw file names
+#  we use internally (and ultimately pass to the linker).
+#
+#  To understand this code, you'll need a working knowledge of Perl 5,
+#  and possibly some quality time with 'man perlref'.
+
+sub load_dependencies;
+sub build_name_map;
+sub find_native_platform;
+sub expand_names (@);
+sub find_all_required_sets (@);
+sub find_all_required_sets_helper ($$@);
+sub maybe_fix_core (@);
+
+# Each "set" contains one or more libraries which must be included as a
+# group (due to cyclic dependencies).  Sets are represented as a Perl array
+# reference pointing to a list of internal library names.
+my @SETS;
+
+# Various mapping tables.
+my %LIB_TO_SET_MAP; # Maps internal library names to their sets.
+my %SET_DEPS;       # Maps sets to a list of libraries they depend on.
+my %NAME_MAP;       # Maps human-entered names to internal names.
+
+# Have our dependencies been loaded yet?
+my $DEPENDENCIES_LOADED = 0;
+
+# Given a list of human-friendly component names, translate them into a
+# complete set of linker arguments.
+sub expand_dependecies (@) {
+    my @libs = @_;
+    load_dependencies;
+    my @required_sets = find_all_required_sets(expand_names(@libs));
+    my @sorted_sets = topologically_sort_sets(@required_sets);
+
+    # Expand the library sets into libraries, and apply any
+    # platform-specific hackery.
+    my @result;
+    foreach my $set (@sorted_sets) { push @result, @{$set}; }
+    return maybe_fix_core(@result);
+}
+
+# Load in the raw dependency data stored at the end of this file.
+sub load_dependencies {
+    return if $DEPENDENCIES_LOADED;
+    $DEPENDENCIES_LOADED = 1;
+    while (<DATA>) {
+        # Parse our line.
+        my ($libs, $deps) = /^(^[^:]+): ?(.*)$/;
+        die "Malformed dependency data" unless defined $deps;
+        my @libs = split(' ', $libs);
+        my @deps = split(' ', $deps);
+
+        # Record our dependency data.
+        my $set = \@libs;
+        push @SETS, $set;
+        foreach my $lib (@libs) { $LIB_TO_SET_MAP{$lib} = $set; }
+        $SET_DEPS{$set} = \@deps;
+    }
+    build_name_map;
+}
+
+# Build a map converting human-friendly component names into internal
+# library names.
+sub build_name_map {
+    # Add entries for all the actual libraries.
+    foreach my $set (@SETS) {
+        foreach my $lib (sort @$set) {
+            my $short_name = $lib;
+            $short_name =~ s/^(lib)?LLVM([^.]*)\..*$/$2/;
+            $short_name =~ tr/A-Z/a-z/;
+            $NAME_MAP{$short_name} = [$lib];
+        }
+    }
+
+    # Add virtual entries.
+    $NAME_MAP{'native'}  = find_native_platform;
+    $NAME_MAP{'jitplus'} = ['native', 'jit', 'bcreader', 'scalaropts'];
+    $NAME_MAP{'all'}     = [name_map_entries]; # Must be last.
+}
+
+# Figure our what native platform we should use, if any.
+sub find_native_platform {
+    my %BUILT;
+    foreach my $target (@TARGETS_BUILT) { $BUILT{$target} = 1; }
+    if (defined $NAME_MAP{$ARCH} && defined $BUILT{$ARCH}) {
+        return [$ARCH];
+    } else {
+        return [];
+    }
+}
+
+# Get all the human-friendly component names.
+sub name_map_entries {
+    load_dependencies;
+    return sort keys %NAME_MAP;
+}
+
+# Map human-readable names to internal library names.
+sub expand_names (@) {
+    my @names = @_;
+    my @result;
+    foreach my $name (@names) {
+        if (defined $LIB_TO_SET_MAP{$name}) {
+            # We've hit bottom: An actual library name.
+            push @result, $name;
+        } elsif (defined $NAME_MAP{$name}) {
+            # We've found a short name to expand.
+            push @result, expand_names(@{$NAME_MAP{$name}});
+        } else {
+            print STDERR "llvm-config: unknown component name: $name\n";
+            exit(1);
+        }
+    }
+    return @result;
+}
+
+# Given a list of internal library names, return all sets of libraries which
+# will need to be included by the linker (in no particular order).
+sub find_all_required_sets (@) {
+    my @libs = @_;
+    my %sets_added;
+    my @result;
+    find_all_required_sets_helper(\%sets_added, \@result, @libs);
+    return @result;
+}
+
+# Recursive closures are pretty broken in Perl, so we're going to separate
+# this function from find_all_required_sets and pass in the state we need
+# manually, as references.  Yes, this is fairly unpleasant.
+sub find_all_required_sets_helper ($$@) {
+    my ($sets_added, $result, @libs) = @_;
+    foreach my $lib (@libs) {
+        my $set = $LIB_TO_SET_MAP{$lib};
+        next if defined $$sets_added{$set};
+        $$sets_added{$set} = 1;
+        push @$result, $set;
+        find_all_required_sets_helper($sets_added, $result, @{$SET_DEPS{$set}});
+    }
+}
+
+# Print a list of sets, with a label.  Used for debugging.
+sub print_sets ($@) {
+    my ($label, @sets) = @_;
+    my @output;
+    foreach my $set (@sets) { push @output, join(',', @$set); }
+    print "$label: ", join(';', @output), "\n";
+}
+
+# Returns true if $lib is a key in $added.
+sub has_lib_been_added ($$) {
+    my ($added, $lib) = @_;
+    return defined $$added{$LIB_TO_SET_MAP{$lib}};
+}
+
+# Returns true if all the dependencies of $set appear in $added.
+sub have_all_deps_been_added ($$) {
+    my ($added, $set) = @_;
+    #print_sets("  Checking", $set);
+    #print_sets("     Wants", $SET_DEPS{$set});
+    foreach my $lib (@{$SET_DEPS{$set}}) {
+        return 0 unless has_lib_been_added($added, $lib);
+    }
+    return 1;
+}
+
+# Given a list of sets, topologically sort them using dependencies.
+sub topologically_sort_sets (@) {
+    my @sets = @_;
+    my %added;
+    my @result;
+    SCAN: while (@sets) { # We'll delete items from @sets as we go.
+        #print_sets("So far", reverse(@result));
+        #print_sets("Remaining", @sets);
+        for (my $i = 0; $i < @sets; ++$i) {
+            my $set = $sets[$i];
+            if (have_all_deps_been_added(\%added, $set)) {
+                push @result, $set;
+                $added{$set} = 1;
+                #print "Removing $i.\n";
+                splice(@sets, $i, 1);
+                next SCAN; # Restart our scan.
+            }
+        }
+        die "Can't find a library with no dependencies";
+    }
+    return reverse(@result);
+}
+
+# Nasty hack to work around the fact that LLVMCore changes file type on
+# certain platforms.
+sub maybe_fix_core (@) {
+    my @libs = @_;
+    my @result;
+    foreach my $lib (@libs) {
+        if ($lib eq "LLVMCore.o" && $CORE_IS_ARCHIVE) {
+            push @result, "libLLVMCore.a";
+        } else {
+            push @result, $lib;
+        }
+    }
+    return @result;
+}
+
+# Our library dependency data will be added after the '__END__' token, and will
+# be read through the magic <DATA> filehandle.
+__END__