From a6f5a81285bab84212209d47b1238505512c7c87 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 10 Nov 2011 18:49:59 +0000 Subject: llvm-config: Replace with C++ version (was llvm-config-2). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144300 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-config/BuildVariables.inc.in | 26 ++ tools/llvm-config/CMakeLists.txt | 151 ++--------- tools/llvm-config/Makefile | 92 ++----- tools/llvm-config/find-cycles.pl | 170 ------------ tools/llvm-config/llvm-config.cpp | 324 ++++++++++++++++++++++ tools/llvm-config/llvm-config.in.in | 466 -------------------------------- 6 files changed, 405 insertions(+), 824 deletions(-) create mode 100644 tools/llvm-config/BuildVariables.inc.in delete mode 100755 tools/llvm-config/find-cycles.pl create mode 100644 tools/llvm-config/llvm-config.cpp delete mode 100644 tools/llvm-config/llvm-config.in.in (limited to 'tools/llvm-config') diff --git a/tools/llvm-config/BuildVariables.inc.in b/tools/llvm-config/BuildVariables.inc.in new file mode 100644 index 00000000000..5969772c9dc --- /dev/null +++ b/tools/llvm-config/BuildVariables.inc.in @@ -0,0 +1,26 @@ +//===-- BuildVariables.inc.in - llvm-config build variables -*- C++ -*-----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is configured by the build system to define the variables +// llvm-config wants to report to the user, but which can only be determined at +// build time. +// +// The non .in variant of this file has been autogenerated by the LLVM build. Do +// not edit! +// +//===----------------------------------------------------------------------===// + +#define LLVM_SRC_ROOT "@LLVM_SRC_ROOT@" +#define LLVM_OBJ_ROOT "@LLVM_OBJ_ROOT@" +#define LLVM_CPPFLAGS "@LLVM_CPPFLAGS@" +#define LLVM_CFLAGS "@LLVM_CFLAGS@" +#define LLVM_LDFLAGS "@LLVM_LDFLAGS@" +#define LLVM_CXXFLAGS "@LLVM_CXXFLAGS@" +#define LLVM_BUILDMODE "@LLVM_BUILDMODE@" +#define LLVM_SYSTEM_LIBS "@LLVM_SYSTEM_LIBS@" diff --git a/tools/llvm-config/CMakeLists.txt b/tools/llvm-config/CMakeLists.txt index 53f00846b79..ed26ba95553 100644 --- a/tools/llvm-config/CMakeLists.txt +++ b/tools/llvm-config/CMakeLists.txt @@ -1,138 +1,41 @@ -include(TestBigEndian) +set(LLVM_LINK_COMPONENTS support) -include(FindPerl) -if( NOT PERL_FOUND ) - message(FATAL_ERROR "Perl required but not found!") -endif( NOT PERL_FOUND ) - -set(PERL ${PERL_EXECUTABLE}) -set(VERSION PACKAGE_VERSION) -set(PREFIX ${CMAKE_INSTALL_PREFIX}) -set(abs_top_srcdir ${LLVM_MAIN_SRC_DIR}) -set(abs_top_builddir ${LLVM_BINARY_DIR}) -execute_process(COMMAND date - OUTPUT_VARIABLE LLVM_CONFIGTIME - OUTPUT_STRIP_TRAILING_WHITESPACE) -# LLVM_ON_UNIX and LLVM_ON_WIN32 already set. -# those are set to blank by `autoconf' on MinGW, so it seems they are not required: -#set(LLVMGCCDIR "") -#set(LLVMGCC "") -#set(LLVMGXX "") -test_big_endian(IS_BIG_ENDIAN) -if( IS_BIG_ENDIAN ) - set(ENDIAN "big") -else( IS_BIG_ENDIAN ) - set(ENDIAN "little") -endif( IS_BIG_ENDIAN ) -set(SHLIBEXT ${LTDL_SHLIB_EXT}) -#EXEEXT already set. -set(OS "${CMAKE_SYSTEM}") -set(target "${TARGET_TRIPLE}") -set(ARCH "${LLVM_NATIVE_ARCH}") +# We need to generate the BuildVariables.inc file containing values which are +# only defined when under certain build modes. Unfortunately, that precludes +# doing this inside CMake so we have to shell out to sed. For now, that means we +# can't expect to build llvm-config on Window.s +set(BUILDVARIABLES_SRCPATH ${CMAKE_CURRENT_SOURCE_DIR}/BuildVariables.inc.in) +set(BUILDVARIABLES_OBJPATH ${CMAKE_CURRENT_BINARY_DIR}/BuildVariables.inc) +set(SEDSCRIPT_OBJPATH ${CMAKE_CURRENT_BINARY_DIR}/BuildVariables.configure.sed) +# Compute the substitution values for various items. get_system_libs(LLVM_SYSTEM_LIBS_LIST) foreach(l ${LLVM_SYSTEM_LIBS_LIST}) - set(LLVM_SYSTEM_LIBS ${LLVM_SYSTEM_LIBS} "-l${l}") + set(SYSTEM_LIBS ${SYSTEM_LIBS} "-l${l}") endforeach() - -foreach(c ${LLVM_TARGETS_TO_BUILD}) - set(TARGETS_BUILT "${TARGETS_BUILT} ${c}") -endforeach(c) -set(TARGETS_TO_BUILD ${TARGETS_BUILT}) -set(TARGET_HAS_JIT "1") # TODO - -# Avoids replacement at config-time: -set(LLVM_CPPFLAGS "@LLVM_CPPFLAGS@") -set(LLVM_CFLAGS "@LLVM_CFLAGS@") -set(LLVM_CXXFLAGS "@LLVM_CXXFLAGS@") -set(LLVM_LDFLAGS "@LLVM_LDFLAGS@") -set(LIBS "@LIBS@") -set(LLVM_BUILDMODE "@LLVM_BUILDMODE@") -set(LLVM_OBJ_SUFFIX "@LLVM_OBJ_SUFFIX@") - -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/llvm-config.in.in - ${CMAKE_CURRENT_BINARY_DIR}/llvm-config.in - @ONLY -) - -set(LIBDEPS LibDeps.txt) -set(LIBDEPS_TMP LibDeps.txt.tmp) -set(FINAL_LIBDEPS FinalLibDeps.txt) -set(LLVM_CONFIG ${LLVM_TOOLS_BINARY_DIR}/llvm-config) -set(LLVM_CONFIG_IN ${CMAKE_CURRENT_BINARY_DIR}/llvm-config.in) - -if( CMAKE_CROSSCOMPILING ) - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) -endif() - -find_program(NM_PATH nm PATH_SUFFIXES /bin) - -if( NOT NM_PATH ) - message(FATAL_ERROR "`nm' not found") -endif() - -get_property(llvm_libs GLOBAL PROPERTY LLVM_LIBS) - -add_custom_command(OUTPUT ${LIBDEPS_TMP} - COMMAND ${PERL_EXECUTABLE} ${LLVM_MAIN_SRC_DIR}/utils/GenLibDeps.pl -flat ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} ${NM_PATH} > ${LIBDEPS_TMP} - DEPENDS ${llvm_libs} - COMMENT "Regenerating ${LIBDEPS_TMP}") - -add_custom_command(OUTPUT ${LIBDEPS} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${LIBDEPS_TMP} ${LIBDEPS} - DEPENDS ${LIBDEPS_TMP} - COMMENT "Updating ${LIBDEPS} if necessary...") - -# This must stop the build if find-cycles.pl returns error: -add_custom_command(OUTPUT ${FINAL_LIBDEPS} - COMMAND ${CMAKE_COMMAND} -E remove -f ${FINAL_LIBDEPS} ${FINAL_LIBDEPS}.tmp - COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/find-cycles.pl < ${LIBDEPS} > ${FINAL_LIBDEPS}.tmp - COMMAND ${CMAKE_COMMAND} -E copy ${FINAL_LIBDEPS}.tmp ${FINAL_LIBDEPS} - DEPENDS ${LIBDEPS} - COMMENT "Checking for cyclic dependencies between LLVM libraries.") - set(C_FLGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") set(CXX_FLGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") set(CPP_FLGS "${CMAKE_CPP_FLAGS} ${CMAKE_CPP_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") -# We don't want certain flags on the output of -# llvm-config --cflags --cxxflags -macro(remove_option_from_llvm_config option) - llvm_replace_compiler_option(C_FLGS "${option}" "") - llvm_replace_compiler_option(CXX_FLGS "${option}" "") - llvm_replace_compiler_option(CPP_FLGS "${option}" "") -endmacro(remove_option_from_llvm_config) -remove_option_from_llvm_config("-pedantic") -remove_option_from_llvm_config("-Wall") -remove_option_from_llvm_config("-W") - -add_custom_command(OUTPUT ${LLVM_CONFIG} - COMMAND echo s!@LLVM_CPPFLAGS@!${CPP_FLGS}! > temp.sed - COMMAND echo s!@LLVM_CFLAGS@!${C_FLGS}! >> temp.sed - COMMAND echo s!@LLVM_CXXFLAGS@!${CXX_FLGS}! >> temp.sed +add_custom_command(OUTPUT ${BUILDVARIABLES_OBJPATH} + COMMAND echo s!@LLVM_SRC_ROOT@!${LLVM_MAIN_SRC_DIR}! > ${SEDSCRIPT_OBJPATH} + COMMAND echo s!@LLVM_OBJ_ROOT@!${LLVM_BINARY_DIR}! >> ${SEDSCRIPT_OBJPATH} + COMMAND echo s!@LLVM_CPPFLAGS@!${CPP_FLGS}! >> ${SEDSCRIPT_OBJPATH} + COMMAND echo s!@LLVM_CFLAGS@!${C_FLGS}! >> ${SEDSCRIPT_OBJPATH} + COMMAND echo s!@LLVM_CXXFLAGS@!${CXX_FLGS}! >> ${SEDSCRIPT_OBJPATH} # TODO: Use general flags for linking! not just for shared libs: - COMMAND echo s!@LLVM_LDFLAGS@!${CMAKE_SHARED_LINKER_FLAGS}! >> temp.sed - COMMAND echo s!@LIBS@!${LLVM_SYSTEM_LIBS}! >> temp.sed - COMMAND echo s!@LLVM_BUILDMODE@!${CMAKE_BUILD_TYPE}! >> temp.sed - COMMAND echo s!@LLVM_OBJ_SUFFIX@!! >> temp.sed - COMMAND sed -f temp.sed < ${LLVM_CONFIG_IN} > ${LLVM_CONFIG} - COMMAND ${CMAKE_COMMAND} -E remove -f temp.sed - COMMAND cat ${FINAL_LIBDEPS} >> ${LLVM_CONFIG} - COMMAND chmod +x ${LLVM_CONFIG} + COMMAND echo s!@LLVM_LDFLAGS@!${CMAKE_SHARED_LINKER_FLAGS}! >> ${SEDSCRIPT_OBJPATH} + COMMAND echo s!@LLVM_BUILDMODE@!${CMAKE_BUILD_TYPE}! >> ${SEDSCRIPT_OBJPATH} + COMMAND echo s!@LLVM_SYSTEM_LIBS@!${SYSTEM_LIBS}! >> ${SEDSCRIPT_OBJPATH} + COMMAND sed -f ${SEDSCRIPT_OBJPATH} < ${BUILDVARIABLES_SRCPATH} > ${BUILDVARIABLES_OBJPATH} VERBATIM - DEPENDS ${FINAL_LIBDEPS} ${LLVM_CONFIG_IN} - COMMENT "Building llvm-config script." + COMMENT "Building BuildVariables.inc include." ) -add_custom_target(llvm-config.target ALL - DEPENDS ${LLVM_CONFIG}) - -# Ensure we build llvm-config after we build all of the libraries so that we -# have their full dependencies. -add_dependencies(llvm-config.target ${llvm_libs}) +# Add the llvm-config tool. +add_llvm_tool(llvm-config + llvm-config.cpp + ) -install(FILES ${LLVM_CONFIG} - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE - DESTINATION bin) +# Add the dependency on the generation step. +add_file_dependencies(${CMAKE_CURRENT_SOURCE_DIR}/llvm-config.cpp ${BUILDVARIABLES_OBJPATH}) diff --git a/tools/llvm-config/Makefile b/tools/llvm-config/Makefile index 184919ea971..a7a2a63f99b 100644 --- a/tools/llvm-config/Makefile +++ b/tools/llvm-config/Makefile @@ -1,5 +1,5 @@ -##===- tools/llvm-config/Makefile --------------------------*- Makefile -*-===## -# +##===- tools/llvm-config/Makefile---------------------------*- Makefile -*-===## +# # The LLVM Compiler Infrastructure # # This file is distributed under the University of Illinois Open Source @@ -7,57 +7,42 @@ # ##===----------------------------------------------------------------------===## -LEVEL = ../.. +LEVEL := ../.. +TOOLNAME := llvm-config +USEDLIBS := LLVMSupport.a -EXTRA_DIST = LibDeps.txt FinalLibDeps.txt llvm-config.in.in find-cycles.pl +# We generate sources in the build directory, make sure it is in the include +# paths. +INCLUDE_BUILD_DIR := 1 -include $(LEVEL)/Makefile.common +# This tool has no plugins, optimize startup time. +TOOL_NO_EXPORTS := 1 -# If we don't have Perl, we can't generate the library dependencies upon which -# llvm-config depends. Therefore, only if we detect perl will we do anything -# useful. -ifeq ($(HAVE_PERL),1) +# Note that we have to use lazy expansion here. +BUILDVARIABLES_SRCPATH = $(PROJ_SRC_ROOT)/tools/$(TOOLNAME)/BuildVariables.inc.in +BUILDVARIABLES_OBJPATH = $(ObjDir)/BuildVariables.inc +BUILT_SOURCES = $(BUILDVARIABLES_OBJPATH) + +include $(LEVEL)/Makefile.common # Combine preprocessor flags (except for -I) and CXX flags. -SUB_CPPFLAGS = ${CPP.BaseFlags} -SUB_CFLAGS = ${CPP.BaseFlags} ${C.Flags} -SUB_CXXFLAGS = ${CPP.BaseFlags} ${CXX.Flags} +SUB_CPPFLAGS := ${CPP.BaseFlags} +SUB_CFLAGS := ${CPP.BaseFlags} ${C.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 = - -FinalLibDeps = $(PROJ_OBJ_DIR)/FinalLibDeps.txt -LibDeps = $(PROJ_OBJ_DIR)/LibDeps.txt -LibDepsTemp = $(PROJ_OBJ_DIR)/LibDeps.txt.tmp -GenLibDeps = $(PROJ_SRC_ROOT)/utils/GenLibDeps.pl - -$(LibDepsTemp): $(GenLibDeps) $(LibDir) $(wildcard $(LibDir)/*.a $(LibDir)/*.o) - $(Echo) "Regenerating LibDeps.txt.tmp" - $(Verb) $(PERL) $(GenLibDeps) -flat $(LibDir) "$(NM_PATH)" > $(LibDepsTemp) - -$(LibDeps): $(LibDepsTemp) - $(Verb) $(CMP) -s $@ $< || ( $(CP) $< $@ && \ - $(EchoCmd) Updated LibDeps.txt because dependencies changed ) - -# Find all the cyclic dependencies between various LLVM libraries, so we -# don't have to process them at runtime. -$(FinalLibDeps): find-cycles.pl $(LibDeps) - $(Echo) "Checking for cyclic dependencies between LLVM libraries." - $(Verb) $(PERL) $< < $(LibDeps) > $@ || rm -f $@ +SUB_LDFLAGS := -# Rerun our configure substitutions as needed. -ConfigInIn = $(PROJ_SRC_DIR)/llvm-config.in.in -llvm-config.in: $(ConfigInIn) $(ConfigStatusScript) - $(Verb) cd $(PROJ_OBJ_ROOT) ; \ - $(ConfigStatusScript) tools/llvm-config/llvm-config.in - -# Build our final script. -$(ToolDir)/llvm-config: llvm-config.in $(FinalLibDeps) - $(Echo) "Building llvm-config script." - $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \ +$(ObjDir)/BuildVariables.inc: $(BUILDVARIABLES_SRCPATH) Makefile $(ObjDir)/.dir + $(Echo) "Building llvm-config BuildVariables.inc file." + $(Verb) $(ECHO) 's/@LLVM_SRC_ROOT@/$(subst /,\/,$(LLVM_SRC_ROOT))/' \ > temp.sed + $(Verb) $(ECHO) 's/@LLVM_OBJ_ROOT@/$(subst /,\/,$(LLVM_OBJ_ROOT))/' \ + >> temp.sed + $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \ + >> temp.sed $(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \ >> temp.sed $(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \ @@ -66,28 +51,7 @@ $(ToolDir)/llvm-config: llvm-config.in $(FinalLibDeps) >> temp.sed $(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(BuildMode))/' \ >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_OBJ_SUFFIX@/$(subst /,\/,/$(BuildMode))/' \ + $(Verb) $(ECHO) 's/@LLVM_SYSTEM_LIBS@/$(subst /,\/,$(LIBS))/' \ >> temp.sed $(Verb) $(SED) -f temp.sed < $< > $@ $(Verb) $(RM) temp.sed - $(Verb) cat $(FinalLibDeps) >> $@ - $(Verb) chmod +x $@ - -else -# We don't have perl, just generate a dummy llvm-config -$(ToolDir)/llvm-config: - $(Echo) "Building place holder llvm-config script." - $(Verb) $(ECHO) 'echo llvm-config: Perl not found so llvm-config could not be generated' >> $@ - $(Verb) chmod +x $@ - -endif -# Hook into the standard Makefile rules. -all-local:: $(ToolDir)/llvm-config -clean-local:: - $(Verb) $(RM) -f $(ToolDir)/llvm-config llvm-config.in $(FinalLibDeps) \ - $(LibDeps) GenLibDeps.out -install-local:: all-local - $(Echo) Installing llvm-config - $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_bindir) - $(Verb) $(ScriptInstall) $(ToolDir)/llvm-config $(DESTDIR)$(PROJ_bindir) - diff --git a/tools/llvm-config/find-cycles.pl b/tools/llvm-config/find-cycles.pl deleted file mode 100755 index 5cbf5b4b277..00000000000 --- a/tools/llvm-config/find-cycles.pl +++ /dev/null @@ -1,170 +0,0 @@ -#!/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 5.006; -use strict; -use warnings; - -my %DEPS; -my @CYCLES; -sub find_all_cycles; - -# Read our dependency information. -while (<>) { - chomp; - my ($module, $dependency_str) = /^\s*([^:]+):\s*(.*)\s*$/; - 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; -my $cycles_found = 0; -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) { - $cycles_found = $cycles_found + 1; - print STDERR "find-cycles.pl: Circular dependency between *.a files:\n"; - print STDERR "find-cycles.pl: ", join(' ', @archives), "\n"; - push @modules, @archives; # WORKAROUND: Duplicate *.a files. Ick. - } elsif (@modules > 1) { - $cycles_found = $cycles_found + 1; - print STDERR "find-cycles.pl: Circular dependency between *.o files:\n"; - print STDERR "find-cycles.pl: ", join(' ', @modules), "\n"; - push @modules, @modules; # WORKAROUND: Duplicate *.o 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; - -exit $cycles_found; - -#========================================================================== -# 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.cpp b/tools/llvm-config/llvm-config.cpp new file mode 100644 index 00000000000..30ace56f4ca --- /dev/null +++ b/tools/llvm-config/llvm-config.cpp @@ -0,0 +1,324 @@ +//===-- llvm-config.cpp - LLVM project configuration utility --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tool encapsulates information about an LLVM project configuration for +// use by other project's build environments (to determine installed path, +// available features, required libraries, etc.). +// +// Note that although this tool *may* be used by some parts of LLVM's build +// itself (i.e., the Makefiles use it to compute required libraries when linking +// tools), this tool is primarily designed to support external projects. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Config/config.h" +#include "llvm/Config/llvm-config.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include + +using namespace llvm; + +// Include the build time variables we can report to the user. This is generated +// at build time from the BuildVariables.inc.in file by the build system. +#include "BuildVariables.inc" + +// Include the component table. This creates an array of struct +// AvailableComponent entries, which record the component name, library name, +// and required components for all of the available libraries. +// +// Not all components define a library, we also use "library groups" as a way to +// create entries for pseudo groups like x86 or all-targets. +#include "LibraryDependencies.inc" + +/// \brief Traverse a single component adding to the topological ordering in +/// \arg RequiredLibs. +/// +/// \param Name - The component to traverse. +/// \param ComponentMap - A prebuilt map of component names to descriptors. +/// \param VisitedComponents [in] [out] - The set of already visited components. +/// \param RequiredLibs [out] - The ordered list of required libraries. +static void VisitComponent(StringRef Name, + const StringMap &ComponentMap, + std::set &VisitedComponents, + std::vector &RequiredLibs) { + // Lookup the component. + AvailableComponent *AC = ComponentMap.lookup(Name); + assert(AC && "Invalid component name!"); + + // Add to the visited table. + if (!VisitedComponents.insert(AC).second) { + // We are done if the component has already been visited. + return; + } + + // Otherwise, visit all the dependencies. + for (unsigned i = 0; AC->RequiredLibraries[i]; ++i) { + VisitComponent(AC->RequiredLibraries[i], ComponentMap, VisitedComponents, + RequiredLibs); + } + + // Add to the required library list. + if (AC->Library) + RequiredLibs.push_back(AC->Library); +} + +/// \brief Compute the list of required libraries for a given list of +/// components, in an order suitable for passing to a linker (that is, libraries +/// appear prior to their dependencies). +/// +/// \param Components - The names of the components to find libraries for. +/// \param RequiredLibs [out] - On return, the ordered list of libraries that +/// are required to link the given components. +void ComputeLibsForComponents(const std::vector &Components, + std::vector &RequiredLibs) { + std::set VisitedComponents; + + // Build a map of component names to information. + StringMap ComponentMap; + for (unsigned i = 0; i != array_lengthof(AvailableComponents); ++i) { + AvailableComponent *AC = &AvailableComponents[i]; + ComponentMap[AC->Name] = AC; + } + + // Visit the components. + for (unsigned i = 0, e = Components.size(); i != e; ++i) { + // Users are allowed to provide mixed case component names. + std::string ComponentLower = Components[i].lower(); + + // Validate that the user supplied a valid component name. + if (!ComponentMap.count(ComponentLower)) { + llvm::errs() << "llvm-config: unknown component name: " << Components[i] + << "\n"; + exit(1); + } + + VisitComponent(ComponentLower, ComponentMap, VisitedComponents, + RequiredLibs); + } + + // The list is now ordered with leafs first, we want the libraries to printed + // in the reverse order of dependency. + std::reverse(RequiredLibs.begin(), RequiredLibs.end()); +} + +/* *** */ + +void usage() { + errs() << "\ +usage: llvm-config