From 3ee4eb41cbc5b2421804b47bdc3173d96384fe07 Mon Sep 17 00:00:00 2001 From: Gabriel Ferreira Date: Thu, 17 Mar 2022 18:52:23 -0300 Subject: [PATCH] build: fix remaining "lib" prefix removal steps in CMake --- .../custom-modules/ns3-cmake-package.cmake | 4 +- .../custom-modules/ns3-configtable.cmake | 3 +- build-support/custom-modules/ns3-lock.cmake | 6 +- .../custom-modules/ns3-module-macros.cmake | 8 +- build-support/macros-and-definitions.cmake | 11 +-- doc/manual/source/working-with-cmake.rst | 32 ++------ utils/tests/test-ns3.py | 73 +++++++++++++++---- 7 files changed, 81 insertions(+), 56 deletions(-) diff --git a/build-support/custom-modules/ns3-cmake-package.cmake b/build-support/custom-modules/ns3-cmake-package.cmake index e6c03e17f..b2ad7cd05 100644 --- a/build-support/custom-modules/ns3-cmake-package.cmake +++ b/build-support/custom-modules/ns3-cmake-package.cmake @@ -23,7 +23,7 @@ function(build_required_and_libs_lists module_name visibility libraries foreach(lib ${libraries}) if(${lib} IN_LIST all_ns3_libraries) get_target_property(lib_real_name ${lib} OUTPUT_NAME) - string(REPLACE "lib" "" required_module_name ${lib}) + remove_lib_prefix(${lib} required_module_name) set(required_modules_list "${required_modules_list} ns3-${required_module_name}" ) @@ -55,7 +55,7 @@ function(pkgconfig_module libname) set(private_libs ${all_libs}) # Create two lists of publicly and privately linked libraries to this module - string(REPLACE "lib" "" module_name ${libname}) + remove_lib_prefix(${libname} module_name) # These filter out ns and non-ns libraries into public and private libraries # linked against module_name diff --git a/build-support/custom-modules/ns3-configtable.cmake b/build-support/custom-modules/ns3-configtable.cmake index c73c5b223..924ab863d 100644 --- a/build-support/custom-modules/ns3-configtable.cmake +++ b/build-support/custom-modules/ns3-configtable.cmake @@ -72,7 +72,8 @@ function(print_formatted_table_with_modules table_name modules output) string(APPEND temp "${table_name}:\n") set(count 0) # Variable to count number of columns set(width 26) # Variable with column width - string(REPLACE "lib" "" modules_to_print "${modules}") + string(REPLACE ";lib" ";" modules_to_print ";${modules}") + string(SUBSTRING "${modules_to_print}" 1 -1 modules_to_print) list(SORT modules_to_print) # Sort for nice output set(modules_with_large_names) foreach(module ${modules_to_print}) diff --git a/build-support/custom-modules/ns3-lock.cmake b/build-support/custom-modules/ns3-lock.cmake index e907a526c..95a1f1c10 100644 --- a/build-support/custom-modules/ns3-lock.cmake +++ b/build-support/custom-modules/ns3-lock.cmake @@ -41,8 +41,7 @@ function(write_lock) string(APPEND lock_contents "NS3_ENABLED_MODULES = [") foreach(module_library ${ns3-libs}) # fetch core module libraries string(APPEND lock_contents "'") - string(REPLACE "lib" "" module_name ${module_library}) # lib${libname} into - # libname + remove_lib_prefix("${module_library}" module_name) string(APPEND lock_contents "ns3-${module_name}', ") endforeach() string(APPEND lock_contents "]\n") @@ -50,8 +49,7 @@ function(write_lock) string(APPEND lock_contents "NS3_ENABLED_CONTRIBUTED_MODULES = [") foreach(module_library ${ns3-contrib-libs}) # fetch core module libraries string(APPEND lock_contents "'") - string(REPLACE "lib" "" module_name ${module_library}) # lib${libname} into - # libname + remove_lib_prefix("${module_library}" module_name) string(APPEND lock_contents "ns3-${module_name}', ") endforeach() string(APPEND lock_contents "]\n") diff --git a/build-support/custom-modules/ns3-module-macros.cmake b/build-support/custom-modules/ns3-module-macros.cmake index dc57cdcd8..4c6dcd1d3 100644 --- a/build-support/custom-modules/ns3-module-macros.cmake +++ b/build-support/custom-modules/ns3-module-macros.cmake @@ -116,8 +116,8 @@ function(build_lib) foreach(library ${BLIB_LIBRARIES_TO_LINK}) remove_lib_prefix("${library}" module_name) - # Check if the module exists in the ns-3 modules list - # or if it is a 3rd-party library + # Check if the module exists in the ns-3 modules list or if it is a + # 3rd-party library if(${module_name} IN_LIST ns3-all-enabled-modules) list(APPEND ns_libraries_to_link ${library}) else() @@ -485,7 +485,9 @@ function(build_lib_example) get_filename_component(FOLDER ${FOLDER} DIRECTORY) # cmake-format: on - check_for_missing_libraries(missing_dependencies "${BLIB_EXAMPLE_LIBRARIES_TO_LINK}") + check_for_missing_libraries( + missing_dependencies "${BLIB_EXAMPLE_LIBRARIES_TO_LINK}" + ) if(NOT missing_dependencies) # Create shared library with sources and headers add_executable( diff --git a/build-support/macros-and-definitions.cmake b/build-support/macros-and-definitions.cmake index e3904c0ce..e2a01abc7 100644 --- a/build-support/macros-and-definitions.cmake +++ b/build-support/macros-and-definitions.cmake @@ -1300,8 +1300,7 @@ function(copy_headers_before_building_lib libname outputdir headers visibility) endfunction(copy_headers_before_building_lib) function(remove_lib_prefix prefixed_library library) - # Check if we still have something remaining - # after removing the "lib" prefix + # Check if we still have something remaining after removing the "lib" prefix string(LENGTH ${prefixed_library} len) if(${len} LESS 4) message(FATAL_ERROR "Invalid library name: ${prefixed_library}") @@ -1323,8 +1322,8 @@ function(check_for_missing_libraries output_variable_name libraries) # check if the example depends on disabled modules remove_lib_prefix("${lib}" lib) - # Check if the module exists in the ns-3 modules list - # or if it is a 3rd-party library + # Check if the module exists in the ns-3 modules list or if it is a + # 3rd-party library if(NOT (${lib} IN_LIST ns3-all-enabled-modules)) list(APPEND missing_dependencies ${lib}) endif() @@ -1347,7 +1346,9 @@ macro(build_example) "EXAMPLE" "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - check_for_missing_libraries(missing_dependencies "${EXAMPLE_LIBRARIES_TO_LINK}") + check_for_missing_libraries( + missing_dependencies "${EXAMPLE_LIBRARIES_TO_LINK}" + ) if(NOT missing_dependencies) # Create shared library with sources and headers diff --git a/doc/manual/source/working-with-cmake.rst b/doc/manual/source/working-with-cmake.rst index b547af072..f4ef67a16 100644 --- a/doc/manual/source/working-with-cmake.rst +++ b/doc/manual/source/working-with-cmake.rst @@ -1588,8 +1588,10 @@ can be turned off by setting ``NS3_REEXPORT_THIRD_PARTY_LIBRARIES=OFF`` set(ns_libraries_to_link) foreach(library ${BLIB_LIBRARIES_TO_LINK}) - # Remove lib prefix from module name (e.g. libcore -> core) - string(REPLACE "lib" "" module_name "${library}") + remove_lib_prefix("${library}" module_name) + + # Check if the module exists in the ns-3 modules list + # or if it is a 3rd-party library if(${module_name} IN_LIST ns3-all-enabled-modules) list(APPEND ns_libraries_to_link ${library}) else() @@ -2065,29 +2067,6 @@ or the src folder. endfunction() Then we check if the ns-3 modules required by the example are enabled to be built. -The ``if(EXISTS ${lib})`` skip external libraries which are listed with their absolute paths. - -.. sourcecode:: cmake - - function(build_lib_example) - # ... - # cmake-format: on - set(missing_dependencies) - foreach(lib ${BLIB_EXAMPLE_LIBRARIES_TO_LINK}) - # skip check for ns-3 modules if its a path to a library - if(EXISTS ${lib}) - continue() - endif() - - # check if the example depends on disabled modules - string(REPLACE "lib" "" lib ${lib}) - if(NOT (${lib} IN_LIST ns3-all-enabled-modules)) - list(APPEND missing_dependencies ${lib}) - endif() - endforeach() - # ... - endfunction() - If the list ``missing_dependencies`` is empty, we create the example. Otherwise, we skip it. The example can be linked to the current module (``${lib${BLIB_EXAMPLE_LIBNAME}}``) and other libraries to link (``${BLIB_EXAMPLE_LIBRARIES_TO_LINK}``) and optionally to the visualizer @@ -2100,7 +2079,8 @@ a single ns-3 static library (``lib-ns3-static``), if either ``NS3_MONOLIB=ON`` .. sourcecode:: cmake function(build_lib_example) - # ... + # ... + check_for_missing_libraries(missing_dependencies "${BLIB_EXAMPLE_LIBRARIES_TO_LINK}") if(NOT missing_dependencies) # Create shared library with sources and headers add_executable( diff --git a/utils/tests/test-ns3.py b/utils/tests/test-ns3.py index 94774d88c..a76f89918 100644 --- a/utils/tests/test-ns3.py +++ b/utils/tests/test-ns3.py @@ -57,7 +57,7 @@ def run_ns3(args, env=None): @return tuple containing (error code, stdout and stderr) """ if "clean" in args: - possible_leftovers = ["contrib/borked"] + possible_leftovers = ["contrib/borked", "contrib/calibre"] for leftover in possible_leftovers: if os.path.exists(leftover): shutil.rmtree(leftover, ignore_errors=True) @@ -246,7 +246,7 @@ class NS3UnusedSourcesTestCase(unittest.TestCase): unused_sources.add(file) # Remove temporary exceptions - exceptions = ["win32-system-wall-clock-ms.cc", # Should be removed with MR784 + exceptions = ["win32-system-wall-clock-ms.cc", # Should be removed with MR784 ] for exception in exceptions: for unused_source in unused_sources: @@ -286,6 +286,7 @@ class NS3UnusedSourcesTestCase(unittest.TestCase): self.assertListEqual([], list(unused_sources)) + class NS3CommonSettingsTestCase(unittest.TestCase): """! ns3 tests related to generic options @@ -941,14 +942,14 @@ class NS3ConfigureTestCase(NS3BaseTestCase): for invalid_or_non_existant_library in ["", "fee", "fi", "fogh", "calibre"]: with open("contrib/borked/CMakeLists.txt", "w") as f: f.write(""" - build_lib( - LIBNAME borked - SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty.cc - LIBRARIES_TO_LINK ${libcore} %s - ) - """ % invalid_or_non_existant_library) + build_lib( + LIBNAME borked + SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty.cc + LIBRARIES_TO_LINK ${libcore} %s + ) + """ % invalid_or_non_existant_library) - return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"") + return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\" --enable-examples") if invalid_or_non_existant_library in ["", "fogh", "calibre"]: self.assertEqual(return_code, 0) elif invalid_or_non_existant_library in ["fee", "fi"]: @@ -984,12 +985,12 @@ class NS3ConfigureTestCase(NS3BaseTestCase): for invalid_or_non_existant_library in ["", "fee", "fi", "fogh", "calibre"]: with open("contrib/borked/examples/CMakeLists.txt", "w") as f: f.write(""" - build_lib_example( - NAME borked-example - SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty-main.cc - LIBRARIES_TO_LINK ${libborked} %s - ) - """ % invalid_or_non_existant_library) + build_lib_example( + NAME borked-example + SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty-main.cc + LIBRARIES_TO_LINK ${libborked} %s + ) + """ % invalid_or_non_existant_library) return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"") if invalid_or_non_existant_library in ["", "fogh", "calibre"]: @@ -1014,6 +1015,48 @@ class NS3ConfigureTestCase(NS3BaseTestCase): shutil.rmtree("contrib/borked", ignore_errors=True) + def test_15_LibrariesContainingLib(self): + """! + Test if CMake can properly handle modules containing "lib", + which is used internally as a prefix for module libraries + @return None + """ + + os.makedirs("contrib/calibre", exist_ok=True) + os.makedirs("contrib/calibre/examples", exist_ok=True) + + # Now test if we can have a library with "lib" in it + with open("contrib/calibre/examples/CMakeLists.txt", "w") as f: + f.write("") + with open("contrib/calibre/CMakeLists.txt", "w") as f: + f.write(""" + build_lib( + LIBNAME calibre + SOURCE_FILES ${PROJECT_SOURCE_DIR}/build-support/empty.cc + LIBRARIES_TO_LINK ${libcore} + ) + """) + + return_code, stdout, stderr = run_ns3("configure -G \"Unix Makefiles\"") + + # This only checks if configuration passes + self.assertEqual(return_code, 0) + + # This checks if the contrib modules were printed correctly + self.assertIn("calibre", stdout) + + # This checks not only if "lib" from "calibre" was incorrectly removed, + # but also if the pkgconfig file was generated with the correct name + self.assertNotIn("care", stdout) + self.assertTrue(os.path.exists(os.path.join(ns3_path, "cmake-cache", "pkgconfig", "ns3-calibre.pc"))) + + # Check if we can build this library + return_code, stdout, stderr = run_ns3("build calibre") + self.assertEqual(return_code, 0) + self.assertIn(cmake_build_target_command(target="libcalibre"), stdout) + + shutil.rmtree("contrib/calibre", ignore_errors=True) + class NS3BuildBaseTestCase(NS3BaseTestCase): """!