build: initial Windows support patches

This commit is contained in:
Gabriel Ferreira
2022-09-23 23:37:14 -03:00
parent f8846d22ed
commit c34abb4ccc
7 changed files with 248 additions and 125 deletions

View File

@@ -152,10 +152,24 @@ function(ns3_cmake_package)
endfunction()
# You will need administrative privileges to run this
# cmake-format: off
if(WIN32)
add_custom_target(
uninstall
COMMAND
powershell -Command \" Remove-Item \\"${CMAKE_INSTALL_FULL_LIBDIR}/libns3*\\" -Recurse \" &&
powershell -Command \" Remove-Item \\"${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig/ns3-*\\" -Recurse \" &&
powershell -Command \" Remove-Item \\"${CMAKE_INSTALL_FULL_LIBDIR}/cmake/ns3\\" -Recurse \" &&
powershell -Command \" Remove-Item \\"${CMAKE_INSTALL_FULL_INCLUDEDIR}/ns3\\" -Recurse \"
)
else()
add_custom_target(
uninstall
COMMAND
rm `ls ${CMAKE_INSTALL_FULL_LIBDIR}/libns3*` && rm -R
${CMAKE_INSTALL_FULL_LIBDIR}/cmake/ns3 && rm -R
${CMAKE_INSTALL_FULL_INCLUDEDIR}/ns3
rm `ls ${CMAKE_INSTALL_FULL_LIBDIR}/libns3*` &&
rm `ls ${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig/ns3-*` &&
rm -R ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/ns3 &&
rm -R ${CMAKE_INSTALL_FULL_INCLUDEDIR}/ns3
)
endif()
# cmake-format: on

View File

@@ -120,6 +120,9 @@ function(build_lib)
PROPERTIES
PUBLIC_HEADER
"${BLIB_HEADER_FILES};${BLIB_DEPRECATED_HEADER_FILES};${config_headers};${CMAKE_HEADER_OUTPUT_DIRECTORY}/${BLIB_LIBNAME}-module.h"
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} # set output
# directory for
# DLLs
)
if(${NS3_CLANG_TIMETRACE})
@@ -243,31 +246,39 @@ function(build_lib)
if(${test_source_len} GREATER 0)
# Create BLIB_LIBNAME of output library test of module
set(test${BLIB_LIBNAME} lib${BLIB_LIBNAME}-test CACHE INTERNAL "")
set(ns3-libs-tests "${test${BLIB_LIBNAME}};${ns3-libs-tests}"
CACHE INTERNAL "list of test libraries"
)
# Create shared library containing tests of the module
add_library(${test${BLIB_LIBNAME}} SHARED "${BLIB_TEST_SOURCES}")
# Link test library to the module library
if(${NS3_MONOLIB})
target_link_libraries(
${test${BLIB_LIBNAME}} ${LIB_AS_NEEDED_PRE} ${lib-ns3-monolib}
${LIB_AS_NEEDED_POST}
# Create shared library containing tests of the module on UNIX and just
# the object file that will be part of test-runner on Windows
if(WIN32)
set(ns3-libs-tests
"$<TARGET_OBJECTS:${test${BLIB_LIBNAME}}>;${ns3-libs-tests}"
CACHE INTERNAL "list of test libraries"
)
add_library(${test${BLIB_LIBNAME}} OBJECT "${BLIB_TEST_SOURCES}")
else()
target_link_libraries(
${test${BLIB_LIBNAME}} ${LIB_AS_NEEDED_PRE} ${lib${BLIB_LIBNAME}}
"${BLIB_LIBRARIES_TO_LINK}" ${LIB_AS_NEEDED_POST}
set(ns3-libs-tests "${test${BLIB_LIBNAME}};${ns3-libs-tests}"
CACHE INTERNAL "list of test libraries"
)
add_library(${test${BLIB_LIBNAME}} SHARED "${BLIB_TEST_SOURCES}")
# Link test library to the module library
if(${NS3_MONOLIB})
target_link_libraries(
${test${BLIB_LIBNAME}} ${LIB_AS_NEEDED_PRE} ${lib-ns3-monolib}
${LIB_AS_NEEDED_POST}
)
else()
target_link_libraries(
${test${BLIB_LIBNAME}} ${LIB_AS_NEEDED_PRE} ${lib${BLIB_LIBNAME}}
"${BLIB_LIBRARIES_TO_LINK}" ${LIB_AS_NEEDED_POST}
)
endif()
set_target_properties(
${test${BLIB_LIBNAME}}
PROPERTIES OUTPUT_NAME
ns${NS3_VER}-${BLIB_LIBNAME}-test${build_profile_suffix}
)
endif()
set_target_properties(
${test${BLIB_LIBNAME}}
PROPERTIES OUTPUT_NAME
ns${NS3_VER}-${BLIB_LIBNAME}-test${build_profile_suffix}
)
target_compile_definitions(
${test${BLIB_LIBNAME}} PRIVATE NS_TEST_SOURCEDIR="${FOLDER}/test"
)
@@ -295,6 +306,7 @@ function(build_lib)
EXPORT ns3ExportTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/ns3"
)
if(${NS3_VERBOSE})

37
ns3
View File

@@ -16,7 +16,10 @@ lock_file = os.sep.join([ns3_path, ".lock-ns3_%s_build" % sys.platform])
max_cpu_threads = max(1, os.cpu_count() - 1)
print_buffer = ""
run_verbose = True
path_sep = ";" if sys.platform == "win32" else ":"
# Windows uses ; as a PATH entry separator,
# but msys shell uses : just like most Unix-like systems
path_sep = ";" if ";" in os.environ["PATH"] else ":"
path_variable = "$PATH" if path_sep == ":" else "%PATH%"
# Prints everything in the print_buffer on exit
@@ -27,6 +30,7 @@ def exit_handler(dry_run):
return
if print_buffer == "":
return
print_buffer = print_buffer.replace('\\','/').replace('//','/').replace('/', os.sep)
if dry_run:
print("The following commands would be executed:")
elif run_verbose:
@@ -664,7 +668,10 @@ def get_program_shortcuts(build_profile, ns3_version):
for program in programs_dict["ns3_runnable_programs"]:
if "pch_exec" in program:
continue
temp_path = program.replace(out_dir, "").split(os.sep)
temp_path = program.replace(out_dir, "")
# Sometimes Windows uses \\, sometimes /
# quite the mess
temp_path = temp_path.split(os.sep if os.sep in temp_path else '/')
temp_path.pop(0) # remove first path separator
# Remove version prefix and build type suffix from shortcuts (or keep them too?)
@@ -696,9 +703,20 @@ def get_program_shortcuts(build_profile, ns3_version):
longest_shortcut_map[shortcut_path].append(longest_shortcut)
ns3_program_map[shortcut_path] = [program]
# 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]
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]
# Store longest shortcut path for collisions
if cc_shortcut_path not in longest_shortcut_map:
@@ -736,7 +754,7 @@ def cmake_check_version():
# Check CMake version
cmake = shutil.which("cmake")
if not cmake:
print("Error: CMake not found; please install version 3.10 or greater, or modify $PATH")
print("Error: CMake not found; please install version 3.10 or greater, or modify", path_variable)
exit(1)
cmake_output = subprocess.check_output([cmake, "--version"]).decode("utf-8")
version = re.findall("version (.*)", cmake_output)[0]
@@ -1023,7 +1041,10 @@ def run_step(args, target_to_run, target_args):
# running gdb?
if args.gdb:
debugging_software.extend([shutil.which("gdb"), "--args"])
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"])
# running lldb?
if args.lldb:
@@ -1051,7 +1072,7 @@ def run_step(args, target_to_run, target_args):
exported_variables = "export "
for (variable, value) in custom_env.items():
if variable == "PATH":
value = "$PATH" + path_sep + libdir
value = path_variable + path_sep + libdir
exported_variables += "%s=%s " % (variable, value)
print_and_buffer("cd %s; %s; %s" % (os.path.relpath(ns3_path, working_dir),
exported_variables,
@@ -1434,8 +1455,8 @@ def main():
:param target_path: path to the executable to run
:return: target_path without the overlapping parts
"""
target_path = target_path.split(os.sep)
base_path = base_path.split(os.sep)
target_path = target_path.replace('/', os.sep).split(os.sep)
base_path = base_path.replace('/', os.sep).split(os.sep)
while target_path[0] in base_path:
target_path = target_path[1:]
target_path = os.sep.join(target_path)
@@ -1451,6 +1472,8 @@ def main():
if os.path.exists(os.sep.join([out_dir, waf_target_to_run])):
target_to_run = waf_target_to_run
target_to_run = os.sep.join([out_dir, target_to_run])
if sys.platform == "win32":
target_to_run += ".exe"
# If we're only trying to run the target, we need to check if it actually exists first
if (run_only or build_and_run) and ".py" not in target_to_run and not os.path.exists(target_to_run):

View File

@@ -66,7 +66,7 @@ if(${NS3_STATIC})
endif()
endif()
# Build the lib-ns3-static (ns3.x-monolib-buildtype.dll/.dylib/.so) with all
# Build the lib-ns3 (ns3.x-monolib-buildtype.dll/.dylib/.so) with all
# sublibraries
if(${NS3_MONOLIB})
add_library(
@@ -74,7 +74,10 @@ if(${NS3_MONOLIB})
"${lib-ns3-static-objs}"
)
set_target_properties(
${lib-ns3-monolib} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE
${lib-ns3-monolib}
PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE
RUNTIME_OUTPUT_DIRECTORY
${CMAKE_LIBRARY_OUTPUT_DIRECTORY} # set output directory for DLLs
)
target_link_libraries(
${lib-ns3-monolib} ${LIB_AS_NEEDED_PRE} ${ns3-external-libs}

View File

@@ -170,6 +170,7 @@ def parse_examples_to_run_file(
# Set the full path for the example.
example_path = os.path.join(cpp_executable_dir, example_path)
example_path += '.exe' if sys.platform == 'win32' else ''
example_name = os.path.join(
os.path.relpath(cpp_executable_dir, NS3_BUILDDIR),
example_name)
@@ -1070,6 +1071,7 @@ def run_tests():
# match what is done in the CMakeLists.txt file.
#
test_runner_name = "%s%s-%s%s" % (APPNAME, VERSION, "test-runner", BUILD_PROFILE_SUFFIX)
test_runner_name += '.exe' if sys.platform == 'win32' else ''
#
# Run ns3 to make sure that everything is built, configured and ready to go
@@ -1299,7 +1301,7 @@ def run_tests():
# This translates into allowing the following options with respect to the
# suites
#
# ./test,py: run all of the suites and examples
# ./test.py: run all of the suites and examples
# ./test.py --constrain=core: run all of the suites of all kinds
# ./test.py --constrain=unit: run all unit suites
# ./test.py --suite=some-test-suite: run a single suite
@@ -1399,6 +1401,8 @@ def run_tests():
stderr_results = stderr_results.decode()
if len(stderr_results) == 0:
processors = int(stdout_results)
else:
processors = os.cpu_count()
if (options.process_limit):
if (processors < options.process_limit):
@@ -1508,6 +1512,7 @@ def run_tests():
# Remove any arguments and directory names from test.
test_name = test.split(' ', 1)[0]
test_name = os.path.basename(test_name)
test_name = test_name[:-4] if sys.platform == 'win32' else test_name
# Don't try to run this example if it isn't runnable.
if test_name in ns3_runnable_programs_dictionary:

View File

@@ -1,16 +1,31 @@
if(${ENABLE_TESTS} AND (test IN_LIST libs_to_build))
add_executable(test-runner $<TARGET_OBJECTS:${libtest}> test-runner.cc)
if(${NS3_MONOLIB})
target_link_libraries(
test-runner ${LIB_AS_NEEDED_PRE} ${ns3-libs-tests} ${LIB_AS_NEEDED_POST}
${lib-ns3-monolib} ${ns3-contrib-libs}
)
if(WIN32)
# DLL linking shenanigans prevent loading symbols unused by a certain program,
# so link the tests libraries (here built as objects) directly to the test runner
add_executable(test-runner test-runner.cc ${ns3-libs-tests} $<TARGET_OBJECTS:${libtest}>)
if(${NS3_MONOLIB})
target_link_libraries(
test-runner ${lib-ns3-monolib} ${ns3-contrib-libs}
)
else()
target_link_libraries(
test-runner ${ns3-libs} ${ns3-contrib-libs}
)
endif()
else()
target_link_libraries(
test-runner ${LIB_AS_NEEDED_PRE} ${ns3-libs-tests} ${LIB_AS_NEEDED_POST}
${ns3-libs} ${ns3-contrib-libs}
)
add_executable(test-runner $<TARGET_OBJECTS:${libtest}> test-runner.cc)
if(${NS3_MONOLIB})
target_link_libraries(
test-runner ${LIB_AS_NEEDED_PRE} ${ns3-libs-tests} ${LIB_AS_NEEDED_POST}
${lib-ns3-monolib} ${ns3-contrib-libs}
)
else()
target_link_libraries(
test-runner ${LIB_AS_NEEDED_PRE} ${ns3-libs-tests} ${LIB_AS_NEEDED_POST}
${ns3-libs} ${ns3-contrib-libs}
)
endif()
endif()
set_runtime_outputdirectory(
test-runner ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/utils/ ""

View File

@@ -48,13 +48,17 @@ cmake_build_project_command = "cmake --build . -j".format(ns3_path=ns3_path)
cmake_build_target_command = partial("cmake --build . -j {jobs} --target {target}".format,
jobs=num_threads
)
win32 = sys.platform == "win32"
platform_makefiles = "MinGW Makefiles" if win32 else "Unix Makefiles"
ext = ".exe" if win32 else ""
def run_ns3(args, env=None):
def run_ns3(args, env=None, generator=platform_makefiles):
"""!
Runs the ns3 wrapper script with arguments
@param args: string containing arguments that will get split before calling ns3
@param env: environment variables dictionary
@param generator: CMake generator
@return tuple containing (error code, stdout and stderr)
"""
if "clean" in args:
@@ -62,6 +66,8 @@ def run_ns3(args, env=None):
for leftover in possible_leftovers:
if os.path.exists(leftover):
shutil.rmtree(leftover, ignore_errors=True)
if " -G " in args:
args = args.format(generator=generator)
return run_program(ns3_script, args, python=True, env=env)
@@ -119,7 +125,13 @@ def get_programs_list():
values = {}
with open(ns3_lock_filename) as f:
exec(f.read(), globals(), values)
return values["ns3_runnable_programs"]
programs_list = values["ns3_runnable_programs"]
# Add .exe suffix to programs if on Windows
if win32:
programs_list = list(map(lambda x: x + ext, programs_list))
return programs_list
def get_libraries_list(lib_outdir=usual_lib_outdir):
@@ -558,7 +570,7 @@ class NS3ConfigureBuildProfileTestCase(unittest.TestCase):
Test the debug build
@return None
"""
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" -d debug --enable-verbose")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" -d debug --enable-verbose")
self.assertEqual(return_code, 0)
self.assertIn("Build profile : debug", stdout)
self.assertIn("Build files have been written to", stdout)
@@ -577,7 +589,7 @@ class NS3ConfigureBuildProfileTestCase(unittest.TestCase):
Test the release build
@return None
"""
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" -d release")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" -d release")
self.assertEqual(return_code, 0)
self.assertIn("Build profile : release", stdout)
self.assertIn("Build files have been written to", stdout)
@@ -587,7 +599,7 @@ class NS3ConfigureBuildProfileTestCase(unittest.TestCase):
Test the optimized build
@return None
"""
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" -d optimized --enable-verbose")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" -d optimized --enable-verbose")
self.assertEqual(return_code, 0)
self.assertIn("Build profile : optimized", stdout)
self.assertIn("Build files have been written to", stdout)
@@ -606,7 +618,7 @@ class NS3ConfigureBuildProfileTestCase(unittest.TestCase):
Test a build type with a typo
@return None
"""
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" -d Optimized")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" -d Optimized")
self.assertEqual(return_code, 2)
self.assertIn("invalid choice: 'Optimized'", stderr)
@@ -615,7 +627,7 @@ class NS3ConfigureBuildProfileTestCase(unittest.TestCase):
Test a build type with another typo
@return None
"""
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" -d OPTIMIZED")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" -d OPTIMIZED")
self.assertEqual(return_code, 2)
self.assertIn("invalid choice: 'OPTIMIZED'", stderr)
@@ -655,7 +667,7 @@ class NS3BaseTestCase(unittest.TestCase):
if not NS3BaseTestCase.cleaned_once:
NS3BaseTestCase.cleaned_once = True
run_ns3("clean")
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" -d release --enable-verbose")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" -d release --enable-verbose")
self.config_ok(return_code, stdout)
# Check if .lock-ns3 exists, then read to get list of executables.
@@ -692,7 +704,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
Test enabling and disabling examples
@return None
"""
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-examples")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-examples")
# This just tests if we didn't break anything, not that we actually have enabled anything.
self.config_ok(return_code, stdout)
@@ -701,7 +713,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
self.assertGreater(len(get_programs_list()), len(self.ns3_executables))
# Now we disabled them back.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --disable-examples")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --disable-examples")
# This just tests if we didn't break anything, not that we actually have enabled anything.
self.config_ok(return_code, stdout)
@@ -715,7 +727,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
@return None
"""
# Try enabling tests
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-tests")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-tests")
self.config_ok(return_code, stdout)
# Then try building the libcore test
@@ -726,7 +738,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
self.assertIn("Built target libcore-test", stdout)
# Now we disabled the tests
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --disable-tests")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --disable-tests")
self.config_ok(return_code, stdout)
# Now building the library test should fail
@@ -742,7 +754,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
@return None
"""
# Try filtering enabled modules to network+Wi-Fi and their dependencies
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-modules='network;wifi'")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-modules='network;wifi'")
self.config_ok(return_code, stdout)
# At this point we should have fewer modules
@@ -752,12 +764,12 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
self.assertIn("ns3-wifi", enabled_modules)
# Try enabling only core
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-modules='core'")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-modules='core'")
self.config_ok(return_code, stdout)
self.assertIn("ns3-core", get_enabled_modules())
# Try cleaning the list of enabled modules to reset to the normal configuration.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-modules=''")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-modules=''")
self.config_ok(return_code, stdout)
# At this point we should have the same amount of modules that we had when we started.
@@ -769,7 +781,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
@return None
"""
# Try filtering disabled modules to disable lte and modules that depend on it.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --disable-modules='lte;wimax'")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --disable-modules='lte;wimax'")
self.config_ok(return_code, stdout)
# At this point we should have fewer modules.
@@ -779,7 +791,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
self.assertNotIn("ns3-wimax", enabled_modules)
# Try cleaning the list of enabled modules to reset to the normal configuration.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --disable-modules=''")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --disable-modules=''")
self.config_ok(return_code, stdout)
# At this point we should have the same amount of modules that we had when we started.
@@ -791,7 +803,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
@return None
"""
# Try filtering enabled modules to network+Wi-Fi and their dependencies.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-modules='network,wifi'")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-modules='network,wifi'")
self.config_ok(return_code, stdout)
# At this point we should have fewer modules.
@@ -801,7 +813,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
self.assertIn("ns3-wifi", enabled_modules)
# Try cleaning the list of enabled modules to reset to the normal configuration.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-modules=''")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-modules=''")
self.config_ok(return_code, stdout)
# At this point we should have the same amount of modules that we had when we started.
@@ -813,7 +825,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
@return None
"""
# Try filtering disabled modules to disable lte and modules that depend on it.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --disable-modules='lte,mpi'")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --disable-modules='lte,mpi'")
self.config_ok(return_code, stdout)
# At this point we should have fewer modules.
@@ -823,7 +835,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
self.assertNotIn("ns3-mpi", enabled_modules)
# Try cleaning the list of enabled modules to reset to the normal configuration.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --disable-modules=''")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --disable-modules=''")
self.config_ok(return_code, stdout)
# At this point we should have the same amount of modules that we had when we started.
@@ -892,7 +904,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
f.write(ns3rc_template.format(modules="'lte'", examples="False", tests="True"))
# Reconfigure.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
self.config_ok(return_code, stdout)
# Check.
@@ -900,14 +912,14 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
self.assertLess(len(get_enabled_modules()), len(self.ns3_modules))
self.assertIn("ns3-lte", enabled_modules)
self.assertTrue(get_test_enabled())
self.assertEqual(len(get_programs_list()), len(self.ns3_executables))
self.assertGreaterEqual(len(get_programs_list()), len(self.ns3_executables))
# Replace the ns3rc file with the wifi module, enabling examples and disabling tests
with open(ns3rc_script, "w") as f:
f.write(ns3rc_template.format(modules="'wifi'", examples="True", tests="False"))
# Reconfigure
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
self.config_ok(return_code, stdout)
# Check
@@ -922,7 +934,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
f.write(ns3rc_template.format(modules="'core','network'", examples="True", tests="False"))
# Reconfigure
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
self.config_ok(return_code, stdout)
# Check
@@ -948,7 +960,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
tests="True")
)
# Reconfigure
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
self.config_ok(return_code, stdout)
# Check
@@ -965,7 +977,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
os.remove(ns3rc_script)
# Reconfigure
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
self.config_ok(return_code, stdout)
# Check
@@ -992,7 +1004,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
run_ns3("clean")
# Build target before using below
run_ns3("configure -G \"Unix Makefiles\" -d release --enable-verbose")
run_ns3("configure -G \"{generator}\" -d release --enable-verbose")
run_ns3("build scratch-simulator")
# Run all cases and then check outputs
@@ -1038,7 +1050,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
return_code, _, _ = run_ns3("clean")
self.assertEqual(return_code, 0)
return_code, _, _ = run_ns3("configure -G \"Unix Makefiles\" --enable-examples --enable-tests")
return_code, _, _ = run_ns3("configure -G \"{generator}\" --enable-examples --enable-tests")
self.assertEqual(return_code, 0)
# Build necessary executables
@@ -1066,8 +1078,12 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
}
""")
return_code, stdout, stderr = run_ns3("run sigsegv")
self.assertEqual(return_code, 245)
self.assertIn("sigsegv-default' died with <Signals.SIGSEGV: 11>", stdout)
if win32:
self.assertEqual(return_code, 4294967295) # unsigned -1
self.assertIn("sigsegv-default.exe' returned non-zero exit status", stdout)
else:
self.assertEqual(return_code, 245)
self.assertIn("sigsegv-default' died with <Signals.SIGSEGV: 11>", stdout)
# Cause an abort
abort_example = os.path.join(ns3_path, "scratch", "abort.cc")
@@ -1083,8 +1099,12 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
}
""")
return_code, stdout, stderr = run_ns3("run abort")
self.assertEqual(return_code, 250)
self.assertIn("abort-default' died with <Signals.SIGABRT: 6>", stdout)
if win32:
self.assertEqual(return_code, 3)
self.assertIn("abort-default.exe' returned non-zero exit status", stdout)
else:
self.assertEqual(return_code, 250)
self.assertIn("abort-default' died with <Signals.SIGABRT: 6>", stdout)
os.remove(sigsegv_example)
os.remove(abort_example)
@@ -1115,7 +1135,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
if shutil.which("git") is None:
self.skipTest("git is not available")
return_code, _, _ = run_ns3("configure -G \"Unix Makefiles\" --enable-build-version")
return_code, _, _ = run_ns3("configure -G \"{generator}\" --enable-build-version")
self.assertEqual(return_code, 0)
return_code, stdout, stderr = run_ns3("show version")
@@ -1149,7 +1169,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
f.write("")
# Reload the cmake cache to pick them up
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
self.assertEqual(return_code, 0)
# Try to build them with ns3 and cmake
@@ -1192,7 +1212,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
if path not in ["scratch/main.cc", "scratch/empty.cc"]:
os.rmdir(os.path.dirname(source_absolute_path))
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
self.assertEqual(return_code, 0)
def test_14_MpiCommandTemplate(self):
@@ -1201,7 +1221,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
@return None
"""
# Skip test if mpi is not installed
if shutil.which("mpiexec") is None:
if shutil.which("mpiexec") is None or win32:
self.skipTest("Mpi is not available")
# Ensure sample simulator was built
@@ -1263,7 +1283,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
)
""" % invalid_or_nonexistent_library)
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-examples")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-examples")
if invalid_or_nonexistent_library in ["", "gsd", "libfi", "calibre"]:
self.assertEqual(return_code, 0)
elif invalid_or_nonexistent_library in ["lib"]:
@@ -1311,7 +1331,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
)
""" % invalid_or_nonexistent_library)
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
if invalid_or_nonexistent_library in ["", "gsd", "libfi", "calibre"]:
self.assertEqual(return_code, 0) # should be able to configure
elif invalid_or_nonexistent_library in ["lib"]:
@@ -1356,7 +1376,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
)
""")
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
# This only checks if configuration passes
self.assertEqual(return_code, 0)
@@ -1384,9 +1404,15 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
"""
return_code, stdout, stderr = run_ns3("configure --trace-performance")
self.assertEqual(return_code, 0)
self.assertIn("--profiling-format=google-trace --profiling-output=../cmake_performance_trace.log", stdout)
if win32:
self.assertIn("--profiling-format=google-trace --profiling-output=", stdout)
else:
self.assertIn("--profiling-format=google-trace --profiling-output=../cmake_performance_trace.log", stdout)
self.assertTrue(os.path.exists(os.path.join(ns3_path, "cmake_performance_trace.log")))
# Reconfigure to clean leftovers before the next test
NS3ConfigureTestCase.cleaned_once = False
def test_18_CheckBuildVersionAndVersionCache(self):
"""!
Check if ENABLE_BUILD_VERSION and version.cache are working
@@ -1502,14 +1528,14 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
@return None
"""
# Try filtering enabled modules to core+network and their dependencies
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-examples --enable-tests")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-examples --enable-tests")
self.config_ok(return_code, stdout)
modules_before_filtering = get_enabled_modules()
programs_before_filtering = get_programs_list()
return_code, stdout, stderr = run_ns3(
"configure -G \"Unix Makefiles\" --filter-module-examples-and-tests='core;network'")
"configure -G \"{generator}\" --filter-module-examples-and-tests='core;network'")
self.config_ok(return_code, stdout)
modules_after_filtering = get_enabled_modules()
@@ -1522,7 +1548,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
# Try filtering in only core
return_code, stdout, stderr = run_ns3(
"configure -G \"Unix Makefiles\" --filter-module-examples-and-tests='core'")
"configure -G \"{generator}\" --filter-module-examples-and-tests='core'")
self.config_ok(return_code, stdout)
# At this point we should have the same number of modules
@@ -1532,7 +1558,7 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
# Try cleaning the list of enabled modules to reset to the normal configuration.
return_code, stdout, stderr = run_ns3(
"configure -G \"Unix Makefiles\" --disable-examples --disable-tests --filter-module-examples-and-tests=''")
"configure -G \"{generator}\" --disable-examples --disable-tests --filter-module-examples-and-tests=''")
self.config_ok(return_code, stdout)
# At this point we should have the same amount of modules that we had when we started.
@@ -1668,7 +1694,7 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
self.assertEqual(return_code, 0)
self.assertIn("Built target", stdout)
for program in get_programs_list():
self.assertTrue(os.path.exists(program))
self.assertTrue(os.path.exists(program), program)
self.assertIn(cmake_build_project_command, stdout)
def test_04_BuildProjectNoTaskLines(self):
@@ -1717,7 +1743,7 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
f.write("3-00\n")
# Reconfigure.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\"")
self.config_ok(return_code, stdout)
# Build.
@@ -1757,8 +1783,10 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
in the right place and still working correctly
@return None
"""
# Re-build to return to the original state.
run_ns3("build")
return_code, stdout, stderr = run_ns3("build")
self.assertEqual(return_code, 0)
## ns3_libraries holds a list of built module libraries # noqa
self.ns3_libraries = get_libraries_list()
@@ -1776,9 +1804,9 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
absolute_path = os.sep.join([ns3_path, "build", "release"])
relative_path = os.sep.join(["build", "release"])
for different_out_dir in [absolute_path, relative_path]:
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --out=%s" % different_out_dir)
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --out=%s" % different_out_dir)
self.config_ok(return_code, stdout)
self.assertIn("Build directory : %s" % absolute_path, stdout)
self.assertIn("Build directory : %s" % absolute_path.replace(os.sep, '/'), stdout)
# Build
run_ns3("build")
@@ -1800,9 +1828,9 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
shutil.rmtree(absolute_path)
# Restore original output directory.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --out=''")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --out=''")
self.config_ok(return_code, stdout)
self.assertIn("Build directory : %s" % usual_outdir, stdout)
self.assertIn("Build directory : %s" % usual_outdir.replace(os.sep, '/'), stdout)
# Try re-building.
run_ns3("build")
@@ -1838,7 +1866,7 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
# Reconfigure setting the installation folder to ns-3-dev/build/install.
install_prefix = os.sep.join([ns3_path, "build", "install"])
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --prefix=%s" % install_prefix)
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --prefix=%s" % install_prefix)
self.config_ok(return_code, stdout)
# Build.
@@ -1925,7 +1953,7 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
# Configure the test project
cmake = shutil.which("cmake")
return_code, stdout, stderr = run_program(cmake,
"-DCMAKE_BUILD_TYPE=debug .",
"-DCMAKE_BUILD_TYPE=debug -G\"{generator}\" .".format(generator=platform_makefiles),
cwd=install_prefix)
if version == "3.00":
self.assertEqual(return_code, 1)
@@ -1952,7 +1980,14 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
self.assertIn("Built target", stdout)
# Try running the test program that imports ns-3
return_code, stdout, stderr = run_program("./test", "", cwd=install_prefix)
if win32:
test_program = os.path.join(install_prefix, "test.exe")
env_sep = ";" if ";" in os.environ["PATH"] else ":"
env = {"PATH": env_sep.join([os.environ["PATH"], os.path.join(install_prefix, "lib")])}
else:
test_program = "./test"
env = None
return_code, stdout, stderr = run_program(test_program, "", cwd=install_prefix, env=env)
self.assertEqual(return_code, 0)
# Uninstall
@@ -1960,6 +1995,7 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
self.assertIn("Built target uninstall", stdout)
# Restore 3-dev version file
os.remove(version_file)
with open(version_file, "w") as f:
f.write("3-dev\n")
@@ -2002,14 +2038,14 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
"""
# First enable examples
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-examples")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-examples")
self.assertEqual(return_code, 0)
# Copy second.cc from the tutorial examples to the scratch folder
shutil.copy("./examples/tutorial/second.cc", "./scratch/second.cc")
# Reconfigure to re-scan the scratches
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-examples")
return_code, stdout, stderr = run_ns3("configure -G \"{generator}\" --enable-examples")
self.assertEqual(return_code, 0)
# Try to run second and collide
@@ -2017,7 +2053,7 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
self.assertEqual(return_code, 1)
self.assertIn(
'Build target "second" is ambiguous. Try one of these: "scratch/second", "examples/tutorial/second"',
stdout
stdout.replace(os.sep, '/')
)
# Try to run scratch/second and succeed
@@ -2035,7 +2071,7 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
self.assertEqual(return_code, 1)
self.assertIn(
'Run target "second" is ambiguous. Try one of these: "scratch/second", "examples/tutorial/second"',
stdout
stdout.replace(os.sep, '/')
)
# Try to run scratch/second and succeed
@@ -2056,17 +2092,24 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
Test if we can build a static ns-3 library and link it to static programs
@return None
"""
# First enable examples and static build
return_code, stdout, stderr = run_ns3(
"configure -G \"Unix Makefiles\" --enable-examples --disable-gtk --enable-static")
"configure -G \"{generator}\" --enable-examples --disable-gtk --enable-static")
# If configuration passes, we are half way done
self.assertEqual(return_code, 0)
if win32:
# Configuration should fail explaining Windows
# socket libraries cannot be statically linked
self.assertEqual(return_code, 1)
self.assertIn("Static builds are unsupported on Windows", stderr)
else:
# If configuration passes, we are half way done
self.assertEqual(return_code, 0)
# Then try to build one example
return_code, stdout, stderr = run_ns3('build sample-simulator')
self.assertEqual(return_code, 0)
self.assertIn("Built target", stdout)
# Then try to build one example
return_code, stdout, stderr = run_ns3('build sample-simulator')
self.assertEqual(return_code, 0)
self.assertIn("Built target", stdout)
# Maybe check the built binary for shared library references? Using objdump, otool, etc
NS3BuildBaseTestCase.cleaned_once = False
@@ -2078,12 +2121,12 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
"""
try:
import cppyy
except ModuleNotFound:
except ModuleNotFoundError:
self.skipTest("Cppyy was not found")
# First enable examples and static build
return_code, stdout, stderr = run_ns3(
"configure -G \"Unix Makefiles\" --enable-python-bindings")
"configure -G \"{generator}\" --enable-python-bindings")
# If configuration passes, we are half way done
self.assertEqual(return_code, 0)
@@ -2121,7 +2164,8 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase):
super().setUp()
# On top of the release build configured by NS3ConfigureTestCase, also enable examples, tests and docs.
return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-examples --enable-tests")
return_code, stdout, stderr = run_ns3(
"configure -d release -G \"{generator}\" --enable-examples --enable-tests")
self.config_ok(return_code, stdout)
# Check if .lock-ns3 exists, then read to get list of executables.
@@ -2215,10 +2259,13 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase):
if shutil.which("gdb") is None:
self.skipTest("Missing gdb")
return_code, stdout, stderr = run_ns3("run scratch-simulator --gdb --verbose --no-build")
return_code, stdout, stderr = run_ns3("run scratch-simulator --gdb --verbose --no-build", env={"gdb_eval": "1"})
self.assertEqual(return_code, 0)
self.assertIn("scratch-simulator", stdout)
self.assertIn("No debugging symbols found", stdout)
if win32:
self.assertIn("GNU gdb", stdout)
else:
self.assertIn("No debugging symbols found", stdout)
def test_09_RunNoBuildValgrind(self):
"""!
@@ -2241,6 +2288,9 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase):
if shutil.which("doxygen") is None:
self.skipTest("Missing doxygen")
if shutil.which("bash") is None:
self.skipTest("Missing bash")
doc_folder = os.path.abspath(os.sep.join([".", "doc"]))
doxygen_files = ["introspected-command-line.h", "introspected-doxygen.h"]
@@ -2386,7 +2436,7 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase):
likely_fuse_mount = ((prev_fstat.st_mode & stat.S_ISUID) == (fstat.st_mode & stat.S_ISUID)) and \
prev_fstat.st_uid == 0 # noqa
if sys.platform == "win32" or likely_fuse_mount:
if win32 or likely_fuse_mount:
self.skipTest("Windows or likely a FUSE mount")
# If this is a valid platform, we can continue
@@ -2444,8 +2494,9 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase):
return_code4, stdout4, _ = run_ns3('run sample-simulator --command-template "%s --PrintVersion" --verbose')
return_code5, stdout5, _ = run_ns3('run sample-simulator --command-template="%s --PrintVersion" --verbose')
self.assertEqual((return_code4, return_code5), (0, 0))
self.assertIn("sample-simulator --PrintVersion", stdout4)
self.assertIn("sample-simulator --PrintVersion", stdout5)
self.assertIn("sample-simulator{ext} --PrintVersion".format(ext=ext), stdout4)
self.assertIn("sample-simulator{ext} --PrintVersion".format(ext=ext), stdout5)
def test_16_ForwardArgumentsToRunTargets(self):
"""!
@@ -2460,9 +2511,9 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase):
return_code2, stdout2, stderr2 = run_ns3('run sample-simulator --verbose -- --help')
self.assertEqual((return_code0, return_code1, return_code2), (0, 0, 0))
self.assertIn("sample-simulator --help", stdout0)
self.assertIn("sample-simulator --help", stdout1)
self.assertIn("sample-simulator --help", stdout2)
self.assertIn("sample-simulator{ext} --help".format(ext=ext), stdout0)
self.assertIn("sample-simulator{ext} --help".format(ext=ext), stdout1)
self.assertIn("sample-simulator{ext} --help".format(ext=ext), stdout2)
# Test if the same thing happens with an additional run argument (e.g. --no-build)
return_code0, stdout0, stderr0 = run_ns3('run "sample-simulator --help" --no-build')
@@ -2480,9 +2531,9 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase):
return_code2, stdout2, stderr2 = run_ns3('run "sample-simulator --PrintTypeIds" --verbose')
self.assertEqual((return_code0, return_code1, return_code2), (0, 0, 0))
self.assertIn("sample-simulator --PrintGlobals", stdout0)
self.assertIn("sample-simulator --PrintGroups", stdout1)
self.assertIn("sample-simulator --PrintTypeIds", stdout2)
self.assertIn("sample-simulator{ext} --PrintGlobals".format(ext=ext), stdout0)
self.assertIn("sample-simulator{ext} --PrintGroups".format(ext=ext), stdout1)
self.assertIn("sample-simulator{ext} --PrintTypeIds".format(ext=ext), stdout2)
# Then check if all the arguments are correctly merged by checking the outputs
cmd = 'run "sample-simulator --PrintGlobals" --command-template="%s --PrintGroups" --verbose -- --PrintTypeIds'
@@ -2492,7 +2543,7 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase):
# The order of the arguments is command template,
# arguments passed with the target itself
# and forwarded arguments after the -- separator
self.assertIn("sample-simulator --PrintGroups --PrintGlobals --PrintTypeIds", stdout)
self.assertIn("sample-simulator{ext} --PrintGroups --PrintGlobals --PrintTypeIds".format(ext=ext), stdout)
# Check if it complains about the missing -- separator
cmd0 = 'run sample-simulator --command-template="%s " --PrintTypeIds'