Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generation of VS Code debug configuration #302

Merged
merged 3 commits into from
Aug 9, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -15,5 +15,8 @@ www/
.project
.settings

# VSCode auto-generated files
.vscode

# CMake default directories
build/
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ enable_testing()
find_package(OmnetPP 5.5.1 MODULE REQUIRED)
include(AddOppRun)
include(AddOppTarget)
include(AddVSCode)
include(CheckGitSubmodule)
include(GenerateOppMessage)
include(GNUInstallDirs)
@@ -102,6 +103,8 @@ add_subdirectory(src/traci)

add_subdirectory(src/artery)

option(VSCODE_LAUNCH_INTEGRATION "Generate VS Code configuration for debugging Artery (requires debug build)" OFF)

# scenarios directory is part of repository but omitted for Docker build context
if(EXISTS ${PROJECT_SOURCE_DIR}/scenarios)
add_subdirectory(scenarios)
101 changes: 101 additions & 0 deletions cmake/AddVSCode.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Generates launch.json for VS Code, containing the default debug configuration. If PROJECT_SOURCE_DIR already
# contains a .vscode/launch.json, the default debug configuration is appended.
#
function(generate_vscode)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A doc-comment explaining the purpose of this function would be beneficial and appreciated 😃

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

set(one_value_args "TARGET;FILE")
cmake_parse_arguments(args "${option_args}" "${one_value_args}" "" ${ARGN})

if(args_UNPARSED_ARGUMENTS)
message(SEND_ERROR "generate_vscode called with invalid arguments: ${args_UNPARSED_ARGUMENTS}")
endif()

if(NOT args_TARGET)
message(SEND_ERROR "generate_vscode: TARGET argument is missing")
endif()

if(NOT args_FILE)
message(SEND_ERROR "generate_vscode: FILE argument is missing")
endif()

# collect all NED folders for given target
get_ned_folders(${args_TARGET} opp_run_ned_folders)
set(opp_run_ned_folders "\"-n$<JOIN:${opp_run_ned_folders},:>\"")

# collect libraries for opp_run
set(opp_run_libraries "")
_get_opp_run_dependencies(${args_TARGET} opp_run_dependencies)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the OmnetC++ dependencies am I right?
Do they change frequently?

Copy link
Contributor Author

@awillecke awillecke Jul 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the libraries of Artery (e.g. libartery_core.so, libtraci.so, ...). These might change when building Artery with other flags (e.g. libartery_envmod.so when WITH_ENVMOD is ON) or when you extend Artery with custom functionalities. Basically, they could change with every (re)generation of the build system.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if one includes all the libs all the time in the launch.json? Will this work?

foreach(opp_run_dependency IN LISTS opp_run_dependencies)
list(APPEND opp_run_libraries "\"-l$<TARGET_FILE:${opp_run_dependency}>\"")
endforeach()
set(opp_run_libraries "$<JOIN:${opp_run_libraries},,>")

set(opp_run_executable ${OMNETPP_RUN_DEBUG})

# substitute variables first, then generator expressions, save in build directory
configure_file(${PROJECT_SOURCE_DIR}/cmake/launch.json.in ${PROJECT_BINARY_DIR}/launch.json.tmp @ONLY)
file(GENERATE OUTPUT ${PROJECT_BINARY_DIR}/launch.json.default INPUT ${PROJECT_BINARY_DIR}/launch.json.tmp)

# if launch.json exists, find generated configuration and modify it
if(EXISTS ${args_FILE})
set(default_config_found false)
file(READ ${args_FILE} current_launch_json)

string(JSON num_configs LENGTH ${current_launch_json} "configurations")
message(STATUS "Found ${num_configs} VS Code Config(s) in .vscode/launch.json")
math(EXPR last_config "${num_configs} - 1")

# read recent build configuration from temporary launch configuraiton
file(READ ${PROJECT_BINARY_DIR}/launch.json.default default_launch_json)

# get generated default configuration
string(JSON default_launch_configuration GET ${default_launch_json} "configurations" 0)

# get the default configuration name
string(JSON default_launch_configuration_name GET ${default_launch_json} "configurations" 0 "name")

# get inputs required by default configuration
string(JSON default_launch_inputs GET ${default_launch_json} "inputs")

# iterate available configs and search for the default config
foreach(config_id RANGE ${last_config})
string(JSON config_name GET ${current_launch_json} "configurations" ${config_id} name)

# found Arterys default debug configuration
if (${config_name} STREQUAL ${default_launch_configuration_name})
message(STATUS "Updating Artery default config in .vscode/launch.json")
set(default_config_found true)

# replace old config with newly generated one and save
string(JSON current_launch_json SET ${current_launch_json} "configurations" ${config_id} ${default_launch_configuration})
file(WRITE ${args_FILE} ${current_launch_json})
endif()
endforeach()

# launch.json is present but no default configuration was found
if (NOT ${default_config_found})
message(STATUS "Append Artery default config to .vscode/launch.json")

# append default configuration
string(JSON current_launch_configuration SET ${current_launch_json} "configurations" ${num_configs} ${default_launch_configuration})

# append inputs to already existing inputs
string(JSON current_num_inputs LENGTH ${current_launch_configuration} "inputs")
string(JSON default_num_inputs LENGTH ${default_launch_inputs})
math(EXPR last_default_input "${default_num_inputs} - 1")

foreach(default_input_index RANGE ${last_default_input})
string(JSON input GET ${default_launch_inputs} ${default_input_index})
math(EXPR current_input_index "${current_num_inputs} + ${default_input_index}")
string(JSON current_launch_configuration SET ${current_launch_configuration} "inputs" ${current_input_index} ${input} )
endforeach()

file(WRITE ${args_FILE} ${current_launch_configuration})
endif()
else()
message(STATUS "Generating default debug config for VS Code")
# substitute variables first, then generator expressions
file(GENERATE OUTPUT ${args_FILE} INPUT ${PROJECT_BINARY_DIR}/launch.json.default)
endif()


endfunction()
77 changes: 77 additions & 0 deletions cmake/launch.json.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Artery in Debugger (generated)",
"description": "Generic debug configuration for Artey. It is (re-)generated with every CMake build generation and any modifications are overwritten!",
"type": "cppdbg",
"request": "launch",

// Set path to OMNet++ debug runner
"program": "@opp_run_executable@",

// Set working directory to scenario
"cwd": "${workspaceFolder}/scenarios/${input:scenario}",

"args": [
// Paths to NED files
@opp_run_ned_folders@,

// Libraries used for Artery
@opp_run_libraries@,

// .ini file to of the scenario
"omnetpp.ini",

// OMNet++ config to run
"-c${input:config}",
// Run number
"-r${input:runId}",

// OMNet++ interface can either be Qtenv or Cmdenv
// "-uQtenv",
"-uCmdenv"
Comment on lines +34 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,
I was wondering, is not QTenv the default graphical environment and CMDenv is deprecated afaik.
I notice this on the website as well.
So should not it be the other way around, QTenv commented in and CMDenv commented out?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that Cmdenv is deprecated but Tkenv. Of course, Cmdenv is not a graphical environment at all but it is very useful for automated/headless simulation runs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I mixed that up. Thank you for the clarification.

],
"stopAtEntry": false,
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Enable all-exceptions",
"text": "catch throw",
"ignoreFailures": true
}
],
// "preLaunchTask": "C/C++: clang++ build active file",
"miDebuggerPath": "/usr/bin/gdb"
}
],
"inputs": [
{
"id": "scenario",
"type": "promptString",
"default": "artery",
"description": "Scenario folder to launch (provide the folder in ./scenarios/)"
},
{
"id": "config",
"type": "promptString",
"default": "inet",
"description": "OMNeT++ config to launch"
},
{
"id": "runId",
"type": "promptString",
"default": "0",
"description": "Run ID of the config to launch"
}
]
}
8 changes: 8 additions & 0 deletions src/artery/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -183,3 +183,11 @@ if(NOT is_multi_config)
PROGRAMS ${PROJECT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/run_artery.sh.install
DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME run_artery.sh)
endif()

if(VSCODE_LAUNCH_INTEGRATION)
if (NOT CMAKE_BUILD_TYPE OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
generate_vscode(TARGET artery FILE ${PROJECT_SOURCE_DIR}/.vscode/launch.json)
else()
message(STATUS "VS Code integration is enabled, but built type is Release")
endif()
endif()