Apply maemo2 patch
[opencv] / utils / gen_make.py
1 #!/usr/bin/env python
2 #
3 # The script that creates Makefiles for several compilers from DSP files
4 #
5 #   Usage: [python] gen_make.py
6 #
7 import re, sys, copy, glob
8
9 def long_list( cur_str, prefix, suffix, bare_list ):
10     total_str = ""
11     for i in bare_list:
12         s = prefix + i + suffix
13         len_delta = len(s);
14         if len(cur_str) + len_delta > 85:
15             total_str = total_str + cur_str + "\\\n"
16             cur_str = ""
17         cur_str = cur_str + s + " "
18     return total_str + cur_str + "\n"
19
20 class CXX_Compiler:
21     def __init__(self,name):
22         self.name = name
23         self.obj = ".obj"
24         self.lib_prefix = ""
25         self.lib_ext = ".lib"
26         self.lib_link = ""
27         self.lib_link_ext = ".lib"
28         self.inline_start = ""
29         self.inline_end = ""
30         self.linkflags_debug = ""
31         self.linkflags_release = ""
32         self.cxx_switch = "-"
33         self.if_prefix = "!"
34         self.linkpoststep = ""
35         # hack to remove MIL
36         self.lib_synonyms = {}
37         # self.lib_synonyms = { "mil" : "kernel32", "milmet2" : "kernel32" }
38
39 vc = CXX_Compiler("vc")
40 vc.desc = "Microsoft Visual C++ >=6.0"
41 vc.cxx = "cl"
42 vc.link = "link"
43 vc.cxx_switch = "/"
44 vc.libdir_opt = "/libpath:"
45 vc.dependents = "$**"
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"
54 vc.make = "nmake"
55
56 icl = copy.copy(vc)
57 icl.name = "icl"
58 icl.cxx = "icl"
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 "
64
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 "
74 bcc.libdir_opt = "-L"
75 bcc.linkflags_all = " -tWD -e$(OUTBIN) "
76 bcc.exeflags_all = " -tWC -e$(OUTBIN) "
77 bcc.linkpoststep = "implib $(OUTLIB) $(OUTBIN)"
78 bcc.make = "make"
79 bcc.lib_synonyms.update({ "zlib" : "zlib_bcc", "libpng" : "libpng_bcc",
80                      "libjpeg" : "libjpeg_bcc", "libtiff" : "libtiff_bcc", "vfw32" : "" })
81
82 gcc = CXX_Compiler("gcc")
83 gcc.desc = "GNU C/C++ 3.x or later"
84 gcc.cxx = gcc.link = "g++"
85 gcc.obj = ".o"
86 gcc.lib_prefix = "lib"
87 gcc.lib_ext = ".a"
88 gcc.lib_link_ext = ""
89 gcc.lib_link = "-l"
90 gcc.if_prefix = ""
91 gcc.dependents = ""
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 "
96 gcc.libdir_opt = "-L"
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" })
101
102 def create_makefile( dsppath, level, cxx, outfilename ):
103
104     projname = re.findall(r"([^/\\]+)\.dsp$", dsppath.lower() )[0]
105     top="..\\" * level;
106
107     temppath = top + "_temp\\" + projname + "$(DR)_" + cxx.name
108     libpath = top + "lib\\" + cxx.lib_prefix + projname + "$(SUFFIX)" + cxx.lib_ext
109
110     dspfile_handle = open( dsppath, "r" )
111     dspfile = dspfile_handle.readlines()
112     dspfile_handle.close()
113
114     outfile = open( outfilename, "w" )
115
116     exe_flag = 0
117
118     # find out if it is DLL or EXE
119     for line in dspfile:
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 )
122             if n and n[0]:
123                 dllpath = n[0][0] + "$(SUFFIX)." + n[0][1]
124                 if dllpath.endswith('.exe'):
125                     exe_flag = 1
126     outfile.write( \
127            "# Makefile for " + cxx.desc + \
128            "\n\nCXX = " + cxx.cxx + \
129            "\nLINK = " + cxx.link + \
130            "\n\n" + cxx.if_prefix + "ifdef debug" + \
131            "\n\nSUFFIX = d" + \
132            "\nDR = _Dbg" + \
133            "\n\n" + cxx.if_prefix + "else" + \
134            "\n\nSUFFIX = " + \
135            "\nDR = _Rls" + \
136            "\n\n" + cxx.if_prefix + "endif" + \
137            "\n\nOUTBIN = " + dllpath + \
138            "\nOUTLIB = " + libpath + "\n\n" )
139
140     filelist = []
141     barelist = []
142     inclist = []
143     incpaths = {}
144     libpaths = {}
145     defines_debug = {}
146     defines_release = {}
147     libs_debug = ""
148     libs_release = ""
149
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 )
154
155     for line in dspfile:
156         # update list of source (object) files
157         src_file = src_file_prog.findall( line )
158         if src_file:
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] )
164             continue
165
166         # update list of headers (for dependency lists) and include paths
167         hdr_file = hdr_file_prog.findall( line )
168         if hdr_file:
169             hdr_file = re.sub( r'\\', r'/', hdr_file[0][0].lower() )
170             inclist.append( hdr_file )
171             incpath = incpath_prog.findall( hdr_file )
172             if incpath:
173                 incpaths[incpath[0][0].lower()] = 1
174             continue
175
176         # compiler options
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 )
180             for inc in incs:
181                 inc = re.sub( r"\\", r"/", inc[:-1] )
182                 incpaths[inc.lower()] = 1
183
184             if re.search( r"_DEBUG", line ):
185                 # debug options
186                 define_dict = defines_debug
187             else:
188                 define_dict = defines_release
189
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
194
195             continue
196
197         # linker options
198         if re.match( r"# ADD LINK32.+", line ) and line.find("AMD64") < 0 and line.find("IA64") < 0:
199             # fetch list of libraries
200             libs_str = ""
201             lib_list = re.findall( r"(\w+)\.lib ", line )
202
203             for lib_link in lib_list:
204                 lib_link = cxx.lib_synonyms.get( lib_link.lower(), lib_link )
205                 if lib_link:
206                     libs_str = libs_str + cxx.lib_link + lib_link.lower() + cxx.lib_link_ext + " "
207
208             if re.search( r'/out:".+?d\.(dll|exe)"', line ):
209                 libs_debug= libs_str
210             else:
211                 libs_release = libs_str
212
213             # fetch a list of lib directories
214             libs = re.findall( r'/libpath:\s*"(\S+)\s+', line )
215             for l in libs:
216                 l = re.sub( r"\\", r"/", l[:-1] )
217                 libpaths[l.lower()] = 1
218
219             continue
220     # end of .dsp processing loop
221
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" )
226
227     cxxflags = ""
228     cxxflags_debug = ""
229     cxxflags_release = ""
230
231     for inc_elem in incpaths.keys():
232         cxxflags = cxxflags + cxx.cxx_switch + 'I"' + inc_elem + '" '
233
234     for define_elem in defines_debug.keys():
235         cxxflags_debug = cxxflags_debug + cxx.cxx_switch + 'D"' + define_elem + '" '
236
237     for define_elem in defines_release.keys():
238         cxxflags_release = cxxflags_release + cxx.cxx_switch + 'D"' + define_elem + '" '
239
240     linkflags = ""
241     for lib_elem in libpaths.keys():
242         linkflags = linkflags + cxx.libdir_opt + '"' + lib_elem + '" '
243
244     if exe_flag:
245         linkflags_all = cxx.exeflags_all
246     else:
247         linkflags_all = cxx.linkflags_all
248
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" )
264
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 )
269     else:
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" )
274
275     inc_str = " " + " ".join( inclist ) + "\n";
276
277     # print dependencies
278     for i in range(len(barelist)):
279         outfile.write( temppath + "\\" + barelist[i] + cxx.obj + \
280                        ": " + filelist[i] + inc_str )
281         if i == 0:
282             outfile.write( "\t@-mkdir " + temppath + " 2>nul\n" )
283
284         outfile.write( "\t-$(CXX) $(CXXFLAGS)" + temppath + "\\" + barelist[i] + \
285                        cxx.obj + " " + filelist[i] + "\n" )
286
287     outfile.close()
288 # end of create_makefile function
289
290 ###################### Main Loop ############################
291
292 folderlist = [
293     "cxcore\\src",
294     "cv\\src",
295     "cvaux\\src",
296     "otherlibs\\highgui",
297     "tests\\cxts",
298     "tests\\cxcore\\src",
299     "tests\\trs",
300     "tests\\cv\\src",
301 ]
302
303 for cxx in [bcc]:
304     makefile = open( "..\\_make\\makefile." + cxx.name, "w" );
305
306     makefile.write( "# " + cxx.desc + \
307                     "\n\n" + cxx.if_prefix + "ifdef debug" + \
308                     "\nOPT= debug=1" + \
309                     "\n" + cxx.if_prefix + "else" + \
310                     "\nOPT= " + \
311                     "\n" + cxx.if_prefix + "endif" + \
312                     "\n\nall:" )
313
314     for folder in folderlist:
315         level = len(re.findall(r'[/\\]', folder )) + 1
316
317         dsp_list = glob.glob("..\\" + folder + "\\*.dsp")
318         if not dsp_list: # if there is no dsp, just put a reference to makefile
319             dsp_list = [""]
320         for dsppath in dsp_list:
321             if dsppath != "":
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" )
328             else:
329                 makefile.write( "\n\t" + cxx.make + " -C ..\\" + folder + \
330                                 " -f makefile." + cxx.name )
331
332     makefile.close()
333