From d50f45e8a2647a280f6c0fe1d57da092e323a661 Mon Sep 17 00:00:00 2001
From: Lars Toenning <lars.toenning@iml.fraunhofer.de>
Date: Tue, 26 Sep 2023 13:33:11 +0200
Subject: [PATCH] build(daisi): Build separate executables per application type

---
 .github/workflows/build-sola.yml              | 10 ++---
 README.md                                     |  4 +-
 daisi/CMakeLists.txt                          |  2 +
 daisi/build_tools/create_ns3_executable.cmake | 10 +++++
 daisi/src/CMakeLists.txt                      |  1 -
 daisi/src/cpps/CMakeLists.txt                 |  9 +++++
 daisi/src/cpps/common/CMakeLists.txt          |  2 +-
 daisi/src/main/CMakeLists.txt                 | 12 ------
 daisi/src/minhton-ns3/CMakeLists.txt          |  9 +++++
 daisi/src/natter-ns3/CMakeLists.txt           |  9 +++++
 daisi/src/sola-ns3/CMakeLists.txt             | 17 +++++++--
 .../daisi_main.cpp.in}                        | 37 ++++---------------
 docs/daisi/using.md                           | 21 +++++------
 13 files changed, 77 insertions(+), 66 deletions(-)
 create mode 100644 daisi/build_tools/create_ns3_executable.cmake
 delete mode 100644 daisi/src/main/CMakeLists.txt
 rename daisi/src/{main/daisi_main.cpp => utils/daisi_main.cpp.in} (64%)

diff --git a/.github/workflows/build-sola.yml b/.github/workflows/build-sola.yml
index 5707f00a..9c1a9281 100644
--- a/.github/workflows/build-sola.yml
+++ b/.github/workflows/build-sola.yml
@@ -148,21 +148,21 @@ jobs:
       run: |
         export LD_LIBRARY_PATH=~/ns-3_install/lib
         mkdir output
-        build/src/main/Main --environment=minhton --scenario=`pwd`/daisi/utils/ci_scenario_files/minhton_test.yml
+        build/src/minhton-ns3/minhton_ns3 --scenario=`pwd`/daisi/utils/ci_scenario_files/minhton_test.yml
         python3 evaluation/minhton_verification.py `find output -name '*.db'`
         rm -rf output
     - name: Run MINHTON Star Cases integrationtest
       run: |
         export LD_LIBRARY_PATH=~/ns-3_install/lib
         mkdir output
-        build/src/main/Main --environment=minhton --scenario=`pwd`/daisi/utils/ci_scenario_files/minhton_cases.yml
+        build/src/minhton-ns3/minhton_ns3 --scenario=`pwd`/daisi/utils/ci_scenario_files/minhton_cases.yml
         python3 evaluation/minhton_verification.py `find output -name '*.db'`
         rm -rf output
     - name: Run MINHCAST integrationtest
       run: |
         export LD_LIBRARY_PATH=~/ns-3_install/lib
         mkdir output
-        build/src/main/Main --environment=natter --scenario=`pwd`/daisi/utils/ci_scenario_files/minhcast_test.yml
+        build/src/natter-ns3/natter_ns3 --scenario=`pwd`/daisi/utils/ci_scenario_files/minhcast_test.yml
         python3 evaluation/natter_verification.py `find output -name '*.db'`
         rm -rf output
     - name: Run CPPS integrationtest
@@ -171,7 +171,7 @@ jobs:
         export MINHTONDIR=$GITHUB_WORKSPACE/minhton
         mkdir output
         export MINHTONDIR=`pwd`/minhton
-        build/src/main/Main --environment=cpps --scenario=`pwd`/daisi/utils/ci_scenario_files/cpps_test.yml
+        build/src/cpps/CPPS_ns3 --scenario=`pwd`/daisi/utils/ci_scenario_files/cpps_test.yml
         python3 evaluation/cpps_verification.py `find output -name '*.db'`
         rm -rf output
     - name: Run ROUND_ROBIN integrationtest
@@ -180,5 +180,5 @@ jobs:
         export MINHTONDIR=$GITHUB_WORKSPACE/minhton
         mkdir output
         export MINHTONDIR=`pwd`/minhton
-        build/src/main/Main --environment=cpps --scenario=`pwd`/daisi/utils/ci_scenario_files/round_robin_test.yml
+        build/src/cpps/CPPS_ns3 --scenario=`pwd`/daisi/utils/ci_scenario_files/round_robin_test.yml
         rm -rf output
diff --git a/README.md b/README.md
index 897fed0c..9985c801 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,7 @@ Then, you can build DAISI from a build subdirectory as a CMake project:
 
 ```sh
 cmake .. -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -Dns3_DIR="PATH_TO_YOUR_NS3_INSTALL"
-cmake --build . --target Main
+cmake --build .
 ```
 
 Please refer to the [documentation](https://iml130.github.io/sola/) for an in depth installation guide including other options as well as further information.
@@ -71,5 +71,5 @@ If you use it for research, please include the following reference in any result
 }
 ```
 
-SOLA is a composition of other components. 
+SOLA is a composition of other components.
 References to the publications are provided in the dedicated documentation.
diff --git a/daisi/CMakeLists.txt b/daisi/CMakeLists.txt
index 84a96351..558b767e 100644
--- a/daisi/CMakeLists.txt
+++ b/daisi/CMakeLists.txt
@@ -31,6 +31,8 @@ if(DAISI_HANDLE_COMPILER_WARNINGS_AS_ERRORS)
   add_compile_options(-Werror)
 endif()
 
+list(APPEND CMAKE_MODULE_PATH ${DAISI_SOURCE_DIR}/build_tools)
+
 #-------------------------------------------------------------------------------
 # Third-party dependencies
 #-------------------------------------------------------------------------------
diff --git a/daisi/build_tools/create_ns3_executable.cmake b/daisi/build_tools/create_ns3_executable.cmake
new file mode 100644
index 00000000..f33ef194
--- /dev/null
+++ b/daisi/build_tools/create_ns3_executable.cmake
@@ -0,0 +1,10 @@
+function(create_ns3_executable MANAGER MANAGER_INCLUDE MANAGER_LIB APP_NAME)
+    configure_file(${DAISI_SOURCE_DIR}/src/utils/daisi_main.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/${APP_NAME}_main.cpp)
+    add_executable(${APP_NAME}_ns3 ${CMAKE_CURRENT_BINARY_DIR}/${APP_NAME}_main.cpp)
+    target_link_libraries(${APP_NAME}_ns3
+        PRIVATE
+            ns3::libcore
+            daisi_utils
+            ${MANAGER_LIB}
+    )
+endfunction()
diff --git a/daisi/src/CMakeLists.txt b/daisi/src/CMakeLists.txt
index f24de3eb..06cee764 100644
--- a/daisi/src/CMakeLists.txt
+++ b/daisi/src/CMakeLists.txt
@@ -1,5 +1,4 @@
 add_subdirectory(logging)
-add_subdirectory(main)
 
 add_subdirectory(cpps)
 add_subdirectory(minhton-ns3)
diff --git a/daisi/src/cpps/CMakeLists.txt b/daisi/src/cpps/CMakeLists.txt
index 70a0ac19..d31eb569 100644
--- a/daisi/src/cpps/CMakeLists.txt
+++ b/daisi/src/cpps/CMakeLists.txt
@@ -1,3 +1,5 @@
+include(create_ns3_executable)
+
 add_subdirectory(amr)
 add_subdirectory(model)
 add_subdirectory(common)
@@ -13,3 +15,10 @@ target_link_libraries(daisi_cpps_packet
         PUBLIC
         ns3::libcore
 )
+
+create_ns3_executable(
+        daisi::cpps::CppsManager # Class
+        cpps/common/cpps_manager.h # Include
+        daisi_cpps_common_cpps_manager # CMake target
+        CPPS # Name
+)
diff --git a/daisi/src/cpps/common/CMakeLists.txt b/daisi/src/cpps/common/CMakeLists.txt
index 60c14425..78010716 100644
--- a/daisi/src/cpps/common/CMakeLists.txt
+++ b/daisi/src/cpps/common/CMakeLists.txt
@@ -99,6 +99,6 @@ target_link_libraries(daisi_cpps_common_cpps_communicator
         INTERFACE
         ManagementOverlayMINHTONSim
         EventDisseminationMinhcastSim
-        SOLA_ns3
+        SOLA_ns3_interface
         NetworkUDPSim
 )
diff --git a/daisi/src/main/CMakeLists.txt b/daisi/src/main/CMakeLists.txt
deleted file mode 100644
index 690e2b0e..00000000
--- a/daisi/src/main/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-add_executable(Main daisi_main.cpp)
-
-target_link_libraries(Main
-        PRIVATE
-            ns3::libcore
-            daisi_minhton_manager
-            daisi_natter_manager
-            daisi_utils
-            daisi_cpps_common_cpps_manager
-            #PathPlanning
-            daisi_sola_manager
-)
diff --git a/daisi/src/minhton-ns3/CMakeLists.txt b/daisi/src/minhton-ns3/CMakeLists.txt
index e799153f..d5d276f1 100644
--- a/daisi/src/minhton-ns3/CMakeLists.txt
+++ b/daisi/src/minhton-ns3/CMakeLists.txt
@@ -1,3 +1,5 @@
+include(create_ns3_executable)
+
 add_subdirectory(adapter)
 
 add_library(daisi_minhton_application STATIC)
@@ -114,3 +116,10 @@ target_include_directories(daisi_minhton_peer_discovery
         INTERFACE
             ${PROJECT_SOURCE_DIR}/src
 )
+
+create_ns3_executable(
+    daisi::minhton_ns3::MinhtonManager # Class
+    minhton-ns3/minhton_manager.h # Include
+    daisi_minhton_manager # CMake target
+    minhton # Name
+)
diff --git a/daisi/src/natter-ns3/CMakeLists.txt b/daisi/src/natter-ns3/CMakeLists.txt
index 210a74ca..f5530283 100644
--- a/daisi/src/natter-ns3/CMakeLists.txt
+++ b/daisi/src/natter-ns3/CMakeLists.txt
@@ -1,3 +1,5 @@
+include(create_ns3_executable)
+
 # Simulator version of natter
 add_library(natter_minhcast_sim STATIC)
 target_sources(natter_minhcast_sim
@@ -117,3 +119,10 @@ target_include_directories(daisi_natter_scenariofile
         PUBLIC
         ${PROJECT_SOURCE_DIR}/src
 )
+
+create_ns3_executable(
+        daisi::natter_ns3::NatterManager # Class
+        natter-ns3/natter_manager.h # Include
+        daisi_natter_manager # CMake target
+        natter # Name
+)
diff --git a/daisi/src/sola-ns3/CMakeLists.txt b/daisi/src/sola-ns3/CMakeLists.txt
index 0bb57cc6..348011ad 100644
--- a/daisi/src/sola-ns3/CMakeLists.txt
+++ b/daisi/src/sola-ns3/CMakeLists.txt
@@ -1,6 +1,8 @@
-add_library(SOLA_ns3 INTERFACE ${SOLA_SOURCE_DIR}/include/SOLA/sola.h)
-target_include_directories(SOLA_ns3 INTERFACE ${SOLA_SOURCE_DIR}/include)
-target_link_libraries(SOLA_ns3 INTERFACE
+include(create_ns3_executable)
+
+add_library(SOLA_ns3_interface INTERFACE ${SOLA_SOURCE_DIR}/include/SOLA/sola.h)
+target_include_directories(SOLA_ns3_interface INTERFACE ${SOLA_SOURCE_DIR}/include)
+target_link_libraries(SOLA_ns3_interface INTERFACE
         sola_service
         sola_logger_interface
         solanet_uuid
@@ -10,7 +12,7 @@ target_link_libraries(SOLA_ns3 INTERFACE
 add_library(daisi_sola_sola_wrapper INTERFACE sola_wrapper.h)
 target_link_libraries(daisi_sola_sola_wrapper
         INTERFACE
-        SOLA_ns3
+        SOLA_ns3_interface
         ManagementOverlayMINHTONSim
         EventDisseminationMinhcastSim
 )
@@ -137,3 +139,10 @@ target_include_directories(daisi_sola_scenariofile
         PUBLIC
         ${PROJECT_SOURCE_DIR}/src
 )
+
+create_ns3_executable(
+        daisi::sola_ns3::SolaManager # Class
+        sola-ns3/sola_manager.h # Include
+        daisi_sola_manager # CMake target
+        SOLA # Name
+)
diff --git a/daisi/src/main/daisi_main.cpp b/daisi/src/utils/daisi_main.cpp.in
similarity index 64%
rename from daisi/src/main/daisi_main.cpp
rename to daisi/src/utils/daisi_main.cpp.in
index c3552304..6cd9bc89 100644
--- a/daisi/src/main/daisi_main.cpp
+++ b/daisi/src/utils/daisi_main.cpp.in
@@ -19,17 +19,13 @@
 #include <iomanip>
 #include <iostream>
 
-#include "cpps/common/cpps_manager.h"
-#include "minhton-ns3/minhton_manager.h"
-#include "natter-ns3/natter_manager.h"
+#include "${MANAGER_INCLUDE}"
 #include "ns3/core-module.h"
-// #include "path_planning/path_planning_manager.h"
-#include "sola-ns3/sola_manager.h"
 #include "utils/sola_utils.h"
 
 using namespace ns3;
 
-template <typename Manager> int runSimulatorWithCatch(Manager &manager) {
+int runSimulatorWithCatch(${MANAGER} & manager) {
   int res = EXIT_SUCCESS;
   try {
     manager.run();
@@ -43,9 +39,10 @@ template <typename Manager> int runSimulatorWithCatch(Manager &manager) {
   return res;
 }
 
-template <typename Manager> int execute(std::string test_file, bool disable_catch) {
-  std::cout << "Executing " << typeid(Manager).name() << std::endl;
-  Manager manager(test_file);
+int execute(std::string test_file, bool disable_catch) {
+  std::cout << "Executing "
+            << "${APP_NAME}" << std::endl;
+  ${MANAGER} manager(test_file);
   manager.setup();
 
   if (disable_catch) {
@@ -60,20 +57,17 @@ template <typename Manager> int execute(std::string test_file, bool disable_catc
 int main(int argc, char *argv[]) {
   auto start_time = std::chrono::high_resolution_clock::now();
 
-  std::string param_environment;
   std::string param_scenariofile;
   std::string param_scenariostring;
   bool disable_catch = false;
 
   CommandLine cmd;
-  cmd.AddValue("environment", "test environment to run - (minhton, natter, cpps, path_planning)",
-               param_environment);
   cmd.AddValue("scenario", "scenario file to run", param_scenariofile);
   cmd.AddValue("scenariostring", "test string to run", param_scenariostring);
   cmd.AddValue("disable-catch", "disable catching fatal errors (for debugging)", disable_catch);
   cmd.Parse(argc, argv);
 
-  std::cout << "NS-3 Simulation " << std::endl;
+  std::cout << "ns-3 Simulation " << std::endl;
 
   std::string test_file;
   int ret = daisi::getTestFile(param_scenariofile, param_scenariostring, test_file);
@@ -89,22 +83,7 @@ int main(int argc, char *argv[]) {
   std::time_t result = std::time(nullptr);
   std::cout << "StartTime: " << std::ctime(&result);
 
-  int res = EXIT_SUCCESS;
-
-  if (param_environment == "minhton") {
-    res = execute<daisi::minhton_ns3::MinhtonManager>(test_file, disable_catch);
-  } else if (param_environment == "natter") {
-    res = execute<daisi::natter_ns3::NatterManager>(test_file, disable_catch);
-  } else if (param_environment == "cpps") {
-    res = execute<daisi::cpps::CppsManager>(test_file, disable_catch);
-    // } else if (param_environment == "path_planning") {
-    //   res = execute<daisi::path_planning::PathPlanningManager>(test_file, disable_catch);
-  } else if (param_environment == "sola") {
-    res = execute<daisi::sola_ns3::SolaManager>(test_file, disable_catch);
-  } else {
-    std::cerr << "Invalid environment! Terminating..." << std::endl;
-    return EXIT_FAILURE;
-  }
+  const int res = execute(test_file, disable_catch);
 
   std::cout << "Simulation Destroy" << std::endl;
   result = std::time(nullptr);
diff --git a/docs/daisi/using.md b/docs/daisi/using.md
index 6c59f11e..234dd839 100644
--- a/docs/daisi/using.md
+++ b/docs/daisi/using.md
@@ -1,7 +1,12 @@
 !!! danger "This is work in progress!"
 
 First you need to build SOLA with the ns-3 integration as described in [Getting Started](../getting_started.md).
-Following these steps, all components are integrated into a single ns-3 simulation executable that is located at ``<SOLA_REPOSITORY_DIR>/build/main/Main``.
+For each component/application, a single ns-3 simulation executable is created.
+Following the building instructions, the executables are located at:
+- [``minhton``](../minhton/introduction.md): ``<SOLA_REPOSITORY_DIR>/build/src/minhton-ns3/minhton_ns3``.
+- [``natter``](../natter/introduction.md): ``<SOLA_REPOSITORY_DIR>/build/src/natter-ns3/natter_ns3``
+- [``sola``](../index.md): ``<SOLA_REPOSITORY_DIR>/build/src/sola-ns3/SOLA_ns3``
+- [``cpps`` (OptiMaFlow)](../optimaflow/introduction.md): ``<SOLA_REPOSITORY_DIR>/build/src/cpps-ns3/CPPS_ns3``
 
 ### Specify logging output path
 
@@ -10,15 +15,7 @@ This database is used for logging simulation events, states and other simulation
 To specify the path, set the environment variable ``DAISI_OUTPUT_PATH`` to the desired output path, like ``export DAISI_OUTPUT_PATH=<PATH>``.
 
 
-### Specifiy application
-
-The name of the application that should run in the simulation must be passed to the executable with ``--environment=<APP_NAME>``.
-The following applications are supported:
-
-- [``minhton``](../minhton/introduction.md)
-- [``natter``](../natter/introduction.md)
-- [``sola``](../index.md)
-- [``cpps`` (OptiMaFlow)](../optimaflow/introduction.md)
+### Application-specific configurations
 
 !!! warning "Running OptiMaFlow"
 
@@ -39,9 +36,9 @@ This path must either be a absolute path or a path relative to the current worki
 
 For example to start a OptiMaFlow simulation with your current working directory being ``<SOLA_REPOSITORY_DIR>``, run:
 
-```build/main/Main --environment=cpps --scenario=daisi/scenarios/cpps/default.yml```
+```build/src/cpps/CPPS_ns3 --scenario=daisi/scenarios/cpps/default.yml```
 
-To start a different application, just pass a different environment and scenariofile path.
+To start a different application, just use a different executable and a different scenariofile.
 
 ### Inspecting the output