diff --git a/CHANGES.md b/CHANGES.md index 6aeb18921..54e160c51 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -57,7 +57,7 @@ Changes from ns-3.36 to ns-3.37 * Added the `build_exec` macro to declare new executables. * Replaced Python-based .ns3rc with a CMake-based version. * Deprecated .ns3rc files will be updated to the new CMake-based format and a backup will be placed alongside it. - +* Added the `./ns3 configure --filter-module-examples-and-tests='module1;module2'` option, which can be used to filter out examples and tests that do not use the listed modules. ### Changed behavior diff --git a/CMakeLists.txt b/CMakeLists.txt index 19b585c77..7cda8a7b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,14 @@ set(NS3_DISABLED_MODULES "" CACHE STRING "List of modules to disable (e.g. lte;wimax;wave)" ) +# Filter in the modules from which examples and tests will be built +set(NS3_FILTER_MODULE_EXAMPLES_AND_TESTS + "" + CACHE + STRING + "List of modules that should have their examples and tests built (e.g. lte;wifi)" +) + # Include macros used below include(build-support/macros-and-definitions.cmake) diff --git a/build-support/custom-modules/ns3-module-macros.cmake b/build-support/custom-modules/ns3-module-macros.cmake index 8ea9ac4a0..49f97d46d 100644 --- a/build-support/custom-modules/ns3-module-macros.cmake +++ b/build-support/custom-modules/ns3-module-macros.cmake @@ -224,8 +224,17 @@ function(build_lib) ) endif() + # Check if the module tests should be built + set(filtered_in ON) + if(NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + set(filtered_in OFF) + if(${BLIB_LIBNAME} IN_LIST NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + set(filtered_in ON) + endif() + endif() + # Build tests if requested - if(${ENABLE_TESTS}) + if(${ENABLE_TESTS} AND ${filtered_in}) list(LENGTH BLIB_TEST_SOURCES test_source_len) if(${test_source_len} GREATER 0) # Create BLIB_LIBNAME of output library test of module @@ -314,7 +323,17 @@ function(build_lib_example) check_for_missing_libraries( missing_dependencies "${BLIB_EXAMPLE_LIBRARIES_TO_LINK}" ) - if(NOT missing_dependencies) + + # Check if a module example should be built + set(filtered_in ON) + if(NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + set(filtered_in OFF) + if(${BLIB_LIBNAME} IN_LIST NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + set(filtered_in ON) + endif() + endif() + + if((NOT missing_dependencies) AND ${filtered_in}) # Convert boolean into text to forward argument if(${BLIB_EXAMPLE_IGNORE_PCH}) set(IGNORE_PCH IGNORE_PCH) @@ -326,7 +345,7 @@ function(build_lib_example) SOURCE_FILES ${BLIB_EXAMPLE_SOURCE_FILES} HEADER_FILES ${BLIB_EXAMPLE_HEADER_FILES} LIBRARIES_TO_LINK - ${lib${BLIB_EXAMPLE_LIBNAME}} ${BLIB_EXAMPLE_LIBRARIES_TO_LINK} + ${lib${BLIB_LIBNAME}} ${BLIB_EXAMPLE_LIBRARIES_TO_LINK} ${optional_visualizer_lib} EXECUTABLE_DIRECTORY_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${FOLDER}/ ${IGNORE_PCH} diff --git a/build-support/macros-and-definitions.cmake b/build-support/macros-and-definitions.cmake index 3caa37ada..46c4a34bf 100644 --- a/build-support/macros-and-definitions.cmake +++ b/build-support/macros-and-definitions.cmake @@ -1506,11 +1506,22 @@ macro(build_example) "EXAMPLE" "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + # Filter examples out if they don't contain one of the filtered in modules + set(filtered_in ON) + if(NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + set(filtered_in OFF) + foreach(filtered_module NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + if(${filtered_module} IN_LIST EXAMPLE_LIBRARIES_TO_LINK) + set(filtered_in ON) + endif() + endforeach() + endif() + check_for_missing_libraries( missing_dependencies "${EXAMPLE_LIBRARIES_TO_LINK}" ) - if(NOT missing_dependencies) + if((NOT missing_dependencies) AND ${filtered_in}) # Convert boolean into text to forward argument if(${EXAMPLE_IGNORE_PCH}) set(IGNORE_PCH IGNORE_PCH) diff --git a/doc/manual/source/working-with-cmake.rst b/doc/manual/source/working-with-cmake.rst index 9b21cb5d1..f65daab03 100644 --- a/doc/manual/source/working-with-cmake.rst +++ b/doc/manual/source/working-with-cmake.rst @@ -1626,13 +1626,25 @@ listed by ``./ns3 show targets`` or your IDE, check if all its dependencies were cmake_parse_arguments( "EXAMPLE" "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # Filter examples out if they don't contain one of the filtered in modules + set(filtered_in ON) + if(NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + set(filtered_in OFF) + foreach(filtered_module NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + if(${filtered_module} IN_LIST EXAMPLE_LIBRARIES_TO_LINK) + set(filtered_in ON) + endif() + endforeach() + endif() + # Check if any of the LIBRARIES_TO_LINK is missing to prevent configuration errors check_for_missing_libraries( missing_dependencies "${EXAMPLE_LIBRARIES_TO_LINK}" ) - if(NOT missing_dependencies) - # Convert boolean into text to forward argument + if((NOT missing_dependencies) AND ${filtered_in}) + # Convert boolean into text to forward argument if(${EXAMPLE_IGNORE_PCH}) set(IGNORE_PCH IGNORE_PCH) endif() @@ -1991,8 +2003,17 @@ The following block creates the test library for the module currently being proc function(build_lib) # ... + # Check if the module tests should be built + set(filtered_in ON) + if(NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + set(filtered_in OFF) + if(${BLIB_LIBNAME} IN_LIST NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + set(filtered_in ON) + endif() + endif() + # Build tests if requested - if(${ENABLE_TESTS}) + if(${ENABLE_TESTS} AND ${filtered_in}) list(LENGTH BLIB_TEST_SOURCES test_source_len) if(${test_source_len} GREATER 0) # Create BLIB_LIBNAME of output library test of module @@ -2117,7 +2138,17 @@ Note that both of these options are handled by the ``build_exec`` macro. function(build_lib_example) # ... check_for_missing_libraries(missing_dependencies "${BLIB_EXAMPLE_LIBRARIES_TO_LINK}") - if(NOT missing_dependencies) + + # Check if a module example should be built + set(filtered_in ON) + if(NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + set(filtered_in OFF) + if(${BLIB_LIBNAME} IN_LIST NS3_FILTER_MODULE_EXAMPLES_AND_TESTS) + set(filtered_in ON) + endif() + endif() + + if((NOT missing_dependencies) AND ${filtered_in}) # Convert boolean into text to forward argument if(${BLIB_EXAMPLE_IGNORE_PCH}) set(IGNORE_PCH IGNORE_PCH) diff --git a/ns3 b/ns3 index 2a9040749..596e21e12 100755 --- a/ns3 +++ b/ns3 @@ -159,6 +159,9 @@ def parse_args(argv): parser_configure.add_argument('--disable-modules', help='List of modules not to build (e.g. lte;wimax)', action="store", type=str, default=None) + parser_configure.add_argument('--filter-module-examples-and-tests', + help='List of modules that should have their examples and tests built (e.g. lte;wifi)', + action="store", type=str, default=None) parser_configure.add_argument('--lcov-report', help=('Generate a code coverage report ' '(use this option after configuring with --enable-gcov and running a program)'), @@ -589,12 +592,15 @@ def configure_cmake(cmake, args, current_cmake_cache_folder, current_cmake_gener cmake_args.append("-DCMAKE_INSTALL_PREFIX=%s" % args.prefix) # Process enabled/disabled modules - if args.enable_modules: + if args.enable_modules is not None: cmake_args.append("-DNS3_ENABLED_MODULES=%s" % args.enable_modules) - if args.disable_modules: + if args.disable_modules is not None: cmake_args.append("-DNS3_DISABLED_MODULES=%s" % args.disable_modules) + if args.filter_module_examples_and_tests is not None: + cmake_args.append("-DNS3_FILTER_MODULE_EXAMPLES_AND_TESTS=%s" % args.filter_module_examples_and_tests) + # Try to set specified generator (will probably fail if there is an old cache) if args.G: cmake_args.extend(["-G", args.G]) diff --git a/utils/tests/test-ns3.py b/utils/tests/test-ns3.py index 621fb6cb0..2d5bebf10 100644 --- a/utils/tests/test-ns3.py +++ b/utils/tests/test-ns3.py @@ -1484,6 +1484,52 @@ class NS3ConfigureTestCase(NS3BaseTestCase): with open(version_cache_file, "r") as version: self.assertNotEqual(version.read(), version_cache_contents) + # Reconfigure to clean leftovers before the next test + NS3ConfigureTestCase.cleaned_once = False + + def test_19_FilterModuleExamplesAndTests(self): + """! + Test filtering in examples and tests from specific modules + @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") + 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'") + self.config_ok(return_code, stdout) + + modules_after_filtering = get_enabled_modules() + programs_after_filtering = get_programs_list() + + # At this point we should have the same number of modules + self.assertEqual(len(modules_after_filtering), len(modules_before_filtering)) + # But less executables + self.assertLess(len(programs_after_filtering), len(programs_before_filtering)) + + # Try filtering in only core + return_code, stdout, stderr = run_ns3( + "configure -G \"Unix Makefiles\" --filter-module-examples-and-tests='core'") + self.config_ok(return_code, stdout) + + # At this point we should have the same number of modules + self.assertEqual(len(get_enabled_modules()), len(modules_after_filtering)) + # But less executables + self.assertLess(len(get_programs_list()), len(programs_after_filtering)) + + # 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=''") + self.config_ok(return_code, stdout) + + # At this point we should have the same amount of modules that we had when we started. + self.assertEqual(len(get_enabled_modules()), len(self.ns3_modules)) + self.assertEqual(len(get_programs_list()), len(self.ns3_executables)) + class NS3BuildBaseTestCase(NS3BaseTestCase): """! @@ -2655,8 +2701,8 @@ def main(): keys = list(tests.keys()) while not args.resume_from_test_name in keys[0] and len(tests) > 0: - suite._tests.remove(tests[keys[0]]) - keys.pop(0) + suite._tests.remove(tests[keys[0]]) + keys.pop(0) # Before running, check if ns3rc exists and save it ns3rc_script_bak = ns3rc_script + ".bak"