diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7f6f199..9e8ea55 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -290,4 +290,9 @@
if((CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") AND ((${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.22.0") OR (NOT CMAKE_CXX_COMPILER_ID MATCHES "ARMClang")))
set(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
endif()
+endif()
+
+# If this is the top-level buildscript, run finalize tasks
+if(MBED_IS_STANDALONE AND (NOT MBED_IS_NATIVE_BUILD))
+ mbed_finalize_build()
endif()
\ No newline at end of file
diff --git a/tools/cmake/app.cmake b/tools/cmake/app.cmake
index a89ffdb..b1c5399 100644
--- a/tools/cmake/app.cmake
+++ b/tools/cmake/app.cmake
@@ -69,3 +69,6 @@
message(STATUS "Mbed: Target does not have any upload method configuration. 'make flash-' commands will not be available unless configured by the upper-level project.")
set(UPLOAD_METHOD_DEFAULT "NONE")
endif()
+
+# Load debug config generator for IDEs
+include(mbed_ide_debug_cfg_generator)
\ No newline at end of file
diff --git a/tools/cmake/mbed_ide_debug_cfg_generator.cmake b/tools/cmake/mbed_ide_debug_cfg_generator.cmake
new file mode 100644
index 0000000..ec7eefa
--- /dev/null
+++ b/tools/cmake/mbed_ide_debug_cfg_generator.cmake
@@ -0,0 +1,104 @@
+# Copyright (c) 2022 ARM Limited. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0
+
+# Script to automatically generate debug configurations for various IDEs.
+
+# Detect IDEs
+# -------------------------------------------------------------
+
+if($ENV{CLION_IDE})
+ message(STATUS "Detected CLion IDE, will generate CLion debug configurations")
+ set(MBED_GENERATE_CLION_DEBUG_CFGS TRUE)
+
+elseif(CMAKE_EXPORT_COMPILE_COMMANDS) # TODO: Is this actually a reliable way of detecting VS Code? Not sure if it will create false positives.
+ message(STATUS "Detected VS Code IDE, will generate VS Code debug configurations")
+ set(MBED_GENERATE_VS_CODE_DEBUG_CFGS TRUE)
+
+endif()
+
+# CLion generator
+# -------------------------------------------------------------
+
+if(MBED_GENERATE_CLION_DEBUG_CFGS)
+
+ # Find CLion run config dir
+ set(CLION_RUN_CONF_DIR ${CMAKE_SOURCE_DIR}/.idea/runConfigurations)
+ file(MAKE_DIRECTORY ${CLION_RUN_CONF_DIR})
+
+ function(mbed_generate_ide_debug_configuration CMAKE_TARGET)
+
+ # Create name (combine target name, Mbed target, and build type to generate a unique string)
+ set(CONFIG_NAME "GDB ${CMAKE_TARGET} ${MBED_TARGET} ${CMAKE_BUILD_TYPE}")
+ set(RUN_CONF_PATH "${CLION_RUN_CONF_DIR}/${CONFIG_NAME}.xml")
+
+ file(GENERATE OUTPUT ${RUN_CONF_PATH} CONTENT
+"
+
+ \" sysroot=\"\">
+
+
+
+")
+ endfunction(mbed_generate_ide_debug_configuration)
+
+ function(mbed_finalize_ide_debug_configurations)
+ # Don't need to do anything
+ endfunction(mbed_finalize_ide_debug_configurations)
+
+
+# VS Code generator
+# -------------------------------------------------------------
+elseif(MBED_GENERATE_VS_CODE_DEBUG_CFGS)
+
+ set(VSCODE_LAUNCH_JSON_PATH ${CMAKE_SOURCE_DIR}/.vscode/launch.json)
+
+ # Start building up json file. Needs to be a global property so we can append to it from anywhere.
+ # Note: Cannot use a cache variable for this because cache variables aren't allowed to contain newlines.
+ set_property(GLOBAL PROPERTY VSCODE_LAUNCH_JSON_CONTENT
+"{
+ \"configurations\": [")
+
+ function(mbed_generate_ide_debug_configuration CMAKE_TARGET)
+
+ # Create name (combine target name, Mbed target, and build config to generate a unique string)
+ set(CONFIG_NAME "Connect to GDB ${CMAKE_TARGET} ${MBED_TARGET} ${CMAKE_BUILD_TYPE}")
+
+ # from here: https://stackoverflow.com/questions/38089178/is-it-possible-to-attach-to-a-remote-gdb-target-with-vscode
+ set_property(GLOBAL APPEND_STRING PROPERTY VSCODE_LAUNCH_JSON_CONTENT "
+ {
+ \"type\": \"gdb\",
+ \"request\": \"attach\",
+ \"name\": \"${CONFIG_NAME}\",
+ \"executable\": \"$\",
+ \"target\": \"localhost:${GDB_PORT}\",
+ \"remote\": true,
+ \"cwd\": \"\${workspaceRoot}\",
+ \"gdbpath\": \"arm-none-eabi-gdb\"
+ },")
+
+ endfunction(mbed_generate_ide_debug_configuration)
+
+ # Take all generated debug configurations and write them to launch.json.
+ function(mbed_finalize_ide_debug_configurations)
+ # Add footer
+ set_property(GLOBAL APPEND_STRING PROPERTY VSCODE_LAUNCH_JSON_CONTENT "
+ ]
+}")
+
+ get_property(VSCODE_LAUNCH_JSON_CONTENT GLOBAL PROPERTY VSCODE_LAUNCH_JSON_CONTENT)
+ file(GENERATE OUTPUT ${VSCODE_LAUNCH_JSON_PATH} CONTENT ${VSCODE_LAUNCH_JSON_CONTENT})
+ endfunction(mbed_finalize_ide_debug_configurations)
+
+# No-op generator
+# -------------------------------------------------------------
+else()
+
+ function(mbed_generate_ide_debug_configuration CMAKE_TARGET)
+ # Empty
+ endfunction(mbed_generate_ide_debug_configuration)
+
+ function(mbed_finalize_ide_debug_configurations)
+ # Empty
+ endfunction(mbed_finalize_ide_debug_configurations)
+
+endif()
\ No newline at end of file
diff --git a/tools/cmake/mbed_set_post_build.cmake b/tools/cmake/mbed_set_post_build.cmake
index d33ba00..eb163b8 100644
--- a/tools/cmake/mbed_set_post_build.cmake
+++ b/tools/cmake/mbed_set_post_build.cmake
@@ -113,4 +113,13 @@
endif()
mbed_generate_upload_debug_targets(${target})
+ mbed_generate_ide_debug_configuration(${target})
endfunction()
+
+#
+# Call this at the very end of the build script. Does some final cleanup tasks such as
+# writing out debug configurations.
+#
+function(mbed_finalize_build)
+ mbed_finalize_ide_debug_configurations()
+endfunction(mbed_finalize_build)
\ No newline at end of file