| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- #!/usr/bin/python3.1
- import sys, os, fnmatch, random, re
- from threading import Thread
- #======================================================================================================================================
- # GLOBAL VARS =
- #======================================================================================================================================
- sourcePaths = []
- precompiledHeaders = []
- executableName = "unamed_project"
- compiler = ""
- compilerFlags = ""
- precompiledHeadersFlags = ""
- linkerFlags = ""
- sourceFilesRegExpr = r".*\.[c++|cpp|cc|cxx|C|c]"
- includePaths = []
- #======================================================================================================================================
- # getCommandOutput =
- #======================================================================================================================================
- def getCommandOutput( command ):
- child = os.popen(command)
- data = child.read()
- err = child.close()
- if err:
- print( "getCommandOutput failed:\n" + command )
- exit( 0 )
- return data
- #======================================================================================================================================
- # Threads =
- #======================================================================================================================================
- threadList = []
- class TargetThread( Thread ):
- def __init__( self, tid, range ):
- Thread.__init__( self )
- self.tid = tid
- self.range = range
- self.out_str = ""
-
- def run( self ):
- for i in self.range:
- source_file = sourceFiles[i]
- self.out_str += getCommandOutput( compiler + " -MM " + compilerFlags + " " + source_file.cppFile + " -MT " + source_file.objFile )
- self.out_str += "\t@echo Compiling " + source_file.cppFile + "...\n"
- self.out_str += "\t@$(CXX) $(INCPATH) $(CFLAGS) " + source_file.cppFile + " -o " + \
- source_file.objFile + "\n\n"
- #print( "Im thread %d and I will make depends for %s" %(self.tid, source_file.fname) )
- #print( "Im thread %d and my i is %d" %(self.tid, i) )
- #======================================================================================================================================
- # SourceFile =
- #======================================================================================================================================
- class SourceFile:
- def __init__( self ):
- self.cppFile = ""
- self.objFile = ""
- #======================================================================================================================================
- # main =
- #======================================================================================================================================
- # Read the arguments
- inputCfgFile = ""
- outputMakefile = ""
- i = 0
- while 1:
- i = i+1
- if i>=len(sys.argv): break
- arg = sys.argv[i]
- if arg == "-h" or arg == "-help" or arg == "--help":
- print( "Makefile generator by GODlike" )
- print( "usage: " + sys.argv[0] + " [options] [-i input] [-o output]" )
- print( "options:" )
- print( "-h, -help, --help Print this text" )
- print( "-i Input config file. Default: gen.cfg.py" )
- print( "-o Output makefile. Default: Makefile" )
- exit(0)
- elif arg == "-i":
- inputCfgFile = sys.argv[i+1]
- i = i+1
- elif arg == "-o":
- outputMakefile = sys.argv[i+1]
- i = i+1
- else:
- print( "Unrecognized argument " + arg )
-
- if outputMakefile == "":
- outputMakefile = "Makefile"
- if inputCfgFile == "":
- inputCfgFile = "gen.cfg.py"
- # Check if cfg exists
- if not os.path.exists( inputCfgFile ):
- print( "File " + inputCfgFile + " doesn't exist" )
- exit(0)
- # compile the cfg
- source = ""
- f = open( inputCfgFile, "r" )
- for line in f.readlines():
- source += line
-
- exec( compile( source, inputCfgFile, "exec" ) )
- # find the cpp files
- sourceFiles = []
- regexpr = re.compile( sourceFilesRegExpr )
- for sourceDir in sourcePaths:
- files = os.listdir( sourceDir )
- for file_ in files:
- if not regexpr.match( file_ ): continue
-
- sfile = SourceFile()
-
- (fname_wo_ext, ext) = os.path.splitext( file_ )
- sfile.cppFile = sourceDir + "/" + file_
- sfile.objFile = fname_wo_ext + ".o"
-
- # search all the source files and resolve conflicts in .o
- for sfile1 in sourceFiles:
- if sfile1.objFile == sfile.objFile:
- print( "There is a naming conflict between \"" + sfile1.cppFile + "\" and \"" + sfile.cppFile + "\" but dont worry." )
- random.seed()
- sfile.objFile = str(random.randint(1,99)) + "." + sfile.objFile;
-
- sourceFiles.append( sfile )
-
- # now the precompiled headers
- phFiles = []
- for header in precompiledHeaders:
- sFile = SourceFile()
- (fnameWoExt, ext) = os.path.splitext( header )
- sFile.cppFile = header
- sFile.objFile = os.path.basename(fnameWoExt) + ".gch"
- phFiles.append( sFile )
- # build the string
- masterStr = ""
- masterStr += "CXX = " + compiler + "\n"
- masterStr += "CFLAGS = " + compilerFlags + "\n"
- masterStr += "PHFLAGS = " + precompiledHeadersFlags + "\n"
- masterStr += "LFLAGS = " + linkerFlags + "\n"
- masterStr += "EXECUTABLE = " + executableName + "\n"
- masterStr += "INCPATH = "
- for path in includePaths:
- masterStr += "-I" + path + " "
- compilerFlags += " -I" + path + " "
- masterStr += "\n"
- masterStr += "SOURCES = "
- for source_file in sourceFiles:
- masterStr += source_file.cppFile + " "
- masterStr += "\n"
- masterStr += "OBJECTS = "
- for source_file in sourceFiles:
- masterStr += source_file.objFile + " "
- masterStr += "\n"
- masterStr += "PRECOMPILED_HEADERS = "
- for header in phFiles:
- masterStr += header.objFile
- masterStr += "\n\n"
- masterStr += "all: $(PRECOMPILED_HEADERS) $(SOURCES) $(EXECUTABLE)\n\n"
- masterStr += "$(EXECUTABLE): $(OBJECTS)\n"
- masterStr += "\t@echo Linking...\n"
- masterStr += "\t@$(CXX) $(OBJECTS) $(LFLAGS) -o $(EXECUTABLE)\n"
- masterStr += "\t@echo All Done!\n\n"
- for header in phFiles:
- # getCommandOutput( compiler + " -MM " + compilerFlags + " " + source_file.cppFile + " -MT " + source_file.objFile )
- dependStr = getCommandOutput( compiler + " -MM " + compilerFlags + " " + header.cppFile + " -MT " + header.objFile )
- masterStr += dependStr
- masterStr += "\t@echo Pre-compiling header " + header.cppFile + "...\n"
- masterStr += "\t@$(CXX) $(INCPATH) $(PHFLAGS) " + header.objFile + "\n\n"
- # write source file target
- threadsNum = os.sysconf('SC_NPROCESSORS_ONLN')
- print( "I will invoke %d threads to make the dependencies..." % threadsNum )
- num = len(sourceFiles);
- itemsPerThread = num // threadsNum;
- for i in range(0, threadsNum):
- begin = i*itemsPerThread
- if i == threadsNum-1:
- end = num
- else:
- end = begin + itemsPerThread
- thread = TargetThread( i, range( int(begin), int(end) ) )
- thread.start()
- threadList.append( thread )
- for thread in threadList:
- thread.join()
- for thread in threadList:
- masterStr += thread.out_str
- #for source_file in sourceFiles:
- #masterStr += source_file.fname_wo_ext + ".o: " + source_file.path + source_file.fname_wo_ext + ".cpp"
- #masterStr += getCommandOutput( compiler + " -M " + compilerFlags + " " + source_file.path + "/" + source_file.fname )
- #masterStr += "\t@echo Compiling " + source_file.fname + "...\n"
- #masterStr += "\t@$(CXX) $(INCPATH) $(CFLAGS) " + source_file.path + "/" + source_file.fname + "\n\n"
- masterStr += "clean:\n"
- masterStr += "\trm -f *.o\n"
- masterStr += "\trm -f *.gch\n"
- masterStr += "\trm -f *~\n"
- masterStr += "\trm -f $(EXECUTABLE)\n\n"
- # write file
- f = open( outputMakefile, "w" )
- f.write( masterStr )
- print( "File \"" + outputMakefile + "\" created!" )
|