private CppCompileUnit GetCompileUnit() { int count = CompileUnits.Count; if (count > 0) { var last = CompileUnits[count - 1]; if (!last.IsFull()) { return(last); } } var unit = new CppCompileUnit("CppUnit_" + CppUnitName++); CompileUnits.Add(unit); return(unit); }
private void GenerateCompileUnits() { List <TypeCppCode> codeSorter = new List <TypeCppCode>(CodeMap.Values); // 构建类型代码依赖关联 foreach (var cppCode in codeSorter) { foreach (string typeName in cppCode.DeclDependNames) { if (GetCodeFromMap(typeName, out var typeCode)) { cppCode.DeclDependTypes.Add(typeCode); } } cppCode.DeclDependNames = null; foreach (string typeName in cppCode.ImplDependNames) { if (GetCodeFromMap(typeName, out var typeCode)) { cppCode.ImplDependTypes.Add(typeCode); } } cppCode.ImplDependNames = null; } CodeMap.Clear(); // 统计依赖计数 foreach (var cppCode in codeSorter) { // 预生成排序索引 cppCode.GetSortedID(); foreach (var typeCode in cppCode.DeclDependTypes) { ++typeCode.DependCounter; } foreach (var typeCode in cppCode.ImplDependTypes) { ++typeCode.DependCounter; } } // 排序代码 codeSorter.Sort((x, y) => { int cmp = x.GetSortedID().CompareTo(y.GetSortedID()); if (cmp == 0) { cmp = y.DependCounter.CompareTo(x.DependCounter); } return(cmp); }); // 划分编译单元 foreach (var cppCode in codeSorter) { var unit = GetCompileUnit(); unit.AddCode(cppCode); cppCode.CompileUnit = unit; } StringGen.GenDefineCode( 100, out var strSplitMap, out var strCodeMap, out string strTypeDefs); // 生成代码 HashSet <string> dependSet = new HashSet <string>(); foreach (var unit in CompileUnits) { // 防止包含自身 dependSet.Add(unit.Name); unit.DeclCode.Append("#pragma once\n"); unit.DeclCode.Append("#include \"il2cpp.h\"\n"); foreach (var cppCode in unit.CodeList) { // 生成头文件依赖包含 foreach (var typeCode in cppCode.DeclDependTypes) { string unitName = typeCode.CompileUnit.Name; if (!dependSet.Contains(unitName)) { dependSet.Add(unitName); unit.DeclCode.AppendFormat("#include \"{0}.h\"\n", unitName); } } } foreach (var cppCode in unit.CodeList) { // 拼接声明代码 unit.DeclCode.Append(cppCode.DeclCode); cppCode.DeclCode = null; cppCode.DeclDependTypes = null; } foreach (var cppCode in unit.CodeList) { // 生成源文件依赖包含 foreach (var typeCode in cppCode.ImplDependTypes) { string unitName = typeCode.CompileUnit.Name; if (!dependSet.Contains(unitName)) { dependSet.Add(unitName); unit.ImplCode.AppendFormat("#include \"{0}.h\"\n", unitName); } } // 生成字符串包含 if (strSplitMap != null && cppCode.DependStrings.Count > 0) { HashSet <int> strUnitSet = new HashSet <int>(); foreach (string str in cppCode.DependStrings) { strUnitSet.Add(strSplitMap[str]); } cppCode.DependStrings = null; foreach (var strUnitId in strUnitSet) { string strUnit = "StringUnit_" + strUnitId; unit.ImplCode.AppendFormat("#include \"{0}.h\"\n", strUnit); } } } foreach (var cppCode in unit.CodeList) { // 拼接实现代码 unit.ImplCode.Append(cppCode.ImplCode); cppCode.ImplCode = null; cppCode.ImplDependTypes = null; } // 如果包含内容则追加头文件 if (unit.ImplCode.Length > 0) { unit.ImplCode.Insert(0, string.Format("#include \"{0}.h\"\n", unit.Name)); } unit.CodeList = null; dependSet.Clear(); } if (strTypeDefs.Length > 0) { foreach (var item in strCodeMap) { var strUnit = new CppCompileUnit("StringUnit_" + item.Key); CompileUnits.Add(strUnit); strUnit.DeclCode.Append("#pragma once\n"); strUnit.DeclCode.Append("#include \"StringTypes.h\"\n"); strUnit.DeclCode.Append(item.Value); } var strTypeDefUnit = new CppCompileUnit("StringTypes"); CompileUnits.Add(strTypeDefUnit); strTypeDefUnit.DeclCode.Append("#pragma once\n"); strTypeDefUnit.DeclCode.Append("#include \"il2cpp.h\"\n"); strTypeDefUnit.DeclCode.Append(strTypeDefs); } // 添加初始化静态变量的函数 if (StaticInitBody.Length > 0) { var firstUnit = CompileUnits[0]; string initDecl = "void il2cpp_InitStaticVars()"; firstUnit.DeclCode.Append(initDecl + ";\n"); CodePrinter staticInitPrt = new CodePrinter(); staticInitPrt.Append(StaticInitDecl.ToString()); staticInitPrt.Append(initDecl); staticInitPrt.AppendLine("\n{"); ++staticInitPrt.Indents; staticInitPrt.Append(StaticInitBody.ToString()); --staticInitPrt.Indents; staticInitPrt.AppendLine("}"); firstUnit.ImplCode.Append(staticInitPrt); } }