merge of 'aac60b186b977130a688c4d00bfde913fb6221eb'
[vuplus_openembedded] / classes / mono.bbclass
1 def mono_get_file_table(packageversion, d):
2         # The packageversion is currently ignored, but might be used in the future
3         # if more than one mono version is available and different versions
4         # need to use different tables
5
6         import bb, sys, os, glob, commands
7         curdir = os.path.dirname( bb.data.getVar('FILE', d, 1)  )
8         if curdir not in sys.path: sys.path.append( curdir )
9         from mono_files import debian_mono_file_table
10         
11         # mono-jay is not being built (for all platforms at least)
12         IGNORE = ("mono-jay", )
13         file_table = [
14             # Standard package
15             {"name": "mono-doc"},
16             
17             # Virtual packages
18             {"name": "mono"},
19             {"name": "mono-runtime"},
20             
21             # Not provided by Debian:
22             {"name": "libnunit2.2-cil",
23              "patterns": [
24                "/usr/lib/mono/gac/nunit.*/2.2.*",
25                "/usr/lib/mono/1.0/nunit.*.dll",
26                "/usr/lib/pkgconfig/mono-nunit.pc",
27               ],
28               "assemblies": [
29                ("nunit.core", "2.2.0.0"),
30                ("nunit.framework", "2.2.0.0"),
31                ("nunit.util", "2.2.0.0"),
32                ("nunit.mocks", "2.2.8.0"),
33               ],
34             },
35             {"name": "libmono-cecil0.5-cil",
36              "patterns": [
37               "/usr/lib/mono/gac/Mono.Cecil/0.5.*",
38              ],
39              "assemblies": [
40               ("Mono.Cecil", "0.5.*"),
41              ],
42             },
43             {"name": "libmono-db2-1.0-cil",
44              "patterns": [
45               "/usr/lib/mono/gac/IBM.Data.DB2/1.0*",
46               "/usr/lib/mono/1.0/IBM.Data.DB2.dll",
47              ],
48              "assemblies": [
49               ("IBM.Data.DB2", "1.0*"),
50              ],
51             },
52         ] + debian_mono_file_table
53         
54         file_table = [e for e in file_table
55                 if not (e.has_key("name") and e["name"] in IGNORE)]
56         
57         return file_table
58
59 def mono_find_provides_and_requires(files, d):
60         provides = []
61         requires = []
62         
63         import bb, os, commands
64         
65         pathprefix = "export PATH=%s; export LANG=; export LC_ALL=; " % bb.data.getVar('PATH', d, 1)
66         for filename in files:
67                 if not filename.endswith(".dll") and not filename.endswith(".exe"):
68                         continue
69                 if not os.path.isfile(filename) or os.path.islink(filename):
70                         continue
71                 
72                 ## Provides
73                 name, version = None, None
74                 
75                 ret, result = commands.getstatusoutput("%smonodis --assembly '%s'" % (pathprefix, filename))
76                 if ret:
77                         bb.error("raw_provides_and_requires: monodis --assembly '%s' failed, dependency information will be inaccurate" % filename)
78                         continue
79                 for line in result.splitlines():
80                         if not ":" in line: continue
81                         key, value = line.split(":", 1)
82                         if key.strip() == "Name":
83                                 name = value.strip()
84                         elif key.strip() == "Version":
85                                 version = value.strip()
86                 if name is not None and version is not None:
87                         if (name, version) not in provides:
88                                 provides.append( (name, version) )
89         
90                 ## Requires
91                 name, version = None, None
92                 ret, result = commands.getstatusoutput("%smonodis --assemblyref '%s'" % (pathprefix, filename))
93                 if ret:
94                         bb.error("raw_provides_and_requires: monodis --assemblyref '%s' failed, dependency information will be inaccurate" % filename)
95                         continue
96                 for line in result.splitlines():
97                         if not "=" in line: continue
98                         key, value = line.split("=", 1)
99                         if ":" in key and key.split(":",1)[1].strip() == "Version":
100                                 version = value.strip()
101                         elif key.strip() == "Name":
102                                 name = value.strip()
103                         if name is not None and version is not None:
104                                 if (name, version) not in requires:
105                                         requires.append( (name, version) )
106                                 name, version = None, None
107         
108         # Remove everything from requires that's already in provides as it's not actually required
109         # to be provided externally
110         requires = [e for e in requires if not e in provides]
111         return provides, requires
112
113 python mono_do_clilibs() {
114         import bb, os, re, os.path
115
116         exclude_clilibs = bb.data.getVar('EXCLUDE_FROM_CLILIBS', d, 0)
117         if exclude_clilibs:
118                 bb.note("not generating clilibs")
119                 return
120                 
121         lib_re = re.compile("^lib.*\.so")
122         libdir_re = re.compile(".*/lib$")
123
124         packages = bb.data.getVar('PACKAGES', d, 1)
125
126         workdir = bb.data.getVar('WORKDIR', d, 1)
127         if not workdir:
128                 bb.error("WORKDIR not defined")
129                 return
130
131         staging = bb.data.getVar('STAGING_DIR', d, 1)
132         if not staging:
133                 bb.error("STAGING_DIR not defined")
134                 return
135
136         pkgdest = bb.data.getVar('PKGDEST', d, 1)
137
138         clilibs_dir = os.path.join(staging, "clilibs")
139         bb.mkdirhier(clilibs_dir)
140
141         provides, requires = {}, {}
142         private_libs = bb.data.getVar('PRIVATE_CLILIBS', d, 1)
143         for pkg in packages.split():
144                 bb.debug(2, "calculating clilib provides for %s" % pkg)
145
146                 files_to_check = []
147                 top = os.path.join(pkgdest, pkg)
148                 for root, dirs, files in os.walk(top):
149                         for file in files:
150                                 path = os.path.join(root, file)
151                                 if file.endswith(".exe") or file.endswith(".dll"):
152                                         files_to_check.append( path )
153                 provides[pkg], requires[pkg] = mono_find_provides_and_requires(files_to_check, d)
154                 clilibs_file = os.path.join(clilibs_dir, pkg + ".list")
155                 if os.path.exists(clilibs_file):
156                         os.remove(clilibs_file)
157                 if len(provides[pkg]) > 0:
158                         fd = open(clilibs_file, 'w')
159                         for s in provides[pkg]:
160                                 fd.write(" ".join(s) + '\n')
161                         fd.close()
162
163         clilib_provider = {}
164         list_re = re.compile('^(.*)\.list$')
165         for file in os.listdir(clilibs_dir):
166                 m = list_re.match(file)
167                 if m:
168                         dep_pkg = m.group(1)
169                         fd = open(os.path.join(clilibs_dir, file))
170                         lines = fd.readlines()
171                         fd.close()
172                         for l in lines:
173                                 clilib_provider[tuple(l.rstrip().split())] = dep_pkg
174
175         for pkg in packages.split():
176                 bb.debug(2, "calculating clilib requirements for %s" % pkg)
177
178                 deps = []
179                 for n in requires[pkg]:
180                         if n in clilib_provider.keys():
181                                 dep_pkg = clilib_provider[n]
182
183                                 if dep_pkg == pkg:
184                                         continue
185                                 
186                                 if not dep_pkg in deps:
187                                         deps.append(dep_pkg)
188                         else:
189                                 bb.note("Couldn't find CLI library provider for %s" % (n,))
190
191                 deps_file = os.path.join(pkgdest, pkg + ".clilibdeps")
192                 if os.path.exists(deps_file):
193                         os.remove(deps_file)
194                 if len(deps) > 0:
195                         fd = open(deps_file, 'w')
196                         for dep in deps:
197                                 fd.write(dep + '\n')
198                         fd.close()
199 }
200
201 def mono_after_parse(d):
202         import bb
203         # Insert mono_do_clilibs into PACKAGEFUNCS
204         # Needs to be called after populate_packages, but before read_shlibdeps
205         PACKAGEFUNCS = bb.data.getVar("PACKAGEFUNCS", d, 1)
206         if PACKAGEFUNCS:
207                 PACKAGEFUNCS = PACKAGEFUNCS.split()
208                 if "read_shlibdeps" in PACKAGEFUNCS:
209                         i = PACKAGEFUNCS.index("read_shlibdeps")
210                         PACKAGEFUNCS.insert(i, "mono_do_clilibs")
211                 elif "populate_packages" in PACKAGEFUNCS:
212                         i = PACKAGEFUNCS.index("populate_packages")
213                         PACKAGEFUNCS.insert(i+1, "mono_do_clilibs")
214                 bb.data.setVar("PACKAGEFUNCS", " ".join(PACKAGEFUNCS), d)
215
216 python () {
217     mono_after_parse(d)
218 }