]> Git Repo - pico-vscode.git/blob - scripts/genExamples.py
Add more examples, with supported boards (#61)
[pico-vscode.git] / scripts / genExamples.py
1 #!/usr/bin/env python3
2
3 import os
4 import glob
5 import shutil
6 import json
7
8 from pico_project import GenerateCMake
9
10 boards = [
11     "pico",
12     "pico_w",
13     "pico2"
14 ]
15
16 platforms = {
17     "pico": ["rp2040"],
18     "pico_w": ["rp2040"],
19     "pico2": [
20         "rp2350-arm-s",
21         "rp2350-riscv"
22     ]
23 }
24
25 examples = {
26     "example_format": {
27         "path": "hello_world/usb",
28         "name": "usb",
29         "libPaths": [],
30         "libNames": [],
31         "boards": [],
32         "supportRiscV": False
33     }
34 }
35
36 examples.clear()
37
38 CURRENT_DATA_VERSION = "0.16.0"
39
40 try:
41     shutil.rmtree("pico-examples")
42 except FileNotFoundError:
43     pass
44 try:
45     for path in glob.glob("errors-pico*"):
46         shutil.rmtree(path)
47 except FileNotFoundError:
48     pass
49 os.system("git -c advice.detachedHead=false clone https://github.com/raspberrypi/pico-examples.git --depth=1 --branch sdk-2.0.0")
50 os.environ["PICO_SDK_PATH"] = "~/.pico-sdk/sdk/2.0.0"
51
52 for board in boards:
53     for platform in platforms[board]:
54         try:
55             shutil.rmtree("build")
56         except FileNotFoundError:
57             pass
58         toolchainVersion = "RISCV_COREV_MAY_24" if "riscv" in platform else "13_2_Rel1"
59         toolchainPath = f"~/.pico-sdk/toolchain/{toolchainVersion}"
60         os.system(f"cmake -S pico-examples -B build -DPICO_BOARD={board} -DPICO_PLATFORM={platform} -DPICO_TOOLCHAIN_PATH={toolchainPath}")
61
62         os.system("cmake --build build --target help > targets.txt")
63
64         targets = []
65
66         with open("targets.txt", "r") as f:
67             for line in f.readlines():
68                 target = line.strip('.').strip()
69                 if (
70                     "all" in target or
71                     target == "clean" or
72                     target == "depend" or
73                     target == "edit_cache" or
74                     target == "rebuild_cache" or
75                     target.endswith("_pio_h")
76                 ):
77                     continue
78                 targets.append(target)
79
80         walk_dir = "./pico-examples"
81         target_locs = {}
82         lib_locs = {}
83
84         for root, subdirs, files in os.walk(walk_dir):
85             for filename in files:
86                 if filename != "CMakeLists.txt":
87                     continue
88                 file_path = os.path.join(root, filename)
89
90                 with open(file_path, 'r') as f:
91                     f_content = f.read()
92                     if "add_library" in f_content:
93                         for target in targets:
94                             if f"add_library({target}" in f_content:
95                                 tmp = lib_locs.get(target, {
96                                     "locs": []
97                                 })
98                                 tmp["locs"].append(file_path)
99                                 lib_locs[target] = tmp
100                     if "add_executable" in f_content:
101                         exes = []
102                         for target in targets:
103                             if f"example_auto_set_url({target})" in f_content:
104                                 exes.append(target)
105                                 tmp = target_locs.get(target, {
106                                     "locs": [],
107                                     "libs": []
108                                 })
109                                 tmp["locs"].append(file_path)
110                                 target_locs[target] = tmp
111
112         for k, v in target_locs.items():
113             if len(v["locs"]) > 1:
114                 raise ValueError(f"Too many locs {v}")
115             target_locs[k]["loc"] = v["locs"][0]
116             with open(v["locs"][0], "r") as f:
117                 f_content = f.read()
118                 for lib in lib_locs:
119                     if lib in f_content:
120                         target_locs[k]["libs"].append(lib)
121
122         for k, v in lib_locs.items():
123             if len(v["locs"]) > 1:
124                 raise ValueError(f"Too many locs {v}")
125             lib_locs[k]["loc"] = v["locs"][0]
126
127         # Test build them all
128         try:
129             shutil.rmtree("tmp")
130             shutil.rmtree("tmp-build")
131         except FileNotFoundError:
132             pass
133         for target, v in target_locs.items():
134             os.mkdir("tmp-build")
135             loc = v["loc"]
136             loc = loc.replace("/CMakeLists.txt", "")
137             shutil.copytree(loc, "tmp")
138             if len(v["libs"]):
139                 for lib in v["libs"]:
140                     shutil.copytree(
141                         lib_locs[lib]["loc"].replace("/CMakeLists.txt", ""),
142                         f"tmp/{lib}"
143                     )
144             params={
145                 'projectName'   : target,
146                 'wantOverwrite' : True,
147                 'wantConvert'   : True,
148                 'wantExample'   : True,
149                 'wantThreadsafeBackground'  : False,
150                 'wantPoll'                  : False,
151                 'boardtype'     : board,
152                 'sdkVersion'    : "2.0.0",
153                 'toolchainVersion': toolchainVersion,
154                 'picotoolVersion': "2.0.0",
155                 'exampleLibs'   : v["libs"]
156             }
157             GenerateCMake("tmp", params)
158             shutil.copy("pico-examples/pico_sdk_import.cmake", "tmp/")
159
160             retcmake = os.system("cmake -S tmp -B tmp-build -DCMAKE_COMPILE_WARNING_AS_ERROR=ON")
161             retbuild = os.system("cmake --build tmp-build --parallel 22")
162             if (retcmake or retbuild):
163                 print(f"Error occurred with {target} {v} - cmake {retcmake}, build {retbuild}")
164                 shutil.copytree("tmp", f"errors-{board}-{platform}/{target}")
165             else:
166                 if examples.get(target) != None:
167                     example = examples[target]
168                     assert(example["path"] == loc.replace(f"{walk_dir}/", ""))
169                     assert(example["name"] == target)
170                     assert(example["libPaths"] == [lib_locs[lib]["loc"].replace("/CMakeLists.txt", "").replace(f"{walk_dir}/", "") for lib in v["libs"]])
171                     assert(example["libNames"] == v["libs"])
172                     if not board in example["boards"]:
173                         example["boards"].append(board)
174                     example["supportRiscV"] |= "riscv" in platform
175                 else:
176                     examples[target] = {
177                         "path": loc.replace(f"{walk_dir}/", ""),
178                         "name": target,
179                         "libPaths": [lib_locs[lib]["loc"].replace("/CMakeLists.txt", "").replace(f"{walk_dir}/", "") for lib in v["libs"]],
180                         "libNames": v["libs"],
181                         "boards": [board],
182                         "supportRiscV": "riscv" in platform
183                     }
184
185             shutil.rmtree("tmp")
186             shutil.rmtree("tmp-build")
187
188 with open(f"{os.path.dirname(os.path.realpath(__file__))}/../data/{CURRENT_DATA_VERSION}/examples.json", "w") as f:
189     json.dump(examples, f, indent=4)
This page took 0.034057 seconds and 4 git commands to generate.