]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/Prototype/Module.java
Added BuildTarget with enumerated data type (DEBUG|RELEASE|BOTH) to the PlatformHeade...
[mirror_edk2.git] / Tools / Source / Prototype / Module.java
CommitLineData
878ddf1f 1import java.util.*;\r
2\r
3public class Module\r
4{\r
5 Module()\r
6 {\r
7 }\r
8 Module(String n)\r
9 {\r
10 name=n;\r
11 }\r
12 String name;\r
13\r
14 public String name() { return name; }\r
15\r
16 public Set<LibClass> consumesLibClasses;\r
17\r
18 // The set of packages that this module depends upon.\r
19 Set<Package> packageDepends;\r
20 public Set<Package> packageDeps() { return packageDepends; }\r
21\r
22 public boolean autoBuild()\r
23 {\r
24 // This should be implemented in the derived class.\r
25 return true;\r
26 }\r
27\r
28 // Make sure that each class in this set of libclasses is declared in one\r
29 // of the packages that this module depends on.\r
30 public boolean validateLibClasses(Set<LibClass> classes)\r
31 {\r
32 for(LibClass lc : classes)\r
33 {\r
34 // Assume we will not find it.\r
35 boolean found = false;\r
36\r
37 for(Package p : packageDepends)\r
38 {\r
39 if(p.libClassDecls.contains(lc))\r
40 {\r
41 found=true;\r
42 break;\r
43 }\r
44 }\r
45 if(found == false)\r
46 {\r
47 // Error: This LibClass is not found in any of our Packages.\r
48 return false;\r
49 }\r
50 }\r
51 // Well, we never came up empty handed, so it looks good.\r
52 return true;\r
53 }\r
54\r
55 public Set<LibClass> libClassesProduced(Collection<LibInst> instances)\r
56 {\r
57 // given a set of lib instances, what is the set of lib classes produced?\r
58\r
59 Set<LibClass> classes = new HashSet<LibClass>();\r
60\r
61 for(LibInst li : instances)\r
62 {\r
63 classes.addAll(li.producesLibClasses);\r
64 }\r
65 return classes;\r
66 }\r
67\r
68 // Search the given set of lib instance to see if, among them, they\r
69 // produce the same LibClass more than once.\r
70 public Set<LibClass> duplicateLibClasses(Set<LibInst> libs)\r
71 {\r
72 // Return true iff each class produced is produced only once.\r
73\r
74 List<LibClass> classes = new LinkedList<LibClass>();\r
75 Set<LibClass> dups = new HashSet<LibClass>();\r
76\r
77 for(LibInst li : libs)\r
78 {\r
79 classes.addAll(li.producesLibClasses);\r
80 }\r
81\r
82 for(LibClass c : classes)\r
83 {\r
84 for(LibClass inner : classes)\r
85 {\r
86 if(c.equals(inner))\r
87 {\r
88 dups.add(c);\r
89 }\r
90 }\r
91 }\r
92 return dups;\r
93 }\r
94\r
95 public Set<LibInst> getProducers(LibClass lc, Set<LibInst> libs)\r
96 {\r
97 // Return the subset of the given libs that produce this LibClass.\r
98\r
99 Set<LibInst> producers = new HashSet<LibInst>();\r
100\r
101 for(LibInst li : libs)\r
102 {\r
103 if(li.producesLibClasses.contains(lc))\r
104 {\r
105 producers.add(li);\r
106 }\r
107 }\r
108 return producers;\r
109 }\r
110 \r
111 // \r
112 // The central dependency relationship between library instances is as follows.\r
113 // A LibInst "A" depends upon LibInst "B" if, and only if, there exists a LibClass\r
114 // "C" such that A consumes C and B produces C. This is the partial order over which \r
115 // we construct a Directed Acyclic Graph (DAG). The DAG can be used to detect\r
116 // cycles in the depends relation (which are illegal) and it can be used to implement a\r
117 // topological sort which is a total ordering over LibInstances. This total order on \r
118 // lib instances is what is needed in order to call the constructors and destructors\r
119 // in the proper sequence.\r
120 //\r
121 public DAG<LibInst> makeDAG(Set<LibInst> libs)\r
122 {\r
123 DAG<LibInst> dag = new DAG<LibInst>();\r
124\r
125 if(duplicateLibClasses(libs).size()>0)\r
126 {\r
127 System.out.format("Error: The library instances implement at least one "\r
128 + "library class more than once.\n");\r
129 }\r
130\r
131 for(LibInst consumer : libs)\r
132 {\r
133 // Find all the producers for each LC that li consumes. \r
134 for(LibClass lc : consumer.consumesLibClasses )\r
135 {\r
136 Set<LibInst> producers = getProducers(lc, libs);\r
137 if(producers.isEmpty())\r
138 {\r
139 System.out.format("Error: Unmet dependency libclass:%s .", lc.name() );\r
140 return null;\r
141 }\r
142\r
143 // There is exactly one lib inst that produces this class.\r
144 LibInst producer = producers.iterator().next();\r
145\r
146 // Now we are ready to add the dependency to the dag. It will flag \r
147 // circular dependencies for us.\r
148 dag.add(consumer, producer);\r
149 }\r
150 }\r
151 return dag;\r
152 }\r
153\r
154 // As you evaluate each node in the graph (starting with the module node), you\r
155 // must call the constructors for all the child nodes before you call the\r
156 // constructor for the current node. \r
157 public List<LibInst> getConstructorOrder(Set<LibInst> libs)\r
158 {\r
159 List<LibInst> rev = new LinkedList<LibInst>();\r
160\r
161 for(LibInst li : getDestructorOrder(libs))\r
162 rev.add(0, li); \r
163\r
164 return rev;\r
165 }\r
166\r
167 // The destructor order is exactly the reverese of the constructor order.\r
168 // As you evaluate each node in the graph (starting with the module node), you\r
169 // must call the destructor for the all the parent nodes before calling the\r
170 // destructors for the current node, and then call the destructors for all the\r
171 // child nodes. \r
172 public List<LibInst> getDestructorOrder(Set<LibInst> libs)\r
173 {\r
174 DAG<LibInst> dag = makeDAG(libs);\r
175\r
176 return dag.sort();\r
177 }\r
178}\r