merge of '1ba9df24f1f8128a61ec636e73db71360782f1fc'
[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 python mono_do_clilibs() {
56         import bb, os, re, os.path
57
58         exclude_clilibs = bb.data.getVar('EXCLUDE_FROM_CLILIBS', d, 0)
59         if exclude_clilibs:
60                 bb.note("not generating clilibs")
61                 return
62                 
63         lib_re = re.compile("^lib.*\.so")
64         libdir_re = re.compile(".*/lib$")
65
66         packages = bb.data.getVar('PACKAGES', d, 1)
67
68         workdir = bb.data.getVar('WORKDIR', d, 1)
69         if not workdir:
70                 bb.error("WORKDIR not defined")
71                 return
72
73         staging = bb.data.getVar('STAGING_DIR', d, 1)
74         if not staging:
75                 bb.error("STAGING_DIR not defined")
76                 return
77
78         pkgdest = bb.data.getVar('PKGDEST', d, 1)
79
80         clilibs_dir = os.path.join(staging, "clilibs")
81         bb.mkdirhier(clilibs_dir)
82
83         provides, requires = {}, {}
84         private_libs = bb.data.getVar('PRIVATE_CLILIBS', d, 1)
85         for pkg in packages.split():
86                 bb.debug(2, "calculating clilib provides for %s" % pkg)
87
88                 files_to_check = []
89                 top = os.path.join(pkgdest, pkg)
90                 for root, dirs, files in os.walk(top):
91                         for file in files:
92                                 path = os.path.join(root, file)
93                                 if file.endswith(".exe") or file.endswith(".dll"):
94                                         files_to_check.append( path )
95                 provides[pkg], requires[pkg] = mono_find_provides_and_requires(files_to_check, d)
96                 clilibs_file = os.path.join(clilibs_dir, pkg + ".list")
97                 if os.path.exists(clilibs_file):
98                         os.remove(clilibs_file)
99                 if len(provides[pkg]) > 0:
100                         fd = open(clilibs_file, 'w')
101                         for s in provides[pkg]:
102                                 fd.write(" ".join(s) + '\n')
103                         fd.close()
104
105         clilib_provider = {}
106         list_re = re.compile('^(.*)\.list$')
107         for file in os.listdir(clilibs_dir):
108                 m = list_re.match(file)
109                 if m:
110                         dep_pkg = m.group(1)
111                         fd = open(os.path.join(clilibs_dir, file))
112                         lines = fd.readlines()
113                         fd.close()
114                         for l in lines:
115                                 clilib_provider[tuple(l.rstrip().split())] = dep_pkg
116
117         for pkg in packages.split():
118                 bb.debug(2, "calculating clilib requirements for %s" % pkg)
119
120                 deps = []
121                 for n in requires[pkg]:
122                         if n in clilib_provider.keys():
123                                 dep_pkg = clilib_provider[n]
124
125                                 if dep_pkg == pkg:
126                                         continue
127                                 
128                                 if not dep_pkg in deps:
129                                         deps.append(dep_pkg)
130                         else:
131                                 bb.note("Couldn't find CLI library provider for %s" % (n,))
132
133                 deps_file = os.path.join(pkgdest, pkg + ".clilibdeps")
134                 if os.path.exists(deps_file):
135                         os.remove(deps_file)
136                 if len(deps) > 0:
137                         fd = open(deps_file, 'w')
138                         for dep in deps:
139                                 fd.write(dep + '\n')
140                         fd.close()
141 }
142
143 def mono_after_parse(d):
144         import bb
145         # Insert mono_do_clilibs into PACKAGEFUNCS
146         # Needs to be called after populate_packages, but before read_shlibdeps
147         PACKAGEFUNCS = bb.data.getVar("PACKAGEFUNCS", d, 1)
148         if PACKAGEFUNCS:
149                 PACKAGEFUNCS = PACKAGEFUNCS.split()
150                 if "read_shlibdeps" in PACKAGEFUNCS:
151                         i = PACKAGEFUNCS.index("read_shlibdeps")
152                         PACKAGEFUNCS.insert(i, "mono_do_clilibs")
153                 elif "populate_packages" in PACKAGEFUNCS:
154                         i = PACKAGEFUNCS.index("populate_packages")
155                         PACKAGEFUNCS.insert(i+1, "mono_do_clilibs")
156                 bb.data.setVar("PACKAGEFUNCS", " ".join(PACKAGEFUNCS), d)
157
158 python () {
159     mono_after_parse(d)
160 }