diff --git a/CMakeLists.txt b/CMakeLists.txt index f851df5af..9dc7caeda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ endif() # ############################################################################## # Project name # # ############################################################################## -project(NS3 CXX C) +project(NS3 CXX) file(STRINGS VERSION NS3_VER) diff --git a/build-support/3rd-party/FindInt128.cmake b/build-support/3rd-party/FindInt128.cmake deleted file mode 100644 index 5e9b918cc..000000000 --- a/build-support/3rd-party/FindInt128.cmake +++ /dev/null @@ -1,152 +0,0 @@ -# # COPYRIGHT -# -# All contributions by Emanuele Ruffaldi Copyright (c) 2016-2019, E All rights -# reserved. -# -# All other contributions: Copyright (c) 2019, the respective contributors. All -# rights reserved. -# -# Each contributor holds copyright over their respective contributions. The -# project versioning (Git) records all such contribution source information. -# -# LICENSE -# -# The BSD 3-Clause License -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# * Neither the name of tiny-dnn nor the names of its contributors may be used -# to endorse or promote products derived from this software without specific -# prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# SOURCE: -# https://github.com/eruffaldi/cppPosit/blob/master/include/FindInt128.cmake -# - -# * this module looks for 128 bit integer support. It sets up the type defs in -# util/int128_types.hpp. Simply add ${INT128_FLAGS} to the compiler flags. - -include(CheckTypeSize) -include(CheckCXXSourceCompiles) - -macro(CHECK_128_BIT_HASH_FUNCTION VAR_NAME DEF_NAME) - - # message("Testing for presence of 128 bit unsigned integer hash function for - # ${VAR_NAME}.") - - check_cxx_source_compiles( - " - #include - #include - int main(int argc, char** argv) { - std::hash<${VAR_NAME}>()(0); - return 0; - }" - has_hash_${VAR_NAME} - ) - - if(has_hash_${VAR_NAME}) - # message("std::hash<${VAR_NAME}> defined.") - set(${DEF_NAME} 1) - else() - # message("std::hash<${VAR_NAME}> not defined.") - endif() -endmacro() - -macro(CHECK_INT128 INT128_NAME VARIABLE DEFINE_NAME) - - if(NOT INT128_FOUND) - # message("Testing for 128 bit integer support with ${INT128_NAME}.") - check_type_size("${INT128_NAME}" int128_t_${DEFINE_NAME}) - if(HAVE_int128_t_${DEFINE_NAME}) - if(int128_t_${DEFINE_NAME} EQUAL 16) - # message("Found: Enabling support for 128 bit integers using - # ${INT128_NAME}.") - set(INT128_FOUND 1) - check_128_bit_hash_function(${INT128_NAME} HAS_INT128_STD_HASH) - set(${VARIABLE} "${DEFINE_NAME}") - else() - # message("${INT128_NAME} has incorrect size, can't use.") - endif() - endif() - endif() -endmacro() - -macro(CHECK_UINT128 UINT128_NAME VARIABLE DEFINE_NAME) - - if(NOT UINT128_FOUND) - # message("Testing for 128 bit unsigned integer support with - # ${UINT128_NAME}.") - check_type_size("${UINT128_NAME}" uint128_t_${DEFINE_NAME}) - if(HAVE_uint128_t_${DEFINE_NAME}) - if(uint128_t_${DEFINE_NAME} EQUAL 16) - # message("Found: Enabling support for 128 bit integers using - # ${UINT128_NAME}.") - set(UINT128_FOUND 1) - check_128_bit_hash_function(${UINT128_NAME} HAS_UINT128_STD_HASH) - set(${VARIABLE} "${DEFINE_NAME}") - else() - # message("${UINT128_NAME} has incorrect size, can't use.") - endif() - endif() - endif() -endmacro() - -macro(FIND_INT128_TYPES) - - check_int128("long long" INT128_DEF "HAVEint128_as_long_long") - check_int128("int128_t" INT128_DEF "HAVEint128_t") - check_int128("__int128_t" INT128_DEF "HAVE__int128_t") - check_int128("__int128" INT128_DEF "HAVE__int128") - check_int128("int128" INT128_DEF "HAVEint128") - - if(INT128_FOUND) - set(INT128_FLAGS "-D${INT128_DEF}") - if(HAS_INT128_STD_HASH) - set(INT128_FLAGS "${INT128_FLAGS} -DHASH_FOR_INT128_DEFINED") - endif() - endif() - - check_uint128("unsigned long long" UINT128_DEF "HAVEuint128_as_u_long_long") - check_uint128("uint128_t" UINT128_DEF "HAVEuint128_t") - check_uint128("__uint128_t" UINT128_DEF "HAVE__uint128_t") - check_uint128("__uint128" UINT128_DEF "HAVE__uint128") - check_uint128("uint128" UINT128_DEF "HAVEuint128") - check_uint128("unsigned __int128_t" UINT128_DEF "HAVEunsigned__int128_t") - check_uint128("unsigned int128_t" UINT128_DEF "HAVEunsignedint128_t") - check_uint128("unsigned __int128" UINT128_DEF "HAVEunsigned__int128") - check_uint128("unsigned int128" UINT128_DEF "HAVEunsignedint128") - - if(UINT128_FOUND) - set(INT128_FLAGS "${INT128_FLAGS} -D${UINT128_DEF}") - if(HAS_UINT128_STD_HASH) - set(INT128_FLAGS "${INT128_FLAGS} -DHASH_FOR_UINT128_DEFINED") - endif() - endif() - - # MSVC doesn't support 128 bit soft operations, which is weird since they - # support 128 bit numbers... Clang does support, but didn't expose them - # https://reviews.llvm.org/D41813 - if(${MSVC}) - set(UINT128_FOUND False) - endif() -endmacro() diff --git a/build-support/custom-modules/ns3-lock.cmake b/build-support/custom-modules/ns3-lock.cmake index e8a7d7d97..e907a526c 100644 --- a/build-support/custom-modules/ns3-lock.cmake +++ b/build-support/custom-modules/ns3-lock.cmake @@ -85,7 +85,7 @@ function(write_lock) string(APPEND lock_contents "APPNAME = 'ns'\n") string(APPEND lock_contents "BUILD_PROFILE = '${build_profile}'\n") string(APPEND lock_contents "VERSION = '${NS3_VER}' \n") - string(APPEND lock_contents "PYTHON = ['${Python_EXECUTABLE}']\n") + string(APPEND lock_contents "PYTHON = ['${Python3_EXECUTABLE}']\n") mark_as_advanced(VALGRIND) find_program(VALGRIND valgrind) diff --git a/build-support/custom-modules/ns3-module-macros.cmake b/build-support/custom-modules/ns3-module-macros.cmake index af9ebd51b..500205d40 100644 --- a/build-support/custom-modules/ns3-module-macros.cmake +++ b/build-support/custom-modules/ns3-module-macros.cmake @@ -279,7 +279,7 @@ function(build_lib) set(module_api_LP64 ${bindings_output_folder}/modulegen__gcc_LP64.py) set(modulescan_modular_command - ${Python_EXECUTABLE} + ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/bindings/python/ns3modulescan-modular.py ) @@ -305,7 +305,7 @@ function(build_lib) if("${arch}" STREQUAL "gcc_LP64") set(module_to_generate_api ${module_api_LP64}) set(LP64toILP32 - ${Python_EXECUTABLE} + ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/build-support/pybindings-LP64-to-ILP32.py ${module_api_LP64} ${module_api_ILP32} ) @@ -316,7 +316,8 @@ function(build_lib) COMMAND ${modulescan_modular_command} ${CMAKE_OUTPUT_DIRECTORY} ${BLIB_LIBNAME} ${PROJECT_BINARY_DIR}/header_map.json ${module_to_generate_api} - \"${arch_flags} ${modulegen_include_dirs}\" + \"${arch_flags} ${modulegen_include_dirs}\" 2> + ${bindings_output_folder}/apiscan.log COMMAND ${LP64toILP32} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${lib${BLIB_LIBNAME}} @@ -357,7 +358,7 @@ function(build_lib) ) set(modulegen_modular_command GCC_RTTI_ABI_COMPLETE=True NS3_ENABLED_FEATURES="${ENABLED_FEATURES}" - ${Python_EXECUTABLE} + ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/bindings/python/ns3modulegen-modular.py ) execute_process( @@ -394,7 +395,7 @@ function(build_lib) set(bindings-name lib${BLIB_LIBNAME}-bindings) add_library(${bindings-name} SHARED "${python_module_files}") target_include_directories( - ${bindings-name} PUBLIC ${PYTHON_INCLUDE_DIRS} ${bindings_output_folder} + ${bindings-name} PUBLIC ${Python3_INCLUDE_DIRS} ${bindings_output_folder} ) target_compile_options(${bindings-name} PRIVATE -Wno-error) @@ -410,7 +411,7 @@ function(build_lib) ${bindings-name} PUBLIC ${LIB_AS_NEEDED_PRE} ${lib${BLIB_LIBNAME}} "${bindings_to_link}" "${BLIB_LIBRARIES_TO_LINK}" ${LIB_AS_NEEDED_POST} - PRIVATE ${Python_LIBRARIES} + PRIVATE ${Python3_LIBRARIES} ) target_include_directories( ${bindings-name} PRIVATE ${PROJECT_SOURCE_DIR}/src/core/bindings diff --git a/build-support/macros-and-definitions.cmake b/build-support/macros-and-definitions.cmake index fa341cf7e..895478c12 100644 --- a/build-support/macros-and-definitions.cmake +++ b/build-support/macros-and-definitions.cmake @@ -282,25 +282,41 @@ endfunction() macro(process_options) clear_global_cached_variables() - # make sure to default to debug if no build type is specified + # make sure to default to RelWithDebInfo if no build type is specified if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE) + set(CMAKE_BUILD_TYPE "default" CACHE STRING "Choose the type of build." + FORCE + ) + set(NS3_ASSERT ON CACHE BOOL "Enable assert on failure" FORCE) + set(NS3_LOG ON CACHE BOOL "Enable logging to be built" FORCE) + set(NS3_WARNINGS_AS_ERRORS OFF + CACHE BOOL "Treat warnings as errors. Requires NS3_WARNINGS=ON" FORCE + ) endif() # process debug switch Used in build-profile-test-suite string(TOLOWER ${CMAKE_BUILD_TYPE} cmakeBuildType) set(build_profile "${cmakeBuildType}" CACHE INTERNAL "") if(${cmakeBuildType} STREQUAL "debug") + string(REPLACE "-g" "-Og -g" CMAKE_CXX_FLAGS_DEBUG + "${CMAKE_CXX_FLAGS_DEBUG}" + ) + add_definitions(-DNS3_BUILD_PROFILE_DEBUG) + elseif(${cmakeBuildType} STREQUAL "relwithdebinfo" OR ${cmakeBuildType} + STREQUAL "default" + ) + set(cmakeBuildType relwithdebinfo) + set(CMAKE_CXX_FLAGS_DEFAULT ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}) add_definitions(-DNS3_BUILD_PROFILE_DEBUG) - elseif(${cmakeBuildType} STREQUAL "relwithdebinfo") - add_definitions(-DNS3_BUILD_PROFILE_RELEASE) elseif(${cmakeBuildType} STREQUAL "release") - add_definitions(-DNS3_BUILD_PROFILE_OPTIMIZED) if(${NS3_NATIVE_OPTIMIZATIONS}) + add_definitions(-DNS3_BUILD_PROFILE_OPTIMIZED) set(build_profile "optimized" CACHE INTERNAL "") + else() + add_definitions(-DNS3_BUILD_PROFILE_RELEASE) endif() else() - add_definitions(-DNS3_BUILD_PROFILE_OPTIMIZED) + add_definitions(-DNS3_BUILD_PROFILE_RELEASE) endif() # Enable examples if activated via command line (NS3_EXAMPLES) or ns3rc config @@ -656,17 +672,36 @@ macro(process_options) endif() endif() - # cmake-format: off - set(Python_ADDITIONAL_VERSIONS 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11) - # cmake-format: on - find_package(PythonInterp) - set(Python_EXECUTABLE) - set(Python_FOUND FALSE) - if(${PythonInterp_FOUND}) - set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) + set(Python3_LIBRARIES) + set(Python3_EXECUTABLE) + set(Python3_FOUND FALSE) + set(Python3_INCLUDE_DIRS) + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12.0") + find_package(Python3 COMPONENTS Interpreter Development) + else() + # cmake-format: off + set(Python_ADDITIONAL_VERSIONS 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9) + # cmake-format: on + find_package(PythonInterp) find_package(PythonLibs) - if(${PythonLibs_FOUND}) - set(Python_FOUND TRUE) + + # Move deprecated results into the FindPython3 resulting variables + set(Python3_Interpreter_FOUND ${PYTHONINTERP_FOUND}) + set(Python3_Development_FOUND ${PYTHONLIBS_FOUND}) + if(${PYTHONINTERP_FOUND}) + set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE}) + set(Python3_FOUND TRUE) + endif() + if(${PYTHONLIBS_FOUND}) + set(Python3_LIBRARIES ${PYTHON_LIBRARIES}) + set(Python3_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS}) + endif() + endif() + + # Check if both Python interpreter and development libraries were found + if(${Python3_Interpreter_FOUND}) + if(${Python3_Development_FOUND}) + set(Python3_FOUND TRUE) else() message(STATUS "Python: development libraries were not found") endif() @@ -679,7 +714,7 @@ macro(process_options) set(ENABLE_PYTHON_BINDINGS OFF) if(${NS3_PYTHON_BINDINGS}) - if(NOT ${Python_FOUND}) + if(NOT ${Python3_FOUND}) message( STATUS "Bindings: python bindings require Python, but it could not be found" @@ -704,14 +739,16 @@ macro(process_options) set(ENABLE_SCAN_PYTHON_BINDINGS OFF) if(${NS3_SCAN_PYTHON_BINDINGS}) - if(NOT ${Python_FOUND}) + if(NOT ${Python3_FOUND}) message( STATUS "Bindings: scanning python bindings require Python, but it could not be found" ) else() # Check if pybindgen, pygccxml and cxxfilt are installed - check_python_packages("pybindgen;pygccxml;cxxfilt" missing_packages) + check_python_packages( + "pybindgen;pygccxml;cxxfilt;castxml" missing_packages + ) if(missing_packages) message( STATUS @@ -728,7 +765,7 @@ macro(process_options) set(ENABLE_VISUALIZER FALSE) if(${NS3_VISUALIZER}) - if((NOT ${ENABLE_PYTHON_BINDINGS}) OR (NOT ${Python_FOUND})) + if((NOT ${ENABLE_PYTHON_BINDINGS}) OR (NOT ${Python3_FOUND})) message(STATUS "Visualizer requires Python bindings") else() set(ENABLE_VISUALIZER TRUE) @@ -750,7 +787,7 @@ macro(process_options) # produce code coverage output add_custom_target( run_test_py - COMMAND ${Python_EXECUTABLE} test.py --no-build + COMMAND ${Python3_EXECUTABLE} test.py --no-build WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} DEPENDS all-test-targets ) @@ -779,8 +816,12 @@ macro(process_options) if(${NS3_VERBOSE}) set_property(GLOBAL PROPERTY TARGET_MESSAGES TRUE) + set(CMAKE_FIND_DEBUG_MODE TRUE) + set(CMAKE_VERBOSE_MAKEFILE TRUE CACHE INTERNAL "") else() set_property(GLOBAL PROPERTY TARGET_MESSAGES OFF) + unset(CMAKE_FIND_DEBUG_MODE) + unset(CMAKE_VERBOSE_MAKEFILE CACHE) endif() mark_as_advanced(Boost_INCLUDE_DIR) @@ -860,7 +901,7 @@ macro(process_options) add_custom_target( run-introspected-command-line COMMAND ${CMAKE_COMMAND} -E env NS_COMMANDLINE_INTROSPECTION=.. - ${Python_EXECUTABLE} ./test.py --no-build --constrain=example + ${Python3_EXECUTABLE} ./test.py --no-build --constrain=example WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} DEPENDS all-test-targets # all-test-targets only exists if ENABLE_TESTS is # set to ON @@ -957,12 +998,34 @@ macro(process_options) endif() # end of checking for documentation dependencies and creating targets + # Adding this module manually is required by CMake 3.10 + include(CheckCXXSourceCompiles) + # Process core-config If INT128 is not found, fallback to CAIRO if(${NS3_INT64X64} MATCHES "INT128") - include(build-support/3rd-party/FindInt128.cmake) - find_int128_types() - if(UINT128_FOUND) - set(HAVE___UINT128_T TRUE) + check_cxx_source_compiles( + "#include + int main(int argc, char **argv) + { + (void)argc; (void)argv; + if ((uint128_t *) 0) return 0; + if (sizeof (uint128_t)) return 0; + return 1; + }" + HAVE_UINT128_T + ) + check_cxx_source_compiles( + "#include + int main(int argc, char **argv) + { + (void)argc; (void)argv; + if ((__uint128_t *) 0) return 0; + if (sizeof (__uint128_t)) return 0; + return 1; + }" + HAVE___UINT128_T + ) + if(HAVE_UINT128_T OR HAVE___UINT128_T) set(INT64X64_USE_128 TRUE) else() message(STATUS "Int128 was not found. Falling back to Cairo.") @@ -994,7 +1057,8 @@ macro(process_options) set(INT64X64_USE_CAIRO TRUE) endif() - include(CheckIncludeFileCXX) + include(CheckIncludeFileCXX) # Used to check a single header at a time + include(CheckIncludeFiles) # Used to check multiple headers at once include(CheckFunctionExists) # Check for required headers and functions, set flags if they're found or warn @@ -1231,10 +1295,7 @@ endfunction() add_custom_target(copy_all_headers) function(copy_headers_before_building_lib libname outputdir headers visibility) foreach(header ${headers}) - configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/${header} ${outputdir}/${header_name} - COPYONLY - ) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${header} ${outputdir}/ COPYONLY) endforeach() endfunction(copy_headers_before_building_lib) @@ -1550,6 +1611,56 @@ function(parse_ns3rc enabled_modules examples_enabled tests_enabled) endif() endfunction(parse_ns3rc) +function(log_find_searched_paths) + # Parse arguments + set(options) + set(oneValueArgs TARGET_TYPE TARGET_NAME SEARCH_RESULT SEARCH_SYSTEM_PREFIX) + set(multiValueArgs SEARCH_PATHS SEARCH_SUFFIXES) + cmake_parse_arguments( + "LOGFIND" "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} + ) + + # Get searched paths and add cmake_system_prefix_path if not explicitly marked + # not to include it + set(tsearch_paths ${LOGFIND_SEARCH_PATHS}) + if("${LOGFIND_SEARCH_SYSTEM_PREFIX}" STREQUAL "") + list(APPEND tsearch_paths "${CMAKE_SYSTEM_PREFIX_PATH}") + endif() + + set(log_find + "Looking for ${LOGFIND_TARGET_TYPE} ${LOGFIND_TARGET_NAME} in:\n" + ) + # For each search path and suffix combination, print a line + foreach(tsearch_path ${tsearch_paths}) + foreach(suffix ${LOGFIND_SEARCH_SUFFIXES}) + string(APPEND log_find + "\t${tsearch_path}${suffix}/${LOGFIND_TARGET_NAME}\n" + ) + endforeach() + endforeach() + + # Add a final line saying if the file was found and where, or if it was not + # found + if("${${LOGFIND_SEARCH_RESULT}}" STREQUAL "${LOGFIND_SEARCH_RESULT}-NOTFOUND") + string(APPEND log_find + "\n\t${LOGFIND_TARGET_TYPE} ${LOGFIND_TARGET_NAME} was not found\n" + ) + else() + string( + APPEND + log_find + "\n\t${LOGFIND_TARGET_TYPE} ${LOGFIND_TARGET_NAME} was found in ${${LOGFIND_SEARCH_RESULT}}\n" + ) + endif() + + # Replace duplicate path separators + string(REPLACE "//" "/" log_find "${log_find}") + + # Print find debug message similar to the one produced by + # CMAKE_FIND_DEBUG_MODE=true in CMake >= 3.17 + message(STATUS ${log_find}) +endfunction() + function(find_external_library) # Parse arguments set(options QUIET) @@ -1575,6 +1686,18 @@ function(find_external_library) set(library_dirs) set(libraries) + # Paths and suffixes where libraries will be searched on + set(library_search_paths + ${search_paths} + ${CMAKE_OUTPUT_DIRECTORY} # Search for libraries in ns-3-dev/build + ${CMAKE_INSTALL_PREFIX} # Search for libraries in the install directory + # (e.g. /usr/) + $ENV{LD_LIBRARY_PATH} # Search for libraries in LD_LIBRARY_PATH + # directories + $ENV{PATH} # Search for libraries in PATH directories + ) + set(suffixes /build /lib /build/lib / /bin ${path_suffixes}) + # For each of the library names in LIBRARY_NAMES or LIBRARY_NAME foreach(library ${library_names}) # We mark this value is advanced not to pollute the configuration with @@ -1585,17 +1708,9 @@ function(find_external_library) # ${name}_library_internal_${library} find_library( ${name}_library_internal_${library} ${library} - HINTS ${search_paths} - ${CMAKE_OUTPUT_DIRECTORY} # Search for libraries in ns-3-dev/build - ${CMAKE_INSTALL_PREFIX} # Search for libraries in the install - # directory (e.g. /usr/) - ENV - LD_LIBRARY_PATH # Search for libraries in LD_LIBRARY_PATH - # directories - ENV - PATH # Search for libraries in PATH directories - PATH_SUFFIXES /build /lib /build/lib / /bin ${path_suffixes} + HINTS ${library_search_paths} PATH_SUFFIXES ${suffixes} ) + # cmake-format: off # Note: the PATH_SUFFIXES above apply to *ALL* PATHS and HINTS Which # translates to CMake searching on standard library directories # CMAKE_SYSTEM_PREFIX_PATH, user-settable CMAKE_PREFIX_PATH or @@ -1607,21 +1722,45 @@ function(find_external_library) # Searched directories without suffixes # # ${CMAKE_SYSTEM_PREFIX_PATH}[0] = /usr/local/ - # ${CMAKE_SYSTEM_PREFIX_PATH}[1] = /usr ${CMAKE_SYSTEM_PREFIX_PATH}[2] = / - # ${CMAKE_SYSTEM_PREFIX_PATH}[3] = /usr/local ${CMAKE_SYSTEM_PREFIX_PATH}[4] - # = /usr/X11R6 ${CMAKE_SYSTEM_PREFIX_PATH}[5] = /usr/pkg - # ${CMAKE_SYSTEM_PREFIX_PATH}[6] = /opt ${search_paths}[0] ... - # ${search_paths}[n] ${CMAKE_OUTPUT_DIRECTORY} ${CMAKE_INSTALL_PREFIX} - # ${LD_LIBRARY_PATH}[0] ... ${LD_LIBRARY_PATH}[m] ${PATH}[0] ... ${PATH}[m] + # ${CMAKE_SYSTEM_PREFIX_PATH}[1] = /usr + # ${CMAKE_SYSTEM_PREFIX_PATH}[2] = / + # ... + # ${CMAKE_SYSTEM_PREFIX_PATH}[6] = /opt + # ${LD_LIBRARY_PATH}[0] + # ... + # ${LD_LIBRARY_PATH}[m] + # ${PATH}[0] + # ... + # ${PATH}[m] # # Searched directories with suffixes include all of the directories above - # plus all suffixes PATH_SUFFIXES /build /lib /build/lib / /bin - # ${path_suffixes} + # plus all suffixes + # PATH_SUFFIXES /build /lib /build/lib / /bin # ${path_suffixes} # - # /usr/local/build /usr/local/lib /usr/local/build/lib /usr/local/bin - # /usr/local/${path_suffixes}[0] ... /usr/local/${path_suffixes}[k] + # /usr/local/build + # /usr/local/lib + # /usr/local/build/lib + # /usr/local/bin + # ... # - # /usr/build /usr/lib /usr/build/lib ... ${PATH}[m]/${path_suffixes}[k] + # cmake-format: on + # Or enable NS3_VERBOSE to print the searched paths + + # Print tested paths to the searched library and if it was found + if(${NS3_VERBOSE} AND (${CMAKE_VERSION} VERSION_LESS "3.17.0")) + log_find_searched_paths( + TARGET_TYPE + Library + TARGET_NAME + ${library} + SEARCH_RESULT + ${name}_library_internal_${library} + SEARCH_PATHS + ${library_search_paths} + SEARCH_SUFFIXES + ${suffixes} + ) + endif() # After searching the library, the internal variable should have either the # absolute path to the library or the name of the variable appended with @@ -1652,22 +1791,26 @@ function(find_external_library) list(APPEND parent_dirs ${parent_libdir} ${parent_parent_libdir}) endforeach() + # If we already found a library somewhere, limit the search paths for the + # header + if(parent_dirs) + set(header_search_paths ${parent_dirs}) + set(header_skip_system_prefix NO_CMAKE_SYSTEM_PATH) + else() + set(header_search_paths + ${search_paths} ${CMAKE_OUTPUT_DIRECTORY} # Search for headers in + # ns-3-dev/build + ${CMAKE_INSTALL_PREFIX} # Search for headers in the install + ) + endif() + set(not_found_headers) set(include_dirs) foreach(header ${header_names}) # The same way with libraries, we mark the internal variable as advanced not # to pollute ccmake configuration with variables used internally mark_as_advanced(${name}_header_internal_${header}) - - # Here we search for the header file named ${header} and store the result in - # ${name}_header_internal_${header} - find_file( - ${name}_header_internal_${header} ${header} - HINTS ${search_paths} ${parent_dirs} - ${CMAKE_OUTPUT_DIRECTORY} # Search for headers in ns-3-dev/build - ${CMAKE_INSTALL_PREFIX} # Search for headers in the install - # directory (e.g. /usr/) - PATH_SUFFIXES + set(suffixes /build /include /build/include @@ -1677,16 +1820,48 @@ function(find_external_library) / ${path_suffixes} ) + + # cmake-format: off + # Here we search for the header file named ${header} and store the result in + # ${name}_header_internal_${header} + # # The same way we did with libraries, here we search on # CMAKE_SYSTEM_PREFIX_PATH, along with user-settable ${search_paths}, the # parent directories from the libraries, CMAKE_OUTPUT_DIRECTORY and # CMAKE_INSTALL_PREFIX # # And again, for each of them, for every suffix listed /usr/local/build - # /usr/local/include /usr/local/build/include - # /usr/local/build/include/${name} /usr/local/include/${name} - # /usr/local/${name} /usr/local/ /usr/local/${path_suffixes}[0] ... - # /usr/local/${path_suffixes}[k] ... + # /usr/local/include + # /usr/local/build/include + # /usr/local/build/include/${name} + # /usr/local/include/${name} + # ... + # + # cmake-format: on + # Or enable NS3_VERBOSE to get the searched paths printed while configuring + + find_file(${name}_header_internal_${header} ${header} + HINTS ${header_search_paths} # directory (e.g. /usr/) + ${header_skip_system_prefix} PATH_SUFFIXES ${suffixes} + ) + + # Print tested paths to the searched header and if it was found + if(${NS3_VERBOSE} AND (${CMAKE_VERSION} VERSION_LESS "3.17.0")) + log_find_searched_paths( + TARGET_TYPE + Header + TARGET_NAME + ${header} + SEARCH_RESULT + ${name}_header_internal_${header} + SEARCH_PATHS + ${header_search_paths} + SEARCH_SUFFIXES + ${suffixes} + SEARCH_SYSTEM_PREFIX + ${header_skip_system_prefix} + ) + endif() # If the header file was not found, append to the not-found list if("${${name}_header_internal_${header}}" STREQUAL @@ -1766,7 +1941,7 @@ function(check_python_packages packages missing_packages) set(missing) foreach(package ${packages}) execute_process( - COMMAND ${Python_EXECUTABLE} -c "import ${package}" + COMMAND ${Python3_EXECUTABLE} -c "import ${package}" RESULT_VARIABLE return_code OUTPUT_QUIET ERROR_QUIET ) if(NOT (${return_code} EQUAL 0)) diff --git a/doc/manual/source/working-with-cmake.rst b/doc/manual/source/working-with-cmake.rst index d720a075c..4bf5b4b7b 100644 --- a/doc/manual/source/working-with-cmake.rst +++ b/doc/manual/source/working-with-cmake.rst @@ -720,6 +720,15 @@ Here is how it works: set(not_found_libraries) set(library_dirs) set(libraries) + # Paths and suffixes where libraries will be searched on + set(library_search_paths + ${search_paths} + ${CMAKE_OUTPUT_DIRECTORY} # Search for libraries in ns-3-dev/build + ${CMAKE_INSTALL_PREFIX} # Search for libraries in the install directory (e.g. /usr/) + $ENV{LD_LIBRARY_PATH} # Search for libraries in LD_LIBRARY_PATH directories + $ENV{PATH} # Search for libraries in PATH directories + ) + set(suffixes /build /lib /build/lib / /bin ${path_suffixes}) # For each of the library names in LIBRARY_NAMES or LIBRARY_NAME foreach(library ${library_names}) @@ -731,17 +740,10 @@ Here is how it works: # ${name}_library_internal_${library} find_library( ${name}_library_internal_${library} ${library} - HINTS ${search_paths} - ${CMAKE_OUTPUT_DIRECTORY} # Search for libraries in ns-3-dev/build - ${CMAKE_INSTALL_PREFIX} # Search for libraries in the install - # directory (e.g. /usr/) - ENV - LD_LIBRARY_PATH # Search for libraries in LD_LIBRARY_PATH - # directories - ENV - PATH # Search for libraries in PATH directories - PATH_SUFFIXES /build /lib /build/lib / /bin ${path_suffixes} + HINTS ${library_search_paths} + PATH_SUFFIXES ${suffixes} ) + # cmake-format: off # Note: the PATH_SUFFIXES above apply to *ALL* PATHS and HINTS Which # translates to CMake searching on standard library directories # CMAKE_SYSTEM_PREFIX_PATH, user-settable CMAKE_PREFIX_PATH or @@ -753,21 +755,38 @@ Here is how it works: # Searched directories without suffixes # # ${CMAKE_SYSTEM_PREFIX_PATH}[0] = /usr/local/ - # ${CMAKE_SYSTEM_PREFIX_PATH}[1] = /usr ${CMAKE_SYSTEM_PREFIX_PATH}[2] = / - # ${CMAKE_SYSTEM_PREFIX_PATH}[3] = /usr/local ${CMAKE_SYSTEM_PREFIX_PATH}[4] - # = /usr/X11R6 ${CMAKE_SYSTEM_PREFIX_PATH}[5] = /usr/pkg - # ${CMAKE_SYSTEM_PREFIX_PATH}[6] = /opt ${search_paths}[0] ... - # ${search_paths}[n] ${CMAKE_OUTPUT_DIRECTORY} ${CMAKE_INSTALL_PREFIX} - # ${LD_LIBRARY_PATH}[0] ... ${LD_LIBRARY_PATH}[m] ${PATH}[0] ... ${PATH}[m] + # ${CMAKE_SYSTEM_PREFIX_PATH}[1] = /usr + # ${CMAKE_SYSTEM_PREFIX_PATH}[2] = / + # ... + # ${CMAKE_SYSTEM_PREFIX_PATH}[6] = /opt + # ${LD_LIBRARY_PATH}[0] + # ... + # ${LD_LIBRARY_PATH}[m] + # ... # # Searched directories with suffixes include all of the directories above - # plus all suffixes PATH_SUFFIXES /build /lib /build/lib / /bin - # ${path_suffixes} + # plus all suffixes + # PATH_SUFFIXES /build /lib /build/lib / /bin # ${path_suffixes} # - # /usr/local/build /usr/local/lib /usr/local/build/lib /usr/local/bin - # /usr/local/${path_suffixes}[0] ... /usr/local/${path_suffixes}[k] + # /usr/local/build + # /usr/local/lib + # /usr/local/build/lib + # /usr/local/bin + # ... # - # /usr/build /usr/lib /usr/build/lib ... ${PATH}[m]/${path_suffixes}[k] + # cmake-format: on + # Or enable NS3_VERBOSE to print the searched paths + + # Print tested paths to the searched library and if it was found + if(${NS3_VERBOSE}) + log_find_searched_paths( + TARGET_TYPE Library + TARGET_NAME ${library} + SEARCH_RESULT ${name}_library_internal_${library} + SEARCH_PATHS ${library_search_paths} + SEARCH_SUFFIXES ${suffixes} + ) + endif() # After searching the library, the internal variable should have either the # absolute path to the library or the name of the variable appended with @@ -798,41 +817,71 @@ Here is how it works: list(APPEND parent_dirs ${parent_libdir} ${parent_parent_libdir}) endforeach() + # If we already found a library somewhere, limit the search paths for the header + if(parent_dirs) + set(header_search_paths ${parent_dirs}) + set(header_skip_system_prefix NO_CMAKE_SYSTEM_PATH) + else() + set(header_search_paths + ${search_paths} + ${CMAKE_OUTPUT_DIRECTORY} # Search for headers in ns-3-dev/build + ${CMAKE_INSTALL_PREFIX} # Search for headers in the install + ) + endif() + set(not_found_headers) set(include_dirs) foreach(header ${header_names}) # The same way with libraries, we mark the internal variable as advanced not # to pollute ccmake configuration with variables used internally mark_as_advanced(${name}_header_internal_${header}) - + set(suffixes + /build + /include + /build/include + /build/include/${name} + /include/${name} + /${name} + / + ${path_suffixes} + ) + # cmake-format: off # Here we search for the header file named ${header} and store the result in # ${name}_header_internal_${header} - find_file( - ${name}_header_internal_${header} ${header} - HINTS ${search_paths} ${parent_dirs} - ${CMAKE_OUTPUT_DIRECTORY} # Search for headers in ns-3-dev/build - ${CMAKE_INSTALL_PREFIX} # Search for headers in the install - # directory (e.g. /usr/) - PATH_SUFFIXES - /build - /include - /build/include - /build/include/${name} - /include/${name} - /${name} - / - ${path_suffixes} - ) + # # The same way we did with libraries, here we search on # CMAKE_SYSTEM_PREFIX_PATH, along with user-settable ${search_paths}, the # parent directories from the libraries, CMAKE_OUTPUT_DIRECTORY and # CMAKE_INSTALL_PREFIX # # And again, for each of them, for every suffix listed /usr/local/build - # /usr/local/include /usr/local/build/include - # /usr/local/build/include/${name} /usr/local/include/${name} - # /usr/local/${name} /usr/local/ /usr/local/${path_suffixes}[0] ... - # /usr/local/${path_suffixes}[k] ... + # /usr/local/include + # /usr/local/build/include + # /usr/local/build/include/${name} + # /usr/local/include/${name} + # ... + # + # cmake-format: on + # Or enable NS3_VERBOSE to get the searched paths printed while configuring + + find_file( + ${name}_header_internal_${header} ${header} + HINTS ${header_search_paths} # directory (e.g. /usr/) + ${header_skip_system_prefix} + PATH_SUFFIXES ${suffixes} + ) + + # Print tested paths to the searched header and if it was found + if(${NS3_VERBOSE}) + log_find_searched_paths( + TARGET_TYPE Header + TARGET_NAME ${header} + SEARCH_RESULT ${name}_header_internal_${header} + SEARCH_PATHS ${header_search_paths} + SEARCH_SUFFIXES ${suffixes} + SEARCH_SYSTEM_PREFIX ${header_skip_system_prefix} + ) + endif() # If the header file was not found, append to the not-found list if("${${name}_header_internal_${header}}" STREQUAL @@ -879,6 +928,20 @@ Here is how it works: endif() endfunction() +Debugging why a header or a library cannot be found is fairly tricky. +For ``find_external_library`` users, enabling the ``NS3_VERBOSE`` switch +will enable the logging of search path directories for both headers and +libraries. + +.. _CMAKE_FIND_DEBUG_MODE: https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_DEBUG_MODE.html + +Note: The logging provided by find_external_library is an alternative to +CMake's own ``CMAKE_FIND_DEBUG_MODE=true`` introduced in CMake 3.17, +which gets used by *ALL* ``find_file``, ``find_library``, ``find_header``, +``find_package`` and ``find_path`` calls throughout CMake and its modules. +If you are using a recent version of CMake, it is recommended to use +`CMAKE_FIND_DEBUG_MODE`_ instead. + A commented version of the Openflow module ``CMakeLists.txt`` has an example of ``find_external_library`` usage. diff --git a/ns3 b/ns3 index c82aa12ee..78fbaa814 100755 --- a/ns3 +++ b/ns3 @@ -14,20 +14,20 @@ out_dir = os.sep.join([ns3_path, "build"]) lock_file = os.sep.join([ns3_path, ".lock-ns3_%s_build" % sys.platform]) print_buffer = "" -verbose = True +run_verbose = True # Prints everything in the print_buffer on exit def exit_handler(dry_run): - global print_buffer, verbose - # We should not print anything in run except if dry_run or verbose - if not dry_run and not verbose: + global print_buffer, run_verbose + # We should not print anything in run except if dry_run or run_verbose + if not dry_run and not run_verbose: return if print_buffer == "": return if dry_run: print("The following commands would be executed:") - elif verbose: + elif run_verbose: print("Finished executing the following commands:") print(print_buffer[1:]) @@ -56,7 +56,7 @@ def on_off_condition(args, cmake_flag, option_name): def parse_args(argv): - parser = argparse.ArgumentParser(description="ns-3 wrapper for the CMake build system") + parser = argparse.ArgumentParser(description="ns-3 wrapper for the CMake build system", add_help=False) sub_parser = parser.add_subparsers() parser_build = sub_parser.add_parser('build', @@ -68,6 +68,12 @@ def parse_args(argv): parser_build.add_argument('--dry-run', help="Do not execute the commands", action="store_true", default=None, dest="build_dry_run") + parser_build.add_argument('-v', '--verbose', + help="Print verbose build commands", + action="store_true", default=None, dest="build_verbose") + parser_build.add_argument('--quiet', + help="Don't print task lines, i.e. messages saying which tasks are being executed.", + action="store_true", default=None, dest="build_quiet") parser_configure = sub_parser.add_parser('configure', help='Try "./ns3 configure --help" for more configuration options') @@ -76,7 +82,7 @@ def parse_args(argv): parser_configure.add_argument('-d', '--build-profile', help='Build profile', dest='build_profile', - choices=["debug", "release", "optimized"], + choices=["debug", "default", "release", "optimized"], action="store", type=str, default=None) parser_configure.add_argument('-G', @@ -162,6 +168,9 @@ def parse_args(argv): parser_configure.add_argument('--dry-run', help="Do not execute the commands", action="store_true", default=None, dest="configure_dry_run") + parser_configure.add_argument('--quiet', + help="Don't print task lines, i.e. messages saying which tasks are being executed.", + action="store_true", default=None, dest="configure_quiet") parser_clean = sub_parser.add_parser('clean', help='Removes files created by ns3') parser_clean.add_argument('clean', action="store_true", default=False) @@ -214,6 +223,9 @@ def parse_args(argv): help='Print which commands were executed', dest='run_verbose', action='store_true', default=False) + parser_run.add_argument('--quiet', + help="Don't print task lines, i.e. messages saying which tasks are being executed.", + action="store_true", default=None, dest="run_quiet") parser_shell = sub_parser.add_parser('shell', help='Try "./ns3 shell --help" for more runtime options') @@ -228,6 +240,9 @@ def parse_args(argv): choices=["manual", "models", "tutorial", "contributing", "sphinx", "doxygen-no-build", "doxygen", "all"], action="store", type=str, default=None) + parser_docs.add_argument('--quiet', + help="Don't print task lines, i.e. messages saying which tasks are being executed.", + action="store_true", default=None, dest="docs_quiet") parser.add_argument('-j', '--jobs', help='Set number of parallel jobs', @@ -235,23 +250,26 @@ def parse_args(argv): parser.add_argument('--dry-run', help="Do not execute the commands", action="store_true", default=None, dest="dry_run") - parser.add_argument('--check-config', - help='Print the current configuration.', - action="store_true", default=None) parser.add_argument('--quiet', help="Don't print task lines, i.e. messages saying which tasks are being executed.", - action="store_true", default=None) + action="store_true", default=None, dest="quiet") + parser.add_argument('--help', + help="Print a summary of available commands", + action="store_true", default=None, dest="help") - parser.add_argument('--check', - help='DEPRECATED (run ./test.py)', - action='store_true', default=None) - parser.add_argument('--check-profile', - help='Print out current build profile', - action='store_true', default=None) - parser.add_argument('--check-version', - help='Print the current build version', - action='store_true', default=None) + parser_show = sub_parser.add_parser('show', + help='Try "./ns3 show --help" for more runtime options') + parser_show.add_argument('show', + help='Print build profile type, ns-3 version or current configuration', + choices=["profile", "version", "config"], + action="store", type=str, default=None) + parser_show.add_argument('--dry-run', + help="Do not execute the commands", + action="store_true", default=None, dest="show_dry_run") + parser_show.add_argument('--quiet', + help="Don't print task lines, i.e. messages saying which tasks are being executed.", + action="store_true", default=None, dest="show_quiet") # parser.add_argument('--docset', # help=( @@ -263,13 +281,37 @@ def parse_args(argv): # Parse known arguments and separate from unknown arguments args, unknown_args = parser.parse_known_args(argv) - # Merge dry_runs - dry_run_args = [(args.__getattribute__(name) if name in args else None) for name in - ["build_dry_run", "clean_dry_run", "configure_dry_run", "dry_run", "run_dry_run"]] - args.dry_run = dry_run_args.count(True) > 0 + if args.help: + print(parser.description) + print("") + print(parser.format_usage()) + + # retrieve subparsers from parser + subparsers_actions = [ + action for action in parser._actions + if isinstance(action, argparse._SubParsersAction)] + # there will probably only be one subparser_action, + # but better safe than sorry + for subparsers_action in subparsers_actions: + # get all subparsers and print help + for choice, subparser in subparsers_action.choices.items(): + #print("Subparser '{}'".format(choice)) + subcommand = subparser.format_usage()[:-1].replace("usage: ", " or: ") + if len(subcommand) > 1: + print(subcommand) + + print(parser.format_help().replace(parser.description, "").replace(parser.format_usage(), "")) + exit(0) + + # Merge attributes + attributes_to_merge = ["dry_run", "verbose", "quiet"] + filtered_attributes = list(filter(lambda x: x if ("disable" not in x and "enable" not in x) else None, args.__dir__())) + for attribute in attributes_to_merge: + merging_attributes = list(map(lambda x: args.__getattribute__(x) if attribute in x else None, filtered_attributes)) + setattr(args, attribute, merging_attributes.count(True) > 0) # If some positional options are not in args, set them to false. - for option in ["clean", "configure", "docs", "install", "run", "shell", "uninstall"]: + for option in ["clean", "configure", "docs", "install", "run", "shell", "uninstall", "show"]: if option not in args: setattr(args, option, False) @@ -445,7 +487,7 @@ def configure_cmake(cmake, args, current_cmake_cache_folder, current_cmake_gener # Set default build type to default if a previous cache doesn't exist if args.build_profile is None: - args.build_profile = "debug" + args.build_profile = "default" # Set generator if a previous cache doesn't exist if args.G is None: @@ -458,13 +500,15 @@ 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", "release", "optimized"]: + if args.build_profile not in ["debug", "default", "release", "optimized"]: raise Exception("Unknown build type") else: if args.build_profile == "debug": - cmake_args.append("-DCMAKE_BUILD_TYPE=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": + cmake_args.extend("-DCMAKE_BUILD_TYPE=default -DNS3_ASSERT=ON -DNS3_LOG=ON -DNS3_WARNINGS_AS_ERRORS=OFF".split()) else: - cmake_args.append("-DCMAKE_BUILD_TYPE=release") + cmake_args.extend("-DCMAKE_BUILD_TYPE=release -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"))) options = (("ASSERT", "asserts"), @@ -652,7 +696,7 @@ def cmake_check_version(): return cmake, version -def cmake_build(current_cmake_cache_folder, output, jobs, target=None, dry_run=False): +def cmake_build(current_cmake_cache_folder, output, jobs, target=None, dry_run=False, build_verbose=False): _, version = cmake_check_version() # Older CMake versions don't accept the number of jobs directly @@ -673,6 +717,11 @@ def cmake_build(current_cmake_cache_folder, output, jobs, target=None, dry_run=F else: kwargs = {"stdout": output} + proc_env = os.environ.copy() + if build_verbose: + proc_env.update({"VERBOSE": "1"}) + kwargs["env"] = proc_env + ret = subprocess.run(cmake_build_command.split(), cwd=current_cmake_cache_folder, **kwargs @@ -815,12 +864,13 @@ def build_step(args, ns3_version, build_profile, output): - # There are two scenarios where we build everything: ./ns3 build and ./ns3 --check - if args.check or ("build" in args and len(args.build) == 0): + # There is one scenarios where we build everything: ./ns3 build + if "build" in args and len(args.build) == 0: cmake_build(current_cmake_cache_folder, jobs=args.jobs, output=output, - dry_run=args.dry_run + dry_run=args.dry_run, + build_verbose=args.verbose ) # If we are building specific targets, we build them one by one @@ -860,7 +910,8 @@ def build_step(args, jobs=args.jobs, target=target, output=output, - dry_run=args.dry_run) + dry_run=args.dry_run, + build_verbose=args.verbose) # The remaining case is when we want to build something to run if build_and_run: @@ -868,7 +919,8 @@ def build_step(args, jobs=args.jobs, target=get_target_to_build(target_to_run, ns3_version, build_profile), output=output, - dry_run=args.dry_run + dry_run=args.dry_run, + build_verbose=args.verbose ) @@ -894,11 +946,7 @@ def run_step(args, target_to_run, target_args): use_shell = False target_args += args.program_args - # running test.py/check? - if args.check: - target_to_run = os.sep.join([ns3_path, "test.py"]) - target_args = ["--no-build", "--jobs=%d" % args.jobs] - elif args.shell: + if args.shell: target_to_run = "bash" use_shell = True else: @@ -941,7 +989,7 @@ def run_step(args, target_to_run, target_args): program_arguments = [*debugging_software, target_to_run, *target_args] - if verbose or args.dry_run: + if run_verbose or args.dry_run: exported_variables = "export " for (variable, value) in custom_env.items(): if variable == "PATH": @@ -1045,7 +1093,7 @@ def refuse_run_as_root(): def main(): - global out_dir, verbose + global out_dir, run_verbose # Refuse to run with sudo refuse_run_as_root() @@ -1090,24 +1138,24 @@ def main(): 'Try "./ns3 docs doxygen-no-build" or enable examples and tests.') exit(1) - if args.check_profile: + if args.show == "profile": if build_profile: print("Build profile: %s" % build_profile) else: project_not_configured() - if args.check_version: + if args.show == "version": args.build = ["check-version"] # Check if running something or reconfiguring ns-3 run_only = False build_and_run = False if args.run: - # When running, default to not verbose - verbose = args.run_verbose + # When running, default to not run_verbose + run_verbose = args.run_verbose - # If not verbose, silence the rest of the script - if not verbose: + # If not run_verbose, silence the rest of the script + if not run_verbose: output = subprocess.DEVNULL # Check whether we are only running or we need to build first @@ -1118,7 +1166,7 @@ def main(): target_to_run = None target_args = [] current_cmake_cache_folder = None - if not args.check and (run_only or build_and_run): + if run_only or build_and_run: target_to_run = args.run if len(target_to_run) > 0: # While testing a weird case appeared where the target to run is between quotes, @@ -1134,7 +1182,7 @@ def main(): # Get current CMake cache folder and CMake generator (used when reconfiguring) current_cmake_cache_folder, current_cmake_generator = search_cmake_cache(build_profile) - if args.check_config: + if args.show == "config": check_config(current_cmake_cache_folder) # We end things earlier if only checking the current project configuration return @@ -1217,7 +1265,7 @@ def main(): target_path = os.sep.join(target_path) return target_path - if not args.check and not args.shell and target_to_run and ".py" not in target_to_run: + if not args.shell and target_to_run and ".py" not in target_to_run: target_to_run = remove_overlapping_path(out_dir, target_to_run) # Waf doesn't add version prefix and build type suffix to the scratches, so we remove them @@ -1237,7 +1285,7 @@ def main(): sudo_step(args, target_to_run, set(ns3_programs.values()[0]) if enable_sudo else set()) # Finally, we try to run it - if args.check or args.shell or run_only or build_and_run: + if args.shell or run_only or build_and_run: run_step(args, target_to_run, target_args) return diff --git a/src/brite/CMakeLists.txt b/src/brite/CMakeLists.txt index 5b6a2219b..6ae2b3364 100644 --- a/src/brite/CMakeLists.txt +++ b/src/brite/CMakeLists.txt @@ -19,7 +19,7 @@ find_external_library( if(NOT ${brite_FOUND} ) - message(STATUS "Brite was not found") + message(STATUS "Skipping src/brite") return() endif() diff --git a/src/click/CMakeLists.txt b/src/click/CMakeLists.txt index d050a2f0b..7346ac4be 100644 --- a/src/click/CMakeLists.txt +++ b/src/click/CMakeLists.txt @@ -20,7 +20,7 @@ find_external_library( if(NOT ${click_FOUND} ) - message(STATUS "Click was not found") + message(STATUS "Skipping src/click") return() endif() diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 3db45cecc..f74892f25 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -15,17 +15,40 @@ if(${GSL_FOUND}) endif() # Check for dependencies and add sources accordingly -check_include_file_cxx( - "boost/units/quantity.hpp" - HAVE_BOOST_UNITS_QUANTITY -) -check_include_file_cxx( - "boost/units/systems/si.hpp" - HAVE_BOOST_UNITS_SI -) -if(${HAVE_BOOST_UNITS_QUANTITY} - AND ${HAVE_BOOST_UNITS_SI} +if(${CMAKE_VERSION} + VERSION_LESS + "3.11.0" ) + check_include_file_cxx( + boost/units/quantity.hpp + HAVE_BOOST_UNITS_QUANTITY + ) + check_include_file_cxx( + boost/units/systems/si.hpp + HAVE_BOOST_UNITS_SI + ) + if(${HAVE_BOOST_UNITS_QUANTITY} + AND ${HAVE_BOOST_UNITS_SI} + ) + set(HAVE_BOOST_UNITS + TRUE + ) + else() + set(HAVE_BOOST_UNITS + FALSE + ) + endif() +else() + # Fast path for CMake >= 3.11 + check_include_files( + "boost/units/quantity.hpp;boost/units/systems/si.hpp" + HAVE_BOOST_UNITS + LANGUAGE + CXX + ) +endif() + +if(${HAVE_BOOST_UNITS}) add_definitions( -DHAVE_BOOST -DHAVE_BOOST_UNITS diff --git a/src/openflow/CMakeLists.txt b/src/openflow/CMakeLists.txt index ebbc8b217..71a3546eb 100644 --- a/src/openflow/CMakeLists.txt +++ b/src/openflow/CMakeLists.txt @@ -19,7 +19,7 @@ find_external_library( if(NOT ${openflow_FOUND} ) - message(STATUS "Openflow was not found") + message(STATUS "Skipping src/openflow") return() endif() diff --git a/src/visualizer/CMakeLists.txt b/src/visualizer/CMakeLists.txt index e3e3f8b6e..4237021da 100644 --- a/src/visualizer/CMakeLists.txt +++ b/src/visualizer/CMakeLists.txt @@ -1,4 +1,4 @@ -include_directories(${PYTHON_INCLUDE_DIRS}) +include_directories(${Python3_INCLUDE_DIRS}) build_lib( LIBNAME visualizer @@ -6,7 +6,7 @@ build_lib( model/visual-simulator-impl.cc HEADER_FILES model/pyviz.h LIBRARIES_TO_LINK - ${PYTHON_LIBRARIES} + ${Python3_LIBRARIES} ${libcore} ${libinternet} ${libwifi} diff --git a/utils/tests/test-ns3.py b/utils/tests/test-ns3.py index 15b082173..32910b9d8 100644 --- a/utils/tests/test-ns3.py +++ b/utils/tests/test-ns3.py @@ -313,28 +313,28 @@ class NS3CommonSettingsTestCase(unittest.TestCase): def test_03_CheckConfig(self): """! - Test only passing --check-config argument to ns3 + Test only passing 'show config' argument to ns3 @return None """ - return_code, stdout, stderr = run_ns3("--check-config") + return_code, stdout, stderr = run_ns3("show config") self.assertEqual(return_code, 1) self.assertIn("You need to configure ns-3 first: try ./ns3 configure", stdout) def test_04_CheckProfile(self): """! - Test only passing --check-profile argument to ns3 + Test only passing 'show profile' argument to ns3 @return None """ - return_code, stdout, stderr = run_ns3("--check-profile") + return_code, stdout, stderr = run_ns3("show profile") self.assertEqual(return_code, 1) self.assertIn("You need to configure ns-3 first: try ./ns3 configure", stdout) def test_05_CheckVersion(self): """! - Test only passing --check-version argument to ns3 + Test only passing 'show version' argument to ns3 @return None """ - return_code, stdout, stderr = run_ns3("--check-version") + return_code, stdout, stderr = run_ns3("show version") self.assertEqual(return_code, 1) self.assertIn("You need to configure ns-3 first: try ./ns3 configure", stdout) @@ -773,31 +773,31 @@ class NS3ConfigureTestCase(NS3BaseTestCase): def test_10_CheckConfig(self): """! - Test passing --check-config argument to ns3 to get the configuration table + Test passing 'show config' argument to ns3 to get the configuration table @return None """ - return_code, stdout, stderr = run_ns3("--check-config") + return_code, stdout, stderr = run_ns3("show config") self.assertEqual(return_code, 0) self.assertIn("Summary of optional NS-3 features", stdout) def test_11_CheckProfile(self): """! - Test passing --check-profile argument to ns3 to get the build profile + Test passing 'show profile' argument to ns3 to get the build profile @return None """ - return_code, stdout, stderr = run_ns3("--check-profile") + return_code, stdout, stderr = run_ns3("show profile") self.assertEqual(return_code, 0) - self.assertIn("Build profile: debug", stdout) + self.assertIn("Build profile: default", stdout) def test_12_CheckVersion(self): """! - Test passing --check-version argument to ns3 to get the build version + Test passing 'show version' argument to ns3 to get the build version @return None """ return_code, _, _ = run_ns3("configure -G \"Unix Makefiles\" --enable-build-version") self.assertEqual(return_code, 0) - return_code, stdout, stderr = run_ns3("--check-version") + return_code, stdout, stderr = run_ns3("show version") self.assertEqual(return_code, 0) self.assertIn("ns-3 version:", stdout) @@ -1657,15 +1657,7 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase): self.assertIn(cmake_build_target_command(target="doxygen"), stdout) self.assertIn("Built target doxygen", stdout) - def test_14_Check(self): - """! - Test if ns3 --check is working as expected - @return None - """ - return_code, stdout, stderr = run_ns3("--check") - self.assertEqual(return_code, 0) - - def test_15_EnableSudo(self): + def test_14_EnableSudo(self): """! Try to set ownership of scratch-simulator from current user to root, and change execution permissions @@ -1742,7 +1734,7 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase): self.assertEqual(fstat.st_uid, 0) # check the file was correctly chown'ed by root self.assertEqual(fstat.st_mode & stat.S_ISUID, stat.S_ISUID) # check if normal users can run as sudo - def test_16_CommandTemplate(self): + def test_15_CommandTemplate(self): """! Check if command template is working @return None @@ -1768,7 +1760,7 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase): self.assertIn("sample-simulator --PrintVersion", stdout4) self.assertIn("sample-simulator --PrintVersion", stdout5) - def test_17_ForwardArgumentsToRunTargets(self): + def test_16_ForwardArgumentsToRunTargets(self): """! Check if all flavors of different argument passing to executable targets are working @@ -1825,7 +1817,7 @@ class NS3ExpectedUseTestCase(NS3BaseTestCase): self.assertIn("To forward configuration or runtime options, put them after '--'", stderr0) self.assertIn("To forward configuration or runtime options, put them after '--'", stderr1) - def test_18_RunNoBuildLldb(self): + def test_17_RunNoBuildLldb(self): """! Test if scratch simulator is executed through lldb @return None