From bc19274a0b7af34b77c9328bba13d98f9f1e5315 Mon Sep 17 00:00:00 2001 From: Fons Rademakers <Fons.Rademakers@cern.ch> Date: Thu, 11 Dec 2003 16:34:29 +0000 Subject: [PATCH] add rlibmap a utility used to build a map between classes and libraries. The rlibmap utility will create a system.rootlibmap file used to load the library for an unknown class. To be enabled in the very near future. git-svn-id: http://root.cern.ch/svn/root/trunk@7733 27541ba8-7e3a-0410-8455-c3a389f83636 --- Makefile | 2 +- utils/Module.mk | 16 +++- utils/src/rlibmap.cxx | 181 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+), 4 deletions(-) create mode 100644 utils/src/rlibmap.cxx diff --git a/Makefile b/Makefile index dd004f46f49..b69a6c4de07 100644 --- a/Makefile +++ b/Makefile @@ -309,7 +309,7 @@ endif include build/dummy.d # must be last include endif -rootcint: all-cint $(ROOTCINTTMP) $(ROOTCINT) +rootcint: all-cint all-utils rootlibs: rootcint compiledata $(ALLLIBS) diff --git a/utils/Module.mk b/utils/Module.mk index 57591fab600..7199768c329 100644 --- a/utils/Module.mk +++ b/utils/Module.mk @@ -19,8 +19,14 @@ ROOTCINTTMPO := $(ROOTCINTS:.cxx=_tmp.o) ROOTCINTTMP := $(MODDIRS)/rootcint_tmp$(EXEEXT) ROOTCINT := bin/rootcint$(EXEEXT) +##### rlibmap ##### +RLIBMAPS := $(MODDIRS)/rlibmap.cxx +RLIBMAPO := $(RLIBMAPS:.cxx=.o) +RLIBMAPDEP := $(RLIBMAPO:.o=.d) +RLIBMAP := bin/rlibmap$(EXEEXT) + # include all dependency files -INCLUDEFILES += $(ROOTCINTDEP) +INCLUDEFILES += $(ROOTCINTDEP) $(RLIBMAPDEP) ##### local rules ##### $(ROOTCINT): $(CINTLIB) $(ROOTCINTO) $(MAKEINFO) $(IOSENUM) @@ -33,15 +39,19 @@ $(ROOTCINTTMP): $(CINTTMPO) $(ROOTCINTS) $(MAKEINFO) $(IOSENUM) $(LD) $(LDFLAGS) -o $@ \ $(ROOTCINTTMPO) $(CINTTMPO) $(CILIBS) -all-utils: $(ROOTCINTTMP) $(ROOTCINT) +$(RLIBMAP): $(RLIBMAPO) + $(LD) $(LDFLAGS) -o $@ $< + +all-utils: $(ROOTCINTTMP) $(ROOTCINT) $(RLIBMAP) clean-utils: - @rm -f $(ROOTCINTTMPO) $(ROOTCINTO) + @rm -f $(ROOTCINTTMPO) $(ROOTCINTO) $(RLIBMAPO) clean:: clean-utils distclean-utils: clean-utils @rm -f $(ROOTCINTDEP) $(ROOTCINTTMP) $(ROOTCINT) \ + $(RLIBMAPDEP) $(RLIBMAP) \ $(UTILSDIRS)/*.exp $(UTILSDIRS)/*.lib distclean:: distclean-utils diff --git a/utils/src/rlibmap.cxx b/utils/src/rlibmap.cxx new file mode 100644 index 00000000000..831718e0274 --- /dev/null +++ b/utils/src/rlibmap.cxx @@ -0,0 +1,181 @@ +// @(#)root/utils:$Name:$:$Id: +// Author: Fons Rademakers 05/12/2003 + +/************************************************************************* + * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +// This program generates a map between class name and shared library. +// Its output is in TEnv format. +// Usage: rlibmap [-f] [-o <libmapfile>] <sofile> <sofile> ... +// -f: output full library path name (not needed when ROOT library +// search path is used) +// -o: output to write to specified file, otherwise to stdout + + +#include <stdio.h> +#include <string> +#include <map> + +const char *usage = "Usage: %s [-f] [-o <libmapfile>] <sofile> <sofile> ...\n"; + +#ifdef __linux +#if defined(__INTEL_COMPILER) || (__GNUC__ >= 3) +const char *kNM = "nm --demangle=gnu-v3"; +#else +const char *kNM = "nm -C"; +#endif +const char kDefined = 'T'; +#endif + +#ifdef __sun +const char *kNM = "nm -C -p"; +const char kDefined = 'T'; +#endif + +#ifdef __alpha +const char *kNM = "nm -B"; +const char kDefined = 'T'; +#endif + +#ifdef __hpux +namespace std { } +const char *kNM = "nm++ -p"; +const char kDefined = 'T'; +#endif + +#ifdef __APPLE__ +const char *kNM = "nm"; +const char kDefined = 'T'; +#endif + +#ifdef __sgi +const char *kNM = "nm -C"; +const char kDefined = 'T'; +#endif + +using namespace std; + + +int libmap(const char *lib, int fullpath, FILE *fp) +{ + char *nm = new char [strlen(lib)+50]; + +#if defined(__APPLE__) + sprintf(nm, "%s %s | c++filt", kNM, lib); +#else + sprintf(nm, "%s %s", kNM, lib); +#endif + + FILE *pf; + if ((pf = ::popen(nm, "r")) == 0) { + fprintf(stderr, "cannot execute: %s\n", nm); + return 1; + } + + map<string,bool> unique; + char line[4096]; + while ((fgets(line, 4096, pf)) != 0) { + //printf("line: %s", line); + unsigned long addr; + char type[5], symbol[4096]; + addr = 0; + if (line[0] == '0') { + sscanf(line, "%lx %s %s", &addr, type, symbol); + //printf("addr = %.8lx, type = %s, symbol = %s\n", addr, type, symbol); + } else { + sscanf(line, "%s %s", type, symbol); + //printf(" type = %s, symbol = %s\n", type, symbol); + } + + if (type[0] == kDefined) { + char *r; + if ((r = strrchr(symbol, ':'))) { + r--; + if (r && *r == ':') { + *r = 0; + string cls = symbol; + r += 2; + char *s; + if ((s = strchr(r, '[')) || (s = strchr(r, '('))) { + *s = 0; + string meth = r; + if (cls == meth) { + //printf("class %s in library %s\n", cls.c_str(), lib); + unique[cls] = true; + } + } + } + } + } + } + + ::pclose(pf); + + const char *libbase = strrchr(lib, '/'); + if (libbase && !fullpath) + libbase++; + else + libbase = lib; + + map<string,bool>::const_iterator it; + for (it = unique.begin(); it != unique.end(); it++) { + fprintf(fp, "Library.%-35s %s\n", ((*it).first+":").c_str(), libbase); + } + + delete [] nm; + + return 0; +} + +int main(int argc, char **argv) +{ + char **libs = 0; + int fullpath = 0; + FILE *fp = stdout; + + if (argc > 1) { + int ic = 1; + if (!strcmp(argv[ic], "-f")) { + fullpath = 1; + ic++; + } + if (!strcmp(argv[ic], "-o")) { + ic++; + fp = fopen(argv[ic], "w"); + if (!fp) { + fprintf(stderr, "cannot open output file %s\n", argv[ic]); + return 1; + } + ic++; + } + if (!strcmp(argv[ic], "-?") || !strcmp(argv[ic], "-h")) { + fprintf(stderr, usage, argv[0]); + return 1; + } + int args = argc - ic + 2; + libs = new char* [args]; + libs[args-1] = 0; + for (int i = ic, j = 0; i < argc; i++, j++) { + libs[j] = argv[i]; + } + } else { + fprintf(stderr, usage, argv[0]); + return 1; + } + + int i = 0; + while (libs[i]) { + libmap(libs[i], fullpath, fp); + i++; + } + + if (fp != stdout) + fclose(fp); + + return 0; +} -- GitLab