ATLAS Offline Software
d3pdReaderLibraryMaker.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # $Id: d3pdReaderLibraryMaker.py 600807 2014-06-08 15:26:51Z krasznaa $
3 #
4 # This script can be used to generate the LinkDef.h and Makefile for compiling some
5 # D3PDReader source files into a standalone (shared and static) library.
6 #
7 # @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
8 
9 # Base module(s):
10 import sys
11 import os
12 import optparse
13 
14 # Athena module(s):
15 from AthenaCommon.Logging import logging
16 
17 # Local module(s):
18 from D3PDMakerReader.Helpers import *
19 
20 #
21 # Template contents of the makefile which is generated. It only needs 4 "parameters" to become a
22 # usable makefile.
23 #
24 makefile_template = \
25  "# Dear emacs, this is a -*- Makefile -*-\n" \
26  "# Makefile for compiling a set of D3PDReader source files into a shared and/or static\n" \
27  "# library. Generated using the D3PDMakerReader package...\n\n" \
28  "#\n" \
29  "# Include the architecture definitions from the ROOT sources\n" \
30  "#\n" \
31  "# Makefile.arch can be in a number of different locations depending on the system\n" \
32  "# you're compiling on. The Fink installed version of ROOT for instance has this file\n" \
33  "# in a different location than the \"normally installed\" ROOT versions...\n" \
34  "#\n" \
35  "ARCH_LOC_1 := $(wildcard $(shell root-config --prefix)/test/Makefile.arch)\n" \
36  "ARCH_LOC_2 := $(wildcard $(shell root-config --prefix)/share/root/test/Makefile.arch)\n" \
37  "ARCH_LOC_3 := $(wildcard $(shell root-config --prefix)/share/doc/root/test/Makefile.arch)\n" \
38  "ARCH_LOC_4 := $(wildcard $(shell root-config --prefix)/etc/Makefile.arch)\n" \
39  "ARCH_LOC_5 := $(wildcard $(shell root-config --prefix)/etc/root/Makefile.arch)\n" \
40  "ifneq ($(strip $(ARCH_LOC_1)),)\n" \
41  " $(info Using $(ARCH_LOC_1))\n" \
42  " include $(ARCH_LOC_1)\n" \
43  "else\n" \
44  " ifneq ($(strip $(ARCH_LOC_2)),)\n" \
45  " $(info Using $(ARCH_LOC_2))\n" \
46  " include $(ARCH_LOC_2)\n" \
47  " else\n" \
48  " ifneq ($(strip $(ARCH_LOC_3)),)\n" \
49  " $(info Using $(ARCH_LOC_3))\n" \
50  " include $(ARCH_LOC_3)\n" \
51  " else\n" \
52  " ifneq ($(strip $(ARCH_LOC_4)),)\n" \
53  " $(info Using $(ARCH_LOC_4))\n" \
54  " include $(ARCH_LOC_4)\n" \
55  " else\n" \
56  " ifneq ($(strip $(ARCH_LOC_5)),)\n" \
57  " $(info Using $(ARCH_LOC_5))\n" \
58  " include $(ARCH_LOC_5)\n" \
59  " else\n" \
60  " $(error Could not find Makefile.arch!)\n" \
61  " endif\n" \
62  " endif\n" \
63  " endif\n" \
64  " endif\n" \
65  "endif\n\n" \
66  "# Name of the library to create:\n" \
67  "LIBRARY = %s\n\n" \
68  "# Set the location of some files:\n" \
69  "OBJDIR = obj\n" \
70  "DEPDIR = $(OBJDIR)/dep\n" \
71  "VPATH += $(OBJDIR) ./\n" \
72  "DICTHEAD = $(LIBRARY)_Dict.h\n" \
73  "DICTFILE = $(LIBRARY)_Dict.$(SrcSuf)\n" \
74  "DICTOBJ = $(OBJDIR)/$(LIBRARY)_Dict.$(ObjSuf)\n" \
75  "DICTLDEF = %s\n" \
76  "SHLIBFILE = lib$(LIBRARY).$(DllSuf)\n" \
77  "LIBFILE = lib$(LIBRARY).a\n\n" \
78  "# Additional command line options:\n" \
79  "CXXFLAGS += -Wall -DCOLLECT_D3PD_READING_STATISTICS\n\n" \
80  "# List of all header and source files to build:\n" \
81  "HLIST = %s\n" \
82  "CPPLIST = %s\n\n" \
83  "# List of all files to build:\n" \
84  "OLIST = $(patsubst %%.$(SrcSuf),%%.o,$(notdir $(CPPLIST)))\n" \
85  "DEPLIST = $(foreach var,$(patsubst %%.$(SrcSuf),%%.d,$(notdir $(CPPLIST))),$(DEPDIR)/$(var))\n\n" \
86  "# The default is to create both libraries:\n" \
87  "default: $(SHLIBFILE) $(LIBFILE)\n\n" \
88  "# Rule to compile the source files:\n" \
89  "%%.$(ObjSuf): %%.$(SrcSuf)\n" \
90  "\t@echo \"Compiling $<\"\n" \
91  "\t@mkdir -p $(OBJDIR)\n" \
92  "\t@$(CXX) $(CXXFLAGS) -c $< -o $(OBJDIR)/$(notdir $@) $(INCLUDES)\n\n" \
93  "# Rule to create the dictionary\n" \
94  "$(DICTFILE): $(HLIST) $(DICTLDEF)\n" \
95  "\t@echo \"Generating dictionary $@\"\n" \
96  "\t@$(shell root-config --exec-prefix)/bin/rootcint -f $(DICTFILE) -c -p $(INCLUDES) $^\n\n" \
97  "# Rule to comile the dictionary\n" \
98  "$(DICTOBJ): $(DICTFILE) \n" \
99  "\t@echo \"Compiling $<\"\n" \
100  "\t@mkdir -p $(OBJDIR)\n" \
101  "\t@$(CXX) $(CXXFLAGS) -c $(INCLUDES) -o $@ $<\n\n" \
102  "# Rule to link the shared library\n" \
103  "$(SHLIBFILE): $(OLIST) $(DICTOBJ)\n" \
104  "\t@echo \"Making shared library: $(SHLIBFILE)\"\n" \
105  "\t@rm -f $(SHLIBFILE)\n" \
106  "\t@$(LD) $(LDFLAGS) $(SOFLAGS) -O2 $(addprefix $(OBJDIR)/,$(OLIST)) $(DICTOBJ) -o $(SHLIBFILE)\n\n" \
107  "# Rule to create the static library\n" \
108  "$(LIBFILE): $(OLIST) $(DICTOBJ)\n" \
109  "\t@echo \"Making static library: $(LIBFILE)\"\n" \
110  "\t@rm -f $(LIBFILE)\n" \
111  "\t@ar rcs $@ $(addprefix $(OBJDIR)/,$(OLIST)) $(DICTOBJ)\n\n" \
112  "# Rule to clean the directory\n" \
113  "clean:\n" \
114  "\t@rm -f $(OBJDIR)/*.$(ObjSuf)\n" \
115  "\t@rm -f $(DICTOBJ)\n" \
116  "\t@rm -f $(DICTFILE) $(DICTHEAD)\n" \
117  "\t@rm -f $(LIBFILE)\n" \
118  "\t@rm -f $(SHLIBFILE)\n\n" \
119  "distclean: clean\n" \
120  "\t@rm -rf $(OBJDIR)\n\n" \
121  "#\n" \
122  "# Dependency generation. This is just copy-pasted from the TMVA makefile...\n" \
123  "#\n" \
124  "ifneq ($(MAKECMDGOALS),clean)\n" \
125  "ifneq ($(MAKECMDGOALS),distclean)\n" \
126  "-include $(DEPLIST)\n" \
127  "endif\n" \
128  "endif\n\n" \
129  "$(DEPDIR)/%%.d: %%.$(SrcSuf)\n" \
130  "\t@mkdir -p $(DEPDIR)\n" \
131  "\t@if test -f $< ; then \\\n" \
132  "\t\techo \"Making $(@F)\"; \\\n" \
133  "\t\t$(SHELL) -ec '`root-config --exec-prefix`/bin/rmkdepend -f- -Y -w 3000 -- -I./ -- $< 2> /dev/null 1| sed -e \"s-src/\\(.*\\).o\\(: .*\\)-$(DEPDIR)\\/\\1.d $(OBJDIR)/\\1.o\\2-\" > $@'; \\\n" \
134  "\tfi\n"
135 
136 def main():
137  # Create a logger object first of all:
138  logger = logging.getLogger( os.path.splitext( os.path.basename( sys.argv[ 0 ] ) )[ 0 ] )
139 
140  #
141  # Specify the command line options:
142  #
143  desc = "This script can be used to generate a LinkDef.h header and a Makefile " \
144  "to compile some D3PDReader source files into a standalone (shared and " \
145  "static) library."
146  vers = "$Revision: 600807 $"
147  parser = optparse.OptionParser( description = desc,
148  version = vers,
149  usage = "%prog [options] <source files>" )
150  parser.add_option( "-v", "--verbosity", dest = "verbosity",
151  action = "store", type = "int", default = 3,
152  help = "Message verbosity level" )
153  parser.add_option( "-o", "--output", dest = "output",
154  action = "store", type = "string", default = "./",
155  help = "Output directory for the generated files" )
156  parser.add_option( "-m", "--makefile", dest = "makefile",
157  action = "store", type = "string", default = "Makefile",
158  help = "File name for the generated makefile" )
159  parser.add_option( "-l", "--linkdef", dest = "linkdef",
160  action = "store", type = "string", default = "LinkDef.h",
161  help = "File name for the generated linkdef header" )
162  parser.add_option( "-n", "--libname", dest = "libname",
163  action = "store", type = "string", default = "D3PDReader",
164  help = "Name of the library to be compiled" )
165 
166  # Parse the command line options:
167  ( options, files ) = parser.parse_args()
168 
169  # Do a small sanity check:
170  if not len( files ):
171  logger.error( "You have to define at least one source file!" )
172  parser.print_help()
173  return 255
174 
175  # Set the default logging level:
176  logging.getLogger( "" ).setLevel( options.verbosity )
177 
178  # Print some welcome message:
179  logger.info( "***********************************************************" )
180  logger.info( "* D3PDReader Library Maker" )
181  logger.info( "* Version: $Revision: 600807 $" )
182  logger.info( "*" )
183  logger.info( "* Output level: " + str( options.verbosity ) )
184  logger.info( "* Output directory: " + options.output )
185  logger.info( "* Makefile name: " + options.makefile )
186  logger.info( "* LinkDef name: " + options.linkdef )
187  logger.info( "* Library name: " + options.libname )
188  logger.info( "* Source files: " + ", ".join( files ) )
189  logger.info( "***********************************************************" )
190 
191  # Filter out the header and source files:
192  ( dummy_header_files, source_files ) = separateSources( files )
193  header_files = dictionaryHeaders( files )
194 
195  # Open the makefile:
196  makefile = open( options.output + "/" + options.makefile, "w" )
197  if not makefile:
198  logger.error( "Couldn't open " + options.output + "/" + options.makefile + " for writing!" )
199  return 255
200  else:
201  logger.info( "Writing makefile to: " + options.output + "/" + options.makefile )
202  pass
203 
204  # Write the makefile's contents:
205  makefile.write( makefile_template % ( options.libname, options.linkdef,
206  " ".join( header_files ),
207  " ".join( source_files ) ) )
208  makefile.close()
209 
210  # Extract the class names from the header files:
211  classnames = dictionaryClasses( header_files )
212  logger.debug( "The class names found: " + ", ".join( classnames ) )
213 
214  # Write the LinkDef file:
215  if writeLinkDefFile( options.output + "/" + options.linkdef,
216  classnames ):
217  logger.error( "Failed writing the LinkDef file!" )
218  return 255
219 
220  return 0
221 
222 if __name__ == "__main__":
223  sys.exit( main() )
pool::DbPrintLvl::setLevel
void setLevel(MsgLevel l)
Definition: DbPrint.h:32
python.Helpers.separateSources
def separateSources(filenames)
Separate the source and header files based on their names.
Definition: PhysicsAnalysis/D3PDMaker/D3PDMakerReader/python/Helpers.py:17
python.Helpers.dictionaryClasses
def dictionaryClasses(filenames)
Function collecting the class names to create a dictionary for.
Definition: PhysicsAnalysis/D3PDMaker/D3PDMakerReader/python/Helpers.py:80
python.Helpers.writeLinkDefFile
def writeLinkDefFile(filename, classnames, headers=[])
Function writing a LinkDef file.
Definition: PhysicsAnalysis/D3PDMaker/D3PDMakerReader/python/Helpers.py:172
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
Trk::open
@ open
Definition: BinningType.h:40
str
Definition: BTagTrackIpAccessor.cxx:11
d3pdReaderLibraryMaker.main
def main()
Definition: d3pdReaderLibraryMaker.py:136
Helpers
python.Helpers.dictionaryHeaders
def dictionaryHeaders(filenames)
Find the headers needed for dictionary generation.
Definition: PhysicsAnalysis/D3PDMaker/D3PDMakerReader/python/Helpers.py:48