2007-05-07 12:01:51 +01:00
|
|
|
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
2008-12-29 13:28:54 +00:00
|
|
|
|
|
|
|
|
# python lib modules
|
2015-09-03 21:14:55 -07:00
|
|
|
from __future__ import print_function
|
2007-05-17 17:02:03 +01:00
|
|
|
import sys
|
2007-05-24 19:21:50 +01:00
|
|
|
import shutil
|
2007-08-08 15:10:36 +01:00
|
|
|
import types
|
|
|
|
|
import optparse
|
|
|
|
|
import os.path
|
2009-05-19 15:39:15 +02:00
|
|
|
import re
|
2010-11-20 17:55:53 +00:00
|
|
|
import shlex
|
2013-04-01 22:33:46 +02:00
|
|
|
import subprocess
|
2011-04-26 14:21:44 -07:00
|
|
|
import textwrap
|
2020-04-27 15:22:11 -07:00
|
|
|
import fileinput
|
|
|
|
|
import glob
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2013-04-01 22:33:46 +02:00
|
|
|
from utils import read_config_file
|
2009-04-13 23:10:37 +01:00
|
|
|
|
2009-01-11 17:51:20 +00:00
|
|
|
|
2013-04-01 22:33:46 +02:00
|
|
|
# WAF modules
|
|
|
|
|
from waflib import Utils, Scripting, Configure, Build, Options, TaskGen, Context, Task, Logs, Errors
|
|
|
|
|
from waflib.Errors import WafError
|
2009-02-14 14:02:40 +00:00
|
|
|
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2013-04-01 22:33:46 +02:00
|
|
|
# local modules
|
|
|
|
|
import wutils
|
2011-09-13 13:47:17 +01:00
|
|
|
|
2011-03-04 15:41:14 -08:00
|
|
|
|
2011-04-12 14:35:16 -07:00
|
|
|
# By default, all modules will be enabled, examples will be disabled,
|
2011-04-12 10:39:17 -07:00
|
|
|
# and tests will be disabled.
|
|
|
|
|
modules_enabled = ['all_modules']
|
2011-04-12 14:35:16 -07:00
|
|
|
examples_enabled = False
|
2011-04-12 10:39:17 -07:00
|
|
|
tests_enabled = False
|
2011-03-04 15:41:14 -08:00
|
|
|
|
2021-09-14 16:43:01 +02:00
|
|
|
# GCC minimum version requirements for C++17 support
|
2021-12-10 10:26:52 -08:00
|
|
|
gcc_min_version = (8, 0, 0)
|
2014-05-28 23:03:23 -07:00
|
|
|
|
2015-09-28 20:23:11 -07:00
|
|
|
# Bug 2181: clang warnings about unused local typedefs and potentially
|
|
|
|
|
# evaluated expressions affecting darwin clang/LLVM version 7.0.0 (Xcode 7)
|
|
|
|
|
# or clang/LLVM version 3.6 or greater. We must make this platform-specific.
|
2018-09-20 21:17:26 -07:00
|
|
|
darwin_clang_version_warn_unused_local_typedefs = (7, 0, 0)
|
|
|
|
|
darwin_clang_version_warn_potentially_evaluated = (7, 0, 0)
|
|
|
|
|
clang_version_warn_unused_local_typedefs = (3, 6, 0)
|
|
|
|
|
clang_version_warn_potentially_evaluated = (3, 6, 0)
|
2015-09-28 20:23:11 -07:00
|
|
|
|
2011-04-12 10:39:17 -07:00
|
|
|
# Get the information out of the NS-3 configuration file.
|
|
|
|
|
config_file_exists = False
|
|
|
|
|
(config_file_exists, modules_enabled, examples_enabled, tests_enabled) = read_config_file()
|
2011-03-04 15:41:14 -08:00
|
|
|
|
2009-09-21 10:59:21 +01:00
|
|
|
sys.path.insert(0, os.path.abspath('waf-tools'))
|
2010-04-23 15:46:46 +01:00
|
|
|
try:
|
|
|
|
|
import cflags # override the build profiles from waf
|
|
|
|
|
finally:
|
|
|
|
|
sys.path.pop(0)
|
2009-09-21 10:59:21 +01:00
|
|
|
|
2008-12-31 11:20:18 +00:00
|
|
|
cflags.profiles = {
|
2016-08-04 12:44:41 -07:00
|
|
|
# profile name: [optimization_level, warnings_level, debug_level]
|
|
|
|
|
'debug': [0, 2, 3],
|
|
|
|
|
'optimized': [3, 2, 1],
|
|
|
|
|
'release': [3, 2, 0],
|
|
|
|
|
}
|
2008-12-31 11:20:18 +00:00
|
|
|
cflags.default_profile = 'debug'
|
|
|
|
|
|
2011-09-08 16:13:40 +01:00
|
|
|
Configure.autoconfig = 0
|
2007-05-07 12:01:51 +01:00
|
|
|
|
|
|
|
|
# the following two variables are used by the target "waf dist"
|
2020-05-13 18:45:06 +01:00
|
|
|
with open("VERSION", "rt") as f:
|
|
|
|
|
VERSION = f.read().strip()
|
2007-05-24 17:59:30 +01:00
|
|
|
APPNAME = 'ns'
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2021-10-22 17:01:42 -07:00
|
|
|
wutils.VERSION = VERSION.replace(".", "-")
|
2008-11-18 13:48:26 +00:00
|
|
|
wutils.APPNAME = APPNAME
|
|
|
|
|
|
2012-01-16 19:39:45 +00:00
|
|
|
# we don't use VNUM anymore (see bug #1327 for details)
|
2011-08-26 12:31:04 +01:00
|
|
|
wutils.VNUM = None
|
2011-06-27 14:55:11 +01:00
|
|
|
|
2007-05-07 12:01:51 +01:00
|
|
|
# these variables are mandatory ('/' are converted automatically)
|
2011-09-12 14:54:27 +01:00
|
|
|
top = '.'
|
|
|
|
|
out = 'build'
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2009-06-25 14:15:27 +02:00
|
|
|
def load_env():
|
|
|
|
|
bld_cls = getattr(Utils.g_module, 'build_context', Utils.Context)
|
|
|
|
|
bld_ctx = bld_cls()
|
|
|
|
|
bld_ctx.load_dirs(os.path.abspath(os.path.join (srcdir,'..')),
|
|
|
|
|
os.path.abspath(os.path.join (srcdir,'..', blddir)))
|
|
|
|
|
bld_ctx.load_envs()
|
|
|
|
|
env = bld_ctx.get_env()
|
|
|
|
|
return env
|
|
|
|
|
|
|
|
|
|
def get_files(base_dir):
|
|
|
|
|
retval = []
|
|
|
|
|
reference=os.path.dirname(base_dir)
|
|
|
|
|
for root, dirs, files in os.walk(base_dir):
|
|
|
|
|
if root.find('.hg') != -1:
|
|
|
|
|
continue
|
|
|
|
|
for file in files:
|
|
|
|
|
if file.find('.hg') != -1:
|
|
|
|
|
continue
|
|
|
|
|
fullname = os.path.join(root,file)
|
|
|
|
|
# we can't use os.path.relpath because it's new in python 2.6
|
|
|
|
|
relname = fullname.replace(reference + '/','')
|
|
|
|
|
retval.append([fullname,relname])
|
|
|
|
|
return retval
|
|
|
|
|
|
2008-04-04 19:33:39 +01:00
|
|
|
|
2007-09-27 12:40:01 +01:00
|
|
|
def dist_hook():
|
2008-04-06 21:57:11 +01:00
|
|
|
import tarfile
|
2007-07-09 14:36:40 +01:00
|
|
|
shutil.rmtree("doc/html", True)
|
|
|
|
|
shutil.rmtree("doc/latex", True)
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2011-05-30 15:30:49 -07:00
|
|
|
# Print the sorted list of module names in columns.
|
2011-05-27 14:48:14 -07:00
|
|
|
def print_module_names(names):
|
2019-12-24 11:58:08 +03:00
|
|
|
"""Print the list of module names in 3 columns."""
|
|
|
|
|
for i, name in enumerate(sorted(names)):
|
|
|
|
|
if i % 3 == 2 or i == len(names) - 1:
|
|
|
|
|
print(name)
|
|
|
|
|
else:
|
|
|
|
|
print(name.ljust(25), end=' ')
|
2011-05-27 14:48:14 -07:00
|
|
|
|
2015-09-09 15:14:27 -07:00
|
|
|
# return types of some APIs differ in Python 2/3 (type string vs class bytes)
|
2020-05-13 18:45:06 +01:00
|
|
|
# This method will decode('utf-8') a byte object in Python 3,
|
2015-09-09 15:14:27 -07:00
|
|
|
# and do nothing in Python 2
|
|
|
|
|
def maybe_decode(input):
|
|
|
|
|
if sys.version_info < (3,):
|
|
|
|
|
return input
|
|
|
|
|
else:
|
|
|
|
|
try:
|
|
|
|
|
return input.decode('utf-8')
|
|
|
|
|
except:
|
|
|
|
|
sys.exc_clear()
|
|
|
|
|
return input
|
|
|
|
|
|
2011-09-08 16:13:40 +01:00
|
|
|
def options(opt):
|
2007-05-07 12:01:51 +01:00
|
|
|
# options provided by the modules
|
2019-04-19 14:11:03 -07:00
|
|
|
opt.load('md5_tstamp')
|
2011-09-08 16:13:40 +01:00
|
|
|
opt.load('compiler_c')
|
|
|
|
|
opt.load('compiler_cxx')
|
|
|
|
|
opt.load('cflags')
|
|
|
|
|
opt.load('gnu_dirs')
|
2021-06-13 19:06:39 -07:00
|
|
|
opt.load('boost', tooldir=['waf-tools'])
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2016-09-19 23:06:16 -07:00
|
|
|
opt.add_option('--check-config',
|
|
|
|
|
help=('Print the current configuration.'),
|
|
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest="check_config")
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2008-03-25 23:17:24 -07:00
|
|
|
opt.add_option('--cwd',
|
|
|
|
|
help=('Set the working directory for a program.'),
|
|
|
|
|
action="store", type="string", default=None,
|
|
|
|
|
dest='cwd_launch')
|
|
|
|
|
|
2007-05-07 12:01:51 +01:00
|
|
|
opt.add_option('--enable-gcov',
|
2007-06-21 12:26:46 +01:00
|
|
|
help=('Enable code coverage analysis.'
|
|
|
|
|
' WARNING: this option only has effect '
|
|
|
|
|
'with the configure command.'),
|
2007-05-07 12:01:51 +01:00
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest='enable_gcov')
|
|
|
|
|
|
2008-04-03 14:15:17 +01:00
|
|
|
opt.add_option('--no-task-lines',
|
|
|
|
|
help=("Don't print task lines, i.e. messages saying which tasks are being executed by WAF."
|
|
|
|
|
" Coupled with a single -v will cause WAF to output only the executed commands,"
|
|
|
|
|
" just like 'make' does by default."),
|
|
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest='no_task_lines')
|
|
|
|
|
|
2007-05-07 12:01:51 +01:00
|
|
|
opt.add_option('--lcov-report',
|
|
|
|
|
help=('Generate a code coverage report '
|
2019-12-24 12:16:05 -08:00
|
|
|
'(use this option after configuring with --enable-gcov and running a program)'),
|
2007-05-07 12:01:51 +01:00
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest='lcov_report')
|
|
|
|
|
|
2019-12-24 12:16:05 -08:00
|
|
|
opt.add_option('--lcov-zerocounters',
|
|
|
|
|
help=('Zero the lcov counters'
|
|
|
|
|
'(use this option before rerunning a program, when generating repeated lcov reports)'),
|
|
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest='lcov_zerocounters')
|
|
|
|
|
|
2007-05-23 19:20:54 +01:00
|
|
|
opt.add_option('--run',
|
2007-07-18 12:20:31 +01:00
|
|
|
help=('Run a locally built program; argument can be a program name,'
|
|
|
|
|
' or a command starting with the program name.'),
|
2007-05-23 19:20:54 +01:00
|
|
|
type="string", default='', dest='run')
|
2019-04-03 15:34:32 -07:00
|
|
|
opt.add_option('--run-no-build',
|
|
|
|
|
help=('Run a locally built program without rebuilding the project; argument can be a program name,'
|
|
|
|
|
' or a command starting with the program name.'),
|
|
|
|
|
type="string", default='', dest='run_no_build')
|
2010-12-06 17:26:06 +00:00
|
|
|
opt.add_option('--visualize',
|
|
|
|
|
help=('Modify --run arguments to enable the visualizer'),
|
|
|
|
|
action="store_true", default=False, dest='visualize')
|
2007-07-18 12:20:31 +01:00
|
|
|
opt.add_option('--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,'
|
|
|
|
|
' which will be replaced by the actual program.'),
|
|
|
|
|
type="string", default=None, dest='command_template')
|
2008-07-12 19:33:29 +01:00
|
|
|
opt.add_option('--pyrun',
|
|
|
|
|
help=('Run a python program using locally built ns3 python module;'
|
|
|
|
|
' argument is the path to the python program, optionally followed'
|
|
|
|
|
' by command-line options that are passed to the program.'),
|
|
|
|
|
type="string", default='', dest='pyrun')
|
2019-04-03 15:34:32 -07:00
|
|
|
opt.add_option('--pyrun-no-build',
|
|
|
|
|
help=('Run a python program using locally built ns3 python module without rebuilding the project;'
|
|
|
|
|
' argument is the path to the python program, optionally followed'
|
|
|
|
|
' by command-line options that are passed to the program.'),
|
|
|
|
|
type="string", default='', dest='pyrun_no_build')
|
2019-03-20 18:42:38 +03:00
|
|
|
opt.add_option('--gdb',
|
|
|
|
|
help=('Change the default command template to run programs and unit tests with gdb'),
|
|
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest='gdb')
|
2008-01-03 14:14:17 +00:00
|
|
|
opt.add_option('--valgrind',
|
|
|
|
|
help=('Change the default command template to run programs and unit tests with valgrind'),
|
|
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest='valgrind')
|
2007-05-23 19:20:54 +01:00
|
|
|
opt.add_option('--shell',
|
2009-04-13 23:10:37 +01:00
|
|
|
help=('DEPRECATED (run ./waf shell)'),
|
2007-05-23 19:20:54 +01:00
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest='shell')
|
2009-01-27 20:26:34 -08:00
|
|
|
opt.add_option('--enable-sudo',
|
|
|
|
|
help=('Use sudo to setup suid bits on ns3 executables.'),
|
|
|
|
|
dest='enable_sudo', action='store_true',
|
|
|
|
|
default=False)
|
2011-04-06 10:13:04 -07:00
|
|
|
opt.add_option('--enable-tests',
|
|
|
|
|
help=('Build the ns-3 tests.'),
|
|
|
|
|
dest='enable_tests', action='store_true',
|
|
|
|
|
default=False)
|
|
|
|
|
opt.add_option('--disable-tests',
|
|
|
|
|
help=('Do not build the ns-3 tests.'),
|
2011-04-12 10:39:17 -07:00
|
|
|
dest='disable_tests', action='store_true',
|
|
|
|
|
default=False)
|
2009-10-06 19:34:29 -07:00
|
|
|
opt.add_option('--enable-examples',
|
2011-04-14 14:22:09 -07:00
|
|
|
help=('Build the ns-3 examples.'),
|
2009-10-06 19:34:29 -07:00
|
|
|
dest='enable_examples', action='store_true',
|
2011-04-12 10:39:17 -07:00
|
|
|
default=False)
|
2009-10-06 19:34:29 -07:00
|
|
|
opt.add_option('--disable-examples',
|
2011-04-14 14:22:09 -07:00
|
|
|
help=('Do not build the ns-3 examples.'),
|
2011-04-12 10:39:17 -07:00
|
|
|
dest='disable_examples', action='store_true',
|
|
|
|
|
default=False)
|
2009-06-12 12:33:37 +01:00
|
|
|
opt.add_option('--check',
|
2009-10-04 20:52:24 -07:00
|
|
|
help=('DEPRECATED (run ./test.py)'),
|
2009-06-12 12:33:37 +01:00
|
|
|
default=False, dest='check', action="store_true")
|
2009-04-21 14:38:47 +02:00
|
|
|
opt.add_option('--enable-static',
|
|
|
|
|
help=('Compile NS-3 statically: works only on linux, without python'),
|
|
|
|
|
dest='enable_static', action='store_true',
|
|
|
|
|
default=False)
|
2010-03-08 21:07:31 -05:00
|
|
|
opt.add_option('--enable-mpi',
|
|
|
|
|
help=('Compile NS-3 with MPI and distributed simulation support'),
|
|
|
|
|
dest='enable_mpi', action='store_true',
|
|
|
|
|
default=False)
|
2009-10-29 11:12:12 +00:00
|
|
|
opt.add_option('--doxygen-no-build',
|
|
|
|
|
help=('Run doxygen to generate html documentation from source comments, '
|
|
|
|
|
'but do not wait for ns-3 to finish the full build.'),
|
|
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest='doxygen_no_build')
|
2020-02-25 13:17:18 -08:00
|
|
|
opt.add_option('--docset',
|
|
|
|
|
help=('Create Docset, without building. This requires the docsetutil tool from Xcode 9.2 or earlier. See Bugzilla 2196 for more details.'),
|
|
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest="docset_build")
|
2016-09-02 22:40:07 -04:00
|
|
|
opt.add_option('--enable-des-metrics',
|
|
|
|
|
help=('Log all events in a json file with the name of the executable (which must call CommandLine::Parse(argc, argv)'),
|
|
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest='enable_desmetrics')
|
2017-11-29 21:13:07 -08:00
|
|
|
opt.add_option('--cxx-standard',
|
|
|
|
|
help=('Compile NS-3 with the given C++ standard'),
|
2021-06-13 14:36:43 -07:00
|
|
|
type='string', dest='cxx_standard')
|
2020-07-03 10:22:20 +02:00
|
|
|
opt.add_option('--enable-asserts',
|
|
|
|
|
help=('Enable the asserts regardless of the compile mode'),
|
|
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest='enable_asserts')
|
|
|
|
|
opt.add_option('--enable-logs',
|
|
|
|
|
help=('Enable the logs regardless of the compile mode'),
|
|
|
|
|
action="store_true", default=False,
|
|
|
|
|
dest='enable_logs')
|
2008-04-04 19:33:39 +01:00
|
|
|
|
2009-10-29 11:12:12 +00:00
|
|
|
# options provided in subdirectories
|
2013-04-01 22:33:46 +02:00
|
|
|
opt.recurse('src')
|
|
|
|
|
opt.recurse('bindings/python')
|
|
|
|
|
opt.recurse('src/internet')
|
2017-04-06 20:32:04 -07:00
|
|
|
opt.recurse('contrib')
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2011-09-24 18:37:22 +01:00
|
|
|
def _check_compilation_flag(conf, flag, mode='cxx', linkflags=None):
|
2008-07-11 19:24:33 +01:00
|
|
|
"""
|
|
|
|
|
Checks if the C++ compiler accepts a certain compilation flag or flags
|
|
|
|
|
flag: can be a string or a list of strings
|
|
|
|
|
"""
|
2011-09-24 18:37:22 +01:00
|
|
|
l = []
|
|
|
|
|
if flag:
|
|
|
|
|
l.append(flag)
|
|
|
|
|
if isinstance(linkflags, list):
|
|
|
|
|
l.extend(linkflags)
|
|
|
|
|
else:
|
|
|
|
|
if linkflags:
|
|
|
|
|
l.append(linkflags)
|
|
|
|
|
if len(l) > 1:
|
|
|
|
|
flag_str = 'flags ' + ' '.join(l)
|
|
|
|
|
else:
|
|
|
|
|
flag_str = 'flag ' + ' '.join(l)
|
2015-09-03 21:14:55 -07:00
|
|
|
if len(flag_str) > 28:
|
2011-09-24 18:37:22 +01:00
|
|
|
flag_str = flag_str[:28] + "..."
|
2008-07-11 19:24:33 +01:00
|
|
|
|
2011-09-24 18:37:22 +01:00
|
|
|
conf.start_msg('Checking for compilation %s support' % (flag_str,))
|
2013-04-01 22:33:46 +02:00
|
|
|
env = conf.env.derive()
|
2011-09-24 18:37:22 +01:00
|
|
|
|
2015-06-23 14:32:41 +02:00
|
|
|
retval = False
|
2011-09-24 18:37:22 +01:00
|
|
|
if mode == 'cc':
|
|
|
|
|
mode = 'c'
|
|
|
|
|
|
2010-03-02 15:29:53 +00:00
|
|
|
if mode == 'cxx':
|
|
|
|
|
env.append_value('CXXFLAGS', flag)
|
|
|
|
|
else:
|
2011-09-24 18:37:22 +01:00
|
|
|
env.append_value('CFLAGS', flag)
|
|
|
|
|
|
|
|
|
|
if linkflags is not None:
|
|
|
|
|
env.append_value("LINKFLAGS", linkflags)
|
|
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
try:
|
2015-07-07 22:01:23 +02:00
|
|
|
retval = conf.check(compiler=mode, fragment='int main() { return 0; }', features='c', env=env)
|
2013-04-01 22:33:46 +02:00
|
|
|
except Errors.ConfigurationError:
|
2008-12-29 13:28:54 +00:00
|
|
|
ok = False
|
|
|
|
|
else:
|
2015-06-23 14:32:41 +02:00
|
|
|
ok = (retval == True)
|
2011-09-08 16:13:40 +01:00
|
|
|
conf.end_msg(ok)
|
2008-12-31 11:20:18 +00:00
|
|
|
return ok
|
2008-12-29 13:28:54 +00:00
|
|
|
|
2015-06-23 14:32:41 +02:00
|
|
|
|
2008-09-05 18:16:29 +01:00
|
|
|
def report_optional_feature(conf, name, caption, was_enabled, reason_not_enabled):
|
2011-09-08 16:13:40 +01:00
|
|
|
conf.env.append_value('NS3_OPTIONAL_FEATURES', [(name, caption, was_enabled, reason_not_enabled)])
|
|
|
|
|
|
2015-06-23 14:32:41 +02:00
|
|
|
|
2012-02-14 18:44:16 +00:00
|
|
|
def check_optional_feature(conf, name):
|
|
|
|
|
for (name1, caption, was_enabled, reason_not_enabled) in conf.env.NS3_OPTIONAL_FEATURES:
|
|
|
|
|
if name1 == name:
|
|
|
|
|
return was_enabled
|
|
|
|
|
raise KeyError("Feature %r not declared yet" % (name,))
|
2011-09-08 16:13:40 +01:00
|
|
|
|
2015-06-23 14:32:41 +02:00
|
|
|
|
2011-09-08 16:13:40 +01:00
|
|
|
# starting with waf 1.6, conf.check() becomes fatal by default if the
|
|
|
|
|
# test fails, this alternative method makes the test non-fatal, as it
|
|
|
|
|
# was in waf <= 1.5
|
|
|
|
|
def _check_nonfatal(conf, *args, **kwargs):
|
|
|
|
|
try:
|
|
|
|
|
return conf.check(*args, **kwargs)
|
|
|
|
|
except conf.errors.ConfigurationError:
|
|
|
|
|
return None
|
2008-07-11 19:24:33 +01:00
|
|
|
|
2016-09-19 23:06:16 -07:00
|
|
|
# Write a summary of optional features status
|
|
|
|
|
def print_config(env, phase='configure'):
|
|
|
|
|
if phase == 'configure':
|
|
|
|
|
profile = get_build_profile(env)
|
|
|
|
|
else:
|
|
|
|
|
profile = get_build_profile()
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2016-09-19 23:06:16 -07:00
|
|
|
print("---- Summary of optional NS-3 features:")
|
|
|
|
|
print("%-30s: %s%s%s" % ("Build profile", Logs.colors('GREEN'),
|
|
|
|
|
profile, Logs.colors('NORMAL')))
|
|
|
|
|
bld = wutils.bld
|
|
|
|
|
print("%-30s: %s%s%s" % ("Build directory", Logs.colors('GREEN'),
|
|
|
|
|
Options.options.out, Logs.colors('NORMAL')))
|
2020-05-13 18:45:06 +01:00
|
|
|
|
|
|
|
|
|
2016-09-19 23:06:16 -07:00
|
|
|
for (name, caption, was_enabled, reason_not_enabled) in sorted(env['NS3_OPTIONAL_FEATURES'], key=lambda s : s[1]):
|
|
|
|
|
if was_enabled:
|
|
|
|
|
status = 'enabled'
|
|
|
|
|
color = 'GREEN'
|
|
|
|
|
else:
|
|
|
|
|
status = 'not enabled (%s)' % reason_not_enabled
|
|
|
|
|
color = 'RED'
|
|
|
|
|
print("%-30s: %s%s%s" % (caption, Logs.colors(color), status, Logs.colors('NORMAL')))
|
2015-06-23 14:32:41 +02:00
|
|
|
|
2021-06-13 19:06:39 -07:00
|
|
|
# Checking for boost headers and libraries
|
|
|
|
|
#
|
|
|
|
|
# There are four cases:
|
|
|
|
|
# A. Only need headers, and they are required
|
|
|
|
|
# B. Also need compiled libraries, and they are required
|
|
|
|
|
# C. Only use headers, but they are not required
|
|
|
|
|
# D. Use compiled libraries, but they are not required
|
|
|
|
|
#
|
|
|
|
|
# A. If you only need includes there are just two steps:
|
|
|
|
|
#
|
|
|
|
|
# A1. Add this in your module wscript configure function:
|
|
|
|
|
#
|
|
|
|
|
# if not conf.require_boost_incs('my-module', 'my module caption'):
|
|
|
|
|
# return
|
|
|
|
|
#
|
|
|
|
|
# A2. Do step FINAL below.
|
|
|
|
|
#
|
|
|
|
|
# B. If you also need some compiled boost libraries there are
|
|
|
|
|
# three steps (instead of the above):
|
|
|
|
|
#
|
|
|
|
|
# B1. Declare the libraries you need by adding to your module wscript:
|
|
|
|
|
#
|
|
|
|
|
# REQUIRED_BOOST_LIBS = ['lib1', 'lib2'...]
|
|
|
|
|
#
|
|
|
|
|
# def required_boost_libs(conf):
|
|
|
|
|
# conf.env['REQUIRED_BOOST_LIBS'] += REQUIRED_BOOST_LIBS
|
|
|
|
|
#
|
|
|
|
|
# B2. Check that the libs are present in your module wscript configure function:
|
|
|
|
|
#
|
|
|
|
|
# if conf.missing_boost_libs('my-module', 'my module caption', REQUIRED_BOOST_LIBS):
|
|
|
|
|
# return
|
|
|
|
|
#
|
|
|
|
|
# B3. Do step FINAL below.
|
|
|
|
|
#
|
|
|
|
|
# Finally,
|
|
|
|
|
#
|
|
|
|
|
# FINAL. Add boost to your module wscript build function:
|
|
|
|
|
#
|
|
|
|
|
# # Assuming you have
|
|
|
|
|
# # module = bld.create_ns3_module('my-module')
|
|
|
|
|
# module.use.append('BOOST')
|
|
|
|
|
#
|
|
|
|
|
# If your use of boost is optional it's even simpler.
|
|
|
|
|
#
|
|
|
|
|
# C. For optional headers only, the two steps above are modified a little:
|
|
|
|
|
#
|
|
|
|
|
# C1. Add this to your module wscript configure function:
|
|
|
|
|
#
|
|
|
|
|
# conf.require_boost_incs('my-module', 'my module caption', required=False)
|
|
|
|
|
# # Continue with config, adjusting for missing boost
|
|
|
|
|
#
|
|
|
|
|
# C2. Modify step FINAL as follows
|
|
|
|
|
#
|
|
|
|
|
# if bld.env['INCLUDES_BOOST']:
|
|
|
|
|
# module.use.append('BOOST')
|
|
|
|
|
#
|
|
|
|
|
# D. For compiled boost libraries
|
|
|
|
|
#
|
|
|
|
|
# D1. Do B1 above to declare the libraries you would like to use
|
|
|
|
|
#
|
|
|
|
|
# D2. If you need to take action at configure time,
|
|
|
|
|
# add to your module wscript configure function:
|
|
|
|
|
#
|
|
|
|
|
# missing_boost_libs = conf.missing_boost_libs('my-module', 'my module caption', REQUIRED_BOOST_LIBS, required=False)
|
|
|
|
|
# # Continue with config, adjusting for missing boost libs
|
|
|
|
|
#
|
|
|
|
|
# At this point you can inspect missing_boost_libs to see
|
|
|
|
|
# what libs were found and do the right thing.
|
|
|
|
|
# See below for preprocessor symbols which will be available
|
|
|
|
|
# in your source files.
|
|
|
|
|
#
|
|
|
|
|
# D3. If any of your libraries are present add to your
|
|
|
|
|
# module wscript build function:
|
|
|
|
|
#
|
|
|
|
|
# missing_boost_libs = bld.missing_boost_libs('lib-opt', REQUIRED_BOOST_LIBS)
|
|
|
|
|
# # Continue with build, adjusting for missing boost libs
|
|
|
|
|
#
|
|
|
|
|
# At this point you can inspect missing_boost_libs to see
|
|
|
|
|
# what libs were found and do the right thing.
|
|
|
|
|
#
|
|
|
|
|
# In all cases you can test for boost in your code with
|
|
|
|
|
#
|
|
|
|
|
# #ifdef HAVE_BOOST
|
|
|
|
|
#
|
|
|
|
|
# Each boost compiled library will be indicated with a 'HAVE_BOOST_<lib>'
|
|
|
|
|
# preprocessor symbol, which you can test. For example, for the boost
|
|
|
|
|
# Signals2 library:
|
|
|
|
|
#
|
|
|
|
|
# #ifdef HAVE_BOOST_SIGNALS2
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
def require_boost_incs(conf, module, caption, required=True):
|
|
|
|
|
|
|
|
|
|
conf.to_log('boost: %s wants incs, required: %s' % (module, required))
|
|
|
|
|
if conf.env['INCLUDES_BOOST']:
|
|
|
|
|
conf.to_log('boost: %s: have boost' % module)
|
|
|
|
|
return True
|
|
|
|
|
elif not required:
|
|
|
|
|
conf.to_log('boost: %s: no boost, but not required' % module)
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
conf.to_log('boost: %s: no boost, but required' % module)
|
|
|
|
|
conf.report_optional_feature(module, caption, False,
|
|
|
|
|
"boost headers required but not found")
|
|
|
|
|
|
|
|
|
|
# Add this module to the list of modules that won't be built
|
|
|
|
|
# if they are enabled.
|
|
|
|
|
conf.env['MODULES_NOT_BUILT'].append(module)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# Report any required boost libs which are missing
|
|
|
|
|
# Return values of truthy are bad; falsey is good:
|
|
|
|
|
# If all are present return False (non missing)
|
|
|
|
|
# If boost not present, or no libs return True
|
|
|
|
|
# If some libs present, return the list of missing libs
|
|
|
|
|
def conf_missing_boost_libs(conf, module, caption, libs, required= True):
|
|
|
|
|
conf.to_log('boost: %s wants %s, required: %s' % (module, libs, required))
|
|
|
|
|
|
|
|
|
|
if not conf.require_boost_incs(module, caption, required):
|
|
|
|
|
# No headers found, so the libs aren't there either
|
|
|
|
|
return libs
|
|
|
|
|
|
|
|
|
|
missing_boost_libs = [lib for lib in libs if lib not in conf.boost_libs]
|
|
|
|
|
|
|
|
|
|
if required and missing_boost_libs:
|
|
|
|
|
if not conf.env['LIB_BOOST']:
|
|
|
|
|
conf.to_log('boost: %s requires libs, but none found' % module)
|
|
|
|
|
conf.report_optional_feature(module, caption, False,
|
|
|
|
|
"No boost libraries were found")
|
|
|
|
|
else:
|
|
|
|
|
conf.to_log('boost: %s requires libs, but missing %s' % (module, missing_boost_libs))
|
|
|
|
|
conf.report_optional_feature(module, caption, False,
|
|
|
|
|
"Required boost libraries not found, missing: %s" % missing_boost_libs)
|
|
|
|
|
|
|
|
|
|
# Add this module to the list of modules that won't be built
|
|
|
|
|
# if they are enabled.
|
|
|
|
|
conf.env['MODULES_NOT_BUILT'].append(module)
|
|
|
|
|
return missing_boost_libs
|
|
|
|
|
|
|
|
|
|
# Required libraries were found, or are not required
|
|
|
|
|
return missing_boost_libs
|
|
|
|
|
|
|
|
|
|
def get_boost_libs(libs):
|
|
|
|
|
names = set()
|
|
|
|
|
for lib in libs:
|
|
|
|
|
if lib.startswith("boost_"):
|
|
|
|
|
lib = lib[6:]
|
|
|
|
|
if lib.endswith("-mt"):
|
|
|
|
|
lib = lib[:-3]
|
|
|
|
|
names.add(lib)
|
|
|
|
|
return names
|
|
|
|
|
|
|
|
|
|
def configure_boost(conf):
|
|
|
|
|
conf.to_log('boost: loading conf')
|
|
|
|
|
conf.load('boost')
|
|
|
|
|
|
|
|
|
|
# Find Boost libraries by modules
|
|
|
|
|
conf.to_log('boost: scanning for required libs')
|
|
|
|
|
conf.env['REQUIRED_BOOST_LIBS'] = []
|
|
|
|
|
for modules_dir in ['src', 'contrib']:
|
|
|
|
|
conf.recurse (modules_dir, name="get_required_boost_libs", mandatory=False)
|
|
|
|
|
# Check for any required boost libraries
|
|
|
|
|
if conf.env['REQUIRED_BOOST_LIBS'] is not []:
|
|
|
|
|
conf.env['REQUIRED_BOOST_LIBS'] = list(set(conf.env['REQUIRED_BOOST_LIBS']))
|
|
|
|
|
conf.to_log("boost: libs required: %s" % conf.env['REQUIRED_BOOST_LIBS'])
|
|
|
|
|
conf.check_boost(lib=' '.join (conf.env['REQUIRED_BOOST_LIBS']), mandatory=False, required=False)
|
|
|
|
|
if not conf.env['LIB_BOOST']:
|
|
|
|
|
conf.env['LIB_BOOST'] = []
|
|
|
|
|
else:
|
|
|
|
|
# Check with no libs, so we find the includes
|
|
|
|
|
conf.check_boost(mandatory=False, required=False)
|
|
|
|
|
|
|
|
|
|
conf.to_log('boost: checking if we should define HAVE_BOOST')
|
|
|
|
|
if conf.env['INCLUDES_BOOST']:
|
|
|
|
|
conf.to_log('boost: defining HAVE_BOOST')
|
|
|
|
|
conf.env.append_value ('CPPFLAGS', '-DHAVE_BOOST')
|
|
|
|
|
|
|
|
|
|
# Some boost libraries may have been found.
|
|
|
|
|
# Add preprocessor symbols for them
|
|
|
|
|
conf.to_log('boost: checking which libs are present')
|
|
|
|
|
if conf.env['LIB_BOOST']:
|
|
|
|
|
conf.boost_libs = get_boost_libs(conf.env['LIB_BOOST'])
|
|
|
|
|
for lib in conf.boost_libs:
|
|
|
|
|
msg='boost: lib present: ' + lib
|
|
|
|
|
if lib in conf.env['REQUIRED_BOOST_LIBS']:
|
|
|
|
|
have = '-DHAVE_BOOST_' + lib.upper()
|
|
|
|
|
conf.to_log('%s, requested, adding %s' % (msg, have))
|
|
|
|
|
conf.env.append_value('CPPFLAGS', have)
|
|
|
|
|
else:
|
|
|
|
|
conf.to_log('%s, not required, ignoring' % msg)
|
|
|
|
|
|
|
|
|
|
boost_libs_missing = [lib for lib in conf.env['REQUIRED_BOOST_LIBS'] if lib not in conf.boost_libs]
|
|
|
|
|
for lib in boost_libs_missing:
|
|
|
|
|
conf.to_log('boost: lib missing: %s' % lib)
|
|
|
|
|
|
|
|
|
|
def bld_missing_boost_libs (bld, module, libs):
|
|
|
|
|
missing_boost_libs = [lib for lib in libs if lib not in bld.boost_libs]
|
|
|
|
|
return missing_boost_libs
|
|
|
|
|
|
2007-05-07 12:01:51 +01:00
|
|
|
def configure(conf):
|
2021-03-27 09:56:55 -07:00
|
|
|
# Waf does not work correctly if the absolute path contains whitespaces
|
|
|
|
|
if (re.search(r"\s", os.getcwd ())):
|
|
|
|
|
conf.fatal('Waf does not support whitespace in the path to current working directory: %s' % os.getcwd())
|
|
|
|
|
|
2013-04-01 22:33:46 +02:00
|
|
|
conf.load('relocation', tooldir=['waf-tools'])
|
2011-09-26 10:41:55 +01:00
|
|
|
|
2008-09-05 18:16:29 +01:00
|
|
|
# attach some extra methods
|
2011-09-08 16:13:40 +01:00
|
|
|
conf.check_nonfatal = types.MethodType(_check_nonfatal, conf)
|
2009-04-13 23:10:37 +01:00
|
|
|
conf.check_compilation_flag = types.MethodType(_check_compilation_flag, conf)
|
2008-09-05 18:16:29 +01:00
|
|
|
conf.report_optional_feature = types.MethodType(report_optional_feature, conf)
|
2012-02-14 18:44:16 +00:00
|
|
|
conf.check_optional_feature = types.MethodType(check_optional_feature, conf)
|
2021-06-13 19:06:39 -07:00
|
|
|
conf.require_boost_incs = types.MethodType(require_boost_incs, conf)
|
|
|
|
|
conf.missing_boost_libs = types.MethodType(conf_missing_boost_libs, conf)
|
|
|
|
|
conf.boost_libs = set()
|
2008-09-05 18:16:29 +01:00
|
|
|
conf.env['NS3_OPTIONAL_FEATURES'] = []
|
|
|
|
|
|
2013-04-01 22:33:46 +02:00
|
|
|
conf.load('compiler_c')
|
2015-06-23 14:32:41 +02:00
|
|
|
cc_string = '.'.join(conf.env['CC_VERSION'])
|
2013-07-26 10:55:03 -07:00
|
|
|
conf.msg('Checking for cc version',cc_string,'GREEN')
|
2013-04-01 22:33:46 +02:00
|
|
|
conf.load('compiler_cxx')
|
|
|
|
|
conf.load('cflags', tooldir=['waf-tools'])
|
|
|
|
|
conf.load('command', tooldir=['waf-tools'])
|
|
|
|
|
conf.load('gnu_dirs')
|
2015-06-23 14:32:41 +02:00
|
|
|
conf.load('clang_compilation_database', tooldir=['waf-tools'])
|
2011-07-05 18:30:43 +01:00
|
|
|
|
2011-09-08 16:13:40 +01:00
|
|
|
env = conf.env
|
2009-06-25 14:15:27 +02:00
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
if Options.options.enable_gcov:
|
2011-09-12 19:19:00 +01:00
|
|
|
env['GCOV_ENABLED'] = True
|
2011-09-08 16:13:40 +01:00
|
|
|
env.append_value('CCFLAGS', '-fprofile-arcs')
|
|
|
|
|
env.append_value('CCFLAGS', '-ftest-coverage')
|
|
|
|
|
env.append_value('CXXFLAGS', '-fprofile-arcs')
|
|
|
|
|
env.append_value('CXXFLAGS', '-ftest-coverage')
|
2011-09-30 14:21:39 -07:00
|
|
|
env.append_value('LINKFLAGS', '-lgcov')
|
2014-11-20 10:50:30 -08:00
|
|
|
env.append_value('LINKFLAGS', '-coverage')
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2008-12-31 11:20:18 +00:00
|
|
|
if Options.options.build_profile == 'debug':
|
2015-07-28 16:33:35 -07:00
|
|
|
env.append_value('DEFINES', 'NS3_BUILD_PROFILE_DEBUG')
|
2011-09-13 13:47:17 +01:00
|
|
|
env.append_value('DEFINES', 'NS3_ASSERT_ENABLE')
|
|
|
|
|
env.append_value('DEFINES', 'NS3_LOG_ENABLE')
|
2007-09-11 14:44:23 +01:00
|
|
|
|
2015-07-28 16:33:35 -07:00
|
|
|
if Options.options.build_profile == 'release':
|
|
|
|
|
env.append_value('DEFINES', 'NS3_BUILD_PROFILE_RELEASE')
|
|
|
|
|
|
|
|
|
|
if Options.options.build_profile == 'optimized':
|
|
|
|
|
env.append_value('DEFINES', 'NS3_BUILD_PROFILE_OPTIMIZED')
|
|
|
|
|
|
2020-07-03 10:22:20 +02:00
|
|
|
if Options.options.enable_logs:
|
2020-07-03 18:58:00 +02:00
|
|
|
env.append_unique('DEFINES', 'NS3_LOG_ENABLE')
|
2020-07-03 10:22:20 +02:00
|
|
|
if Options.options.enable_asserts:
|
2020-07-03 18:58:00 +02:00
|
|
|
env.append_unique('DEFINES', 'NS3_ASSERT_ENABLE')
|
2020-07-03 10:22:20 +02:00
|
|
|
|
2009-02-11 18:07:52 -08:00
|
|
|
env['PLATFORM'] = sys.platform
|
2012-01-11 14:34:14 +00:00
|
|
|
env['BUILD_PROFILE'] = Options.options.build_profile
|
2012-07-12 12:35:31 +01:00
|
|
|
if Options.options.build_profile == "release":
|
|
|
|
|
env['BUILD_SUFFIX'] = ''
|
|
|
|
|
else:
|
|
|
|
|
env['BUILD_SUFFIX'] = '-'+Options.options.build_profile
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2012-01-13 10:17:39 -08:00
|
|
|
env['APPNAME'] = wutils.APPNAME
|
|
|
|
|
env['VERSION'] = wutils.VERSION
|
2009-02-11 18:07:52 -08:00
|
|
|
|
2018-05-20 07:13:47 -07:00
|
|
|
if conf.env['CXX_NAME'] in ['gcc']:
|
|
|
|
|
if tuple(map(int, conf.env['CC_VERSION'])) < gcc_min_version:
|
|
|
|
|
conf.fatal('gcc version %s older than minimum supported version %s' %
|
|
|
|
|
('.'.join(conf.env['CC_VERSION']), '.'.join(map(str, gcc_min_version))))
|
|
|
|
|
|
2009-09-25 12:28:32 +01:00
|
|
|
if conf.env['CXX_NAME'] in ['gcc', 'icc']:
|
2021-11-15 01:03:54 -03:00
|
|
|
env.append_value('CXXFLAGS', '-fno-semantic-interposition')
|
2020-05-13 18:45:06 +01:00
|
|
|
if Options.options.build_profile == 'release':
|
|
|
|
|
env.append_value('CXXFLAGS', '-fomit-frame-pointer')
|
|
|
|
|
if Options.options.build_profile == 'optimized':
|
2009-10-27 13:56:38 +03:00
|
|
|
if conf.check_compilation_flag('-march=native'):
|
2020-05-13 18:45:06 +01:00
|
|
|
env.append_value('CXXFLAGS', '-march=native')
|
2014-04-30 21:32:57 -07:00
|
|
|
env.append_value('CXXFLAGS', '-fstrict-overflow')
|
2018-05-20 07:13:47 -07:00
|
|
|
if conf.env['CXX_NAME'] in ['gcc']:
|
2016-09-13 16:14:13 -07:00
|
|
|
env.append_value('CXXFLAGS', '-Wstrict-overflow=2')
|
2009-10-27 13:56:38 +03:00
|
|
|
|
2009-04-17 12:44:11 +01:00
|
|
|
if sys.platform == 'win32':
|
2008-12-31 11:20:18 +00:00
|
|
|
env.append_value("LINKFLAGS", "-Wl,--enable-runtime-pseudo-reloc")
|
2009-04-17 12:44:11 +01:00
|
|
|
elif sys.platform == 'cygwin':
|
|
|
|
|
env.append_value("LINKFLAGS", "-Wl,--enable-auto-import")
|
2009-05-18 11:06:26 +01:00
|
|
|
|
2012-11-13 14:24:27 +01:00
|
|
|
cxx = env['CXX']
|
2012-11-16 22:23:40 +01:00
|
|
|
cxx_check_libstdcxx = cxx + ['-print-file-name=libstdc++.so']
|
2012-11-13 14:24:27 +01:00
|
|
|
p = subprocess.Popen(cxx_check_libstdcxx, stdout=subprocess.PIPE)
|
2015-09-09 15:14:27 -07:00
|
|
|
libstdcxx_output = maybe_decode(p.stdout.read().strip())
|
|
|
|
|
libstdcxx_location = os.path.dirname(libstdcxx_output)
|
2009-04-21 09:58:58 +02:00
|
|
|
p.wait()
|
2009-04-21 10:55:07 +01:00
|
|
|
if libstdcxx_location:
|
|
|
|
|
conf.env.append_value('NS3_MODULE_PATH', libstdcxx_location)
|
2007-05-17 17:02:03 +01:00
|
|
|
|
2018-08-24 18:02:14 -07:00
|
|
|
if Utils.unversioned_sys_platform() in ['linux']:
|
2009-05-18 14:10:49 +01:00
|
|
|
if conf.check_compilation_flag('-Wl,--soname=foo'):
|
|
|
|
|
env['WL_SONAME_SUPPORTED'] = True
|
2009-05-18 11:06:26 +01:00
|
|
|
|
2015-09-28 20:23:11 -07:00
|
|
|
# bug 2181 on clang warning suppressions
|
|
|
|
|
if conf.env['CXX_NAME'] in ['clang']:
|
2018-08-26 11:01:00 -07:00
|
|
|
if Utils.unversioned_sys_platform() == 'darwin':
|
2018-09-20 21:17:26 -07:00
|
|
|
if tuple(map(int, conf.env['CC_VERSION'])) >= darwin_clang_version_warn_unused_local_typedefs:
|
2015-09-28 20:23:11 -07:00
|
|
|
env.append_value('CXXFLAGS', '-Wno-unused-local-typedefs')
|
2021-06-13 19:06:39 -07:00
|
|
|
|
2018-09-20 21:17:26 -07:00
|
|
|
if tuple(map(int, conf.env['CC_VERSION'])) >= darwin_clang_version_warn_potentially_evaluated:
|
2021-06-13 19:06:39 -07:00
|
|
|
|
2015-09-28 20:23:11 -07:00
|
|
|
env.append_value('CXXFLAGS', '-Wno-potentially-evaluated-expression')
|
2021-06-13 19:06:39 -07:00
|
|
|
|
2015-09-28 20:23:11 -07:00
|
|
|
else:
|
2018-09-20 21:17:26 -07:00
|
|
|
if tuple(map(int, conf.env['CC_VERSION'])) >= clang_version_warn_unused_local_typedefs:
|
2021-06-13 19:06:39 -07:00
|
|
|
|
2015-09-28 20:23:11 -07:00
|
|
|
env.append_value('CXXFLAGS', '-Wno-unused-local-typedefs')
|
2021-06-13 19:06:39 -07:00
|
|
|
|
2018-09-20 21:17:26 -07:00
|
|
|
if tuple(map(int, conf.env['CC_VERSION'])) >= clang_version_warn_potentially_evaluated:
|
2015-09-28 20:23:11 -07:00
|
|
|
env.append_value('CXXFLAGS', '-Wno-potentially-evaluated-expression')
|
2021-06-13 19:06:39 -07:00
|
|
|
|
2011-05-27 14:48:14 -07:00
|
|
|
env['ENABLE_STATIC_NS3'] = False
|
2011-09-12 18:57:10 +01:00
|
|
|
if Options.options.enable_static:
|
2018-08-26 11:01:00 -07:00
|
|
|
if Utils.unversioned_sys_platform() == 'darwin':
|
2011-09-24 18:37:22 +01:00
|
|
|
if conf.check_compilation_flag(flag=[], linkflags=['-Wl,-all_load']):
|
2011-05-27 14:48:14 -07:00
|
|
|
conf.report_optional_feature("static", "Static build", True, '')
|
2011-09-24 18:37:22 +01:00
|
|
|
env['ENABLE_STATIC_NS3'] = True
|
|
|
|
|
else:
|
|
|
|
|
conf.report_optional_feature("static", "Static build", False,
|
|
|
|
|
"Link flag -Wl,-all_load does not work")
|
2011-05-27 14:48:14 -07:00
|
|
|
else:
|
2011-09-24 18:37:22 +01:00
|
|
|
if conf.check_compilation_flag(flag=[], linkflags=['-Wl,--whole-archive,-Bstatic', '-Wl,-Bdynamic,--no-whole-archive']):
|
|
|
|
|
conf.report_optional_feature("static", "Static build", True, '')
|
|
|
|
|
env['ENABLE_STATIC_NS3'] = True
|
|
|
|
|
else:
|
|
|
|
|
conf.report_optional_feature("static", "Static build", False,
|
|
|
|
|
"Link flag -Wl,--whole-archive,-Bstatic does not work")
|
2011-05-27 14:48:14 -07:00
|
|
|
|
2021-06-13 14:36:43 -07:00
|
|
|
# Checks if environment variable specifies the C++ language standard and/or
|
|
|
|
|
# if the user has specified the standard via the -cxx-standard argument
|
|
|
|
|
# to 'waf configure'. The following precedence and behavior is implemented:
|
|
|
|
|
# 1) if user does not specify anything, Waf will use the default standard
|
|
|
|
|
# configured for ns-3, which is configured below
|
|
|
|
|
# 2) if user specifies the '-cxx-standard' option, it will be used instead
|
|
|
|
|
# of the default.
|
|
|
|
|
# Example: ./waf configure --cxx-standard=-std=c++14
|
|
|
|
|
# 3) if user specifies the C++ standard via the CXXFLAGS environment
|
|
|
|
|
# variable, it will be used instead of the default.
|
|
|
|
|
# Example: CXXFLAGS="-std=c++14" ./waf configure
|
|
|
|
|
# 4) if user specifies both the CXXFLAGS environment variable and the
|
|
|
|
|
# -cxx-standard argument, the latter will take precedence and a warning
|
|
|
|
|
# will be emitted in the configure output if there were conflicting
|
|
|
|
|
# standards between the two.
|
|
|
|
|
# Example: CXXFLAGS="-std=c++14" ./waf configure --cxx-standard=-std=c++17
|
|
|
|
|
# (in the above scenario, Waf will use c++17 but warn about it)
|
|
|
|
|
# Note: If the C++ standard is not recognized, configuration will error exit
|
|
|
|
|
cxx_standard = ""
|
|
|
|
|
cxx_standard_env = ""
|
|
|
|
|
for flag in env['CXXFLAGS']:
|
|
|
|
|
if flag[:5] == "-std=":
|
|
|
|
|
cxx_standard_env = flag
|
|
|
|
|
|
|
|
|
|
if not cxx_standard_env and Options.options.cxx_standard:
|
|
|
|
|
cxx_standard = Options.options.cxx_standard
|
|
|
|
|
env.append_value('CXXFLAGS', cxx_standard)
|
|
|
|
|
elif cxx_standard_env and not Options.options.cxx_standard:
|
|
|
|
|
cxx_standard = cxx_standard_env
|
|
|
|
|
# No need to change CXXFLAGS
|
|
|
|
|
elif cxx_standard_env and Options.options.cxx_standard and cxx_standard_env != Options.options.cxx_standard:
|
|
|
|
|
Logs.warn("user-specified --cxx-standard (" +
|
|
|
|
|
Options.options.cxx_standard + ") does not match the value in CXXFLAGS (" + cxx_standard_env + "); Waf will use the --cxx-standard value")
|
|
|
|
|
cxx_standard = Options.options.cxx_standard
|
|
|
|
|
env['CXXFLAGS'].remove(cxx_standard_env)
|
|
|
|
|
env.append_value('CXXFLAGS', cxx_standard)
|
|
|
|
|
elif cxx_standard_env and Options.options.cxx_standard and cxx_standard_env == Options.options.cxx_standard:
|
|
|
|
|
cxx_standard = Options.options.cxx_standard
|
|
|
|
|
# No need to change CXXFLAGS
|
|
|
|
|
elif not cxx_standard and not Options.options.cxx_standard:
|
2021-09-14 16:43:01 +02:00
|
|
|
cxx_standard = "-std=c++17"
|
2021-06-13 14:36:43 -07:00
|
|
|
env.append_value('CXXFLAGS', cxx_standard)
|
|
|
|
|
|
|
|
|
|
if not conf.check_compilation_flag(cxx_standard):
|
|
|
|
|
raise Errors.ConfigurationError("Exiting because C++ standard value " + cxx_standard + " is not recognized")
|
2016-05-17 09:19:08 -07:00
|
|
|
|
2021-06-13 19:06:39 -07:00
|
|
|
# Handle boost
|
|
|
|
|
configure_boost(conf)
|
2018-12-06 17:43:16 -08:00
|
|
|
|
2011-12-14 21:50:12 -08:00
|
|
|
# Set this so that the lists won't be printed at the end of this
|
|
|
|
|
# configure command.
|
|
|
|
|
conf.env['PRINT_BUILT_MODULES_AT_END'] = False
|
|
|
|
|
|
2011-05-30 15:30:49 -07:00
|
|
|
conf.env['MODULES_NOT_BUILT'] = []
|
|
|
|
|
|
2013-04-01 22:33:46 +02:00
|
|
|
conf.recurse('bindings/python')
|
2012-02-14 18:44:16 +00:00
|
|
|
|
2013-04-01 22:33:46 +02:00
|
|
|
conf.recurse('src')
|
2017-04-06 20:32:04 -07:00
|
|
|
conf.recurse('contrib')
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2011-03-04 15:41:14 -08:00
|
|
|
# Set the list of enabled modules.
|
2008-12-29 13:28:54 +00:00
|
|
|
if Options.options.enable_modules:
|
2020-05-13 18:45:06 +01:00
|
|
|
# Use the modules explicitly enabled.
|
2017-04-06 20:32:04 -07:00
|
|
|
_enabled_mods = []
|
|
|
|
|
_enabled_contrib_mods = []
|
2020-05-13 18:45:06 +01:00
|
|
|
for mod in Options.options.enable_modules.split(','):
|
|
|
|
|
if mod in conf.env['NS3_MODULES'] and mod.startswith('ns3-'):
|
2017-04-06 20:32:04 -07:00
|
|
|
_enabled_mods.append(mod)
|
2020-05-13 18:45:06 +01:00
|
|
|
elif 'ns3-' + mod in conf.env['NS3_MODULES']:
|
2017-04-06 20:32:04 -07:00
|
|
|
_enabled_mods.append('ns3-' + mod)
|
2020-05-13 18:45:06 +01:00
|
|
|
elif mod in conf.env['NS3_CONTRIBUTED_MODULES'] and mod.startswith('ns3-'):
|
2017-04-06 20:32:04 -07:00
|
|
|
_enabled_contrib_mods.append(mod)
|
2020-05-13 18:45:06 +01:00
|
|
|
elif 'ns3-' + mod in conf.env['NS3_CONTRIBUTED_MODULES']:
|
2017-04-06 20:32:04 -07:00
|
|
|
_enabled_contrib_mods.append('ns3-' + mod)
|
|
|
|
|
conf.env['NS3_ENABLED_MODULES'] = _enabled_mods
|
|
|
|
|
conf.env['NS3_ENABLED_CONTRIBUTED_MODULES'] = _enabled_contrib_mods
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2011-03-04 15:41:14 -08:00
|
|
|
else:
|
|
|
|
|
# Use the enabled modules list from the ns3 configuration file.
|
|
|
|
|
if modules_enabled[0] == 'all_modules':
|
|
|
|
|
# Enable all modules if requested.
|
|
|
|
|
conf.env['NS3_ENABLED_MODULES'] = conf.env['NS3_MODULES']
|
2017-04-06 20:32:04 -07:00
|
|
|
conf.env['NS3_ENABLED_CONTRIBUTED_MODULES'] = conf.env['NS3_CONTRIBUTED_MODULES']
|
2011-03-04 15:41:14 -08:00
|
|
|
else:
|
|
|
|
|
# Enable the modules from the list.
|
2017-04-06 20:32:04 -07:00
|
|
|
_enabled_mods = []
|
|
|
|
|
_enabled_contrib_mods = []
|
2020-05-13 18:45:06 +01:00
|
|
|
for mod in modules_enabled:
|
|
|
|
|
if mod in conf.env['NS3_MODULES'] and mod.startswith('ns3-'):
|
2017-04-06 20:32:04 -07:00
|
|
|
_enabled_mods.append(mod)
|
2020-05-13 18:45:06 +01:00
|
|
|
elif 'ns3-' + mod in conf.env['NS3_MODULES']:
|
2017-04-06 20:32:04 -07:00
|
|
|
_enabled_mods.append('ns3-' + mod)
|
2020-05-13 18:45:06 +01:00
|
|
|
elif mod in conf.env['NS3_CONTRIBUTED_MODULES'] and mod.startswith('ns3-'):
|
2017-04-06 20:32:04 -07:00
|
|
|
_enabled_contrib_mods.append(mod)
|
2020-05-13 18:45:06 +01:00
|
|
|
elif 'ns3-' + mod in conf.env['NS3_CONTRIBUTED_MODULES']:
|
2017-04-06 20:32:04 -07:00
|
|
|
_enabled_contrib_mods.append('ns3-' + mod)
|
|
|
|
|
conf.env['NS3_ENABLED_MODULES'] = _enabled_mods
|
|
|
|
|
conf.env['NS3_ENABLED_CONTRIBUTED_MODULES'] = _enabled_contrib_mods
|
2011-05-27 14:48:14 -07:00
|
|
|
|
2011-05-30 15:30:49 -07:00
|
|
|
# Add the template module to the list of enabled modules that
|
|
|
|
|
# should not be built if this is a static build on Darwin. They
|
|
|
|
|
# don't work there for the template module, and this is probably
|
|
|
|
|
# because the template module has no source files.
|
|
|
|
|
if conf.env['ENABLE_STATIC_NS3'] and sys.platform == 'darwin':
|
|
|
|
|
conf.env['MODULES_NOT_BUILT'].append('template')
|
|
|
|
|
|
|
|
|
|
# Remove these modules from the list of enabled modules.
|
|
|
|
|
for not_built in conf.env['MODULES_NOT_BUILT']:
|
|
|
|
|
not_built_name = 'ns3-' + not_built
|
|
|
|
|
if not_built_name in conf.env['NS3_ENABLED_MODULES']:
|
|
|
|
|
conf.env['NS3_ENABLED_MODULES'].remove(not_built_name)
|
2011-05-27 14:48:14 -07:00
|
|
|
if not conf.env['NS3_ENABLED_MODULES']:
|
2011-09-13 17:50:05 +01:00
|
|
|
raise WafError('Exiting because the ' + not_built + ' module can not be built and it was the only one enabled.')
|
2017-04-06 20:32:04 -07:00
|
|
|
elif not_built_name in conf.env['NS3_ENABLED_CONTRIBUTED_MODULES']:
|
|
|
|
|
conf.env['NS3_ENABLED_CONTRIBUTED_MODULES'].remove(not_built_name)
|
2007-12-09 14:39:07 +00:00
|
|
|
|
2008-10-27 13:01:28 -07:00
|
|
|
# for suid bits
|
2011-09-21 19:10:14 +01:00
|
|
|
try:
|
|
|
|
|
conf.find_program('sudo', var='SUDO')
|
|
|
|
|
except WafError:
|
|
|
|
|
pass
|
2008-10-27 13:01:28 -07:00
|
|
|
|
2009-01-31 20:48:05 -08:00
|
|
|
why_not_sudo = "because we like it"
|
|
|
|
|
if Options.options.enable_sudo and conf.env['SUDO']:
|
|
|
|
|
env['ENABLE_SUDO'] = True
|
|
|
|
|
else:
|
|
|
|
|
env['ENABLE_SUDO'] = False
|
|
|
|
|
if Options.options.enable_sudo:
|
|
|
|
|
why_not_sudo = "program sudo not found"
|
|
|
|
|
else:
|
|
|
|
|
why_not_sudo = "option --enable-sudo not selected"
|
|
|
|
|
|
|
|
|
|
conf.report_optional_feature("ENABLE_SUDO", "Use sudo to set suid bit", env['ENABLE_SUDO'], why_not_sudo)
|
|
|
|
|
|
2011-04-12 10:39:17 -07:00
|
|
|
# Decide if tests will be built or not.
|
2011-04-06 10:13:04 -07:00
|
|
|
if Options.options.enable_tests:
|
2020-05-13 18:45:06 +01:00
|
|
|
# Tests were explicitly enabled.
|
2011-04-06 10:13:04 -07:00
|
|
|
env['ENABLE_TESTS'] = True
|
|
|
|
|
why_not_tests = "option --enable-tests selected"
|
2011-04-12 10:39:17 -07:00
|
|
|
elif Options.options.disable_tests:
|
2020-05-13 18:45:06 +01:00
|
|
|
# Tests were explicitly disabled.
|
2011-04-06 10:13:04 -07:00
|
|
|
env['ENABLE_TESTS'] = False
|
2011-04-12 10:39:17 -07:00
|
|
|
why_not_tests = "option --disable-tests selected"
|
|
|
|
|
else:
|
|
|
|
|
# Enable tests based on the ns3 configuration file.
|
|
|
|
|
env['ENABLE_TESTS'] = tests_enabled
|
|
|
|
|
if config_file_exists:
|
|
|
|
|
why_not_tests = "based on configuration file"
|
|
|
|
|
elif tests_enabled:
|
|
|
|
|
why_not_tests = "defaults to enabled"
|
|
|
|
|
else:
|
|
|
|
|
why_not_tests = "defaults to disabled"
|
2011-04-06 10:13:04 -07:00
|
|
|
|
2016-07-05 15:18:47 -07:00
|
|
|
conf.report_optional_feature("ENABLE_TESTS", "Tests", env['ENABLE_TESTS'], why_not_tests)
|
2011-04-06 10:13:04 -07:00
|
|
|
|
2011-04-12 10:39:17 -07:00
|
|
|
# Decide if examples will be built or not.
|
2009-10-06 19:34:29 -07:00
|
|
|
if Options.options.enable_examples:
|
2020-05-13 18:45:06 +01:00
|
|
|
# Examples were explicitly enabled.
|
2009-10-06 19:34:29 -07:00
|
|
|
env['ENABLE_EXAMPLES'] = True
|
2011-04-12 10:39:17 -07:00
|
|
|
why_not_examples = "option --enable-examples selected"
|
|
|
|
|
elif Options.options.disable_examples:
|
2020-05-13 18:45:06 +01:00
|
|
|
# Examples were explicitly disabled.
|
2009-10-06 19:34:29 -07:00
|
|
|
env['ENABLE_EXAMPLES'] = False
|
|
|
|
|
why_not_examples = "option --disable-examples selected"
|
2011-04-12 10:39:17 -07:00
|
|
|
else:
|
|
|
|
|
# Enable examples based on the ns3 configuration file.
|
|
|
|
|
env['ENABLE_EXAMPLES'] = examples_enabled
|
|
|
|
|
if config_file_exists:
|
|
|
|
|
why_not_examples = "based on configuration file"
|
|
|
|
|
elif examples_enabled:
|
|
|
|
|
why_not_examples = "defaults to enabled"
|
|
|
|
|
else:
|
|
|
|
|
why_not_examples = "defaults to disabled"
|
2009-10-06 19:34:29 -07:00
|
|
|
|
2020-05-13 18:45:06 +01:00
|
|
|
conf.report_optional_feature("ENABLE_EXAMPLES", "Examples", env['ENABLE_EXAMPLES'],
|
2009-10-06 19:34:29 -07:00
|
|
|
why_not_examples)
|
2015-09-06 22:19:22 -07:00
|
|
|
try:
|
|
|
|
|
for dir in os.listdir('examples'):
|
|
|
|
|
if dir.startswith('.') or dir == 'CVS':
|
|
|
|
|
continue
|
|
|
|
|
conf.env.append_value('EXAMPLE_DIRECTORIES', dir)
|
|
|
|
|
except OSError:
|
|
|
|
|
return
|
2009-10-06 19:34:29 -07:00
|
|
|
|
2013-06-14 16:31:10 -07:00
|
|
|
env['VALGRIND_FOUND'] = False
|
2011-09-21 19:10:14 +01:00
|
|
|
try:
|
|
|
|
|
conf.find_program('valgrind', var='VALGRIND')
|
2013-06-14 16:31:10 -07:00
|
|
|
env['VALGRIND_FOUND'] = True
|
2011-09-21 19:10:14 +01:00
|
|
|
except WafError:
|
|
|
|
|
pass
|
2009-01-24 18:09:29 +00:00
|
|
|
|
2011-03-18 10:58:21 -07:00
|
|
|
# These flags are used for the implicitly dependent modules.
|
|
|
|
|
if env['ENABLE_STATIC_NS3']:
|
|
|
|
|
if sys.platform == 'darwin':
|
2013-04-01 22:33:46 +02:00
|
|
|
env.STLIB_MARKER = '-Wl,-all_load'
|
2011-03-18 10:58:21 -07:00
|
|
|
else:
|
2013-04-01 22:33:46 +02:00
|
|
|
env.STLIB_MARKER = '-Wl,--whole-archive,-Bstatic'
|
2011-03-18 10:58:21 -07:00
|
|
|
env.SHLIB_MARKER = '-Wl,-Bdynamic,--no-whole-archive'
|
|
|
|
|
|
2009-09-12 20:00:36 -07:00
|
|
|
|
2013-04-01 22:33:46 +02:00
|
|
|
have_gsl = conf.check_cfg(package='gsl', args=['--cflags', '--libs'],
|
|
|
|
|
uselib_store='GSL', mandatory=False)
|
|
|
|
|
conf.env['ENABLE_GSL'] = have_gsl
|
2009-09-12 20:00:36 -07:00
|
|
|
conf.report_optional_feature("GSL", "GNU Scientific Library (GSL)",
|
|
|
|
|
conf.env['ENABLE_GSL'],
|
|
|
|
|
"GSL not found")
|
2009-04-21 14:38:47 +02:00
|
|
|
|
2016-09-02 22:40:07 -04:00
|
|
|
why_not_desmetrics = "defaults to disabled"
|
|
|
|
|
if Options.options.enable_desmetrics:
|
|
|
|
|
conf.env['ENABLE_DES_METRICS'] = True
|
|
|
|
|
env.append_value('DEFINES', 'ENABLE_DES_METRICS')
|
|
|
|
|
why_not_desmetrics = "option --enable-des-metrics selected"
|
|
|
|
|
conf.report_optional_feature("DES Metrics", "DES Metrics event collection", conf.env['ENABLE_DES_METRICS'], why_not_desmetrics)
|
|
|
|
|
|
2015-12-16 11:48:03 +01:00
|
|
|
|
2010-02-18 15:37:51 +00:00
|
|
|
# for compiling C code, copy over the CXX* flags
|
|
|
|
|
conf.env.append_value('CCFLAGS', conf.env['CXXFLAGS'])
|
|
|
|
|
|
2010-06-17 09:56:38 +01:00
|
|
|
def add_gcc_flag(flag):
|
|
|
|
|
if env['COMPILER_CXX'] == 'g++' and 'CXXFLAGS' not in os.environ:
|
|
|
|
|
if conf.check_compilation_flag(flag, mode='cxx'):
|
|
|
|
|
env.append_value('CXXFLAGS', flag)
|
|
|
|
|
if env['COMPILER_CC'] == 'gcc' and 'CCFLAGS' not in os.environ:
|
|
|
|
|
if conf.check_compilation_flag(flag, mode='cc'):
|
|
|
|
|
env.append_value('CCFLAGS', flag)
|
|
|
|
|
|
|
|
|
|
add_gcc_flag('-fstrict-aliasing')
|
|
|
|
|
add_gcc_flag('-Wstrict-aliasing')
|
|
|
|
|
|
2011-09-13 13:47:17 +01:00
|
|
|
try:
|
|
|
|
|
conf.find_program('doxygen', var='DOXYGEN')
|
|
|
|
|
except WafError:
|
|
|
|
|
pass
|
2010-03-02 15:29:53 +00:00
|
|
|
|
2009-10-23 17:35:38 +04:00
|
|
|
# append user defined flags after all our ones
|
|
|
|
|
for (confvar, envvar) in [['CCFLAGS', 'CCFLAGS_EXTRA'],
|
|
|
|
|
['CXXFLAGS', 'CXXFLAGS_EXTRA'],
|
|
|
|
|
['LINKFLAGS', 'LINKFLAGS_EXTRA'],
|
|
|
|
|
['LINKFLAGS', 'LDFLAGS_EXTRA']]:
|
|
|
|
|
if envvar in os.environ:
|
2010-11-20 17:55:53 +00:00
|
|
|
value = shlex.split(os.environ[envvar])
|
|
|
|
|
conf.env.append_value(confvar, value)
|
2009-10-23 17:35:38 +04:00
|
|
|
|
2016-09-19 23:06:16 -07:00
|
|
|
print_config(env)
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2011-09-12 14:54:27 +01:00
|
|
|
|
2013-04-01 22:33:46 +02:00
|
|
|
class SuidBuild_task(Task.Task):
|
2008-10-27 13:01:28 -07:00
|
|
|
"""task that makes a binary Suid
|
|
|
|
|
"""
|
2019-04-21 11:52:53 -07:00
|
|
|
after = ['cxxprogram', 'cxxshlib', 'cxxstlib']
|
2011-09-12 14:54:27 +01:00
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
super(SuidBuild_task, self).__init__(*args, **kwargs)
|
2008-10-27 13:01:28 -07:00
|
|
|
self.m_display = 'build-suid'
|
|
|
|
|
try:
|
2012-01-20 20:05:33 +00:00
|
|
|
program_obj = wutils.find_program(self.generator.name, self.generator.env)
|
2015-09-03 21:14:55 -07:00
|
|
|
except ValueError as ex:
|
2011-09-12 14:54:27 +01:00
|
|
|
raise WafError(str(ex))
|
|
|
|
|
program_node = program_obj.path.find_or_declare(program_obj.target)
|
2013-04-01 22:33:46 +02:00
|
|
|
self.filename = program_node.get_bld().abspath()
|
2009-02-03 08:31:48 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def run(self):
|
2015-09-03 21:14:55 -07:00
|
|
|
print('setting suid bit on executable ' + self.filename, file=sys.stderr)
|
2009-02-03 08:31:48 -08:00
|
|
|
if subprocess.Popen(['sudo', 'chown', 'root', self.filename]).wait():
|
|
|
|
|
return 1
|
|
|
|
|
if subprocess.Popen(['sudo', 'chmod', 'u+s', self.filename]).wait():
|
|
|
|
|
return 1
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
def runnable_status(self):
|
|
|
|
|
"RUN_ME SKIP_ME or ASK_LATER"
|
2012-01-23 11:11:08 +00:00
|
|
|
try:
|
|
|
|
|
st = os.stat(self.filename)
|
|
|
|
|
except OSError:
|
|
|
|
|
return Task.ASK_LATER
|
2009-02-03 08:31:48 -08:00
|
|
|
if st.st_uid == 0:
|
2011-09-08 16:13:40 +01:00
|
|
|
return Task.SKIP_ME
|
2009-02-03 08:31:48 -08:00
|
|
|
else:
|
2011-09-08 16:13:40 +01:00
|
|
|
return Task.RUN_ME
|
2008-10-27 13:01:28 -07:00
|
|
|
|
|
|
|
|
def create_suid_program(bld, name):
|
2011-09-12 14:54:27 +01:00
|
|
|
grp = bld.current_group
|
|
|
|
|
bld.add_group() # this to make sure no two sudo tasks run at the same time
|
2013-04-01 22:33:46 +02:00
|
|
|
program = bld(features='cxx cxxprogram')
|
2008-10-27 13:01:28 -07:00
|
|
|
program.is_ns3_program = True
|
|
|
|
|
program.module_deps = list()
|
|
|
|
|
program.name = name
|
2012-07-12 12:35:31 +01:00
|
|
|
program.target = "%s%s-%s%s" % (wutils.APPNAME, wutils.VERSION, name, bld.env.BUILD_SUFFIX)
|
2009-01-27 20:26:34 -08:00
|
|
|
|
2009-01-31 20:48:05 -08:00
|
|
|
if bld.env['ENABLE_SUDO']:
|
2018-10-04 16:27:38 -07:00
|
|
|
program.create_task("SuidBuild_task")
|
2011-09-12 14:54:27 +01:00
|
|
|
|
|
|
|
|
bld.set_group(grp)
|
2009-01-31 20:48:05 -08:00
|
|
|
|
2008-10-27 13:01:28 -07:00
|
|
|
return program
|
|
|
|
|
|
2011-02-18 16:05:39 -08:00
|
|
|
def create_ns3_program(bld, name, dependencies=('core',)):
|
2013-04-01 22:33:46 +02:00
|
|
|
program = bld(features='cxx cxxprogram')
|
2011-11-11 00:13:30 -08:00
|
|
|
|
2008-04-26 21:54:36 +01:00
|
|
|
program.is_ns3_program = True
|
2007-08-08 15:10:36 +01:00
|
|
|
program.name = name
|
2012-07-12 12:35:31 +01:00
|
|
|
program.target = "%s%s-%s%s" % (wutils.APPNAME, wutils.VERSION, name, bld.env.BUILD_SUFFIX)
|
2011-03-18 10:58:21 -07:00
|
|
|
# Each of the modules this program depends on has its own library.
|
2007-11-20 18:27:43 +00:00
|
|
|
program.ns3_module_dependencies = ['ns3-'+dep for dep in dependencies]
|
2021-01-07 00:46:26 +01:00
|
|
|
program.includes = Context.out_dir
|
2020-07-24 22:06:08 -07:00
|
|
|
#make a copy here to prevent additions to program.use from polluting program.ns3_module_dependencies
|
|
|
|
|
program.use = program.ns3_module_dependencies.copy()
|
2011-09-13 17:21:44 +01:00
|
|
|
if program.env['ENABLE_STATIC_NS3']:
|
|
|
|
|
if sys.platform == 'darwin':
|
|
|
|
|
program.env.STLIB_MARKER = '-Wl,-all_load'
|
|
|
|
|
else:
|
2013-04-01 22:33:46 +02:00
|
|
|
program.env.STLIB_MARKER = '-Wl,-Bstatic,--whole-archive'
|
2011-09-13 17:21:44 +01:00
|
|
|
program.env.SHLIB_MARKER = '-Wl,-Bdynamic,--no-whole-archive'
|
2011-11-11 00:13:30 -08:00
|
|
|
else:
|
|
|
|
|
if program.env.DEST_BINFMT == 'elf':
|
|
|
|
|
# All ELF platforms are impacted but only the gcc compiler has a flag to fix it.
|
2020-05-13 18:45:06 +01:00
|
|
|
if 'gcc' in (program.env.CXX_NAME, program.env.CC_NAME):
|
2011-11-11 00:13:30 -08:00
|
|
|
program.env.append_value ('SHLIB_MARKER', '-Wl,--no-as-needed')
|
|
|
|
|
|
2007-08-08 15:10:36 +01:00
|
|
|
return program
|
|
|
|
|
|
2011-04-28 09:10:29 -07:00
|
|
|
def register_ns3_script(bld, name, dependencies=('core',)):
|
|
|
|
|
ns3_module_dependencies = ['ns3-'+dep for dep in dependencies]
|
2011-09-08 16:13:40 +01:00
|
|
|
bld.env.append_value('NS3_SCRIPT_DEPENDENCIES', [(name, ns3_module_dependencies)])
|
2011-04-28 09:10:29 -07:00
|
|
|
|
2009-12-11 15:53:54 +01:00
|
|
|
def add_examples_programs(bld):
|
2011-09-08 16:13:40 +01:00
|
|
|
env = bld.env
|
2009-12-11 15:53:54 +01:00
|
|
|
if env['ENABLE_EXAMPLES']:
|
2020-05-26 21:42:16 +00:00
|
|
|
# Add a define, so this is testable from code
|
|
|
|
|
env.append_value('DEFINES', 'NS3_ENABLE_EXAMPLES')
|
|
|
|
|
|
2015-07-07 13:37:52 +02:00
|
|
|
try:
|
|
|
|
|
for dir in os.listdir('examples'):
|
|
|
|
|
if dir.startswith('.') or dir == 'CVS':
|
|
|
|
|
continue
|
|
|
|
|
if os.path.isdir(os.path.join('examples', dir)):
|
|
|
|
|
bld.recurse(os.path.join('examples', dir))
|
|
|
|
|
except OSError:
|
|
|
|
|
return
|
2009-12-11 15:53:54 +01:00
|
|
|
|
2008-06-16 14:17:27 +01:00
|
|
|
def add_scratch_programs(bld):
|
2017-04-06 20:32:04 -07:00
|
|
|
all_modules = [mod[len("ns3-"):] for mod in bld.env['NS3_ENABLED_MODULES'] + bld.env['NS3_ENABLED_CONTRIBUTED_MODULES']]
|
|
|
|
|
|
2015-07-07 13:37:52 +02:00
|
|
|
try:
|
|
|
|
|
for filename in os.listdir("scratch"):
|
|
|
|
|
if filename.startswith('.') or filename == 'CVS':
|
|
|
|
|
continue
|
|
|
|
|
if os.path.isdir(os.path.join("scratch", filename)):
|
|
|
|
|
obj = bld.create_ns3_program(filename, all_modules)
|
|
|
|
|
obj.path = obj.path.find_dir('scratch').find_dir(filename)
|
|
|
|
|
obj.source = obj.path.ant_glob('*.cc')
|
|
|
|
|
obj.target = filename
|
|
|
|
|
obj.name = obj.target
|
|
|
|
|
obj.install_path = None
|
|
|
|
|
elif filename.endswith(".cc"):
|
|
|
|
|
name = filename[:-len(".cc")]
|
|
|
|
|
obj = bld.create_ns3_program(name, all_modules)
|
|
|
|
|
obj.path = obj.path.find_dir('scratch')
|
|
|
|
|
obj.source = filename
|
|
|
|
|
obj.target = name
|
|
|
|
|
obj.name = obj.target
|
|
|
|
|
obj.install_path = None
|
|
|
|
|
except OSError:
|
|
|
|
|
return
|
2007-08-08 15:10:36 +01:00
|
|
|
|
2011-09-12 14:54:27 +01:00
|
|
|
def _get_all_task_gen(self):
|
|
|
|
|
for group in self.groups:
|
|
|
|
|
for taskgen in group:
|
|
|
|
|
yield taskgen
|
2011-09-08 16:13:40 +01:00
|
|
|
|
2011-07-03 12:01:29 +01:00
|
|
|
|
2011-09-12 14:54:27 +01:00
|
|
|
# ok, so WAF does not provide an API to prevent an
|
|
|
|
|
# arbitrary taskgen from running; we have to muck around with
|
|
|
|
|
# WAF internal state, something that might stop working if
|
|
|
|
|
# WAF is upgraded...
|
|
|
|
|
def _exclude_taskgen(self, taskgen):
|
|
|
|
|
for group in self.groups:
|
|
|
|
|
for tg1 in group:
|
|
|
|
|
if tg1 is taskgen:
|
|
|
|
|
group.remove(tg1)
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
continue
|
|
|
|
|
break
|
2011-09-08 16:13:40 +01:00
|
|
|
|
|
|
|
|
|
2012-04-06 16:05:51 +01:00
|
|
|
def _find_ns3_module(self, name):
|
|
|
|
|
for obj in _get_all_task_gen(self):
|
|
|
|
|
# disable the modules themselves
|
|
|
|
|
if hasattr(obj, "is_ns3_module") and obj.name == name:
|
|
|
|
|
return obj
|
|
|
|
|
raise KeyError(name)
|
|
|
|
|
|
2016-09-19 23:06:16 -07:00
|
|
|
# Parse the waf lockfile generated by latest 'configure' operation
|
|
|
|
|
def get_build_profile(env=None):
|
2018-03-05 20:59:15 -08:00
|
|
|
if env:
|
|
|
|
|
return Options.options.build_profile
|
|
|
|
|
|
|
|
|
|
lockfile = os.environ.get('WAFLOCK', '.lock-waf_%s_build' % sys.platform)
|
|
|
|
|
with open(lockfile, "r") as f:
|
|
|
|
|
for line in f:
|
|
|
|
|
if line.startswith("options ="):
|
|
|
|
|
_, val = line.split('=', 1)
|
|
|
|
|
for x in val.split(','):
|
|
|
|
|
optkey, optval = x.split(':')
|
|
|
|
|
if (optkey.lstrip() == '\'build_profile\''):
|
|
|
|
|
return str(optval.lstrip()).replace("'","")
|
|
|
|
|
|
|
|
|
|
return "not found"
|
2016-09-19 23:06:16 -07:00
|
|
|
|
|
|
|
|
def build(bld):
|
|
|
|
|
env = bld.env
|
|
|
|
|
|
|
|
|
|
if Options.options.check_config:
|
|
|
|
|
print_config(env, 'build')
|
|
|
|
|
else:
|
|
|
|
|
if Options.options.check_profile:
|
|
|
|
|
profile = get_build_profile()
|
|
|
|
|
print("Build profile: %s" % profile)
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2016-09-19 23:06:16 -07:00
|
|
|
if Options.options.check_profile or Options.options.check_config:
|
2016-01-06 09:11:14 -08:00
|
|
|
raise SystemExit(0)
|
|
|
|
|
return
|
|
|
|
|
|
2011-05-04 11:20:20 -07:00
|
|
|
# If --enabled-modules option was given, then print a warning
|
|
|
|
|
# message and exit this function.
|
|
|
|
|
if Options.options.enable_modules:
|
|
|
|
|
Logs.warn("No modules were built. Use waf configure --enable-modules to enable modules.")
|
|
|
|
|
return
|
|
|
|
|
|
2011-03-21 11:26:56 -07:00
|
|
|
bld.env['NS3_MODULES_WITH_TEST_LIBRARIES'] = []
|
2011-03-18 10:58:21 -07:00
|
|
|
bld.env['NS3_ENABLED_MODULE_TEST_LIBRARIES'] = []
|
2011-04-28 09:10:29 -07:00
|
|
|
bld.env['NS3_SCRIPT_DEPENDENCIES'] = []
|
|
|
|
|
bld.env['NS3_RUNNABLE_PROGRAMS'] = []
|
|
|
|
|
bld.env['NS3_RUNNABLE_SCRIPTS'] = []
|
2011-03-18 10:58:21 -07:00
|
|
|
|
2009-04-13 23:10:37 +01:00
|
|
|
wutils.bld = bld
|
2008-12-29 13:28:54 +00:00
|
|
|
if Options.options.no_task_lines:
|
2013-04-01 22:33:46 +02:00
|
|
|
from waflib import Runner
|
2008-04-03 14:15:17 +01:00
|
|
|
def null_printout(s):
|
|
|
|
|
pass
|
|
|
|
|
Runner.printout = null_printout
|
|
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
Options.cwd_launch = bld.path.abspath()
|
2007-08-08 15:10:36 +01:00
|
|
|
bld.create_ns3_program = types.MethodType(create_ns3_program, bld)
|
2011-04-28 09:10:29 -07:00
|
|
|
bld.register_ns3_script = types.MethodType(register_ns3_script, bld)
|
2008-10-27 13:01:28 -07:00
|
|
|
bld.create_suid_program = types.MethodType(create_suid_program, bld)
|
2011-09-12 14:54:27 +01:00
|
|
|
bld.__class__.all_task_gen = property(_get_all_task_gen)
|
|
|
|
|
bld.exclude_taskgen = types.MethodType(_exclude_taskgen, bld)
|
2012-04-06 16:05:51 +01:00
|
|
|
bld.find_ns3_module = types.MethodType(_find_ns3_module, bld)
|
2021-06-13 19:06:39 -07:00
|
|
|
bld.missing_boost_libs = types.MethodType(bld_missing_boost_libs, bld)
|
2008-12-29 13:28:54 +00:00
|
|
|
|
2013-02-18 20:22:50 -08:00
|
|
|
# Clean documentation build directories; other cleaning happens later
|
|
|
|
|
if bld.cmd == 'clean':
|
|
|
|
|
_cleandocs()
|
|
|
|
|
|
2021-06-13 19:06:39 -07:00
|
|
|
# Cache available boost lib names
|
|
|
|
|
bld.boost_libs = set()
|
|
|
|
|
if bld.env['LIB_BOOST']:
|
|
|
|
|
bld.boost_libs = get_boost_libs(bld.env['LIB_BOOST'])
|
|
|
|
|
|
|
|
|
|
|
2007-05-07 12:01:51 +01:00
|
|
|
# process subfolders from here
|
2013-04-01 22:33:46 +02:00
|
|
|
bld.recurse('src')
|
2017-04-06 20:32:04 -07:00
|
|
|
bld.recurse('contrib')
|
2008-06-16 14:17:27 +01:00
|
|
|
|
2011-03-21 11:26:56 -07:00
|
|
|
# If modules have been enabled, then set lists of enabled modules
|
|
|
|
|
# and enabled module test libraries.
|
2017-04-06 20:32:04 -07:00
|
|
|
if env['NS3_ENABLED_MODULES'] or env['NS3_ENABLED_CONTRIBUTED_MODULES']:
|
|
|
|
|
|
2007-12-09 14:39:07 +00:00
|
|
|
modules = env['NS3_ENABLED_MODULES']
|
2017-04-06 20:32:04 -07:00
|
|
|
contribModules = env['NS3_ENABLED_CONTRIBUTED_MODULES']
|
2010-10-25 18:17:12 +01:00
|
|
|
|
|
|
|
|
# Find out about additional modules that need to be enabled
|
|
|
|
|
# due to dependency constraints.
|
2007-12-09 14:39:07 +00:00
|
|
|
changed = True
|
|
|
|
|
while changed:
|
|
|
|
|
changed = False
|
2017-04-06 20:32:04 -07:00
|
|
|
for module in modules + contribModules:
|
2011-09-12 14:54:27 +01:00
|
|
|
module_obj = bld.get_tgen_by_name(module)
|
2007-12-09 14:39:07 +00:00
|
|
|
if module_obj is None:
|
|
|
|
|
raise ValueError("module %s not found" % module)
|
2011-03-18 10:58:21 -07:00
|
|
|
# Each enabled module has its own library.
|
2011-09-08 16:13:40 +01:00
|
|
|
for dep in module_obj.use:
|
2007-12-09 14:39:07 +00:00
|
|
|
if not dep.startswith('ns3-'):
|
|
|
|
|
continue
|
2017-04-06 20:32:04 -07:00
|
|
|
if dep not in modules and dep not in contribModules:
|
2020-05-13 18:45:06 +01:00
|
|
|
if dep in env['NS3_MODULES']:
|
2018-03-30 09:24:09 -07:00
|
|
|
modules.append(dep)
|
|
|
|
|
changed = True
|
2020-05-13 18:45:06 +01:00
|
|
|
elif dep in env['NS3_CONTRIBUTED_MODULES']:
|
2018-03-30 09:24:09 -07:00
|
|
|
contribModules.append(dep)
|
|
|
|
|
changed = True
|
|
|
|
|
else:
|
|
|
|
|
Logs.error("Error: Cannot find dependency \'" + dep[4:] + "\' of module \'"
|
|
|
|
|
+ module[4:] + "\'; check the module wscript for errors.")
|
|
|
|
|
raise SystemExit(1)
|
2007-12-09 14:39:07 +00:00
|
|
|
|
2010-10-25 18:17:12 +01:00
|
|
|
env['NS3_ENABLED_MODULES'] = modules
|
|
|
|
|
|
2017-04-06 20:32:04 -07:00
|
|
|
env['NS3_ENABLED_CONTRIBUTED_MODULES'] = contribModules
|
|
|
|
|
|
2011-04-06 10:13:04 -07:00
|
|
|
# If tests are being built, then set the list of the enabled
|
|
|
|
|
# module test libraries.
|
|
|
|
|
if env['ENABLE_TESTS']:
|
|
|
|
|
for (mod, testlib) in bld.env['NS3_MODULES_WITH_TEST_LIBRARIES']:
|
2017-04-06 20:32:04 -07:00
|
|
|
if mod in bld.env['NS3_ENABLED_MODULES'] or mod in bld.env['NS3_ENABLED_CONTRIBUTED_MODULES']:
|
2011-04-06 10:13:04 -07:00
|
|
|
bld.env.append_value('NS3_ENABLED_MODULE_TEST_LIBRARIES', testlib)
|
2011-03-21 11:26:56 -07:00
|
|
|
|
|
|
|
|
add_examples_programs(bld)
|
|
|
|
|
add_scratch_programs(bld)
|
|
|
|
|
|
2017-04-06 20:32:04 -07:00
|
|
|
if env['NS3_ENABLED_MODULES'] or env['NS3_ENABLED_CONTRIBUTED_MODULES']:
|
2011-03-21 11:26:56 -07:00
|
|
|
modules = env['NS3_ENABLED_MODULES']
|
2017-04-06 20:32:04 -07:00
|
|
|
contribModules = env['NS3_ENABLED_CONTRIBUTED_MODULES']
|
2011-03-18 10:58:21 -07:00
|
|
|
|
2010-10-25 18:17:12 +01:00
|
|
|
# Exclude the programs other misc task gens that depend on disabled modules
|
2009-04-13 23:10:37 +01:00
|
|
|
for obj in list(bld.all_task_gen):
|
2010-10-25 18:17:12 +01:00
|
|
|
|
|
|
|
|
# check for ns3moduleheader_taskgen
|
2011-09-12 14:54:27 +01:00
|
|
|
if 'ns3moduleheader' in getattr(obj, "features", []):
|
2017-04-06 20:32:04 -07:00
|
|
|
if ("ns3-%s" % obj.module) not in modules and ("ns3-%s" % obj.module) not in contribModules:
|
2010-10-26 15:11:17 +01:00
|
|
|
obj.mode = 'remove' # tell it to remove headers instead of installing
|
2010-10-25 18:17:12 +01:00
|
|
|
|
|
|
|
|
# check for programs
|
2007-12-09 14:39:07 +00:00
|
|
|
if hasattr(obj, 'ns3_module_dependencies'):
|
2010-10-25 18:17:12 +01:00
|
|
|
# this is an NS-3 program (bld.create_ns3_program)
|
2011-04-28 09:10:29 -07:00
|
|
|
program_built = True
|
2007-12-09 14:39:07 +00:00
|
|
|
for dep in obj.ns3_module_dependencies:
|
2017-04-06 20:32:04 -07:00
|
|
|
if dep not in modules and dep not in contribModules: # prog. depends on a module that isn't enabled?
|
2011-09-08 16:13:40 +01:00
|
|
|
bld.exclude_taskgen(obj)
|
2011-04-28 09:10:29 -07:00
|
|
|
program_built = False
|
2007-12-09 14:39:07 +00:00
|
|
|
break
|
2010-10-25 18:17:12 +01:00
|
|
|
|
2011-04-28 09:10:29 -07:00
|
|
|
# Add this program to the list if all of its
|
|
|
|
|
# dependencies will be built.
|
|
|
|
|
if program_built:
|
2020-05-13 18:45:06 +01:00
|
|
|
object_name = "%s%s-%s%s" % (wutils.APPNAME, wutils.VERSION,
|
2012-07-12 12:35:31 +01:00
|
|
|
obj.name, bld.env.BUILD_SUFFIX)
|
2012-09-14 11:48:14 -07:00
|
|
|
|
|
|
|
|
# Get the relative path to the program from the
|
|
|
|
|
# launch directory.
|
|
|
|
|
launch_dir = os.path.abspath(Context.launch_dir)
|
|
|
|
|
object_relative_path = os.path.join(
|
2013-04-01 22:33:46 +02:00
|
|
|
wutils.relpath(obj.path.get_bld().abspath(), launch_dir),
|
2012-09-14 11:48:14 -07:00
|
|
|
object_name)
|
|
|
|
|
|
|
|
|
|
bld.env.append_value('NS3_RUNNABLE_PROGRAMS', object_relative_path)
|
2011-04-28 09:10:29 -07:00
|
|
|
|
2010-10-25 22:21:50 +01:00
|
|
|
# disable the modules themselves
|
2017-04-06 20:32:04 -07:00
|
|
|
if hasattr(obj, "is_ns3_module") and obj.name not in modules and obj.name not in contribModules:
|
2011-09-08 16:13:40 +01:00
|
|
|
bld.exclude_taskgen(obj) # kill the module
|
2010-10-25 22:21:50 +01:00
|
|
|
|
2011-03-18 10:58:21 -07:00
|
|
|
# disable the module test libraries
|
2011-04-06 10:13:04 -07:00
|
|
|
if hasattr(obj, "is_ns3_module_test_library"):
|
2017-04-06 20:32:04 -07:00
|
|
|
if not env['ENABLE_TESTS'] or ((obj.module_name not in modules) and (obj.module_name not in contribModules)) :
|
2011-09-08 16:13:40 +01:00
|
|
|
bld.exclude_taskgen(obj) # kill the module test library
|
2011-03-18 10:58:21 -07:00
|
|
|
|
2010-10-25 22:21:50 +01:00
|
|
|
# disable the ns3header_taskgen
|
2011-09-12 14:54:27 +01:00
|
|
|
if 'ns3header' in getattr(obj, "features", []):
|
2017-04-06 20:32:04 -07:00
|
|
|
if ("ns3-%s" % obj.module) not in modules and ("ns3-%s" % obj.module) not in contribModules:
|
2020-05-13 18:45:06 +01:00
|
|
|
obj.mode = 'remove' # tell it to remove headers instead of installing
|
2007-12-09 14:39:07 +00:00
|
|
|
|
2015-01-29 19:00:01 -08:00
|
|
|
# disable the ns3privateheader_taskgen
|
|
|
|
|
if 'ns3privateheader' in getattr(obj, "features", []):
|
2017-04-06 20:32:04 -07:00
|
|
|
if ("ns3-%s" % obj.module) not in modules and ("ns3-%s" % obj.module) not in contribModules:
|
|
|
|
|
|
2020-05-13 18:45:06 +01:00
|
|
|
obj.mode = 'remove' # tell it to remove headers instead of installing
|
2015-01-29 19:00:01 -08:00
|
|
|
|
2012-02-13 18:54:22 +00:00
|
|
|
# disable pcfile taskgens for disabled modules
|
|
|
|
|
if 'ns3pcfile' in getattr(obj, "features", []):
|
2017-04-06 20:32:04 -07:00
|
|
|
if obj.module not in bld.env.NS3_ENABLED_MODULES and obj.module not in bld.env.NS3_ENABLED_CONTRIBUTED_MODULES:
|
2012-02-13 18:54:22 +00:00
|
|
|
bld.exclude_taskgen(obj)
|
|
|
|
|
|
2020-06-14 16:19:41 -07:00
|
|
|
# disable python bindings for disabled modules
|
|
|
|
|
if 'pybindgen' in obj.name:
|
|
|
|
|
if ("ns3-%s" % obj.module) not in modules and ("ns3-%s" % obj.module) not in contribModules:
|
|
|
|
|
bld.exclude_taskgen(obj)
|
|
|
|
|
if 'pyext' in getattr(obj, "features", []):
|
|
|
|
|
if ("ns3-%s" % obj.module) not in modules and ("ns3-%s" % obj.module) not in contribModules:
|
|
|
|
|
bld.exclude_taskgen(obj)
|
|
|
|
|
|
2012-02-13 18:54:22 +00:00
|
|
|
|
2007-12-09 14:39:07 +00:00
|
|
|
if env['NS3_ENABLED_MODULES']:
|
2008-07-08 10:43:58 -07:00
|
|
|
env['NS3_ENABLED_MODULES'] = list(modules)
|
2007-12-09 14:39:07 +00:00
|
|
|
|
2017-04-06 20:32:04 -07:00
|
|
|
if env['NS3_ENABLED_CONTRIBUTED_MODULES']:
|
|
|
|
|
env['NS3_ENABLED_CONTRIBUTED_MODULES'] = list(contribModules)
|
|
|
|
|
|
2011-04-28 09:10:29 -07:00
|
|
|
# Determine which scripts will be runnable.
|
|
|
|
|
for (script, dependencies) in bld.env['NS3_SCRIPT_DEPENDENCIES']:
|
|
|
|
|
script_runnable = True
|
|
|
|
|
for dep in dependencies:
|
2017-04-06 20:32:04 -07:00
|
|
|
if dep not in modules and dep not in contribModules:
|
2011-04-28 09:10:29 -07:00
|
|
|
script_runnable = False
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
# Add this script to the list if all of its dependencies will
|
|
|
|
|
# be built.
|
|
|
|
|
if script_runnable:
|
|
|
|
|
bld.env.append_value('NS3_RUNNABLE_SCRIPTS', script)
|
|
|
|
|
|
2013-04-01 22:33:46 +02:00
|
|
|
bld.recurse('bindings/python')
|
2007-12-09 14:39:07 +00:00
|
|
|
|
2011-07-05 11:05:53 +01:00
|
|
|
# Process this subfolder here after the lists of enabled modules
|
|
|
|
|
# and module test libraries have been set.
|
2013-04-01 22:33:46 +02:00
|
|
|
bld.recurse('utils')
|
2011-07-05 11:05:53 +01:00
|
|
|
|
2011-12-14 21:50:12 -08:00
|
|
|
# Set this so that the lists will be printed at the end of this
|
|
|
|
|
# build command.
|
|
|
|
|
bld.env['PRINT_BUILT_MODULES_AT_END'] = True
|
|
|
|
|
|
2013-06-12 06:20:14 -07:00
|
|
|
# Do not print the modules built if build command was "clean"
|
|
|
|
|
if bld.cmd == 'clean':
|
|
|
|
|
bld.env['PRINT_BUILT_MODULES_AT_END'] = False
|
|
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
if Options.options.run:
|
2008-11-24 17:49:33 +00:00
|
|
|
# Check that the requested program name is valid
|
2009-01-24 18:09:29 +00:00
|
|
|
program_name, dummy_program_argv = wutils.get_run_program(Options.options.run, wutils.get_command_template(env))
|
2008-11-26 14:55:35 +00:00
|
|
|
|
2008-11-24 17:49:33 +00:00
|
|
|
# When --run'ing a program, tell WAF to only build that program,
|
|
|
|
|
# nothing more; this greatly speeds up compilation when all you
|
|
|
|
|
# want to do is run a test program.
|
2011-09-08 16:13:40 +01:00
|
|
|
Options.options.targets += ',' + os.path.basename(program_name)
|
2012-06-06 18:42:13 +01:00
|
|
|
if getattr(Options.options, "visualize", False):
|
|
|
|
|
program_obj = wutils.find_program(program_name, bld.env)
|
|
|
|
|
program_obj.use.append('ns3-visualizer')
|
2009-09-07 11:59:10 +01:00
|
|
|
for gen in bld.all_task_gen:
|
2015-01-29 19:00:01 -08:00
|
|
|
if type(gen).__name__ in ['ns3header_taskgen', 'ns3privateheader_taskgen', 'ns3moduleheader_taskgen']:
|
2009-09-07 11:59:10 +01:00
|
|
|
gen.post()
|
2017-01-24 17:44:10 -08:00
|
|
|
|
|
|
|
|
if Options.options.run or Options.options.pyrun:
|
2020-05-13 18:45:06 +01:00
|
|
|
bld.env['PRINT_BUILT_MODULES_AT_END'] = False
|
2008-11-24 17:49:33 +00:00
|
|
|
|
2009-10-29 11:12:12 +00:00
|
|
|
if Options.options.doxygen_no_build:
|
2020-03-10 18:08:22 -07:00
|
|
|
_doxygen(bld, skip_pid=True)
|
2009-10-29 11:12:12 +00:00
|
|
|
raise SystemExit(0)
|
|
|
|
|
|
2019-04-03 15:34:32 -07:00
|
|
|
if Options.options.run_no_build:
|
|
|
|
|
# Check that the requested program name is valid
|
|
|
|
|
program_name, dummy_program_argv = wutils.get_run_program(Options.options.run_no_build, wutils.get_command_template(bld.env))
|
|
|
|
|
# Run the program
|
|
|
|
|
wutils.run_program(Options.options.run_no_build, bld.env, wutils.get_command_template(bld.env), visualize=Options.options.visualize)
|
|
|
|
|
raise SystemExit(0)
|
|
|
|
|
|
|
|
|
|
if Options.options.pyrun_no_build:
|
|
|
|
|
wutils.run_python_program(Options.options.pyrun_no_build, bld.env,
|
|
|
|
|
visualize=Options.options.visualize)
|
|
|
|
|
raise SystemExit(0)
|
|
|
|
|
|
2013-02-18 20:22:50 -08:00
|
|
|
def _cleandir(name):
|
|
|
|
|
try:
|
|
|
|
|
shutil.rmtree(name)
|
|
|
|
|
except:
|
|
|
|
|
pass
|
2011-09-13 17:21:44 +01:00
|
|
|
|
2013-02-18 20:22:50 -08:00
|
|
|
def _cleandocs():
|
|
|
|
|
_cleandir('doc/html')
|
2017-09-17 19:53:45 -07:00
|
|
|
_cleandir('doc/html-warn')
|
2013-02-18 20:22:50 -08:00
|
|
|
_cleandir('doc/manual/build')
|
2013-07-07 14:20:41 -07:00
|
|
|
_cleandir('doc/manual/source-temp')
|
2013-02-18 20:22:50 -08:00
|
|
|
_cleandir('doc/tutorial/build')
|
|
|
|
|
_cleandir('doc/models/build')
|
|
|
|
|
_cleandir('doc/models/source-temp')
|
2021-10-27 18:33:26 -07:00
|
|
|
_cleandir('doc/contributing/build')
|
2013-02-18 20:22:50 -08:00
|
|
|
|
|
|
|
|
# 'distclean' typically only cleans out build/ directory
|
|
|
|
|
# Here we clean out any build or documentation artifacts not in build/
|
|
|
|
|
def distclean(ctx):
|
|
|
|
|
_cleandocs()
|
|
|
|
|
# Now call waf's normal distclean
|
|
|
|
|
Scripting.distclean(ctx)
|
2011-09-13 17:21:44 +01:00
|
|
|
|
2009-04-13 23:10:37 +01:00
|
|
|
def shutdown(ctx):
|
|
|
|
|
bld = wutils.bld
|
2009-04-16 12:02:11 +01:00
|
|
|
if wutils.bld is None:
|
|
|
|
|
return
|
2009-04-13 23:10:37 +01:00
|
|
|
env = bld.env
|
|
|
|
|
|
2011-12-14 21:50:12 -08:00
|
|
|
# Only print the lists if a build was done.
|
|
|
|
|
if (env['PRINT_BUILT_MODULES_AT_END']):
|
2011-04-29 12:10:45 -07:00
|
|
|
|
2011-05-27 14:48:14 -07:00
|
|
|
# Print the list of built modules.
|
2015-09-03 21:14:55 -07:00
|
|
|
print()
|
|
|
|
|
print('Modules built:')
|
2012-04-24 12:00:10 -07:00
|
|
|
names_without_prefix = []
|
2017-04-06 20:32:04 -07:00
|
|
|
for name in env['NS3_ENABLED_MODULES'] + env['NS3_ENABLED_CONTRIBUTED_MODULES']:
|
2012-04-24 12:00:10 -07:00
|
|
|
name1 = name[len('ns3-'):]
|
|
|
|
|
if name not in env.MODULAR_BINDINGS_MODULES:
|
|
|
|
|
name1 += " (no Python)"
|
|
|
|
|
names_without_prefix.append(name1)
|
2011-05-30 15:30:49 -07:00
|
|
|
print_module_names(names_without_prefix)
|
2015-09-03 21:14:55 -07:00
|
|
|
print()
|
2011-04-18 10:50:55 -07:00
|
|
|
|
2011-05-27 14:48:14 -07:00
|
|
|
# Print the list of enabled modules that were not built.
|
2011-05-30 15:30:49 -07:00
|
|
|
if env['MODULES_NOT_BUILT']:
|
2015-09-03 21:14:55 -07:00
|
|
|
print('Modules not built (see ns-3 tutorial for explanation):')
|
2011-05-30 15:30:49 -07:00
|
|
|
print_module_names(env['MODULES_NOT_BUILT'])
|
2015-09-03 21:14:55 -07:00
|
|
|
print()
|
2011-05-27 14:48:14 -07:00
|
|
|
|
2011-12-14 21:50:12 -08:00
|
|
|
# Set this so that the lists won't be printed until the next
|
|
|
|
|
# build is done.
|
|
|
|
|
bld.env['PRINT_BUILT_MODULES_AT_END'] = False
|
|
|
|
|
|
2011-04-28 09:10:29 -07:00
|
|
|
# Write the build status file.
|
2011-09-13 17:21:44 +01:00
|
|
|
build_status_file = os.path.join(bld.out_dir, 'build-status.py')
|
2020-05-13 18:45:06 +01:00
|
|
|
with open(build_status_file, 'w') as out:
|
|
|
|
|
out.write('#! /usr/bin/env python3\n')
|
|
|
|
|
out.write('\n')
|
|
|
|
|
out.write('# Programs that are runnable.\n')
|
|
|
|
|
out.write('ns3_runnable_programs = ' + str(env['NS3_RUNNABLE_PROGRAMS']) + '\n')
|
|
|
|
|
out.write('\n')
|
|
|
|
|
out.write('# Scripts that are runnable.\n')
|
|
|
|
|
out.write('ns3_runnable_scripts = ' + str(env['NS3_RUNNABLE_SCRIPTS']) + '\n')
|
|
|
|
|
out.write('\n')
|
2011-04-28 09:10:29 -07:00
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
if Options.options.lcov_report:
|
2011-09-12 19:19:00 +01:00
|
|
|
lcov_report(bld)
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2019-12-24 12:16:05 -08:00
|
|
|
if Options.options.lcov_zerocounters:
|
|
|
|
|
lcov_zerocounters(bld)
|
|
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
if Options.options.run:
|
2010-12-06 17:26:06 +00:00
|
|
|
wutils.run_program(Options.options.run, env, wutils.get_command_template(env),
|
|
|
|
|
visualize=Options.options.visualize)
|
2007-07-18 12:20:31 +01:00
|
|
|
raise SystemExit(0)
|
|
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
if Options.options.pyrun:
|
2010-12-06 17:26:06 +00:00
|
|
|
wutils.run_python_program(Options.options.pyrun, env,
|
|
|
|
|
visualize=Options.options.visualize)
|
2008-07-12 19:33:29 +01:00
|
|
|
raise SystemExit(0)
|
|
|
|
|
|
2009-04-13 23:10:37 +01:00
|
|
|
if Options.options.shell:
|
2011-09-13 17:50:05 +01:00
|
|
|
raise WafError("Please run `./waf shell' now, instead of `./waf --shell'")
|
2009-10-04 20:52:24 -07:00
|
|
|
|
|
|
|
|
if Options.options.check:
|
2011-09-13 17:50:05 +01:00
|
|
|
raise WafError("Please run `./test.py' now, instead of `./waf --check'")
|
2009-04-13 23:10:37 +01:00
|
|
|
|
|
|
|
|
check_shell(bld)
|
|
|
|
|
|
2009-10-04 20:52:24 -07:00
|
|
|
|
2011-09-20 11:23:59 +01:00
|
|
|
|
|
|
|
|
class CheckContext(Context.Context):
|
2009-10-06 22:54:24 -07:00
|
|
|
"""run the equivalent of the old ns-3 unit tests using test.py"""
|
2011-09-20 11:23:59 +01:00
|
|
|
cmd = 'check'
|
|
|
|
|
def execute(self):
|
|
|
|
|
# first we execute the build
|
2015-09-03 21:14:55 -07:00
|
|
|
bld = Context.create_context("build")
|
|
|
|
|
bld.options = Options.options # provided for convenience
|
|
|
|
|
bld.cmd = "build"
|
|
|
|
|
bld.execute()
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2011-09-20 11:23:59 +01:00
|
|
|
wutils.bld = bld
|
|
|
|
|
wutils.run_python_program("test.py -n -c core", bld.env)
|
2009-06-12 12:33:37 +01:00
|
|
|
|
2009-04-13 23:10:37 +01:00
|
|
|
def check_shell(bld):
|
2010-02-05 10:15:18 -08:00
|
|
|
if ('NS3_MODULE_PATH' not in os.environ) or ('NS3_EXECUTABLE_PATH' not in os.environ):
|
2007-08-01 21:35:34 +01:00
|
|
|
return
|
2009-04-13 23:10:37 +01:00
|
|
|
env = bld.env
|
2007-08-01 21:35:34 +01:00
|
|
|
correct_modpath = os.pathsep.join(env['NS3_MODULE_PATH'])
|
|
|
|
|
found_modpath = os.environ['NS3_MODULE_PATH']
|
2010-02-05 10:15:18 -08:00
|
|
|
correct_execpath = os.pathsep.join(env['NS3_EXECUTABLE_PATH'])
|
|
|
|
|
found_execpath = os.environ['NS3_EXECUTABLE_PATH']
|
|
|
|
|
if (found_modpath != correct_modpath) or (correct_execpath != found_execpath):
|
2009-04-13 23:10:37 +01:00
|
|
|
msg = ("Detected shell (./waf shell) with incorrect configuration\n"
|
2007-08-01 21:35:34 +01:00
|
|
|
"=========================================================\n"
|
|
|
|
|
"Possible reasons for this problem:\n"
|
|
|
|
|
" 1. You switched to another ns-3 tree from inside this shell\n"
|
|
|
|
|
" 2. You switched ns-3 debug level (waf configure --debug)\n"
|
|
|
|
|
" 3. You modified the list of built ns-3 modules\n"
|
|
|
|
|
"You should correct this situation before running any program. Possible solutions:\n"
|
|
|
|
|
" 1. Exit this shell, and start a new one\n"
|
|
|
|
|
" 2. Run a new nested shell")
|
2011-09-13 17:50:05 +01:00
|
|
|
raise WafError(msg)
|
2007-08-01 21:35:34 +01:00
|
|
|
|
2007-05-23 19:20:54 +01:00
|
|
|
|
2011-09-08 16:13:40 +01:00
|
|
|
class Ns3ShellContext(Context.Context):
|
2009-04-13 23:10:37 +01:00
|
|
|
"""run a shell with an environment suitably modified to run locally built programs"""
|
2011-09-08 16:13:40 +01:00
|
|
|
cmd = 'shell'
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2011-09-08 16:13:40 +01:00
|
|
|
def execute(self):
|
|
|
|
|
# first we execute the build
|
2015-09-03 21:14:55 -07:00
|
|
|
bld = Context.create_context("build")
|
|
|
|
|
bld.options = Options.options # provided for convenience
|
|
|
|
|
bld.cmd = "build"
|
|
|
|
|
bld.execute()
|
2011-09-08 16:13:40 +01:00
|
|
|
|
2011-12-14 21:50:12 -08:00
|
|
|
# Set this so that the lists won't be printed when the user
|
|
|
|
|
# exits the shell.
|
|
|
|
|
bld.env['PRINT_BUILT_MODULES_AT_END'] = False
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2011-09-08 16:13:40 +01:00
|
|
|
if sys.platform == 'win32':
|
|
|
|
|
shell = os.environ.get("COMSPEC", "cmd.exe")
|
|
|
|
|
else:
|
|
|
|
|
shell = os.environ.get("SHELL", "/bin/sh")
|
|
|
|
|
|
|
|
|
|
env = bld.env
|
|
|
|
|
os_env = {
|
|
|
|
|
'NS3_MODULE_PATH': os.pathsep.join(env['NS3_MODULE_PATH']),
|
|
|
|
|
'NS3_EXECUTABLE_PATH': os.pathsep.join(env['NS3_EXECUTABLE_PATH']),
|
|
|
|
|
}
|
|
|
|
|
wutils.run_argv([shell], env, os_env)
|
2007-08-01 21:35:34 +01:00
|
|
|
|
2007-05-23 19:20:54 +01:00
|
|
|
|
2020-03-18 17:10:36 -07:00
|
|
|
def _print_introspected_doxygen(bld):
|
2020-03-24 12:30:38 -07:00
|
|
|
env = wutils.bld.env
|
|
|
|
|
proc_env = wutils.get_proc_env()
|
2009-10-08 17:57:06 -07:00
|
|
|
try:
|
|
|
|
|
program_obj = wutils.find_program('print-introspected-doxygen', env)
|
2020-05-13 18:45:06 +01:00
|
|
|
except ValueError:
|
2009-10-08 17:57:06 -07:00
|
|
|
Logs.warn("print-introspected-doxygen does not exist")
|
|
|
|
|
raise SystemExit(1)
|
|
|
|
|
return
|
|
|
|
|
|
2013-04-01 22:33:46 +02:00
|
|
|
prog = program_obj.path.find_or_declare(program_obj.target).get_bld().abspath()
|
2010-04-20 11:31:54 +01:00
|
|
|
|
|
|
|
|
if not os.path.exists(prog):
|
|
|
|
|
Logs.error("print-introspected-doxygen has not been built yet."
|
|
|
|
|
" You need to build ns-3 at least once before "
|
|
|
|
|
"generating doxygen docs...")
|
|
|
|
|
raise SystemExit(1)
|
|
|
|
|
|
2020-03-24 12:30:38 -07:00
|
|
|
Logs.info("Running print-introspected-doxygen")
|
|
|
|
|
|
2011-09-22 09:24:54 -07:00
|
|
|
# Create a header file with the introspected information.
|
2020-05-13 18:45:06 +01:00
|
|
|
with open(os.path.join('doc', 'introspected-doxygen.h'), 'w') as doxygen_out:
|
|
|
|
|
if subprocess.Popen([prog], stdout=doxygen_out, env=proc_env).wait():
|
|
|
|
|
raise SystemExit(1)
|
2009-10-08 17:57:06 -07:00
|
|
|
|
2011-09-22 09:24:54 -07:00
|
|
|
# Create a text file with the introspected information.
|
2020-05-13 18:45:06 +01:00
|
|
|
with open(os.path.join('doc', 'ns3-object.txt'), 'w') as text_out:
|
|
|
|
|
if subprocess.Popen([prog, '--output-text'], stdout=text_out, env=proc_env).wait():
|
|
|
|
|
raise SystemExit(1)
|
2007-10-02 11:10:31 +01:00
|
|
|
|
2020-04-27 15:22:11 -07:00
|
|
|
# Gather the CommandLine doxy
|
|
|
|
|
# test.py appears not to create or keep the output directory
|
|
|
|
|
# if no real tests are run, so we just stuff all the
|
|
|
|
|
# .command-line output files into testpy-output/
|
2022-01-09 00:55:38 -03:00
|
|
|
# NS_COMMANDLINE_INTROSPECTION=".." test.py -n --constrain=example
|
2020-04-27 15:22:11 -07:00
|
|
|
Logs.info("Running CommandLine introspection")
|
|
|
|
|
proc_env['NS_COMMANDLINE_INTROSPECTION'] = '..'
|
2022-01-09 00:55:38 -03:00
|
|
|
subprocess.run(["./test.py", "-n", "--constrain=example"],
|
2020-04-27 15:22:11 -07:00
|
|
|
env=proc_env, stdout=subprocess.DEVNULL)
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2020-04-27 15:22:11 -07:00
|
|
|
doxygen_out = os.path.join('doc', 'introspected-command-line.h')
|
|
|
|
|
try:
|
|
|
|
|
os.remove(doxygen_out)
|
|
|
|
|
except OSError as e:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
with open(doxygen_out, 'w') as out_file:
|
|
|
|
|
lines="""
|
|
|
|
|
/* This file is automatically generated by
|
|
|
|
|
CommandLine::PrintDoxygenUsage() from the CommandLine configuration
|
|
|
|
|
in various example programs. Do not edit this file! Edit the
|
|
|
|
|
CommandLine configuration in those files instead.
|
|
|
|
|
*/\n
|
|
|
|
|
"""
|
|
|
|
|
out_file.write(lines)
|
|
|
|
|
|
|
|
|
|
with open(doxygen_out,'a') as outfile:
|
|
|
|
|
for in_file in glob.glob('testpy-output/*.command-line'):
|
|
|
|
|
with open(in_file,'r') as infile:
|
|
|
|
|
outfile.write(infile.read())
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2020-03-10 18:08:22 -07:00
|
|
|
def _doxygen(bld, skip_pid=False):
|
|
|
|
|
env = wutils.bld.env
|
|
|
|
|
proc_env = wutils.get_proc_env()
|
|
|
|
|
|
|
|
|
|
if not env['DOXYGEN']:
|
|
|
|
|
Logs.error("waf configure did not detect doxygen in the system -> cannot build api docs.")
|
|
|
|
|
raise SystemExit(1)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if not skip_pid:
|
|
|
|
|
_print_introspected_doxygen(bld)
|
|
|
|
|
|
2012-08-08 12:52:30 -07:00
|
|
|
_getVersion()
|
2007-05-23 17:32:32 +01:00
|
|
|
doxygen_config = os.path.join('doc', 'doxygen.conf')
|
2015-06-28 20:24:41 -07:00
|
|
|
if subprocess.Popen(env['DOXYGEN'] + [doxygen_config]).wait():
|
2012-08-08 14:04:05 -07:00
|
|
|
Logs.error("Doxygen build returned an error.")
|
2007-05-23 17:32:32 +01:00
|
|
|
raise SystemExit(1)
|
|
|
|
|
|
2020-02-25 13:17:18 -08:00
|
|
|
def _docset(bld):
|
|
|
|
|
# Get the doxygen config
|
|
|
|
|
doxyfile = os.path.join('doc', 'doxygen.conf')
|
|
|
|
|
Logs.info("docset: reading " + doxyfile)
|
2020-05-13 18:45:06 +01:00
|
|
|
with open(doxyfile, 'r') as doxygen_config:
|
|
|
|
|
doxygen_config_contents = doxygen_config.read()
|
2020-02-25 13:17:18 -08:00
|
|
|
|
|
|
|
|
# Create the output directory
|
|
|
|
|
docset_path = os.path.join('doc', 'docset')
|
|
|
|
|
Logs.info("docset: checking for output directory " + docset_path)
|
|
|
|
|
if not os.path.exists(docset_path):
|
|
|
|
|
Logs.info("docset: creating output directory " + docset_path)
|
|
|
|
|
os.mkdir(docset_path)
|
|
|
|
|
|
|
|
|
|
doxyfile = os.path.join('doc', 'doxygen.docset.conf')
|
2020-05-13 18:45:06 +01:00
|
|
|
with open(doxyfile, 'w') as doxygen_config:
|
|
|
|
|
Logs.info("docset: writing doxygen conf " + doxyfile)
|
|
|
|
|
doxygen_config.write(doxygen_config_contents)
|
|
|
|
|
doxygen_config.write(
|
|
|
|
|
"""
|
|
|
|
|
HAVE_DOT = NO
|
|
|
|
|
GENERATE_DOCSET = YES
|
|
|
|
|
DISABLE_INDEX = YES
|
|
|
|
|
SEARCHENGINE = NO
|
|
|
|
|
GENERATE_TREEVIEW = NO
|
|
|
|
|
OUTPUT_DIRECTORY=""" + docset_path + "\n"
|
|
|
|
|
)
|
2020-02-25 13:17:18 -08:00
|
|
|
|
|
|
|
|
# Run Doxygen manually, so as to avoid build
|
|
|
|
|
Logs.info("docset: running doxygen")
|
|
|
|
|
env = wutils.bld.env
|
|
|
|
|
_getVersion()
|
|
|
|
|
if subprocess.Popen(env['DOXYGEN'] + [doxyfile]).wait():
|
|
|
|
|
Logs.error("Doxygen docset build returned an error.")
|
|
|
|
|
raise SystemExit(1)
|
|
|
|
|
|
|
|
|
|
# Build docset
|
|
|
|
|
docset_path = os.path.join(docset_path, 'html')
|
|
|
|
|
Logs.info("docset: Running docset Make")
|
|
|
|
|
if subprocess.Popen(["make"], cwd=docset_path).wait():
|
|
|
|
|
Logs.error("Docset make returned and error.")
|
|
|
|
|
raise SystemExit(1)
|
|
|
|
|
|
|
|
|
|
# Additional steps from
|
|
|
|
|
# https://github.com/Kapeli/Dash-User-Contributions/tree/master/docsets/ns-3
|
|
|
|
|
docset_out = os.path.join(docset_path, 'org.nsnam.ns3.docset')
|
|
|
|
|
icons = os.path.join('doc', 'ns3_html_theme', 'static')
|
|
|
|
|
shutil.copy(os.path.join(icons, 'ns-3-bars-16x16.png'),
|
|
|
|
|
os.path.join(docset_out, 'icon.png'))
|
|
|
|
|
shutil.copy(os.path.join(icons, 'ns-3-bars-32x32.png'),
|
|
|
|
|
os.path.join(docset_out, 'icon@x2.png'))
|
|
|
|
|
shutil.copy(os.path.join(docset_path, 'Info.plist'),
|
|
|
|
|
os.path.join(docset_out, 'Contents'))
|
|
|
|
|
shutil.move(docset_out, os.path.join('doc', 'ns-3.docset'))
|
|
|
|
|
|
|
|
|
|
print("Docset built successfully.")
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2011-09-20 18:58:33 +01:00
|
|
|
|
2012-07-31 11:18:23 -07:00
|
|
|
def _getVersion():
|
|
|
|
|
"""update the ns3_version.js file, when building documentation"""
|
|
|
|
|
|
2012-08-08 12:52:30 -07:00
|
|
|
prog = "doc/ns3_html_theme/get_version.sh"
|
|
|
|
|
if subprocess.Popen([prog]).wait() :
|
2012-08-08 14:04:05 -07:00
|
|
|
Logs.error(prog + " returned an error")
|
2012-07-31 11:18:23 -07:00
|
|
|
raise SystemExit(1)
|
|
|
|
|
|
2011-09-23 11:21:00 +01:00
|
|
|
class Ns3DoxygenContext(Context.Context):
|
2009-10-29 11:12:12 +00:00
|
|
|
"""do a full build, generate the introspected doxygen and then the doxygen"""
|
2011-09-20 18:58:33 +01:00
|
|
|
cmd = 'doxygen'
|
|
|
|
|
def execute(self):
|
|
|
|
|
# first we execute the build
|
2015-09-03 21:14:55 -07:00
|
|
|
bld = Context.create_context("build")
|
|
|
|
|
bld.options = Options.options # provided for convenience
|
|
|
|
|
bld.cmd = "build"
|
|
|
|
|
bld.execute()
|
2011-09-20 18:58:33 +01:00
|
|
|
_doxygen(bld)
|
|
|
|
|
|
2012-06-13 18:46:38 -07:00
|
|
|
class Ns3SphinxContext(Context.Context):
|
2021-10-27 18:33:26 -07:00
|
|
|
"""build the Sphinx documentation: manual, tutorial, models, contributing"""
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2012-06-13 18:46:38 -07:00
|
|
|
cmd = 'sphinx'
|
|
|
|
|
|
|
|
|
|
def sphinx_build(self, path):
|
2015-09-03 21:14:55 -07:00
|
|
|
print()
|
|
|
|
|
print("[waf] Building sphinx docs for " + path)
|
2012-07-31 11:18:23 -07:00
|
|
|
if subprocess.Popen(["make", "SPHINXOPTS=-N", "-k",
|
|
|
|
|
"html", "singlehtml", "latexpdf" ],
|
2012-07-30 15:15:52 -07:00
|
|
|
cwd=path).wait() :
|
2012-08-08 14:04:05 -07:00
|
|
|
Logs.error("Sphinx build of " + path + " returned an error.")
|
2012-06-13 18:46:38 -07:00
|
|
|
raise SystemExit(1)
|
2009-10-29 11:12:12 +00:00
|
|
|
|
2012-06-13 18:46:38 -07:00
|
|
|
def execute(self):
|
2012-08-08 12:52:30 -07:00
|
|
|
_getVersion()
|
2021-10-27 18:33:26 -07:00
|
|
|
for sphinxdir in ["manual", "models", "tutorial", "contributing"] :
|
2012-06-13 18:46:38 -07:00
|
|
|
self.sphinx_build(os.path.join("doc", sphinxdir))
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2012-06-13 18:46:38 -07:00
|
|
|
|
|
|
|
|
class Ns3DocContext(Context.Context):
|
2021-10-27 18:33:26 -07:00
|
|
|
"""build all the documentation: doxygen, manual, tutorial, models, contributing"""
|
2020-05-13 18:45:06 +01:00
|
|
|
|
2012-06-13 18:46:38 -07:00
|
|
|
cmd = 'docs'
|
|
|
|
|
|
|
|
|
|
def execute(self):
|
|
|
|
|
steps = ['doxygen', 'sphinx']
|
|
|
|
|
Options.commands = steps + Options.commands
|
2020-05-13 18:45:06 +01:00
|
|
|
|
|
|
|
|
|
2011-09-12 19:19:00 +01:00
|
|
|
def lcov_report(bld):
|
|
|
|
|
env = bld.env
|
2007-05-23 17:32:32 +01:00
|
|
|
|
2011-09-12 19:19:00 +01:00
|
|
|
if not env['GCOV_ENABLED']:
|
|
|
|
|
raise WafError("project not configured for code coverage;"
|
|
|
|
|
" reconfigure with --enable-gcov")
|
2019-12-24 12:16:05 -08:00
|
|
|
try:
|
|
|
|
|
subprocess.call(["lcov", "--help"], stdout=subprocess.DEVNULL)
|
|
|
|
|
except OSError as e:
|
|
|
|
|
if e.errno == os.errno.ENOENT:
|
|
|
|
|
raise WafError("Error: lcov program not found")
|
|
|
|
|
else:
|
|
|
|
|
raise
|
|
|
|
|
try:
|
|
|
|
|
subprocess.call(["genhtml", "--help"], stdout=subprocess.DEVNULL)
|
|
|
|
|
except OSError as e:
|
|
|
|
|
if e.errno == os.errno.ENOENT:
|
|
|
|
|
raise WafError("Error: genhtml program not found")
|
|
|
|
|
else:
|
|
|
|
|
raise
|
2011-09-12 19:19:00 +01:00
|
|
|
os.chdir(out)
|
2007-05-23 17:32:32 +01:00
|
|
|
try:
|
2011-09-12 19:19:00 +01:00
|
|
|
lcov_report_dir = 'lcov-report'
|
2007-05-23 17:32:32 +01:00
|
|
|
create_dir_command = "rm -rf " + lcov_report_dir
|
|
|
|
|
create_dir_command += " && mkdir " + lcov_report_dir + ";"
|
|
|
|
|
|
|
|
|
|
if subprocess.Popen(create_dir_command, shell=True).wait():
|
|
|
|
|
raise SystemExit(1)
|
|
|
|
|
|
2011-09-12 19:19:00 +01:00
|
|
|
info_file = os.path.join(lcov_report_dir, 'report.info')
|
2019-12-24 12:16:05 -08:00
|
|
|
lcov_command = "lcov -c -d . -o " + info_file
|
2011-09-30 14:21:39 -07:00
|
|
|
lcov_command += " -b " + os.getcwd()
|
2007-05-23 17:32:32 +01:00
|
|
|
if subprocess.Popen(lcov_command, shell=True).wait():
|
|
|
|
|
raise SystemExit(1)
|
|
|
|
|
|
2019-12-24 12:16:05 -08:00
|
|
|
genhtml_command = "genhtml -o " + lcov_report_dir
|
2007-05-23 17:32:32 +01:00
|
|
|
genhtml_command += " " + info_file
|
|
|
|
|
if subprocess.Popen(genhtml_command, shell=True).wait():
|
2007-05-07 12:01:51 +01:00
|
|
|
raise SystemExit(1)
|
2007-05-23 17:32:32 +01:00
|
|
|
finally:
|
|
|
|
|
os.chdir("..")
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2019-12-24 12:16:05 -08:00
|
|
|
def lcov_zerocounters(bld):
|
|
|
|
|
env = bld.env
|
|
|
|
|
|
|
|
|
|
if not env['GCOV_ENABLED']:
|
|
|
|
|
raise WafError("project not configured for code coverage;"
|
|
|
|
|
" reconfigure with --enable-gcov")
|
|
|
|
|
try:
|
|
|
|
|
subprocess.call(["lcov", "--help"], stdout=subprocess.DEVNULL)
|
|
|
|
|
except OSError as e:
|
|
|
|
|
if e.errno == os.errno.ENOENT:
|
|
|
|
|
raise WafError("Error: lcov program not found")
|
|
|
|
|
else:
|
|
|
|
|
raise
|
|
|
|
|
|
|
|
|
|
os.chdir(out)
|
|
|
|
|
lcov_clear_command = "lcov -d . --zerocounters"
|
|
|
|
|
if subprocess.Popen(lcov_clear_command, shell=True).wait():
|
|
|
|
|
raise SystemExit(1)
|
|
|
|
|
os.chdir("..")
|