build: ns3 and CMake fixes
- fix scratch shortcut transformation to build target and binary
- scan scratch files for a main function to use them as the target name
- fix CMake generator parsing
- update the -- separator message
- use -- separator to forward CMake flags from ns3
- add --vis option to ns3
- embedded version fixes
Fix NS3_VERSION_PATCH and NS3_VERSION_RELEASE_CANDIDATE default values.
Add check-version target to CMake.
Add --enable-build-version to ns3.
Add --check-profile and --check-version options to ns3.
- process each scratch subdirectory as a single target
- forward ns3 arguments after -- separator to the program to run
- fix escape sequence in command-template help string
- handle modules with very long names
This commit is contained in:
@@ -85,6 +85,11 @@ macro(
|
||||
set(config_headers ${CMAKE_HEADER_OUTPUT_DIRECTORY}/config-store-config.h
|
||||
${CMAKE_HEADER_OUTPUT_DIRECTORY}/core-config.h
|
||||
)
|
||||
if(${NS3_ENABLE_BUILD_VERSION})
|
||||
list(APPEND config_headers
|
||||
${CMAKE_HEADER_OUTPUT_DIRECTORY}/version-defines.h
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
set_target_properties(
|
||||
${lib${libname}}
|
||||
|
||||
@@ -64,3 +64,86 @@ function(check_ns3_closest_tags CLOSEST_TAG VERSION_TAG_DISTANCE
|
||||
set(${VERSION_DIRTY_FLAG} 1 PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(configure_embedded_version)
|
||||
find_program(GIT git)
|
||||
if(${NS3_ENABLE_BUILD_VERSION} AND (NOT GIT))
|
||||
message(FATAL_ERROR "Embedding build version into libraries require Git.")
|
||||
endif()
|
||||
|
||||
# Check version target will not be created
|
||||
if(NOT GIT)
|
||||
message(
|
||||
STATUS "Git was not found. Version related targets won't be enabled"
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
|
||||
check_git_repo_has_ns3_tags(HAS_NS3_TAGS NS3_VERSION_TAG)
|
||||
|
||||
if(NOT ${HAS_NS3_TAGS})
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"This repository doesn't contain ns-3 git tags to bake into the libraries."
|
||||
)
|
||||
endif()
|
||||
|
||||
check_ns3_closest_tags(
|
||||
NS3_VERSION_CLOSEST_TAG NS3_VERSION_TAG_DISTANCE NS3_VERSION_COMMIT_HASH
|
||||
NS3_VERSION_DIRTY_FLAG
|
||||
)
|
||||
set(DIRTY)
|
||||
if(${NS3_VERSION_DIRTY_FLAG})
|
||||
set(DIRTY "-dirty")
|
||||
endif()
|
||||
|
||||
set(version
|
||||
${NS3_VERSION_TAG}+${NS3_VERSION_TAG_DISTANCE}@${NS3_VERSION_COMMIT_HASH}${DIRTY}-${build_profile}
|
||||
)
|
||||
add_custom_target(check-version COMMAND echo ns-3 version: ${version})
|
||||
|
||||
# Split commit tag (ns-3.<minor>[.patch][-RC<digit>]) into
|
||||
# (ns;3.<minor>[.patch];[-RC<digit>]):
|
||||
string(REPLACE "-" ";" NS3_VER_LIST ${NS3_VERSION_TAG})
|
||||
list(LENGTH NS3_VER_LIST NS3_VER_LIST_LEN)
|
||||
|
||||
# Get last version tag fragment (RC<digit>)
|
||||
set(RELEASE_CANDIDATE " ")
|
||||
if(${NS3_VER_LIST_LEN} GREATER 2)
|
||||
list(GET NS3_VER_LIST 2 RELEASE_CANDIDATE)
|
||||
endif()
|
||||
|
||||
# Get 3.<minor>[.patch]
|
||||
list(GET NS3_VER_LIST 1 VERSION_STRING)
|
||||
# Split into a list 3;<minor>[;patch]
|
||||
string(REPLACE "." ";" VERSION_LIST ${VERSION_STRING})
|
||||
list(LENGTH VERSION_LIST VER_LIST_LEN)
|
||||
|
||||
list(GET VERSION_LIST 0 NS3_VERSION_MAJOR)
|
||||
if(${VER_LIST_LEN} GREATER 1)
|
||||
list(GET VERSION_LIST 1 NS3_VERSION_MINOR)
|
||||
if(${VER_LIST_LEN} GREATER 2)
|
||||
list(GET VERSION_LIST 2 NS3_VERSION_PATCH)
|
||||
else()
|
||||
set(NS3_VERSION_PATCH "00")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Transform list with 1 entry into strings
|
||||
set(NS3_VERSION_MAJOR "${NS3_VERSION_MAJOR}")
|
||||
set(NS3_VERSION_MINOR "${NS3_VERSION_MINOR}")
|
||||
set(NS3_VERSION_PATCH "${NS3_VERSION_PATCH}")
|
||||
set(NS3_VERSION_TAG "${NS3_VERSION_TAG}")
|
||||
set(NS3_VERSION_RELEASE_CANDIDATE "${RELEASE_CANDIDATE}")
|
||||
set(NS3_VERSION_BUILD_PROFILE ${cmakeBuildType})
|
||||
|
||||
# Enable embedding build version
|
||||
if(${NS3_ENABLE_BUILD_VERSION})
|
||||
add_definitions(-DENABLE_BUILD_VERSION=1)
|
||||
configure_file(
|
||||
buildsupport/version-defines-template.h
|
||||
${CMAKE_HEADER_OUTPUT_DIRECTORY}/version-defines.h
|
||||
)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
@@ -74,10 +74,17 @@ function(print_formatted_table_with_modules table_name modules output)
|
||||
set(width 26) # Variable with column width
|
||||
string(REPLACE "lib" "" modules_to_print "${modules}")
|
||||
list(SORT modules_to_print) # Sort for nice output
|
||||
set(modules_with_large_names)
|
||||
foreach(module ${modules_to_print})
|
||||
# Get the size of the module string name
|
||||
string(LENGTH ${module} module_name_length)
|
||||
|
||||
# Skip modules with names wider than 26 characters
|
||||
if(${module_name_length} GREATER_EQUAL ${width})
|
||||
list(APPEND modules_with_large_names ${module})
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Calculate trailing spaces to fill the column
|
||||
math(EXPR num_trailing_spaces "${width} - ${module_name_length}")
|
||||
|
||||
@@ -94,7 +101,13 @@ function(print_formatted_table_with_modules table_name modules output)
|
||||
set(count 0)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Print modules with large names one by one
|
||||
foreach(module ${modules_with_large_names})
|
||||
string(APPEND temp "${module}\n")
|
||||
endforeach()
|
||||
string(APPEND temp "\n")
|
||||
|
||||
# Save the table outer scope out variable
|
||||
set(${output} ${${output}}${temp} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -326,68 +326,8 @@ macro(process_options)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${NS3_ENABLE_BUILD_VERSION})
|
||||
include(buildsupport/custom_modules/ns3_versioning.cmake)
|
||||
add_definitions(-DENABLE_BUILD_VERSION=1)
|
||||
|
||||
find_program(GIT git)
|
||||
if(NOT GIT)
|
||||
message(FATAL_ERROR "Baking build version into libraries require Git.")
|
||||
endif()
|
||||
|
||||
check_git_repo_has_ns3_tags(HAS_NS3_TAGS NS3_VERSION_TAG)
|
||||
|
||||
if(NOT ${HAS_NS3_TAGS})
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"This repository doesn't contain ns-3 git tags to bake into the libraries."
|
||||
)
|
||||
endif()
|
||||
|
||||
check_ns3_closest_tags(
|
||||
NS3_VERSION_CLOSEST_TAG NS3_VERSION_TAG_DISTANCE NS3_VERSION_COMMIT_HASH
|
||||
NS3_VERSION_DIRTY_FLAG
|
||||
)
|
||||
|
||||
# Split commit tag (ns-3.<minor>[.patch][-RC<digit>]) into
|
||||
# (ns;3.<minor>[.patch];[-RC<digit>]):
|
||||
string(REPLACE "-" ";" NS3_VER_LIST ${NS3_VERSION_TAG})
|
||||
list(LENGTH NS3_VER_LIST NS3_VER_LIST_LEN)
|
||||
|
||||
# Get last version tag fragment (RC<digit>)
|
||||
set(NS3_VERSION_RELEASE_CANDIDATE)
|
||||
if(${NS3_VER_LIST_LEN} GREATER 2)
|
||||
list(GET NS3_VER_LIST 2 RELEASE_CANDIDATE)
|
||||
set(NS3_VERSION_RELEASE_CANDIDATE "${RELEASE_CANDIDATE}")
|
||||
endif()
|
||||
|
||||
# Get 3.<minor>[.patch]
|
||||
list(GET NS3_VER_LIST 1 VERSION_STRING)
|
||||
# Split into a list 3;<minor>[;patch]
|
||||
string(REPLACE "." ";" VERSION_LIST ${VERSION_STRING})
|
||||
list(LENGTH VERSION_LIST VER_LIST_LEN)
|
||||
|
||||
list(GET VERSION_LIST 0 NS3_VERSION_MAJOR)
|
||||
if(${VER_LIST_LEN} GREATER 1)
|
||||
list(GET VERSION_LIST 1 NS3_VERSION_MINOR)
|
||||
if(${VER_LIST_LEN} GREATER 2)
|
||||
list(GET VERSION_LIST 2 NS3_VERSION_PATCH)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Transform list with 1 entry into strings
|
||||
set(NS3_VERSION_MAJOR "${NS3_VERSION_MAJOR}")
|
||||
set(NS3_VERSION_MINOR "${NS3_VERSION_MINOR}")
|
||||
set(NS3_VERSION_PATCH "${NS3_VERSION_PATCH}")
|
||||
set(NS3_VERSION_TAG "${NS3_VERSION_TAG}")
|
||||
|
||||
# Set
|
||||
set(NS3_VERSION_BUILD_PROFILE ${cmakeBuildType})
|
||||
configure_file(
|
||||
buildsupport/version-defines-template.h
|
||||
${CMAKE_HEADER_OUTPUT_DIRECTORY}/version-defines.h
|
||||
)
|
||||
endif()
|
||||
include(buildsupport/custom_modules/ns3_versioning.cmake)
|
||||
configure_embedded_version()
|
||||
|
||||
if(${NS3_CLANG_FORMAT})
|
||||
find_program(CLANG_FORMAT clang-format)
|
||||
|
||||
97
ns3
97
ns3
@@ -72,8 +72,7 @@ def parse_args(argv):
|
||||
parser_configure = sub_parser.add_parser('configure',
|
||||
help='Try "./ns3 configure --help" for more configuration options')
|
||||
parser_configure.add_argument('configure',
|
||||
nargs='?',
|
||||
action='store', default=True)
|
||||
action='store_true', default=False)
|
||||
parser_configure.add_argument('-d', '--build-profile',
|
||||
help='Build profile',
|
||||
dest='build_profile',
|
||||
@@ -93,6 +92,8 @@ def parse_args(argv):
|
||||
parser_configure = on_off_argument(parser_configure, "des-metrics",
|
||||
"Logging all events in a json file with the name of the executable "
|
||||
"(which must call CommandLine::Parse(argc, argv)")
|
||||
parser_configure = on_off_argument(parser_configure, "build-version",
|
||||
"embedding git changes as a build version during build")
|
||||
parser_configure = on_off_argument(parser_configure, "examples", "the ns-3 examples")
|
||||
parser_configure = on_off_argument(parser_configure, "gcov", "code coverage analysis")
|
||||
parser_configure = on_off_argument(parser_configure, "gtk", "GTK support in ConfigStore")
|
||||
@@ -151,21 +152,16 @@ def parse_args(argv):
|
||||
action="store_true", default=None, dest="configure_dry_run")
|
||||
|
||||
parser_clean = sub_parser.add_parser('clean', help='Removes files created by waf and ns3')
|
||||
parser_clean.add_argument('clean',
|
||||
nargs="?",
|
||||
action="store", default=True)
|
||||
parser_clean.add_argument('clean', action="store_true", default=False)
|
||||
parser_clean.add_argument('--dry-run',
|
||||
help="Do not execute the commands",
|
||||
action="store_true", default=None, dest="clean_dry_run")
|
||||
|
||||
parser_install = sub_parser.add_parser('install', help='Install ns-3')
|
||||
parser_install.add_argument('install',
|
||||
nargs="?",
|
||||
action="store", default=True)
|
||||
parser_install.add_argument('install', action="store_true", default=False)
|
||||
|
||||
parser_uninstall = sub_parser.add_parser('uninstall', help='Uninstall ns-3')
|
||||
parser_uninstall.add_argument('uninstall',
|
||||
nargs="?",
|
||||
action="store", default=True)
|
||||
parser_uninstall.add_argument('uninstall', action="store_true", default=False)
|
||||
|
||||
parser_run = sub_parser.add_parser('run',
|
||||
help='Try "./ns3 run --help" for more runtime options')
|
||||
@@ -177,7 +173,7 @@ def parse_args(argv):
|
||||
action="store_true", default=False)
|
||||
parser_run.add_argument('--command-template',
|
||||
help=('Template of the command used to run the program given by run;'
|
||||
' It should be a shell command string containing %s inside,'
|
||||
' It should be a shell command string containing %%s inside,'
|
||||
' which will be replaced by the actual program.'),
|
||||
type=str, default=None)
|
||||
parser_run.add_argument('--cwd',
|
||||
@@ -189,9 +185,9 @@ def parse_args(argv):
|
||||
parser_run.add_argument('--valgrind',
|
||||
help='Change the default command template to run programs with valgrind',
|
||||
action="store_true", default=None)
|
||||
parser_run.add_argument('--visualize',
|
||||
parser_run.add_argument('--vis', '--visualize',
|
||||
help='Modify --run arguments to enable the visualizer',
|
||||
action="store_true", default=None)
|
||||
action="store_true", dest="visualize", default=None)
|
||||
parser_run.add_argument('--dry-run',
|
||||
help="Do not execute the commands",
|
||||
action="store_true", default=None, dest="run_dry_run")
|
||||
@@ -203,9 +199,8 @@ def parse_args(argv):
|
||||
parser_shell = sub_parser.add_parser('shell',
|
||||
help='Try "./ns3 shell --help" for more runtime options')
|
||||
parser_shell.add_argument('shell',
|
||||
nargs="?",
|
||||
help='Export necessary environment variables and open a shell',
|
||||
action="store", default=True)
|
||||
action="store_true", default=False)
|
||||
|
||||
parser_docs = sub_parser.add_parser('docs',
|
||||
help='Try "./ns3 docs --help" for more documentation options')
|
||||
@@ -231,6 +226,12 @@ def parse_args(argv):
|
||||
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.add_argument('--docset',
|
||||
# help=(
|
||||
@@ -239,7 +240,8 @@ def parse_args(argv):
|
||||
# action="store_true", default=None,
|
||||
# dest="docset_build")
|
||||
|
||||
args = parser.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
|
||||
@@ -253,6 +255,23 @@ def parse_args(argv):
|
||||
|
||||
if args.run and args.enable_sudo is None:
|
||||
args.enable_sudo = True
|
||||
|
||||
# Filter arguments before --
|
||||
setattr(args, "program_args", [])
|
||||
if unknown_args:
|
||||
try:
|
||||
args_separator_index = argv.index('--')
|
||||
args.program_args = argv[args_separator_index + 1:]
|
||||
except ValueError:
|
||||
msg = "Unknown options were given: {options}.\n"\
|
||||
"To see the allowed options add the `--help` option.\n"\
|
||||
"To forward configuration or runtime options, put them after '--'.\n"
|
||||
if args.run:
|
||||
msg += "Try: ./ns3 run {target} -- {options}\n"
|
||||
if args.configure:
|
||||
msg += "Try: ./ns3 configure -- {options}\n"
|
||||
msg = msg.format(options=", ".join(unknown_args), target=args.run)
|
||||
raise Exception(msg)
|
||||
return args
|
||||
|
||||
|
||||
@@ -337,7 +356,7 @@ def search_cmake_cache(build_profile):
|
||||
current_cmake_cache_folder = os.path.dirname(cmake_cache_file)
|
||||
|
||||
# Check the generator
|
||||
if "CMAKE_GENERATOR" in line:
|
||||
if "CMAKE_GENERATOR:" in line:
|
||||
current_cmake_generator = line.split("=")[-1]
|
||||
|
||||
if not current_cmake_generator:
|
||||
@@ -360,12 +379,17 @@ def search_cmake_cache(build_profile):
|
||||
return current_cmake_cache_folder, current_cmake_generator
|
||||
|
||||
|
||||
def project_not_configured(config_msg=""):
|
||||
print("You need to configure ns-3 first: try ./ns3 configure%s" % config_msg)
|
||||
exit(1)
|
||||
|
||||
|
||||
def check_config(current_cmake_cache_folder):
|
||||
if current_cmake_cache_folder is None:
|
||||
raise Exception("Project was not configured")
|
||||
project_not_configured()
|
||||
waf_like_config_table = current_cmake_cache_folder + os.sep + "ns3wafconfig.txt"
|
||||
if not os.path.exists(waf_like_config_table):
|
||||
raise Exception("Project was not configured")
|
||||
project_not_configured()
|
||||
with open(waf_like_config_table, "r") as f:
|
||||
print(f.read())
|
||||
|
||||
@@ -419,6 +443,7 @@ def configure_cmake(cmake, args, current_cmake_cache_folder, current_cmake_gener
|
||||
options = (("ASSERT", "asserts"),
|
||||
("COVERAGE", "gcov"),
|
||||
("DES_METRICS", "des_metrics"),
|
||||
("ENABLE_BUILD_VERSION", "build_version"),
|
||||
("ENABLE_SUDO", "sudo"),
|
||||
("EXAMPLES", "examples"),
|
||||
("GTK3", "gtk"),
|
||||
@@ -468,6 +493,9 @@ def configure_cmake(cmake, args, current_cmake_cache_folder, current_cmake_gener
|
||||
cmake_args.append("-G")
|
||||
cmake_args.append(args.G)
|
||||
|
||||
# Append CMake flags passed using the -- separator
|
||||
cmake_args.extend(args.program_args)
|
||||
|
||||
# Configure cmake
|
||||
cmake_args.append("..") # for now, assuming the cmake_cache directory is inside the ns-3-dev folder
|
||||
|
||||
@@ -502,6 +530,11 @@ def get_program_shortcuts(build_profile, ns3_version):
|
||||
# Remove version prefix and build type suffix from shortcuts (or keep them too?)
|
||||
temp_path[-1] = temp_path[-1].replace("-" + build_profile, "").replace("ns" + ns3_version + "-", "")
|
||||
|
||||
# Deal with scratch subdirs
|
||||
if "scratch" in temp_path and len(temp_path) > 3:
|
||||
subdir = "_".join([*temp_path[2:-1], ""])
|
||||
temp_path[-1] = temp_path[-1].replace(subdir, "")
|
||||
|
||||
# Check if there is a .cc file for that specific program
|
||||
source_file_path = os.sep.join(temp_path) + ".cc"
|
||||
source_shortcut = False
|
||||
@@ -611,7 +644,7 @@ def get_target_to_build(program_path, ns3_version, build_profile):
|
||||
if "scratch" in program_path:
|
||||
# Get the path to the program and replace slashes with underlines
|
||||
# to get unique targets for CMake, preventing collisions with modules examples
|
||||
return program_name.split(out_dir + "/")[1].replace("/", "_")
|
||||
return program_name.replace(out_dir, "").replace("/", "_")[1:]
|
||||
else:
|
||||
# Other programs just use their normal names (without version prefix and build_profile suffix) as targets
|
||||
return program_name.split("/")[-1]
|
||||
@@ -661,7 +694,9 @@ def build_step(args,
|
||||
|
||||
# If we are building specific targets, we build them one by one
|
||||
if "build" in args:
|
||||
non_executable_targets = ["docs",
|
||||
non_executable_targets = ["check-version",
|
||||
"cmake-format",
|
||||
"docs",
|
||||
"doxygen",
|
||||
"doxygen-no-build",
|
||||
"sphinx",
|
||||
@@ -670,7 +705,7 @@ def build_step(args,
|
||||
"tutorial",
|
||||
"install",
|
||||
"uninstall",
|
||||
"cmake-format"]
|
||||
]
|
||||
# Build targets in the list
|
||||
for target in args.build:
|
||||
if target in ns3_modules:
|
||||
@@ -723,6 +758,7 @@ def run_step(args, target_to_run, target_args):
|
||||
debugging_software = []
|
||||
working_dir = ns3_path
|
||||
use_shell = False
|
||||
target_args += args.program_args
|
||||
|
||||
# running test.py/check?
|
||||
if args.check:
|
||||
@@ -893,6 +929,15 @@ def main():
|
||||
# Get build profile
|
||||
build_profile, ns3_version, ns3_modules, enable_sudo = check_build_profile(out_dir)
|
||||
|
||||
if args.check_profile:
|
||||
if build_profile:
|
||||
print("Build profile: %s" % build_profile)
|
||||
else:
|
||||
project_not_configured()
|
||||
|
||||
if args.check_version:
|
||||
args.build = ["check-version"]
|
||||
|
||||
# Check if running something or reconfiguring ns-3
|
||||
run_only = False
|
||||
build_and_run = False
|
||||
@@ -934,8 +979,10 @@ def main():
|
||||
)
|
||||
|
||||
if not project_configured(current_cmake_cache_folder):
|
||||
print("You need to configure ns-3 first: try ./ns3 configure")
|
||||
exit(0)
|
||||
project_not_configured()
|
||||
|
||||
if ns3_modules is None:
|
||||
project_not_configured()
|
||||
|
||||
# We could also replace the "ns3-" prefix used in c4che with the "lib" prefix currently used in cmake
|
||||
ns3_modules = [module.replace("ns3-", "") for module in ns3_modules]
|
||||
|
||||
@@ -1,36 +1,78 @@
|
||||
file(GLOB_RECURSE scratches ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
|
||||
|
||||
set(DONT_BUILD)
|
||||
set(target_prefix scratch_)
|
||||
|
||||
foreach(scratch_src ${scratches})
|
||||
# Get source filename without path or extension
|
||||
get_filename_component(scratch_name ${scratch_src} NAME)
|
||||
string(REGEX REPLACE "\\.[^.]*$" "" scratch_name ${scratch_name})
|
||||
function(create_scratch source_files)
|
||||
# Return early if no sources in the subdirectory
|
||||
list(LENGTH source_files number_sources)
|
||||
if(number_sources EQUAL 0)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# If the scratch has more than a source file, we need
|
||||
# to find the source with the main function
|
||||
unset(scratch_src)
|
||||
foreach(source_file ${source_files})
|
||||
file(READ ${source_file} source_file_contents)
|
||||
string(REGEX MATCHALL "main[(| (]" main_position "${source_file_contents}")
|
||||
if(CMAKE_MATCH_0)
|
||||
set(scratch_src ${source_file})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Get parent directory name
|
||||
get_filename_component(scratch_dirname ${scratch_src} DIRECTORY)
|
||||
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" scratch_dirname
|
||||
${scratch_dirname}
|
||||
)
|
||||
# Get source name
|
||||
get_filename_component(scratch_name ${scratch_src} NAME_WE)
|
||||
|
||||
set(target_prefix scratch_)
|
||||
if(${scratch_dirname})
|
||||
# Join the names together if dirname is not the scratch folder
|
||||
set(target_prefix scratch_${scratch_dirname}_)
|
||||
endif()
|
||||
|
||||
# Get source absolute path and transform into relative path
|
||||
get_filename_component(scratch_absolute_directory ${scratch_src} DIRECTORY)
|
||||
string(REPLACE "${PROJECT_SOURCE_DIR}" "${CMAKE_OUTPUT_DIRECTORY}"
|
||||
scratch_directory ${scratch_absolute_directory}
|
||||
)
|
||||
|
||||
# Build scratch if not listed as a DONT_BUILD
|
||||
string(FIND "${DONT_BUILD}" "${scratch_name}" res)
|
||||
if(res LESS 0)
|
||||
add_executable(${target_prefix}${scratch_name} "${scratch_src}")
|
||||
if(${NS3_STATIC})
|
||||
target_link_libraries(
|
||||
${target_prefix}${scratch_name} ${LIB_AS_NEEDED_PRE_STATIC}
|
||||
${lib-ns3-static}
|
||||
)
|
||||
else()
|
||||
target_link_libraries(
|
||||
${target_prefix}${scratch_name} "${ns3-libs}" "${ns3-contrib-libs}"
|
||||
"${ns3-external-libs}"
|
||||
)
|
||||
endif()
|
||||
set_runtime_outputdirectory(
|
||||
${scratch_name} ${scratch_directory}/ ${target_prefix}
|
||||
add_executable(${target_prefix}${scratch_name} "${source_files}")
|
||||
if(${NS3_STATIC})
|
||||
target_link_libraries(
|
||||
${target_prefix}${scratch_name} ${LIB_AS_NEEDED_PRE_STATIC}
|
||||
${lib-ns3-static}
|
||||
)
|
||||
else()
|
||||
target_link_libraries(
|
||||
${target_prefix}${scratch_name} "${ns3-libs}" "${ns3-contrib-libs}"
|
||||
"${ns3-external-libs}"
|
||||
)
|
||||
endif()
|
||||
set_runtime_outputdirectory(
|
||||
${scratch_name} ${scratch_directory}/ ${target_prefix}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# Scan *.cc files in ns-3-dev/scratch and build a target for each
|
||||
file(GLOB single_source_file_scratches ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
|
||||
foreach(scratch_src ${single_source_file_scratches})
|
||||
create_scratch(${scratch_src})
|
||||
endforeach()
|
||||
|
||||
# Scan *.cc files in ns-3-dev/scratch subdirectories and build a target for each
|
||||
# subdirectory
|
||||
file(GLOB_RECURSE scratch_subdirectories LIST_DIRECTORIES true
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/**
|
||||
)
|
||||
# Filter out files
|
||||
foreach(entry ${scratch_subdirectories})
|
||||
if(NOT (IS_DIRECTORY ${entry}))
|
||||
list(REMOVE_ITEM scratch_subdirectories ${entry})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(subdir ${scratch_subdirectories})
|
||||
file(GLOB scratch_sources ${subdir}/*.cc)
|
||||
create_scratch("${scratch_sources}")
|
||||
endforeach()
|
||||
|
||||
@@ -288,7 +288,7 @@ class NS3CommonSettingsTestCase(unittest.TestCase):
|
||||
@return None
|
||||
"""
|
||||
return_code, stdout, stderr = run_ns3("")
|
||||
self.assertEqual(return_code, 0)
|
||||
self.assertEqual(return_code, 1)
|
||||
self.assertIn("You need to configure ns-3 first: try ./ns3 configure", stdout)
|
||||
|
||||
def test_02_NoTaskLines(self):
|
||||
@@ -297,7 +297,7 @@ class NS3CommonSettingsTestCase(unittest.TestCase):
|
||||
@return None
|
||||
"""
|
||||
return_code, stdout, stderr = run_ns3("--quiet")
|
||||
self.assertEqual(return_code, 0)
|
||||
self.assertEqual(return_code, 1)
|
||||
self.assertIn("You need to configure ns-3 first: try ./ns3 configure", stdout)
|
||||
|
||||
def test_03_CheckConfig(self):
|
||||
@@ -307,7 +307,25 @@ class NS3CommonSettingsTestCase(unittest.TestCase):
|
||||
"""
|
||||
return_code, stdout, stderr = run_ns3("--check-config")
|
||||
self.assertEqual(return_code, 1)
|
||||
self.assertIn("Project was not configured", stderr)
|
||||
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
|
||||
@return None
|
||||
"""
|
||||
return_code, stdout, stderr = run_ns3("--check-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
|
||||
@return None
|
||||
"""
|
||||
return_code, stdout, stderr = run_ns3("--check-version")
|
||||
self.assertEqual(return_code, 1)
|
||||
self.assertIn("You need to configure ns-3 first: try ./ns3 configure", stdout)
|
||||
|
||||
|
||||
class NS3ConfigureBuildProfileTestCase(unittest.TestCase):
|
||||
@@ -734,6 +752,33 @@ class NS3ConfigureTestCase(NS3BaseTestCase):
|
||||
)
|
||||
self.assertNotEqual(return_code, 0)
|
||||
|
||||
def test_10_CheckConfig(self):
|
||||
"""!
|
||||
Test passing --check-config argument to ns3 to get the configuration table
|
||||
@return None
|
||||
"""
|
||||
return_code, stdout, stderr = run_ns3("--check-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
|
||||
@return None
|
||||
"""
|
||||
return_code, stdout, stderr = run_ns3("--check-profile")
|
||||
self.assertEqual(return_code, 0)
|
||||
self.assertIn("Build profile: debug", stdout)
|
||||
|
||||
def test_12_CheckVersion(self):
|
||||
"""!
|
||||
Test passing --check-version argument to ns3 to get the build version
|
||||
@return None
|
||||
"""
|
||||
return_code, stdout, stderr = run_ns3("--check-version")
|
||||
self.assertEqual(return_code, 0)
|
||||
self.assertIn("ns-3 version:", stdout)
|
||||
|
||||
|
||||
class NS3BuildBaseTestCase(NS3BaseTestCase):
|
||||
"""!
|
||||
@@ -1047,6 +1092,32 @@ class NS3BuildBaseTestCase(NS3BaseTestCase):
|
||||
# Reset flag to let it clean the build
|
||||
NS3BuildBaseTestCase.cleaned_once = False
|
||||
|
||||
def test_09_Scratches(self):
|
||||
"""!
|
||||
Tries to build scratch-simulator and subdir/scratch-simulator-subdir
|
||||
@return None
|
||||
"""
|
||||
# Build.
|
||||
targets = {"scratch/scratch-simulator": "scratch-simulator",
|
||||
"scratch-simulator": "scratch-simulator",
|
||||
"scratch/subdir/scratch-simulator-subdir": "subdir_scratch-simulator-subdir",
|
||||
"subdir/scratch-simulator-subdir": "subdir_scratch-simulator-subdir",
|
||||
"scratch-simulator-subdir": "subdir_scratch-simulator-subdir",
|
||||
}
|
||||
for (target_to_run, target_cmake) in targets.items():
|
||||
# Test if build is working.
|
||||
build_line = "target scratch_%s" % target_cmake
|
||||
return_code, stdout, stderr = run_ns3("build %s" % target_to_run)
|
||||
self.assertEqual(return_code, 0)
|
||||
self.assertIn(build_line, stdout)
|
||||
|
||||
# Test if run is working
|
||||
return_code, stdout, stderr = run_ns3("run %s" % target_to_run)
|
||||
self.assertEqual(return_code, 0)
|
||||
self.assertIn(build_line, stdout)
|
||||
stdout = stdout.replace("scratch_%s" % target_cmake, "") # remove build lines
|
||||
self.assertIn(target_to_run.split("/")[-1], stdout)
|
||||
|
||||
|
||||
class NS3ExpectedUseTestCase(NS3BaseTestCase):
|
||||
"""!
|
||||
@@ -1354,6 +1425,89 @@ 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):
|
||||
"""!
|
||||
Check if command template is working
|
||||
@return None
|
||||
"""
|
||||
|
||||
# Command templates that are empty or do not have a %s should fail
|
||||
return_code0, stdout0, stderr0 = run_ns3('run sample-simulator --command-template')
|
||||
self.assertEqual(return_code0, 2)
|
||||
self.assertIn("argument --command-template: expected one argument", stderr0)
|
||||
|
||||
return_code1, stdout1, stderr1 = run_ns3('run sample-simulator --command-template=" "')
|
||||
return_code2, stdout2, stderr2 = run_ns3('run sample-simulator --command-template " "')
|
||||
return_code3, stdout3, stderr3 = run_ns3('run sample-simulator --command-template "echo "')
|
||||
self.assertEqual((return_code1, return_code2, return_code3), (1, 1, 1))
|
||||
self.assertIn("not all arguments converted during string formatting", stderr1)
|
||||
self.assertEqual(stderr1, stderr2)
|
||||
self.assertEqual(stderr2, stderr3)
|
||||
|
||||
# Command templates with %s should at least continue and try to run the target
|
||||
return_code4, stdout4, stderr4 = run_ns3('run sample-simulator --command-template "%s --PrintVersion"')
|
||||
return_code5, stdout5, stderr5 = run_ns3('run sample-simulator --command-template="%s --PrintVersion"')
|
||||
self.assertEqual((return_code4, return_code5), (0, 0))
|
||||
self.assertIn("sample-simulator --PrintVersion", stdout4)
|
||||
self.assertIn("sample-simulator --PrintVersion", stdout5)
|
||||
|
||||
def test_17_ForwardArgumentsToRunTargets(self):
|
||||
"""!
|
||||
Check if all flavors of different argument passing to
|
||||
executable targets are working
|
||||
@return None
|
||||
"""
|
||||
|
||||
# Test if all argument passing flavors are working
|
||||
return_code0, stdout0, stderr0 = run_ns3('run "sample-simulator --help"')
|
||||
return_code1, stdout1, stderr1 = run_ns3('run sample-simulator --command-template="%s --help"')
|
||||
return_code2, stdout2, stderr2 = run_ns3('run sample-simulator -- --help')
|
||||
|
||||
self.assertEqual((return_code0, return_code1, return_code2), (0, 0, 0))
|
||||
self.assertIn("sample-simulator --help", stdout0)
|
||||
self.assertIn("sample-simulator --help", stdout1)
|
||||
self.assertIn("sample-simulator --help", stdout2)
|
||||
|
||||
# Test if the same thing happens with an additional run argument (e.g. --no-build)
|
||||
return_code0, stdout0, stderr0 = run_ns3('run "sample-simulator --help" --no-build')
|
||||
return_code1, stdout1, stderr1 = run_ns3('run sample-simulator --command-template="%s --help" --no-build')
|
||||
return_code2, stdout2, stderr2 = run_ns3('run sample-simulator --no-build -- --help')
|
||||
self.assertEqual((return_code0, return_code1, return_code2), (0, 0, 0))
|
||||
self.assertEqual(stdout0, stdout1)
|
||||
self.assertEqual(stdout1, stdout2)
|
||||
self.assertEqual(stderr0, stderr1)
|
||||
self.assertEqual(stderr1, stderr2)
|
||||
|
||||
# Now collect results for each argument individually
|
||||
return_code0, stdout0, stderr0 = run_ns3('run "sample-simulator --PrintGlobals"')
|
||||
return_code1, stdout1, stderr1 = run_ns3('run "sample-simulator --PrintGroups"')
|
||||
return_code2, stdout2, stderr2 = run_ns3('run "sample-simulator --PrintTypeIds"')
|
||||
|
||||
self.assertEqual((return_code0, return_code1, return_code2), (0, 0, 0))
|
||||
self.assertIn("sample-simulator --PrintGlobals", stdout0)
|
||||
self.assertIn("sample-simulator --PrintGroups", stdout1)
|
||||
self.assertIn("sample-simulator --PrintTypeIds", stdout2)
|
||||
|
||||
# Then check if all the arguments are correctly merged by checking the outputs
|
||||
cmd = 'run "sample-simulator --PrintGlobals" --command-template="%s --PrintGroups" -- --PrintTypeIds'
|
||||
return_code, stdout, stderr = run_ns3(cmd)
|
||||
self.assertEqual(return_code, 0)
|
||||
|
||||
# The order of the arguments is command template,
|
||||
# arguments passed with the target itself
|
||||
# and forwarded arguments after the -- separator
|
||||
self.assertIn("sample-simulator --PrintGroups --PrintGlobals --PrintTypeIds", stdout)
|
||||
|
||||
# Check if it complains about the missing -- separator
|
||||
cmd0 = 'run sample-simulator --command-template="%s " --PrintTypeIds'
|
||||
cmd1 = 'run sample-simulator --PrintTypeIds'
|
||||
|
||||
return_code0, stdout0, stderr0 = run_ns3(cmd0)
|
||||
return_code1, stdout1, stderr1 = run_ns3(cmd1)
|
||||
self.assertEqual((return_code0, return_code1), (1, 1))
|
||||
self.assertIn("To forward configuration or runtime options, put them after '--'", stderr0)
|
||||
self.assertIn("To forward configuration or runtime options, put them after '--'", stderr1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
Reference in New Issue
Block a user