xref: /aosp_15_r20/external/swiftshader/third_party/llvm-16.0/scripts/generate_build_files.py (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1#!/usr/bin/env python3
2
3# Copyright 2023 The SwiftShader Authors. All Rights Reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#    http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import contextlib
18import os
19import sys
20from string import Template
21
22## Generates `CMakeLists.txt`, `Android.bp`, and `BUILD.gn`
23
24CMAKE_TEMPLATE_PATH = "template_CMakeLists.txt"
25DESTINATION_CMAKELISTS_PATH = "../CMakeLists.txt"
26
27ANDROID_BP_TEMPLATE_PATH = "template_Android.bp"
28DESTINATION_ANDROID_BP_PATH = "../Android.bp"
29
30BUILD_GN_TEMPLATE_PATH = "template_BUILD.gn"
31DESTINATION_BUILD_GN_PATH = "../BUILD.gn"
32
33# This custom template class changes the delimiter from '$' to
34# '%$%'.
35# This is needed because CMake build files use '$' extensively.
36class CustomTemplate(Template):
37	delimiter = '%$%'
38
39@contextlib.contextmanager
40def pushd(new_dir):
41    previous_dir = os.getcwd()
42    os.chdir(new_dir)
43    try:
44        yield
45    finally:
46        os.chdir(previous_dir)
47
48# Returns a list of all the .cpp and .c files in the CWD.
49def list_all_potentially_compiled_files():
50    all_files = []
51    for root, sub_folders, files in os.walk("."):
52        for file in files:
53            file_path = os.path.join(root,file)
54            extensions = os.path.splitext(file_path)
55            if extensions[1] == ".cpp" or extensions[1] == ".c":
56                assert(file_path[0] == '.')
57                # Trim the leading '.' out of the path.
58                all_files.append(file_path[1:])
59    all_files.sort()
60    return all_files
61
62# Returns the subset of `files` that do no starts with `banned_prefixes`
63def exclude_files_with_prefixes(files, banned_prefixes):
64    result = []
65    for f in files:
66        file_start_with_banned_prefix = False
67        for prefix in banned_prefixes:
68            if f.startswith(prefix):
69                file_start_with_banned_prefix = True
70                break
71        if not file_start_with_banned_prefix:
72            result.append(f)
73    return result
74
75# Returns the subset of `files` that starts `needed_prefix`
76def keep_files_with_prefix(files, needed_prefix):
77    result = []
78    for f in files:
79        if f.startswith(needed_prefix):
80            result.append(f)
81    return result
82
83# Get all the files
84with pushd("../llvm"):
85    all_files = list_all_potentially_compiled_files()
86
87# Split the `all_files`` in several groups
88# LLVM common files
89prefixes_of_files_not_needed_by_llvm = [
90    # The following is a list of files and directories that were
91    # removed during the process of making llvm 16 build.
92    "/lib/DebugInfo/PDB/DIA/",
93    "/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp",
94    "/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp",
95    "/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp",
96    "/lib/ExecutionEngine/OProfileJIT",
97    "/lib/Frontend/OpenACC/",
98    "/lib/ObjCopy/",
99    "/lib/Support/BLAKE3/",
100    "/lib/Target/",
101    "/lib/Testing/",
102    "/lib/ToolDrivers/llvm-lib/LibDriver.cpp",
103    "/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp",
104    "/lib/WindowsManifest/WindowsManifestMerger.cpp",
105    # The following is a list of files and directories founds by running
106    # build/strip_cmakelists.sh on a build that uses CMakeLists.txt.
107    # The files removed were copied here.
108    "/lib/Analysis/AliasAnalysisSummary.cpp",
109    "/lib/Analysis/Analysis.cpp",
110    "/lib/Analysis/DevelopmentModeInlineAdvisor.cpp",
111    "/lib/Analysis/DomPrinter.cpp",
112    "/lib/Analysis/Interval.cpp",
113    "/lib/Analysis/IntervalPartition.cpp",
114    "/lib/Analysis/MLInlineAdvisor.cpp",
115    "/lib/Analysis/MemDepPrinter.cpp",
116    "/lib/Analysis/ModelUnderTrainingRunner.cpp",
117    "/lib/Analysis/NoInferenceModelRunner.cpp",
118    "/lib/Analysis/RegionPrinter.cpp",
119    "/lib/Analysis/TFLiteUtils.cpp",
120    "/lib/Analysis/Trace.cpp",
121    "/lib/Analysis/TrainingLogger.cpp",
122    "/lib/BinaryFormat/AMDGPUMetadataVerifier.cpp",
123    "/lib/BinaryFormat/DXContainer.cpp",
124    "/lib/BinaryFormat/ELF.cpp",
125    "/lib/BinaryFormat/Minidump.cpp",
126    "/lib/BinaryFormat/MsgPackDocument.cpp",
127    "/lib/BinaryFormat/MsgPackDocumentYAML.cpp",
128    "/lib/BinaryFormat/MsgPackReader.cpp",
129    "/lib/BinaryFormat/MsgPackWriter.cpp",
130    "/lib/Bitcode/Reader/BitReader.cpp",
131    "/lib/Bitcode/Reader/BitcodeAnalyzer.cpp",
132    "/lib/Bitcode/Writer/BitWriter.cpp",
133    "/lib/Bitcode/Writer/BitcodeWriterPass.cpp",
134    "/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp",
135    "/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp",
136    "/lib/CodeGen/CodeGenPassBuilder.cpp",
137    "/lib/CodeGen/CommandFlags.cpp",
138    "/lib/CodeGen/MIRParser/MILexer.cpp",
139    "/lib/CodeGen/MIRParser/MIParser.cpp",
140    "/lib/CodeGen/MIRParser/MIRParser.cpp",
141    "/lib/CodeGen/MIRYamlMapping.cpp",
142    "/lib/CodeGen/MLRegallocPriorityAdvisor.cpp",
143    "/lib/CodeGen/MachinePassManager.cpp",
144    "/lib/CodeGen/MultiHazardRecognizer.cpp",
145    "/lib/CodeGen/NonRelocatableStringpool.cpp",
146    "/lib/CodeGen/ParallelCG.cpp",
147    "/lib/CodeGen/RegAllocScore.cpp",
148    "/lib/CodeGen/VLIWMachineScheduler.cpp",
149    "/lib/DWARFLinker/DWARFLinker.cpp",
150    "/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp",
151    "/lib/DWARFLinker/DWARFLinkerDeclContext.cpp",
152    "/lib/DWARFLinker/DWARFStreamer.cpp",
153    "/lib/DWARFLinkerParallel/DWARFLinker.cpp",
154    "/lib/DWP/DWP.cpp",
155    "/lib/DWP/DWPError.cpp",
156    "/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp",
157    "/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp",
158    "/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp",
159    "/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp",
160    "/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp",
161    "/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp",
162    "/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp",
163    "/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp",
164    "/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp",
165    "/lib/DebugInfo/CodeView/DebugSubsection.cpp",
166    "/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp",
167    "/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp",
168    "/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp",
169    "/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp",
170    "/lib/DebugInfo/CodeView/Formatters.cpp",
171    "/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp",
172    "/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp",
173    "/lib/DebugInfo/CodeView/StringsAndChecksums.cpp",
174    "/lib/DebugInfo/CodeView/SymbolDumper.cpp",
175    "/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp",
176    "/lib/DebugInfo/CodeView/SymbolSerializer.cpp",
177    "/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp",
178    "/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp",
179    "/lib/DebugInfo/CodeView/TypeStreamMerger.cpp",
180    "/lib/DebugInfo/DWARF/DWARFLocationExpression.cpp",
181    "/lib/DebugInfo/GSYM/",
182    "/lib/DebugInfo/LogicalView/",
183    "/lib/DebugInfo/MSF/",
184    "/lib/DebugInfo/PDB/",
185    "/lib/DebugInfo/Symbolize/",
186    "/lib/Debuginfod/",
187    "/lib/ExecutionEngine/ExecutionEngine.cpp",
188    "/lib/ExecutionEngine/ExecutionEngineBindings.cpp",
189    "/lib/ExecutionEngine/GDBRegistrationListener.cpp",
190    "/lib/ExecutionEngine/IntelJITEvents/jitprofiling.c",
191    "/lib/ExecutionEngine/Interpreter/Execution.cpp",
192    "/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp",
193    "/lib/ExecutionEngine/Interpreter/Interpreter.cpp",
194    "/lib/ExecutionEngine/MCJIT/MCJIT.cpp",
195    "/lib/ExecutionEngine/Orc/COFFPlatform.cpp",
196    "/lib/ExecutionEngine/Orc/COFFVCRuntimeSupport.cpp",
197    "/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp",
198    "/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp",
199    "/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp",
200    "/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp",
201    "/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp",
202    "/lib/ExecutionEngine/Orc/EPCEHFrameRegistrar.cpp",
203    "/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp",
204    "/lib/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.cpp",
205    "/lib/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.cpp",
206    "/lib/ExecutionEngine/Orc/EPCIndirectionUtils.cpp",
207    "/lib/ExecutionEngine/Orc/IRTransformLayer.cpp",
208    "/lib/ExecutionEngine/Orc/IndirectionUtils.cpp",
209    "/lib/ExecutionEngine/Orc/LLJIT.cpp",
210    "/lib/ExecutionEngine/Orc/LazyReexports.cpp",
211    "/lib/ExecutionEngine/Orc/LookupAndRecordAddrs.cpp",
212    "/lib/ExecutionEngine/Orc/MapperJITLinkMemoryManager.cpp",
213    "/lib/ExecutionEngine/Orc/MemoryMapper.cpp",
214    "/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp",
215    "/lib/ExecutionEngine/Orc/OrcABISupport.cpp",
216    "/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp",
217    "/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp",
218    "/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp",
219    "/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp",
220    "/lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp",
221    "/lib/ExecutionEngine/Orc/Speculation.cpp",
222    "/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp",
223    "/lib/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.cpp",
224    "/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp",
225    "/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.cpp",
226    "/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorMemoryManager.cpp",
227    "/lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp",
228    "/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp",
229    "/lib/ExecutionEngine/TargetSelect.cpp",
230    "/lib/Extensions/Extensions.cpp",
231    "/lib/FileCheck/FileCheck.cpp",
232    "/lib/Frontend/HLSL/HLSLResource.cpp",
233    "/lib/Frontend/OpenMP/OMP.cpp",
234    "/lib/Frontend/OpenMP/OMPContext.cpp",
235    "/lib/FuzzMutate/",
236    "/lib/IR/Core.cpp",
237    "/lib/IR/ReplaceConstant.cpp",
238    "/lib/IR/StructuralHash.cpp",
239    "/lib/IR/TypedPointerType.cpp",
240    "/lib/IR/VectorBuilder.cpp",
241    "/lib/InterfaceStub/",
242    "/lib/LTO/",
243    "/lib/LineEditor/LineEditor.cpp",
244    "/lib/Linker/LinkModules.cpp",
245    "/lib/MC/ConstantPools.cpp",
246    "/lib/MC/MCAsmInfoGOFF.cpp",
247    "/lib/MC/MCAsmInfoWasm.cpp",
248    "/lib/MC/MCAsmInfoXCOFF.cpp",
249    "/lib/MC/MCDisassembler/Disassembler.cpp",
250    "/lib/MC/MCDisassembler/MCDisassembler.cpp",
251    "/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp",
252    "/lib/MC/MCDisassembler/MCSymbolizer.cpp",
253    "/lib/MC/MCInstrInfo.cpp",
254    "/lib/MC/MCLabel.cpp",
255    "/lib/MC/MCParser/COFFMasmParser.cpp",
256    "/lib/MC/MCParser/MasmParser.cpp",
257    "/lib/MC/MCTargetOptionsCommandFlags.cpp",
258    "/lib/MC/MCWasmObjectTargetWriter.cpp",
259    "/lib/MC/MCXCOFFObjectTargetWriter.cpp",
260    "/lib/MCA/",
261    "/lib/Object/ArchiveWriter.cpp",
262    "/lib/Object/BuildID.cpp",
263    "/lib/Object/COFFImportFile.cpp",
264    "/lib/Object/COFFModuleDefinition.cpp",
265    "/lib/Object/DXContainer.cpp",
266    "/lib/Object/FaultMapParser.cpp",
267    "/lib/Object/MachOUniversalWriter.cpp",
268    "/lib/Object/Object.cpp",
269    "/lib/Object/SymbolSize.cpp",
270    "/lib/Object/WindowsMachineFlag.cpp",
271    "/lib/ObjectYAML/",
272    "/lib/Passes/PassBuilderBindings.cpp",
273    "/lib/Passes/PassPlugin.cpp",
274    "/lib/Passes/StandardInstrumentations.cpp",
275    "/lib/ProfileData/Coverage/CoverageMapping.cpp",
276    "/lib/ProfileData/Coverage/CoverageMappingReader.cpp",
277    "/lib/ProfileData/Coverage/CoverageMappingWriter.cpp",
278    "/lib/ProfileData/GCOV.cpp",
279    "/lib/ProfileData/InstrProfWriter.cpp",
280    "/lib/ProfileData/RawMemProfReader.cpp",
281    "/lib/ProfileData/SampleProfWriter.cpp",
282    "/lib/Remarks/Remark.cpp",
283    "/lib/Remarks/RemarkLinker.cpp",
284    "/lib/Support/AMDGPUMetadata.cpp",
285    "/lib/Support/APFixedPoint.cpp",
286    "/lib/Support/ARMWinEH.cpp",
287    "/lib/Support/AddressRanges.cpp",
288    "/lib/Support/Allocator.cpp",
289    "/lib/Support/Atomic.cpp",
290    "/lib/Support/AutoConvert.cpp",
291    "/lib/Support/Base64.cpp",
292    "/lib/Support/BuryPointer.cpp",
293    "/lib/Support/COM.cpp",
294    "/lib/Support/CSKYAttributeParser.cpp",
295    "/lib/Support/CSKYAttributes.cpp",
296    "/lib/Support/CachePruning.cpp",
297    "/lib/Support/Caching.cpp",
298    "/lib/Support/DAGDeltaAlgorithm.cpp",
299    "/lib/Support/DeltaAlgorithm.cpp",
300    "/lib/Support/FileCollector.cpp",
301    "/lib/Support/FileOutputBuffer.cpp",
302    "/lib/Support/FileUtilities.cpp",
303    "/lib/Support/InitLLVM.cpp",
304    "/lib/Support/LockFileManager.cpp",
305    "/lib/Support/MSP430AttributeParser.cpp",
306    "/lib/Support/MSP430Attributes.cpp",
307    "/lib/Support/Parallel.cpp",
308    "/lib/Support/PluginLoader.cpp",
309    "/lib/Support/RWMutex.cpp",
310    "/lib/Support/SHA256.cpp",
311    "/lib/Support/SystemUtils.cpp",
312    "/lib/Support/TarWriter.cpp",
313    "/lib/Support/ThreadPool.cpp",
314    "/lib/Support/UnicodeNameToCodepoint.cpp",
315    "/lib/Support/UnicodeNameToCodepointGenerated.cpp",
316    "/lib/Support/Watchdog.cpp",
317    "/lib/Support/Z3Solver.cpp",
318    "/lib/Support/raw_os_ostream.cpp",
319    "/lib/TableGen/",
320    "/lib/TargetParser/CSKYTargetParser.cpp",
321    "/lib/TargetParser/LoongArchTargetParser.cpp",
322    "/lib/TargetParser/RISCVTargetParser.cpp",
323    "/lib/TargetParser/TargetParser.cpp",
324    "/lib/TargetParser/X86TargetParser.cpp",
325    "/lib/TextAPI/Symbol.cpp",
326    "/lib/Transforms/Hello/Hello.cpp",
327    "/lib/Transforms/IPO/BarrierNoopPass.cpp",
328    "/lib/Transforms/IPO/ExtractGV.cpp",
329    "/lib/Transforms/IPO/IPO.cpp",
330    "/lib/Transforms/IPO/InlineSimple.cpp",
331    "/lib/Transforms/IPO/PassManagerBuilder.cpp",
332    "/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp",
333    "/lib/Transforms/Scalar/PlaceSafepoints.cpp",
334    "/lib/Transforms/Scalar/Scalar.cpp",
335    "/lib/Transforms/Utils/AMDGPUEmitPrintf.cpp",
336    "/lib/Transforms/Utils/LowerMemIntrinsics.cpp",
337    "/lib/Transforms/Utils/SanitizerStats.cpp",
338    "/lib/Transforms/Utils/SplitModule.cpp",
339    "/lib/Transforms/Utils/Utils.cpp",
340    "/lib/Transforms/Vectorize/VPlanSLP.cpp",
341    "/lib/Transforms/Vectorize/Vectorize.cpp",
342    "/lib/WindowsDriver/MSVCPaths.cpp",
343    "/lib/XRay/",
344    "/lib/Target/X86/Disassembler/X86Disassembler.cpp",
345    "/lib/Target/X86/MCA/X86CustomBehaviour.cpp",
346    "/lib/Target/Mips/Disassembler/MipsDisassembler.cpp",
347    "/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp",
348    "/lib/Target/ARM/Disassembler/ARMDisassembler.cpp",
349    "/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp",
350    "/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp",
351]
352files_to_add_back_for_llvm = [
353    "/lib/Target/TargetLoweringObjectFile.cpp",
354    "/lib/Target/TargetMachine.cpp",
355    "/lib/Support/BLAKE3/blake3.c",
356    "/lib/Support/BLAKE3/blake3_dispatch.c",
357    "/lib/Support/BLAKE3/blake3_portable.c"
358]
359files_llvm = exclude_files_with_prefixes(all_files, prefixes_of_files_not_needed_by_llvm)
360files_llvm.extend(files_to_add_back_for_llvm)
361
362files_llvm_debug = [
363    "/lib/Analysis/RegionPrinter.cpp",
364    "/lib/MC/MCDisassembler/MCDisassembler.cpp",
365]
366
367files_to_add_back_for_llvm_arm = [
368    "/lib/CodeGen/MultiHazardRecognizer.cpp",
369    "/lib/MC/ConstantPools.cpp",
370    "/lib/MC/MCInstrInfo.cpp",
371    "/lib/Transforms/IPO/BarrierNoopPass.cpp",
372]
373
374files_to_add_back_for_llvm_loongarch = [
375    "/lib/TargetParser/LoongArchTargetParser.cpp",
376    "/lib/Transforms/IPO/BarrierNoopPass.cpp",
377]
378
379files_to_add_back_for_llvm_riscv = [
380    "/lib/TargetParser/RISCVTargetParser.cpp",
381    "/lib/Transforms/IPO/BarrierNoopPass.cpp",
382]
383
384# Architecture specific files
385files_x86 = keep_files_with_prefix(all_files, "/lib/Target/X86/")
386files_Mips = keep_files_with_prefix(all_files, "/lib/Target/Mips/")
387files_AArch64 = keep_files_with_prefix(all_files, "/lib/Target/AArch64/")
388files_AArch64.extend(files_to_add_back_for_llvm_arm)
389files_AArch64.sort()
390files_ARM = keep_files_with_prefix(all_files, "/lib/Target/ARM/")
391files_ARM.extend(files_to_add_back_for_llvm_arm)
392files_ARM.sort()
393files_LoongArch = keep_files_with_prefix(all_files, "/lib/Target/LoongArch/")
394files_LoongArch.extend(files_to_add_back_for_llvm_loongarch)
395files_LoongArch.sort()
396files_PowerPC = keep_files_with_prefix(all_files, "/lib/Target/PowerPC/")
397files_RISCV = keep_files_with_prefix(all_files, "/lib/Target/RISCV/")
398files_RISCV.extend(files_to_add_back_for_llvm_riscv)
399files_RISCV.sort()
400
401generated_file_comment = "File generated by " + sys.argv[0]
402
403# Generate CMakeLists.txt
404def format_file_list_for_cmake(files):
405    return '\n'.join(["        ${LLVM_DIR}" + s for s in files])
406cmake_template_data = {
407    'generated_file_comment' : "# " + generated_file_comment,
408    'files_llvm' : '\n'.join(["    ${LLVM_DIR}" + s for s in files_llvm]),
409    'files_x86' : format_file_list_for_cmake(files_x86),
410    'files_LoongArch' : format_file_list_for_cmake(files_LoongArch),
411    'files_Mips' : format_file_list_for_cmake(files_Mips),
412    'files_AArch64' : format_file_list_for_cmake(files_AArch64),
413    'files_ARM' : format_file_list_for_cmake(files_ARM),
414    'files_PowerPC' : format_file_list_for_cmake(files_PowerPC),
415    'files_RISCV' : format_file_list_for_cmake(files_RISCV),
416}
417with open(CMAKE_TEMPLATE_PATH, 'r') as f:
418    cmake_template = CustomTemplate(f.read())
419    result = cmake_template.substitute(cmake_template_data)
420    cmake_output = open(DESTINATION_CMAKELISTS_PATH, "w")
421    cmake_output.write(result)
422
423# Generate Android.bp
424def format_file_list_for_android_bp(files, indent):
425    spaces = '    ' * indent
426    return '\n'.join([spaces + "\"llvm" + s + "\"," for s in files])
427android_bp_template_data = {
428    'generated_file_comment' : "// " + generated_file_comment,
429    'files_llvm' : format_file_list_for_android_bp(files_llvm, indent=2),
430    'files_llvm_debug': format_file_list_for_android_bp(files_llvm_debug, indent=2),
431    'files_x86' : format_file_list_for_android_bp(files_x86, indent=4),
432    'files_AArch64' : format_file_list_for_android_bp(files_AArch64, indent=4),
433    'files_ARM' : format_file_list_for_android_bp(files_ARM, indent=4),
434    'files_RISCV' : format_file_list_for_android_bp(files_RISCV, indent=4),
435}
436with open(ANDROID_BP_TEMPLATE_PATH, 'r') as f:
437    android_bp_template = CustomTemplate(f.read())
438    result = android_bp_template.substitute(android_bp_template_data)
439    cmake_output = open(DESTINATION_ANDROID_BP_PATH, "w")
440    cmake_output.write(result)
441
442# Generate BUILD.gn
443
444# Remove 3 files that are special cases.
445# They are dealt with in the template file.
446files_llvm_build_gn = exclude_files_with_prefixes(files_llvm, ['/lib/MC/MCWasmObjectTargetWriter.cpp', '/lib/MC/MCXCOFFObjectTargetWriter.cpp'])
447files_ARM_build_gn = exclude_files_with_prefixes(files_ARM, ['/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp'])
448
449# GN doesn't allow for duplicate source file names, even if they are
450# in different subdirectories. Because of this, `files_llvm_build_gn` is
451# partitionned into multiple targets.
452def get_filename(path):
453        return path.split("/")[-1]
454# Takes a list of paths and returns multiple lists of paths.
455# Every list will contain a unique set of filenames.
456def partition_paths(filepaths):
457    partitions = []
458    for path in filepaths:
459        # Convert to lower case to support case-insensitive filesystem
460        filename = get_filename(path).lower()
461        inserted = False
462        for partition in partitions:
463            if not filename in partition:
464                partition[filename] = path
465                inserted = True
466                break
467        if not inserted:
468            new_partition = {filename : path}
469            partitions.append(new_partition)
470    return [[p for f, p in partition.items()] for partition in partitions]
471# Returns a string containing a GN source set containing the filepaths
472def create_source_set(source_set_name, filepaths):
473    s = 'swiftshader_llvm_source_set("%s") {\n' % source_set_name
474    s += '  sources = [\n'
475    for filepath in filepaths:
476        s += '    "llvm%s",\n' % filepath
477    s += '  ]\n'
478    s += '}\n'
479    return s
480def source_set_name(i):
481    return 'swiftshader_llvm_source_set_%i' % i
482
483# Generate the GN source set code
484files_llvm_partitions = partition_paths(files_llvm_build_gn)
485source_set_code = ""
486i = 0
487for partition in files_llvm_partitions:
488    source_set_code += create_source_set(source_set_name(i), partition)
489    i = i+1
490
491# Generate the GN deps code
492deps_code = ''
493i = 0
494for partition in files_llvm_partitions:
495    deps_code += '    ":%s",\n' % source_set_name(i)
496    i = i+1
497
498def format_file_list_for_build_gn(files):
499    return '\n'.join(["    \"llvm" + s + "\"," for s in files])
500build_gn_template_data = {
501    'generated_file_comment' : "# " + generated_file_comment,
502    'llvm_source_sets' : source_set_code,
503    'llvm_deps' : deps_code,
504    'files_x86' : format_file_list_for_build_gn(files_x86),
505    'files_AArch64' : format_file_list_for_build_gn(files_AArch64),
506    'files_ARM' : format_file_list_for_build_gn(files_ARM_build_gn),
507    'files_LoongArch' : format_file_list_for_build_gn(files_LoongArch),
508    'files_Mips' : format_file_list_for_build_gn(files_Mips),
509    'files_PowerPC' : format_file_list_for_build_gn(files_PowerPC),
510    'files_RISCV' : format_file_list_for_build_gn(files_RISCV),
511    'files_llvm_debug': format_file_list_for_build_gn(files_llvm_debug),
512}
513with open(BUILD_GN_TEMPLATE_PATH, 'r') as f:
514    build_gn_template = CustomTemplate(f.read())
515    result = build_gn_template.substitute(build_gn_template_data)
516    cmake_output = open(DESTINATION_BUILD_GN_PATH, "w")
517    cmake_output.write(result)