Skip to content

Commit e2bb7db

Browse files
committed
add vs code launch.json auto generation in waf configure
1 parent e4de4c9 commit e2bb7db

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

wscript

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ def options(opt):
155155
action='store_true',
156156
default=False,
157157
help='Add debug symbolds to build.')
158+
159+
g.add_option('--vs-launch',
160+
action='store_true',
161+
default=False,
162+
help='Generate launch.json template for Visual Studio Code.')
158163

159164
g.add_option('--disable-watchdog',
160165
action='store_true',
@@ -502,6 +507,7 @@ def configure(cfg):
502507

503508
cfg.env.BOARD = cfg.options.board
504509
cfg.env.DEBUG = cfg.options.debug
510+
cfg.env.VS_LAUNCH = cfg.options.vs_launch
505511
cfg.env.DEBUG_SYMBOLS = cfg.options.debug_symbols
506512
cfg.env.COVERAGE = cfg.options.coverage
507513
cfg.env.FORCE32BIT = cfg.options.force_32bit
@@ -607,6 +613,13 @@ def configure(cfg):
607613
else:
608614
cfg.end_msg('disabled', color='YELLOW')
609615

616+
if cfg.env.DEBUG:
617+
cfg.start_msg('VS Code launch')
618+
if cfg.env.VS_LAUNCH:
619+
cfg.end_msg('enabled')
620+
else:
621+
cfg.end_msg('disabled', color='YELLOW')
622+
610623
cfg.start_msg('Coverage build')
611624
if cfg.env.COVERAGE:
612625
cfg.end_msg('enabled')
@@ -652,6 +665,9 @@ def configure(cfg):
652665
cfg.remove_target_list()
653666
_collect_autoconfig_files(cfg)
654667

668+
if cfg.env.VS_LAUNCH:
669+
_create_vscode_launch_json(cfg)
670+
655671
def collect_dirs_to_recurse(bld, globs, **kw):
656672
dirs = []
657673
globs = Utils.to_list(globs)
@@ -875,6 +891,132 @@ def _load_pre_build(bld):
875891
if getattr(brd, 'pre_build', None):
876892
brd.pre_build(bld)
877893

894+
def _create_vscode_launch_json(cfg):
895+
launch_json_path = os.path.join(cfg.srcnode.abspath(), '.vscode', 'launch.json')
896+
if os.path.exists(launch_json_path):
897+
default_template = {
898+
"version": "0.2.0",
899+
"configurations": []
900+
}
901+
try:
902+
with open(launch_json_path, 'r') as f:
903+
content = f.read().strip()
904+
if content:
905+
launch_json = json.loads(content)
906+
else:
907+
launch_json = default_template
908+
if "configurations" not in launch_json:
909+
launch_json["configurations"] = [] #initialize configurations
910+
if type(launch_json["configurations"]) is not list:
911+
launch_json["configurations"] = [] #overwrite invalid configurations
912+
except json.JSONDecodeError:
913+
print(f"\033[91mError: Invalid JSON in {launch_json_path}. Creating a new launch.json file.\033[0m")
914+
launch_json = default_template
915+
else:
916+
launch_json = default_template
917+
918+
configurations = [
919+
{'name': 'ArduCopter', 'target': 'arducopter'},
920+
{'name': 'ArduPlane', 'target': 'arduplane'},
921+
{'name': 'ArduCopter-Heli', 'target': 'arducopter-heli'},
922+
{'name': 'ArduRover', 'target': 'ardurover'},
923+
{'name': 'ArduSub', 'target': 'ardusub'},
924+
{'name': 'AP_Periph', 'target': 'AP_Periph'},
925+
{'name': 'AP_Blimp', 'target': 'blimp'},
926+
{'name': 'AntennaTracker', 'target': 'antennatracker'},
927+
{'name': 'AP_Bootloader', 'target': 'ap_bootloader'},
928+
] #pending to add more targets
929+
930+
for configuration in configurations:
931+
if cfg.options.board == 'sitl':
932+
if configuration['name'] == 'AP_Bootloader':
933+
continue
934+
launch_configuration = {
935+
"name": configuration['name'],
936+
"type": "cppdbg",
937+
"request": "launch",
938+
"program": "${workspaceFolder}/build/sitl/bin/" + configuration['target'],
939+
"args": [
940+
"-S",
941+
"--model",
942+
"+",
943+
"--speedup",
944+
"1",
945+
"--slave",
946+
"0",
947+
"--sim-address=127.0.0.1",
948+
"-I0"
949+
],
950+
"stopAtEntry": False,
951+
"cwd": "${workspaceFolder}",
952+
"environment": [],
953+
"externalConsole": False,
954+
"MIMode": "lldb",
955+
"setupCommands": [
956+
{
957+
"description": "Enable pretty-printing for gdb",
958+
"text": "-enable-pretty-printing",
959+
"ignoreFailures": False
960+
}
961+
],
962+
}
963+
else:
964+
if configuration['name'] == 'AP_Bootloader':
965+
executable_path = "${workspaceFolder}/build/"+ cfg.options.board + "/bootloader/AP_Bootloader"
966+
else:
967+
executable_path = "${workspaceFolder}/build/"+ cfg.options.board + "/bin/" + configuration['target']
968+
launch_configuration = {
969+
"name": configuration['name'],
970+
"cwd": "${workspaceFolder}",
971+
"executable": executable_path,
972+
"liveWatch": {
973+
"enabled": True,
974+
"samplesPerSecond": 4
975+
},
976+
"request": "launch",
977+
"type": "cortex-debug",
978+
"servertype": "openocd",
979+
"configFiles": [
980+
"${workspaceFolder}/build/" + cfg.options.board + "/openocd.cfg",
981+
]
982+
}
983+
984+
configuration_overwrited = False
985+
for index, current_configuration in enumerate(launch_json["configurations"]):
986+
if current_configuration.get('name') == launch_configuration['name']:
987+
launch_json["configurations"][index] = launch_configuration
988+
configuration_overwrited = True
989+
break
990+
if not configuration_overwrited:
991+
launch_json["configurations"].append(launch_configuration)
992+
993+
with open(launch_json_path, 'w') as f:
994+
json.dump(launch_json, f, indent=4)
995+
996+
#create openocd.cfg file
997+
if cfg.options.board != 'sitl':
998+
openocd_cfg_path = os.path.join(cfg.srcnode.abspath(), 'build', cfg.options.board, 'openocd.cfg')
999+
mcu_type = cfg.env.get_flat('APJ_BOARD_TYPE')
1000+
openocd_target = ''
1001+
if mcu_type.startswith("STM32H7"):
1002+
openocd_target = 'stm32h7x.cfg'
1003+
elif mcu_type.startswith("STM32F7"):
1004+
openocd_target = 'stm32f7x.cfg'
1005+
elif mcu_type.startswith("STM32F4"):
1006+
openocd_target = 'stm32f4x.cfg'
1007+
elif mcu_type.startswith("STM32F3"):
1008+
openocd_target = 'stm32f3x.cfg'
1009+
elif mcu_type.startswith("STM32L4"):
1010+
openocd_target = 'stm32l4x.cfg'
1011+
elif mcu_type.startswith("STM32G4"):
1012+
openocd_target = 'stm32g4x.cfg'
1013+
1014+
with open(openocd_cfg_path, 'w+') as f:
1015+
f.write("source [find interface/stlink-v2.cfg]\n")
1016+
f.write(f"source [find target/{openocd_target}]\n")
1017+
f.write("init\n")
1018+
f.write("$_TARGETNAME configure -rtos auto\n")
1019+
8781020
def build(bld):
8791021
config_hash = Utils.h_file(bld.bldnode.make_node('ap_config.h').abspath())
8801022
bld.env.CCDEPS = config_hash

0 commit comments

Comments
 (0)