Merge tag 'ns-3.37' into unison
ns-3.37 release
This commit is contained in:
93
ns3
93
ns3
@@ -30,7 +30,7 @@ def exit_handler(dry_run):
|
||||
return
|
||||
if print_buffer == "":
|
||||
return
|
||||
print_buffer = print_buffer.replace('\\','/').replace('//','/').replace('/', os.sep)
|
||||
print_buffer = print_buffer.replace('\\', '/').replace('//', '/').replace('/', os.sep)
|
||||
if dry_run:
|
||||
print("The following commands would be executed:")
|
||||
elif run_verbose:
|
||||
@@ -110,7 +110,7 @@ def parse_args(argv):
|
||||
parser_configure.add_argument('-d', '--build-profile',
|
||||
help='Build profile',
|
||||
dest='build_profile',
|
||||
choices=["debug", "default", "release", "optimized"],
|
||||
choices=["debug", "default", "release", "optimized", "minsizerel"],
|
||||
action="store", type=str, default=None)
|
||||
|
||||
parser_configure.add_argument('-G',
|
||||
@@ -246,6 +246,15 @@ def parse_args(argv):
|
||||
parser_run.add_argument('-g', '--valgrind',
|
||||
help='Change the default command template to run programs with valgrind',
|
||||
action="store_true", default=None)
|
||||
parser_run.add_argument('--memray',
|
||||
help='Use Memray memory profiler for Python scripts. Output will be saved to memray.output',
|
||||
action="store_true", default=None)
|
||||
parser_run.add_argument('--heaptrack',
|
||||
help='Use Heaptrack memory profiler for C++',
|
||||
action="store_true", default=None)
|
||||
parser_run.add_argument('--perf',
|
||||
help='Use Linux\'s perf to profile a program',
|
||||
action="store_true", default=None)
|
||||
parser_run.add_argument('--vis', '--visualize',
|
||||
help='Modify --run arguments to enable the visualizer',
|
||||
action="store_true", dest="visualize", default=None)
|
||||
@@ -411,8 +420,10 @@ def print_and_buffer(message):
|
||||
|
||||
def clean_cmake_artifacts(dry_run=False):
|
||||
print_and_buffer("rm -R %s" % os.path.relpath(out_dir, ns3_path))
|
||||
|
||||
if not dry_run:
|
||||
if out_dir == ns3_path:
|
||||
raise Exception("The output directory and the ns-3 directory are the same. "
|
||||
"Deleting it can cause data loss.")
|
||||
shutil.rmtree(out_dir, ignore_errors=True)
|
||||
|
||||
cmake_cache_files = glob.glob("%s/**/CMakeCache.txt" % ns3_path, recursive=True)
|
||||
@@ -420,6 +431,9 @@ def clean_cmake_artifacts(dry_run=False):
|
||||
dirname = os.path.dirname(cmake_cache_file)
|
||||
print_and_buffer("rm -R %s" % os.path.relpath(dirname, ns3_path))
|
||||
if not dry_run:
|
||||
if dirname == ns3_path:
|
||||
raise Exception("The CMake cache directory and the ns-3 directory are the same. "
|
||||
"Deleting it can cause data loss.")
|
||||
shutil.rmtree(dirname, ignore_errors=True)
|
||||
|
||||
if os.path.exists(lock_file):
|
||||
@@ -539,18 +553,21 @@ def configure_cmake(cmake, args, current_cmake_cache_folder, current_cmake_gener
|
||||
# Build type
|
||||
if args.build_profile is not None:
|
||||
args.build_profile = args.build_profile.lower()
|
||||
if args.build_profile not in ["debug", "default", "release", "optimized"]:
|
||||
if args.build_profile not in ["debug", "default", "release", "optimized", "minsizerel", "relwithdebinfo"]:
|
||||
raise Exception("Unknown build type")
|
||||
else:
|
||||
if args.build_profile == "debug":
|
||||
cmake_args.extend(
|
||||
"-DCMAKE_BUILD_TYPE=debug -DNS3_ASSERT=ON -DNS3_LOG=ON -DNS3_WARNINGS_AS_ERRORS=ON".split())
|
||||
elif args.build_profile == "default":
|
||||
elif args.build_profile in ["default", "relwithdebinfo"]:
|
||||
cmake_args.extend(
|
||||
"-DCMAKE_BUILD_TYPE=default -DNS3_ASSERT=ON -DNS3_LOG=ON -DNS3_WARNINGS_AS_ERRORS=OFF".split())
|
||||
elif args.build_profile in ["release", "optimized"]:
|
||||
cmake_args.extend(
|
||||
"-DCMAKE_BUILD_TYPE=release -DNS3_ASSERT=OFF -DNS3_LOG=OFF -DNS3_WARNINGS_AS_ERRORS=OFF".split())
|
||||
else:
|
||||
cmake_args.extend(
|
||||
"-DCMAKE_BUILD_TYPE=release -DNS3_ASSERT=OFF -DNS3_LOG=OFF -DNS3_WARNINGS_AS_ERRORS=OFF".split()
|
||||
"-DCMAKE_BUILD_TYPE=minsizerel -DNS3_ASSERT=OFF -DNS3_LOG=OFF -DNS3_WARNINGS_AS_ERRORS=OFF".split()
|
||||
)
|
||||
cmake_args.append("-DNS3_NATIVE_OPTIMIZATIONS=%s" % on_off((args.build_profile == "optimized")))
|
||||
|
||||
@@ -652,7 +669,7 @@ def update_scratches_list(current_cmake_cache_folder):
|
||||
|
||||
|
||||
def refresh_cmake(current_cmake_cache_folder, output):
|
||||
ret = subprocess.run([shutil.which("cmake"), ".."], cwd=current_cmake_cache_folder, stdout=output)
|
||||
ret = subprocess.run([check_program_installed("cmake"), ".."], cwd=current_cmake_cache_folder, stdout=output)
|
||||
if ret.returncode != 0:
|
||||
exit(ret.returncode)
|
||||
update_scratches_list(current_cmake_cache_folder)
|
||||
@@ -708,17 +725,16 @@ def get_program_shortcuts(build_profile, ns3_version):
|
||||
|
||||
# Add an additional shortcut with .exe suffix when running on Windows
|
||||
if sys.platform == "win32":
|
||||
ns3_program_map[shortcut_path.replace("\\","/")] = [program]
|
||||
ns3_program_map[shortcut_path+".exe"] = [program]
|
||||
ns3_program_map[shortcut_path.replace("\\","/")+".exe"] = [program]
|
||||
|
||||
ns3_program_map[shortcut_path.replace("\\", "/")] = [program]
|
||||
ns3_program_map[shortcut_path + ".exe"] = [program]
|
||||
ns3_program_map[shortcut_path.replace("\\", "/") + ".exe"] = [program]
|
||||
|
||||
if source_shortcut:
|
||||
cc_shortcut_path = shortcut_path + ".cc"
|
||||
ns3_program_map[cc_shortcut_path] = [program]
|
||||
if sys.platform == "win32":
|
||||
ns3_program_map[cc_shortcut_path] = [program]
|
||||
ns3_program_map[cc_shortcut_path.replace("\\","/")] = [program]
|
||||
ns3_program_map[cc_shortcut_path.replace("\\", "/")] = [program]
|
||||
|
||||
# Store longest shortcut path for collisions
|
||||
if cc_shortcut_path not in longest_shortcut_map:
|
||||
@@ -953,6 +969,7 @@ def build_step(args,
|
||||
non_executable_targets = ["assemble-introspected-command-line",
|
||||
"check-version",
|
||||
"cmake-format",
|
||||
"coverage_gcc",
|
||||
"docs",
|
||||
"doxygen",
|
||||
"doxygen-no-build",
|
||||
@@ -1003,6 +1020,23 @@ def build_step(args,
|
||||
)
|
||||
|
||||
|
||||
def check_program_installed(program_name: str) -> str:
|
||||
program_path = shutil.which(program_name)
|
||||
if program_path is None:
|
||||
print("Executable '{program}' was not found".format(program=program_name.capitalize()))
|
||||
exit(-1)
|
||||
return program_path
|
||||
|
||||
|
||||
def check_module_installed(module_name: str):
|
||||
import importlib
|
||||
try:
|
||||
importlib.import_module(module_name)
|
||||
except ImportError:
|
||||
print("Python module '{module}' was not found".format(module=module_name))
|
||||
exit(-1)
|
||||
|
||||
|
||||
def run_step(args, target_to_run, target_args):
|
||||
libdir = "%s/lib" % out_dir
|
||||
|
||||
@@ -1033,24 +1067,42 @@ def run_step(args, target_to_run, target_args):
|
||||
target_args = [target_to_run] + target_args
|
||||
target_to_run = "python3"
|
||||
|
||||
# running with memray?
|
||||
if args.memray:
|
||||
check_module_installed("memray")
|
||||
target_args = ["-m", "memray", "run", "-o", "memray.output", "--native"] + target_args
|
||||
|
||||
# running from ns-3-dev (ns3_path) or cwd
|
||||
if args.cwd:
|
||||
working_dir = args.cwd
|
||||
|
||||
# running with heaptrack?
|
||||
if args.heaptrack:
|
||||
debugging_software.append(check_program_installed("heaptrack"))
|
||||
|
||||
# running valgrind?
|
||||
if args.valgrind:
|
||||
debugging_software.extend([shutil.which("valgrind"), "--leak-check=full", "--show-leak-kinds=all"])
|
||||
debugging_software.extend(
|
||||
[check_program_installed("valgrind"), "--leak-check=full", "--show-leak-kinds=all"])
|
||||
|
||||
# running gdb?
|
||||
if args.gdb:
|
||||
gdb_eval_command = []
|
||||
if os.getenv("gdb_eval"):
|
||||
gdb_eval_command.append("--eval-command=quit")
|
||||
debugging_software.extend([shutil.which("gdb"), *gdb_eval_command, "--args"])
|
||||
debugging_software.extend([check_program_installed("gdb"), *gdb_eval_command, "--args"])
|
||||
|
||||
# running lldb?
|
||||
if args.lldb:
|
||||
debugging_software.extend([shutil.which("lldb"), "--"])
|
||||
debugging_software.extend([check_program_installed("lldb"), "--"])
|
||||
|
||||
# running with perf?
|
||||
if args.perf:
|
||||
debugging_software.extend([
|
||||
check_program_installed("perf"),
|
||||
"record", "--call-graph", "dwarf", "-a", "-e",
|
||||
"cache-misses,branch-misses,cpu-cycles,stalled-cycles-frontend,stalled-cycles-backend,context-switches"
|
||||
])
|
||||
|
||||
# running with the visualizer?
|
||||
if args.visualize:
|
||||
@@ -1059,6 +1111,7 @@ def run_step(args, target_to_run, target_args):
|
||||
# running with command template?
|
||||
if args.command_template:
|
||||
commands = (args.command_template % target_to_run).split()
|
||||
check_program_installed(commands[0])
|
||||
target_to_run = commands[0]
|
||||
target_args = commands[1:] + target_args
|
||||
|
||||
@@ -1086,10 +1139,10 @@ def run_step(args, target_to_run, target_args):
|
||||
try:
|
||||
subprocess.run(program_arguments, env=proc_env, cwd=working_dir, shell=use_shell, check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
# Replace full path to binary to relative path
|
||||
e.cmd[0] = os.path.relpath(target_to_run, ns3_path)
|
||||
# Replace list of arguments with a single string
|
||||
e.cmd = " ".join(e.cmd)
|
||||
# Replace full path to binary to relative path
|
||||
e.cmd = e.cmd.replace(os.path.abspath(target_to_run), os.path.relpath(target_to_run, ns3_path))
|
||||
# Print error message and forward the return code
|
||||
print(e)
|
||||
exit(e.returncode)
|
||||
@@ -1117,7 +1170,7 @@ def non_ambiguous_program_target_list(programs: dict) -> list:
|
||||
|
||||
|
||||
def print_targets_list(ns3_modules: list, ns3_programs: dict) -> None:
|
||||
def list_to_table(l: list) -> str:
|
||||
def list_to_table(targets_list: list) -> str:
|
||||
# Set column width and check how much is space is left at the end
|
||||
columnwidth = 30
|
||||
try:
|
||||
@@ -1127,10 +1180,10 @@ def print_targets_list(ns3_modules: list, ns3_programs: dict) -> None:
|
||||
dead_space = terminal_width % columnwidth
|
||||
|
||||
# Filter the targets with names longer than the column width
|
||||
large_items = list(filter(lambda x: len(x) >= columnwidth, l))
|
||||
large_items = list(filter(lambda x: len(x) >= columnwidth, targets_list))
|
||||
|
||||
# Then filter the targets with names shorter than the column width
|
||||
small_items = sorted(list(set(l) - set(large_items)))
|
||||
small_items = sorted(list(set(targets_list) - set(large_items)))
|
||||
|
||||
prev_new_line = 0
|
||||
output = "\n"
|
||||
|
||||
Reference in New Issue
Block a user