commit 1d4a6f5903f81eb865e7880d0a97e5b1cf4941b7 Author: Sebastian Rust Date: Mon Jul 1 10:26:48 2024 +0200 initial commit diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..265cdd0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM ns3-base AS sim +COPY ./scratch /ns3/latest/scratch +COPY ./contrib /ns3/latest/contrib +ENV PATH="/ns3/latest:$PATH" diff --git a/Dockerfile.base b/Dockerfile.base new file mode 100644 index 0000000..1c4d024 --- /dev/null +++ b/Dockerfile.base @@ -0,0 +1,74 @@ +FROM debian:trixie-slim AS base + +LABEL Description="Docker image for NS-3 Network Simulator" + +ARG VERSION=3.41 + +# Timezone things? +ENV TZ=Europe/Berlin +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +# System packages +# Required: build-essetial through wget +# Optional for ns3 features: libsqlite3-dev through libgsl-dev +# +# Optional, but probably useful: +# tcpdump: to read pcap files +# cccache: to speed up the build +# clang-format, clang-tidy: linters +# gdb, valgrind: to debug +# +# Quality of life deps: vim, less, git +# +# Finally, clean up the cache to save some space +RUN apt-get update && apt-get install -y \ +# build-essential \ + g++ \ + python3 \ + cmake \ + wget \ + bzip2 \ + libsqlite3-dev \ + libeigen3-dev \ + libgsl-dev \ + tcpdump \ + ccache \ +# clang-format \ +# clang-tidy \ +# gdb \ +# valgrind \ + vim \ + less \ +# git \ + && rm -rf /var/lib/apt/lists/* + +# Create a user +RUN mkdir -p /ns3 + +WORKDIR /tmp + +# Get sources +RUN wget https://www.nsnam.org/releases/ns-allinone-$VERSION.tar.bz2 +RUN tar xfj ns-allinone-$VERSION.tar.bz2 +RUN rm ns-allinone-$VERSION.tar.bz2 + +# We don't need this anymore +RUN apt-get -y purge wget bzip2 + +# Move to somewhere nicer +RUN mv ./ns-allinone-$VERSION/ns-$VERSION /ns3/$VERSION && ln -s /ns3/$VERSION /ns3/latest +WORKDIR /ns3/latest + +# Configure +RUN ./ns3 configure +#--enable-examples --enable-tests + +# Build +RUN ./ns3 build + +ENV PATH="/ns3/latest :${PATH}" + +# Test +#RUN ./test.py + +CMD ["bash"] diff --git a/compose.dev.yml b/compose.dev.yml new file mode 100644 index 0000000..a35f686 --- /dev/null +++ b/compose.dev.yml @@ -0,0 +1,20 @@ +version: '3.8' + +services: + base: + build: + context: . + dockerfile: Dockerfile.base + image: ns3-base + + sim: + build: + context: . + volumes: + - ./scratch:/ns3/latest/scratch + - ./contrib:/ns3/latest/contrib + depends_on: + - base + image: ns3-sim + + diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..250aa87 --- /dev/null +++ b/compose.yml @@ -0,0 +1,17 @@ +version: '3.8' + +services: + base: + build: + context: . + dockerfile: Dockerfile.base + image: ns3-base + + sim: + build: + context: . + depends_on: + - base + image: ns3-sim + + diff --git a/scratch/CMakeLists.txt b/scratch/CMakeLists.txt new file mode 100644 index 0000000..adeeb2c --- /dev/null +++ b/scratch/CMakeLists.txt @@ -0,0 +1,111 @@ +set(target_prefix scratch_) + +function(create_scratch source_files) + # Return early if no sources in the subdirectory + list(LENGTH source_files number_sources) + if(number_sources EQUAL 0) + return() + endif() + + # If the scratch has more than a source file, we need to find the source with + # the main function + set(scratch_src) + foreach(source_file ${source_files}) + file(READ ${source_file} source_file_contents) + string(REGEX MATCHALL "main[(| (]" main_position "${source_file_contents}") + if(CMAKE_MATCH_0) + list(APPEND scratch_src ${source_file}) + endif() + endforeach() + + list(LENGTH scratch_src scratch_src_len) + + # If there is no main function, raise an error + if(${scratch_src_len} EQUAL 0) + message(FATAL_ERROR "The following scratch source files do not contain a main function: ${source_files}") + endif() + + # If there are multiple main functions, raise an error + if(${scratch_src_len} GREATER 1) + message(FATAL_ERROR "The following scratch source files contain ${scratch_src_len} files with a main function: ${scratch_src}") + endif() + + # If there is a single main function, continue normally + + # Get parent directory name + get_filename_component(scratch_dirname ${scratch_src} DIRECTORY) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "" scratch_dirname + "${scratch_dirname}" + ) + string(REPLACE "/" "_" scratch_dirname "${scratch_dirname}") + + # Get source name + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14.0") + get_filename_component(scratch_name ${scratch_src} NAME_WLE) + else() + get_filename_component(scratch_name ${scratch_src} NAME) + string(FIND "${scratch_name}" "." ext_position REVERSE) + if(${ext_position} EQUAL -1) + message(FATAL_ERROR "Source file has no extension: ${scratch_src}") + else() + string(SUBSTRING "${scratch_name}" 0 ${ext_position} scratch_name) + endif() + endif() + + set(target_prefix scratch_) + if(scratch_dirname) + # Join the names together if dirname is not the scratch folder + set(target_prefix scratch${scratch_dirname}_) + endif() + + # Get source absolute path and transform into relative path + get_filename_component(scratch_src ${scratch_src} ABSOLUTE) + get_filename_component(scratch_absolute_directory ${scratch_src} DIRECTORY) + string(REPLACE "${PROJECT_SOURCE_DIR}" "${CMAKE_OUTPUT_DIRECTORY}" + scratch_directory ${scratch_absolute_directory} + ) + build_exec( + EXECNAME ${scratch_name} + EXECNAME_PREFIX ${target_prefix} + SOURCE_FILES "${source_files}" + LIBRARIES_TO_LINK "${ns3-libs}" "${ns3-contrib-libs}" + EXECUTABLE_DIRECTORY_PATH ${scratch_directory}/ + ) +endfunction() + +# Scan *.cc files in ns-3-dev/scratch and build a target for each +file(GLOB single_source_file_scratches CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/[^.]*.cc) +foreach(scratch_src ${single_source_file_scratches}) + create_scratch(${scratch_src}) +endforeach() + +# Scan ns-3-dev/scratch subdirectories +file( + GLOB scratch_subdirectories + CONFIGURE_DEPENDS + LIST_DIRECTORIES true + ${CMAKE_CURRENT_SOURCE_DIR}/** +) +# Filter out files +foreach(entry ${scratch_subdirectories}) + if(NOT (IS_DIRECTORY ${entry})) + list(REMOVE_ITEM scratch_subdirectories ${entry}) + endif() +endforeach() + +# Build scratches per directory or following CMakeLists.txt instructions +foreach(subdir ${scratch_subdirectories}) + if(EXISTS ${subdir}/CMakeLists.txt) + # If the subdirectory contains a CMakeLists.txt file + # we let the CMake file manage the source files + # + # Use this if you want to link to external libraries + # without creating a module + add_subdirectory(${subdir}) + else() + # Otherwise we pick all the files in the subdirectory + # and create a scratch for them automatically + file(GLOB scratch_sources CONFIGURE_DEPENDS ${subdir}/[^.]*.cc) + create_scratch("${scratch_sources}") + endif() +endforeach() diff --git a/scratch/subdir/scratch-subdir-additional-header.cc b/scratch/subdir/scratch-subdir-additional-header.cc new file mode 100644 index 0000000..69efcd4 --- /dev/null +++ b/scratch/subdir/scratch-subdir-additional-header.cc @@ -0,0 +1,30 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// This file contains the implementation of the functions declared in the +// corresponding header file. + +#include "scratch-subdir-additional-header.h" + +namespace ns3 +{ + +std::string +ScratchSubdirGetMessage() +{ + return "Scratch Subdir"; +} + +} // namespace ns3 diff --git a/scratch/subdir/scratch-subdir-additional-header.h b/scratch/subdir/scratch-subdir-additional-header.h new file mode 100644 index 0000000..c6a7c89 --- /dev/null +++ b/scratch/subdir/scratch-subdir-additional-header.h @@ -0,0 +1,32 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// This header does not provide much functionality but is meant to demonstrate how, +// in a scratch subdirectory, one can create new programs that are implemented +// in multiple files and headers. + +#include + +namespace ns3 +{ + +/** + * Get a message from the subdir. + * + * \return The message from the subdir + */ +std::string ScratchSubdirGetMessage(); + +} // namespace ns3 diff --git a/scratch/subdir/scratch-subdir.cc b/scratch/subdir/scratch-subdir.cc new file mode 100644 index 0000000..23373d0 --- /dev/null +++ b/scratch/subdir/scratch-subdir.cc @@ -0,0 +1,50 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// This example shows how to create new simulations that are implemented in +// multiple files and headers. The structure of this simulation project +// is as follows: +// +// scratch/ +// | subdir/ +// | | - scratch-subdir.cc // Main simulation file +// | | - scratch-subdir-additional-header.h // Additional header +// | | - scratch-subdir-additional-header.cc // Additional header implementation +// +// This file contains the main() function, which calls an external function +// defined in the "scratch-subdir-additional-header.h" header file and +// implemented in "scratch-subdir-additional-header.cc". + +#include "scratch-subdir-additional-header.h" + +#include "ns3/core-module.h" + +#include + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE("ScratchSubdir"); + +int +main(int argc, char* argv[]) +{ + std::string message = ScratchSubdirGetMessage(); + NS_LOG_UNCOND(message); + + Simulator::Run(); + Simulator::Destroy(); + + return 0; +}