build: refactoring CMake and ns3

Includes:
- summarize ns3 commands on top-level --help
- add --quiet as a post-positional argument
- refactor verbose variable names
- aggregate ./ns3 --check-config|profile|version into ./ns3 show config|profile|version
- remove ns3 --check deprecated option
- set VERBOSE environment variable when building/running with -v/--verbose
  https://gitlab.com/nsnam/ns-3-dev/-/issues/590#note_870520212
- enable verbose Makefiles when NS3_VERBOSE is enabled
  https://gitlab.com/nsnam/ns-3-dev/-/issues/590
- introduce default build profile and refactor others
  https://gitlab.com/nsnam/ns-3-dev/-/issues/591
- use "-Og" in "CMAKE_BUILD_TYPE=Debug"/"ns3 -d debug"
- add back FindPython3 and fallback to FindPythonInterp if needed
- redirect pybindgen apiscan output to apiscan.log
- enable CMAKE_FIND_DEBUG_MODE with NS3_VERBOSE and CMake >= 3.17
- add search path logging to find_external_library
  Requires NS3_VERBOSE=ON. This is an anternative to CMAKE_FIND_DEBUG_MODE=true available in CMake >= 3.17
- remove C support
- reduce Int128 checks
- fuse Boost Units Quantity and SI header checks
- replace not found messages with skipping
This commit is contained in:
Gabriel Ferreira
2022-03-02 11:51:53 -03:00
parent f728b1f8d0
commit fbebb61a6f
13 changed files with 511 additions and 361 deletions

View File

@@ -19,7 +19,7 @@ endif()
# ##############################################################################
# Project name #
# ##############################################################################
project(NS3 CXX C)
project(NS3 CXX)
file(STRINGS VERSION NS3_VER)

View File

@@ -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 <functional>
#include <cstdint>
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()

View File

@@ -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)

View File

@@ -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

View File

@@ -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()
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 3.10 3.11)
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)
set(Python_EXECUTABLE)
set(Python_FOUND FALSE)
if(${PythonInterp_FOUND})
set(Python_EXECUTABLE ${PYTHON_EXECUTABLE})
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 <stdint.h>
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 <stdint.h>
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))

View File

@@ -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,22 +817,25 @@ 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})
# 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
@@ -823,16 +845,43 @@ Here is how it works:
/
${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})
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.

152
ns3
View File

@@ -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

View File

@@ -19,7 +19,7 @@ find_external_library(
if(NOT
${brite_FOUND}
)
message(STATUS "Brite was not found")
message(STATUS "Skipping src/brite")
return()
endif()

View File

@@ -20,7 +20,7 @@ find_external_library(
if(NOT
${click_FOUND}
)
message(STATUS "Click was not found")
message(STATUS "Skipping src/click")
return()
endif()

View File

@@ -15,17 +15,40 @@ if(${GSL_FOUND})
endif()
# Check for dependencies and add sources accordingly
if(${CMAKE_VERSION}
VERSION_LESS
"3.11.0"
)
check_include_file_cxx(
"boost/units/quantity.hpp"
boost/units/quantity.hpp
HAVE_BOOST_UNITS_QUANTITY
)
check_include_file_cxx(
"boost/units/systems/si.hpp"
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

View File

@@ -19,7 +19,7 @@ find_external_library(
if(NOT
${openflow_FOUND}
)
message(STATUS "Openflow was not found")
message(STATUS "Skipping src/openflow")
return()
endif()

View File

@@ -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}

View File

@@ -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