SFrame 3.6
|
00001 # $Id: PARHelpers.py 323 2012-08-17 08:00:10Z krasznaa $ 00002 00003 # Import the needed module(s): 00004 import os.path 00005 import os 00006 import re 00007 import shutil 00008 00009 ## PAR package creator function 00010 # 00011 # This function creates PAR packages based on a number of parameters. 00012 # 00013 # @param srcdir Base directory from which the PAR package is made 00014 # @param makefile Name of the makefile in the package 00015 # @param include Name of the include directory in the package 00016 # @param src Name of the source file directory in the package 00017 # @param proofdir Name of the directory holding the special PROOF files 00018 # @param output Name of the output file 00019 # @param verbose <code>True</code> if verbose printout is requested 00020 def PARMaker( srcdir, makefile, include, src, proofdir, output, verbose ): 00021 00022 # Tell the user what we're doing: 00023 if verbose: 00024 print " >>" 00025 print " >> Running PARHelpers.PARMaker" 00026 print " >>" 00027 pass 00028 00029 # Split the output file name into constituents: 00030 ( outputdir, outputfile ) = os.path.split( output ) 00031 ( outputbase, outputext ) = os.path.splitext( outputfile ) 00032 if verbose: 00033 print " >> outputdir = " + outputdir 00034 print " >> outputbase = " + outputbase 00035 print " >> outputext = " + outputext 00036 pass 00037 00038 # Check that the output file name has the correct extension: 00039 if( outputext != ".par" ): 00040 print "ERROR: The output file's extension must be \".par\"" 00041 return 00042 00043 # Create an appropriate temporary directory for the package creation: 00044 import tempfile 00045 tempdir = tempfile.mkdtemp() 00046 if verbose: 00047 print " >> tempdir = " + tempdir 00048 pass 00049 00050 # Create the temporary directories for the package: 00051 os.system( "rm -rf " + tempdir + "/" + outputbase ) 00052 os.mkdir( tempdir + "/" + outputbase ) 00053 os.mkdir( tempdir + "/" + outputbase + "/" + include ) 00054 os.mkdir( tempdir + "/" + outputbase + "/" + src ) 00055 os.mkdir( tempdir + "/" + outputbase + "/PROOF-INF" ) 00056 00057 # Get the list of header files to be included in the package: 00058 headers = os.listdir( srcdir + include ) 00059 headers_filt = [ file for file in headers if 00060 ( re.search( "\.h$", file ) or 00061 re.search( "\.icc$", file ) ) ] 00062 if verbose: 00063 print " >> headers = " + ", ".join( headers_filt ) 00064 pass 00065 00066 # Get the list of source files to be included in the package: 00067 sources = os.listdir( srcdir + src ) 00068 sources_filt = [ file for file in sources if 00069 ( ( re.search( "\.cxx$", file ) or re.search( "\.h$", file ) ) and not 00070 ( re.search( "\_Dict\.cxx$", file ) or re.search( "\_Dict\.h$", file ) ) ) ] 00071 if verbose: 00072 print " >> sources = " + ", ".join( sources_filt ) 00073 pass 00074 00075 # Copy the header and source files to the correct directories, and 00076 # then transform them in-situ: 00077 for header in headers_filt: 00078 shutil.copy( srcdir + "/" + include + "/" + header, 00079 tempdir + "/" + outputbase + "/" + include ) 00080 SourceTransform( tempdir + "/" + outputbase + "/" + include + "/" + header ) 00081 pass 00082 for source in sources_filt: 00083 shutil.copy( srcdir + "/" + src + "/" + source, 00084 tempdir + "/" + outputbase + "/" + src ) 00085 SourceTransform( tempdir + "/" + outputbase + "/" + src + "/" + source ) 00086 pass 00087 00088 # Copy the package makefile to the correct directory: 00089 shutil.copy( srcdir + "/" + makefile, 00090 tempdir + "/" + outputbase ) 00091 ( makefiledir, makefilename ) = os.path.split( makefile ) 00092 MakefileTransform( tempdir + "/" + outputbase + "/" + makefilename, verbose ) 00093 00094 # Create the Makefile.proof makefile fragment: 00095 MakefileProof( tempdir + "/" + outputbase + "/Makefile.proof", verbose ) 00096 00097 # Get the list of files in the proof directory: 00098 proof = os.listdir( srcdir + proofdir ) 00099 proof_filt = [ file for file in proof if 00100 ( not re.search( "~$", file ) and 00101 os.path.isfile( srcdir + "/" + proofdir + "/" + file ) ) ] 00102 if verbose: 00103 print " >> proof files = " + ", ".join( proof_filt ) 00104 pass 00105 00106 # Copy the proof files: 00107 for pfile in proof_filt: 00108 shutil.copy( srcdir + "/" + proofdir + "/" + pfile, 00109 tempdir + "/" + outputbase + "/PROOF-INF" ) 00110 pass 00111 00112 # Create the PAR package: 00113 if verbose: 00114 print " >> Now creating " + output 00115 pass 00116 os.system( "tar -C " + tempdir + " -czf " + output + " " + outputbase + "/" ) 00117 00118 # Remove the temporary directory: 00119 if verbose: 00120 print " >> Now removing " + tempdir + "/" + outputbase 00121 pass 00122 os.system( "rm -rf " + tempdir + "/" + outputbase ) 00123 # The temporary directory itself has to be removed as well: 00124 os.system( "rmdir " + tempdir ) 00125 00126 # Tell the user what we did: 00127 print " Created PAR package: " + output 00128 00129 return 00130 00131 ## Transform the contents of the specified makefile for PROOF usage 00132 # 00133 # @param makefile_path Path to the makefile that should be transformed 00134 # @param verbose <code>True</code> if verbose printout is requested 00135 def MakefileTransform( makefile_path, verbose ): 00136 00137 if verbose: 00138 print " >>" 00139 print " >> Running PARHelpers.MakefileTransform" 00140 print " >>" 00141 00142 # Read in the contents of the makefile: 00143 makefile = open( makefile_path, "r" ) 00144 contents = makefile.read() 00145 makefile.close() 00146 00147 # Do the necessary changes: 00148 new_contents = re.sub( "\$\(SFRAME_DIR\)\/Makefile\.common", 00149 "Makefile.proof", contents ) 00150 00151 # Write out the modified contents in the same file: 00152 makefile = open( makefile_path, "w" ) 00153 makefile.write( new_contents ) 00154 makefile.close() 00155 00156 return 00157 00158 ## Create a makefile fragment with the directives for PROOF usage 00159 # 00160 # @param makefile_path Path to the makefile that should be created 00161 # @param verbose <code>True</code> if verbose printout is requested 00162 def MakefileProof( makefile_path, verbose ): 00163 00164 if verbose: 00165 print " >>" 00166 print " >> Running PARHelpers.MakefileProof" 00167 print " >>" 00168 00169 makefile = open( makefile_path, "w" ) 00170 makefile.write( MakefileProofContent ) 00171 makefile.close() 00172 00173 return 00174 00175 ## Transform the contents of the specified source file for PROOF usage 00176 # 00177 # @param file_path Path to the source file that should be transformed 00178 def SourceTransform( file_path ): 00179 00180 # Read in the contents of the source file: 00181 file = open( file_path, "r" ) 00182 contents = file.read() 00183 file.close() 00184 00185 # Do the necessary changes: 00186 contents = re.sub( "core\/include", 00187 "SFrameCore/include", contents ) 00188 contents = re.sub( "plug\-ins\/include", 00189 "SFramePlugIns/include", contents ) 00190 00191 # Write out the modified contents in the same file: 00192 file = open( file_path, "w" ) 00193 file.write( contents ) 00194 file.close() 00195 00196 return 00197 00198 ## Contents of the makefile for PROOF compilation 00199 MakefileProofContent = """MAKEFLAGS = --no-print-directory -r -s 00200 00201 # Include the architecture definitions from the ROOT source: 00202 ARCH_LOC_1 := $(wildcard $(shell root-config --prefix)/test/Makefile.arch) 00203 ARCH_LOC_2 := $(wildcard $(shell root-config --prefix)/share/root/test/Makefile.arch) 00204 ARCH_LOC_3 := $(wildcard $(shell root-config --prefix)/share/doc/root/test/Makefile.arch) 00205 ARCH_LOC_4 := $(wildcard $(shell root-config --prefix)/etc/Makefile.arch) 00206 ARCH_LOC_5 := $(wildcard $(shell root-config --prefix)/etc/root/Makefile.arch) 00207 ifneq ($(strip $(ARCH_LOC_1)),) 00208 $(info Using $(ARCH_LOC_1)) 00209 include $(ARCH_LOC_1) 00210 else 00211 ifneq ($(strip $(ARCH_LOC_2)),) 00212 $(info Using $(ARCH_LOC_2)) 00213 include $(ARCH_LOC_2) 00214 else 00215 ifneq ($(strip $(ARCH_LOC_3)),) 00216 $(info Using $(ARCH_LOC_3)) 00217 include $(ARCH_LOC_3) 00218 else 00219 ifneq ($(strip $(ARCH_LOC_4)),) 00220 $(info Using $(ARCH_LOC_4)) 00221 include $(ARCH_LOC_4) 00222 else 00223 ifneq ($(strip $(ARCH_LOC_5)),) 00224 $(info Using $(ARCH_LOC_5)) 00225 include $(ARCH_LOC_5) 00226 else 00227 $(error Could not find Makefile.arch!) 00228 endif 00229 endif 00230 endif 00231 endif 00232 endif 00233 00234 # Some compilation options 00235 VPATH += $(OBJDIR) $(SRCDIR) 00236 INCLUDES += -I./ -I../ 00237 CXXFLAGS += -Wall -Wno-overloaded-virtual -Wno-unused $(USERCXXFLAGS) 00238 00239 # Set the locations of some files 00240 DICTHEAD = $(SRCDIR)/$(LIBRARY)_Dict.h 00241 DICTFILE = $(SRCDIR)/$(LIBRARY)_Dict.$(SrcSuf) 00242 DICTOBJ = $(OBJDIR)/$(LIBRARY)_Dict.$(ObjSuf) 00243 DICTLDEF = $(INCDIR)/$(LIBRARY)_LinkDef.h 00244 SKIPCPPLIST = $(DICTFILE) 00245 SKIPHLIST = $(DICTHEAD) $(DICTLDEF) 00246 SHLIBFILE = lib$(LIBRARY).$(DllSuf) 00247 UNAME = $(shell uname) 00248 00249 # Set up the default targets 00250 default: shlib 00251 00252 # List of all header and source files to build 00253 HLIST = $(filter-out $(SKIPHLIST),$(wildcard $(INCDIR)/*.h)) 00254 CPPLIST = $(filter-out $(SKIPCPPLIST),$(wildcard $(SRCDIR)/*.$(SrcSuf))) 00255 00256 # List of all object files to build 00257 OLIST = $(patsubst %.$(SrcSuf),%.o,$(notdir $(CPPLIST))) 00258 00259 # Implicit rule to compile all sources 00260 %.o : %.$(SrcSuf) 00261 @echo "Compiling $<" 00262 @mkdir -p $(OBJDIR) 00263 @$(CXX) $(CXXFLAGS) -c $< -o $(OBJDIR)/$(notdir $@) $(INCLUDES) 00264 00265 # Rule to create the dictionary 00266 $(DICTFILE): $(HLIST) $(DICTLDEF) 00267 @echo "Generating dictionary $@" 00268 @$(shell root-config --exec-prefix)/bin/rootcint -f $(DICTFILE) -c -p $(INCLUDES) $^ 00269 00270 # Rule to comile the dictionary 00271 $(DICTOBJ): $(DICTFILE) 00272 @echo "Compiling $<" 00273 @mkdir -p $(OBJDIR) 00274 $(CXX) $(CXXFLAGS) -c $(INCLUDES) -o $@ $< 00275 00276 -include $(foreach var,$(notdir $(CPPLIST:.$(SrcSuf)=.d)),$(DEPDIR)/$(var)) 00277 00278 $(DEPDIR)/%.d: %.$(SrcSuf) 00279 @mkdir -p $(DEPDIR) 00280 if test -f $< ; then \ 00281 echo "Making $(@F)"; \ 00282 $(SHELL) -ec '$(CPP) -MM $(CXXFLAGS) $(INCLUDES) $< | sed '\''/Cstd\/rw/d'\'' > $@'; \ 00283 fi 00284 00285 # Rule to combine objects into a unix shared library 00286 $(SHLIBFILE): $(OLIST) $(DICTOBJ) 00287 @echo "Making shared library: $(SHLIBFILE)" 00288 @rm -f $(SHLIBFILE) 00289 ifneq (,$(findstring macosx,$(ARCH))) 00290 @$(LD) $(LDFLAGS) $(USERLDFLAGS) -dynamiclib -single_module -undefined dynamic_lookup $(addprefix $(OBJDIR)/,$(OLIST)) $(DICTOBJ) -o $(SHLIBFILE) 00291 else 00292 @$(LD) $(LDFLAGS) $(USERLDFLAGS) $(SOFLAGS) $(addprefix $(OBJDIR)/,$(OLIST)) $(DICTOBJ) -o $(SHLIBFILE) 00293 endif 00294 00295 # Useful build targets 00296 shlib: $(SHLIBFILE) 00297 00298 clean: 00299 rm -f $(DICTFILE) $(DICTHEAD) 00300 rm -f $(OBJDIR)/*.o 00301 rm -f $(SHLIBFILE) 00302 rm -f lib$(LIBRARY).so 00303 00304 distclean: 00305 rm -rf $(OBJDIR) 00306 rm -f *~ 00307 rm -f $(INCDIR)/*~ 00308 rm -f $(SRCDIR)/*~ 00309 rm -f $(DICTFILE) $(DICTHEAD) 00310 rm -f $(DEPDIR)/*.d 00311 rm -f $(SHLIBFILE) 00312 rm -f lib$(LIBRARY).so 00313 00314 .PHONY : shlib default clean 00315 """