Update drivers
[vuplus_openembedded] / classes / mono.bbclass
1 def mono_find_provides_and_requires(files, d):
2         provides = []
3         requires = []
4         
5         import bb, os, commands
6         
7         pathprefix = "export PATH=%s; export LANG=; export LC_ALL=; " % bb.data.getVar('PATH', d, 1)
8         for filename in files:
9                 if not filename.endswith(".dll") and not filename.endswith(".exe"):
10                         continue
11                 if not os.path.isfile(filename) or os.path.islink(filename):
12                         continue
13                 
14                 ## Provides
15                 name, version = None, None
16                 
17                 ret, result = commands.getstatusoutput("%smonodis --assembly '%s'" % (pathprefix, filename))
18                 if ret:
19                         bb.error("raw_provides_and_requires: monodis --assembly '%s' failed, dependency information will be inaccurate" % filename)
20                         continue
21                 for line in result.splitlines():
22                         if not ":" in line: continue
23                         key, value = line.split(":", 1)
24                         if key.strip() == "Name":
25                                 name = value.strip()
26                         elif key.strip() == "Version":
27                                 version = value.strip()
28                 if name is not None and version is not None:
29                         if (name, version) not in provides:
30                                 provides.append( (name, version) )
31         
32                 ## Requires
33                 name, version = None, None
34                 ret, result = commands.getstatusoutput("%smonodis --assemblyref '%s'" % (pathprefix, filename))
35                 if ret:
36                         bb.error("raw_provides_and_requires: monodis --assemblyref '%s' failed, dependency information will be inaccurate" % filename)
37                         continue
38                 for line in result.splitlines():
39                         if not "=" in line: continue
40                         key, value = line.split("=", 1)
41                         if ":" in key and key.split(":",1)[1].strip() == "Version":
42                                 version = value.strip()
43                         elif key.strip() == "Name":
44                                 name = value.strip()
45                         if name is not None and version is not None:
46                                 if (name, version) not in requires:
47                                         requires.append( (name, version) )
48                                 name, version = None, None
49         
50         # Remove everything from requires that's already in provides as it's not actually required
51         # to be provided externally
52         requires = [e for e in requires if not e in provides]
53         return provides, requires
54
55 CLILIBSDIR = "${STAGING_DIR_HOST}/clilibs"
56
57 python mono_do_clilibs() {
58         import bb, os, re, os.path
59
60         exclude_clilibs = bb.data.getVar('EXCLUDE_FROM_CLILIBS', d, 0)
61         if exclude_clilibs:
62                 bb.note("not generating clilibs")
63                 return
64                 
65         lib_re = re.compile("^lib.*\.so")
66         libdir_re = re.compile(".*/lib$")
67
68         packages = bb.data.getVar('PACKAGES', d, 1)
69
70         workdir = bb.data.getVar('WORKDIR', d, 1)
71         if not workdir:
72                 bb.error("WORKDIR not defined")
73                 return
74
75         pkgdest = bb.data.getVar('PKGDEST', d, 1)
76
77         clilibs_dir = bb.data.getVar('CLILIBSDIR', d, 1)
78         bb.mkdirhier(clilibs_dir)
79
80         provides, requires = {}, {}
81         private_libs = bb.data.getVar('PRIVATE_CLILIBS', d, 1)
82         for pkg in packages.split():
83                 bb.debug(2, "calculating clilib provides for %s" % pkg)
84
85                 files_to_check = []
86                 top = os.path.join(pkgdest, pkg)
87                 for root, dirs, files in os.walk(top):
88                         for file in files:
89                                 path = os.path.join(root, file)
90                                 if file.endswith(".exe") or file.endswith(".dll"):
91                                         files_to_check.append( path )
92                 provides[pkg], requires[pkg] = mono_find_provides_and_requires(files_to_check, d)
93                 clilibs_file = os.path.join(clilibs_dir, pkg + ".list")
94                 if os.path.exists(clilibs_file):
95                         os.remove(clilibs_file)
96                 if len(provides[pkg]) > 0:
97                         fd = open(clilibs_file, 'w')
98                         for s in provides[pkg]:
99                                 fd.write(" ".join(s) + '\n')
100                         fd.close()
101
102         clilib_provider = {}
103         list_re = re.compile('^(.*)\.list$')
104         for file in os.listdir(clilibs_dir):
105                 m = list_re.match(file)
106                 if m:
107                         dep_pkg = m.group(1)
108                         fd = open(os.path.join(clilibs_dir, file))
109                         lines = fd.readlines()
110                         fd.close()
111                         for l in lines:
112                                 clilib_provider[tuple(l.rstrip().split())] = dep_pkg
113
114         for pkg in packages.split():
115                 bb.debug(2, "calculating clilib requirements for %s" % pkg)
116
117                 deps = []
118                 for n in requires[pkg]:
119                         if n in clilib_provider.keys():
120                                 dep_pkg = clilib_provider[n]
121
122                                 if dep_pkg == pkg:
123                                         continue
124                                 
125                                 if not dep_pkg in deps:
126                                         deps.append(dep_pkg)
127                         else:
128                                 bb.note("Couldn't find CLI library provider for %s" % (n,))
129
130                 deps_file = os.path.join(pkgdest, pkg + ".clilibdeps")
131                 if os.path.exists(deps_file):
132                         os.remove(deps_file)
133                 if len(deps) > 0:
134                         fd = open(deps_file, 'w')
135                         for dep in deps:
136                                 fd.write(dep + '\n')
137                         fd.close()
138 }
139
140 do_mono_stage() {
141         if [ "${INHIBIT_MONO_STAGE}" = "1" ]
142         then
143                 return
144         fi
145         
146         for package in ${PACKAGES}; do
147                 if [ -d  "${PKGDEST}/${package}/${libdir}" ]; then
148                         cd "${PKGDEST}/${package}/${libdir}"
149                         for file in `find . -iname "*.dll"`; do
150                                 cp --parent -fpPR "${file}" "${STAGING_LIBDIR}/"
151                         done
152                 fi
153         done
154 }
155 addtask mono_stage after do_package before do_populate_staging
156
157 def mono_after_parse(d):
158         import bb
159         # Insert mono_do_clilibs into PACKAGEFUNCS
160         # Needs to be called after populate_packages, but before read_shlibdeps
161         PACKAGEFUNCS = bb.data.getVar("PACKAGEFUNCS", d, 1)
162         if PACKAGEFUNCS:
163                 PACKAGEFUNCS = PACKAGEFUNCS.split()
164                 if "read_shlibdeps" in PACKAGEFUNCS:
165                         i = PACKAGEFUNCS.index("read_shlibdeps")
166                         PACKAGEFUNCS.insert(i, "mono_do_clilibs")
167                 elif "populate_packages" in PACKAGEFUNCS:
168                         i = PACKAGEFUNCS.index("populate_packages")
169                         PACKAGEFUNCS.insert(i+1, "mono_do_clilibs")
170                 bb.data.setVar("PACKAGEFUNCS", " ".join(PACKAGEFUNCS), d)
171
172 python () {
173     mono_after_parse(d)
174 }