3 # The script that creates Makefiles for several compilers from DSP files
5 # Usage: [python] gen_make.py
7 import re, sys, copy, glob
9 def long_list( cur_str, prefix, suffix, bare_list ):
12 s = prefix + i + suffix
14 if len(cur_str) + len_delta > 85:
15 total_str = total_str + cur_str + "\\\n"
17 cur_str = cur_str + s + " "
18 return total_str + cur_str + "\n"
21 def __init__(self,name):
27 self.lib_link_ext = ".lib"
28 self.inline_start = ""
30 self.linkflags_debug = ""
31 self.linkflags_release = ""
34 self.linkpoststep = ""
36 self.lib_synonyms = {}
37 # self.lib_synonyms = { "mil" : "kernel32", "milmet2" : "kernel32" }
39 vc = CXX_Compiler("vc")
40 vc.desc = "Microsoft Visual C++ >=6.0"
44 vc.libdir_opt = "/libpath:"
46 vc.cxxflags_all = '/nologo /GX /GB /W4 /Zm200 /c /Fo '
47 vc.cxxflags_release = "/MD /Ox /Ob2 "
48 vc.cxxflags_debug = "/MDd /Gm /Zi /Od /FD /GZ "
49 vc.linkflags_all = "/nologo /subsystem:windows /dll /pdb:none " + \
50 "/machine:I386 /out:$(OUTBIN) /implib:$(OUTLIB) "
51 vc.exeflags_all = "/nologo /subsystem:console /pdb:none " + \
52 "/machine:I386 /out:$(OUTBIN) "
53 vc.linkflags_debug = "/debug"
59 icl.desc = "Intel Proton Compiler >=5.0"
60 icl.cxxflags_all = '/nologo /GX /G6 /W4 "/Qwd68,171,424,444,869,981,522,9" /c /Fo '
61 icl.cxxflags_release = "/MD /O3 /Ob2 "
62 icl.cxxflags_debug = "/MDd /Gm /Zi /Od /FD /GZ "
63 icl.linkflags_all = vc.linkflags_all + "/nodefaultlib:libmmd /nodefaultlib:libmmdd /nodefaultlib:libm /nodefaultlib:libirc "
65 bcc = CXX_Compiler("bcc")
66 bcc.desc = "Borland C++ >=5.5"
67 bcc.cxx = bcc.link = "bcc32"
68 bcc.inline_start = "@&&|\n"
69 bcc.inline_end = "\n|"
70 bcc.dependents = "$**"
71 bcc.cxxflags_all = "-3 -a8 -b- -c -d -RT- -tWM -w-inl -w-aus -j200 -o "
72 bcc.cxxflags_release = "-O2 "
73 bcc.cxxflags_debug = "-Od -v "
75 bcc.linkflags_all = " -tWD -e$(OUTBIN) "
76 bcc.exeflags_all = " -tWC -e$(OUTBIN) "
77 bcc.linkpoststep = "implib $(OUTLIB) $(OUTBIN)"
79 bcc.lib_synonyms.update({ "zlib" : "zlib_bcc", "libpng" : "libpng_bcc",
80 "libjpeg" : "libjpeg_bcc", "libtiff" : "libtiff_bcc", "vfw32" : "" })
82 gcc = CXX_Compiler("gcc")
83 gcc.desc = "GNU C/C++ 3.x or later"
84 gcc.cxx = gcc.link = "g++"
86 gcc.lib_prefix = "lib"
92 gcc.cxxflags_all = "-Wall -c -o "
93 gcc.cxxflags_release = "-O3 -g -fomit-frame-pointer -march=i686 -ffast-math "
94 #gcc.cxxflags_release = "-O0 -s "
95 gcc.cxxflags_debug = "-O0 -ggdb3 "
97 gcc.linkflags_all = "-o$(OUTBIN) -shared -Wl,-call_shared,--out-implib,$(OUTLIB) "
98 gcc.exeflags_all = "-o$(OUTBIN) -Wl,-call_shared "
99 gcc.make = "mingw32-make"
100 gcc.lib_synonyms.update( { "zlib" : "z", "vfw32" : "vfw_avi32 -lvfw_cap32 -lvfw_ms32" })
102 def create_makefile( dsppath, level, cxx, outfilename ):
104 projname = re.findall(r"([^/\\]+)\.dsp$", dsppath.lower() )[0]
107 temppath = top + "_temp\\" + projname + "$(DR)_" + cxx.name
108 libpath = top + "lib\\" + cxx.lib_prefix + projname + "$(SUFFIX)" + cxx.lib_ext
110 dspfile_handle = open( dsppath, "r" )
111 dspfile = dspfile_handle.readlines()
112 dspfile_handle.close()
114 outfile = open( outfilename, "w" )
118 # find out if it is DLL or EXE
120 if re.match( r"^# ADD LINK32.+", line ) and line.find("AMD64") < 0 and line.find("IA64") < 0:
121 n = re.findall( r'/out:"(.+?)d\.(dll|exe)"', line )
123 dllpath = n[0][0] + "$(SUFFIX)." + n[0][1]
124 if dllpath.endswith('.exe'):
127 "# Makefile for " + cxx.desc + \
128 "\n\nCXX = " + cxx.cxx + \
129 "\nLINK = " + cxx.link + \
130 "\n\n" + cxx.if_prefix + "ifdef debug" + \
133 "\n\n" + cxx.if_prefix + "else" + \
136 "\n\n" + cxx.if_prefix + "endif" + \
137 "\n\nOUTBIN = " + dllpath + \
138 "\nOUTLIB = " + libpath + "\n\n" )
150 src_file_prog = re.compile( r'^SOURCE=(.*?\.(c|cpp))\n$', re.I )
151 hdr_file_prog = re.compile( r'^SOURCE=(.*?\.(h|hpp|inc))\n$', re.I )
152 barename_prog = re.compile( r'.*?(\w+)\.(c|cpp)$', re.I )
153 incpath_prog = re.compile( r'(.*?)/\w+\.(h|hpp|inc)', re.I )
156 # update list of source (object) files
157 src_file = src_file_prog.findall( line )
159 # [0][0] is used because there are 2 groups in the pattern
160 src_file = src_file[0][0].lower()
161 filelist.append( src_file )
162 barename = barename_prog.findall( src_file )
163 barelist.append( barename[0][0] )
166 # update list of headers (for dependency lists) and include paths
167 hdr_file = hdr_file_prog.findall( line )
169 hdr_file = re.sub( r'\\', r'/', hdr_file[0][0].lower() )
170 inclist.append( hdr_file )
171 incpath = incpath_prog.findall( hdr_file )
173 incpaths[incpath[0][0].lower()] = 1
177 if re.match( r"^# ADD CPP.+", line ) and line.find("WIN64") < 0:
178 # fetch a list of include directories
179 incs = re.findall( r'/I\s*"(\S+)\s+', line )
181 inc = re.sub( r"\\", r"/", inc[:-1] )
182 incpaths[inc.lower()] = 1
184 if re.search( r"_DEBUG", line ):
186 define_dict = defines_debug
188 define_dict = defines_release
190 # update list of defines
191 define_list = re.findall( r'/D\s*"(\S+)\s+', line )
192 for define_elem in define_list:
193 define_dict[define_elem[:-1]] = 1
198 if re.match( r"# ADD LINK32.+", line ) and line.find("AMD64") < 0 and line.find("IA64") < 0:
199 # fetch list of libraries
201 lib_list = re.findall( r"(\w+)\.lib ", line )
203 for lib_link in lib_list:
204 lib_link = cxx.lib_synonyms.get( lib_link.lower(), lib_link )
206 libs_str = libs_str + cxx.lib_link + lib_link.lower() + cxx.lib_link_ext + " "
208 if re.search( r'/out:".+?d\.(dll|exe)"', line ):
211 libs_release = libs_str
213 # fetch a list of lib directories
214 libs = re.findall( r'/libpath:\s*"(\S+)\s+', line )
216 l = re.sub( r"\\", r"/", l[:-1] )
217 libpaths[l.lower()] = 1
220 # end of .dsp processing loop
222 outfile.write( long_list( "OBJS = ", temppath + "\\", cxx.obj, barelist ) + "\n" )
223 if cxx.name == "gcc":
224 outfile.write( long_list( "OBJ_SHRT = ", "", cxx.obj, barelist ) + "\n" )
225 outfile.write( long_list( "\n\nINC = ", "", "", inclist ) + "\n" )
229 cxxflags_release = ""
231 for inc_elem in incpaths.keys():
232 cxxflags = cxxflags + cxx.cxx_switch + 'I"' + inc_elem + '" '
234 for define_elem in defines_debug.keys():
235 cxxflags_debug = cxxflags_debug + cxx.cxx_switch + 'D"' + define_elem + '" '
237 for define_elem in defines_release.keys():
238 cxxflags_release = cxxflags_release + cxx.cxx_switch + 'D"' + define_elem + '" '
241 for lib_elem in libpaths.keys():
242 linkflags = linkflags + cxx.libdir_opt + '"' + lib_elem + '" '
245 linkflags_all = cxx.exeflags_all
247 linkflags_all = cxx.linkflags_all
249 # print middle part of makefile
250 outfile.write( "\nCXXFLAGS2 = " + cxxflags + cxx.cxxflags_all + \
251 "\nLINKFLAGS2 = " + linkflags + linkflags_all + \
252 "\n\n" + cxx.if_prefix + "ifdef debug" + \
253 "\n\nCXXFLAGS = " + cxxflags_debug + cxx.cxxflags_debug + "$(CXXFLAGS2)" + \
254 "\nLIBS = " + libs_debug + \
255 "\nLINKFLAGS = $(LINKFLAGS2) " + cxx.linkflags_debug + \
256 "\n\n" + cxx.if_prefix + "else" + \
257 "\n\nCXXFLAGS = " + cxxflags_release + cxx.cxxflags_release + "$(CXXFLAGS2)" + \
258 "\nLIBS = " + libs_release + \
259 "\nLINKFLAGS = $(LINKFLAGS2) " + cxx.linkflags_release + \
260 "\n\n" + cxx.if_prefix + "endif" + \
261 "\n\n\n$(OUTBIN): $(OBJS)" + \
262 "\n\t-mkdir " + top + "bin 2> nul" + \
263 "\n\t-mkdir " + top + "lib 2> nul" )
265 if cxx.name != "gcc":
266 outfile.write( "\n\t$(LINK) " + cxx.inline_start + "$(LINKFLAGS) " + \
267 cxx.dependents + " $(LIBS) " + cxx.inline_end + \
268 "\n\t" + cxx.linkpoststep )
270 outfile.write( '\n\t-move "' + temppath + '\\*.o" .' + \
271 '\n\t$(LINK) $(LINKFLAGS) $(OBJ_SHRT) $(LIBS)' + \
272 '\n\t-move *.o "' + temppath + '"' )
273 outfile.write( "\n\nall: $(OUTBIN)\n\n" )
275 inc_str = " " + " ".join( inclist ) + "\n";
278 for i in range(len(barelist)):
279 outfile.write( temppath + "\\" + barelist[i] + cxx.obj + \
280 ": " + filelist[i] + inc_str )
282 outfile.write( "\t@-mkdir " + temppath + " 2>nul\n" )
284 outfile.write( "\t-$(CXX) $(CXXFLAGS)" + temppath + "\\" + barelist[i] + \
285 cxx.obj + " " + filelist[i] + "\n" )
288 # end of create_makefile function
290 ###################### Main Loop ############################
296 "otherlibs\\highgui",
298 "tests\\cxcore\\src",
304 makefile = open( "..\\_make\\makefile." + cxx.name, "w" );
306 makefile.write( "# " + cxx.desc + \
307 "\n\n" + cxx.if_prefix + "ifdef debug" + \
309 "\n" + cxx.if_prefix + "else" + \
311 "\n" + cxx.if_prefix + "endif" + \
314 for folder in folderlist:
315 level = len(re.findall(r'[/\\]', folder )) + 1
317 dsp_list = glob.glob("..\\" + folder + "\\*.dsp")
318 if not dsp_list: # if there is no dsp, just put a reference to makefile
320 for dsppath in dsp_list:
322 create_makefile( dsppath, level, cxx, "..\\" + folder + "\\makefile." + cxx.name )
323 if cxx.name != "gcc":
324 makefile.write( "\n\tcd ..\\" + folder + \
325 "\n\t" + cxx.make + " -f makefile." + \
326 cxx.name + " $(OPT)" + \
327 "\n\tcd " + "..\\" * level + "_make" )
329 makefile.write( "\n\t" + cxx.make + " -C ..\\" + folder + \
330 " -f makefile." + cxx.name )