Bug 1174 - Ns-3 does not generate static libraries
This commit is contained in:
160
src/wscript
160
src/wscript
@@ -103,52 +103,126 @@ def configure(conf):
|
||||
conf.env['NS3_MODULES'] = ['ns3-' + module.split('/')[-1] for module in all_modules]
|
||||
|
||||
|
||||
def create_ns3_module(bld, name, dependencies=(), test=False):
|
||||
# Create a separate library for this module.
|
||||
if bld.env['ENABLE_STATIC_NS3']:
|
||||
module = bld.new_task_gen('cxx', 'cstaticlib')
|
||||
else:
|
||||
module = bld.new_task_gen('cxx', 'cshlib')
|
||||
if not test:
|
||||
pcfile = bld.new_task_gen('ns3pcfile')
|
||||
pcfile.module = module
|
||||
class ns3module_taskgen(TaskGen.task_gen):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ns3module_taskgen, self).__init__(*args, **kwargs)
|
||||
self.libs = []
|
||||
|
||||
def apply(self):
|
||||
static_enabled = False
|
||||
shared_enabled = True
|
||||
bld = self.bld
|
||||
if bld.env['ENABLE_STATIC_NS3']:
|
||||
static_enabled = True
|
||||
shared_enabled = False
|
||||
if bld.env['ENABLE_SHARED_AND_STATIC_NS3']:
|
||||
static_enabled = True
|
||||
shared_enabled = True
|
||||
|
||||
assert self.name.startswith("ns3-")
|
||||
name = self.name.split("ns3-")[1]
|
||||
|
||||
if static_enabled:
|
||||
static = self._create_ns3_module(self.bld, name, self.dependencies, True)
|
||||
self.libs.append(static)
|
||||
else:
|
||||
static = None
|
||||
|
||||
if shared_enabled:
|
||||
shared = self._create_ns3_module(self.bld, name, self.dependencies, False)
|
||||
self.libs.append(shared)
|
||||
else:
|
||||
shared = None
|
||||
|
||||
if static is not None and shared is None:
|
||||
static.name = self.name + "--lib"
|
||||
static.uselib_local = ['ns3-%s--lib' % (dep,) for dep in self.dependencies]
|
||||
|
||||
elif shared is not None and static is None:
|
||||
shared.name = self.name + "--lib"
|
||||
shared.uselib_local = ['ns3-%s--lib' % (dep,) for dep in self.dependencies]
|
||||
else:
|
||||
shared.name = self.name + "--lib"
|
||||
shared.uselib_local = ['ns3-%s--lib' % (dep,) for dep in self.dependencies]
|
||||
static.name = self.name + "--static"
|
||||
static.uselib_local = ['ns3-%s--static' % (dep,) for dep in self.dependencies]
|
||||
|
||||
if not self.test:
|
||||
pcfile = bld.new_task_gen('ns3pcfile')
|
||||
pcfile.module = self
|
||||
|
||||
|
||||
def _create_ns3_module(self, bld, name, dependencies, static):
|
||||
|
||||
# FIXME: env modifications are overwritten by parent caller
|
||||
|
||||
# Create a separate library for this module.
|
||||
if static:
|
||||
module = bld.new_task_gen('cxx', 'cstaticlib')
|
||||
else:
|
||||
module = bld.new_task_gen('cxx', 'cshlib')
|
||||
|
||||
module.source = self.source
|
||||
module.env = self.env.copy()
|
||||
features = list(self.features)
|
||||
features.remove("ns3module")
|
||||
module.features.extend(features)
|
||||
module.path = self.path
|
||||
module.uselib = self.uselib
|
||||
if hasattr(self, 'includes'):
|
||||
module.includes = self.includes
|
||||
if hasattr(self, "is_ns3_module"):
|
||||
module.is_ns3_module = self.is_ns3_module
|
||||
|
||||
module.is_static = static
|
||||
module.vnum = wutils.VNUM
|
||||
# Add the proper path to the module's name.
|
||||
module.target = '%s/ns3-%s' % (bld.srcnode.relpath_gen(self.path), name)
|
||||
# Set the libraries this module depends on.
|
||||
module.module_deps = list(dependencies)
|
||||
if not static:
|
||||
module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS'])
|
||||
module.env.append_value('CCFLAGS', module.env['shlib_CXXFLAGS'])
|
||||
# Turn on the link flags for shared libraries if we have the
|
||||
# proper compiler and platform.
|
||||
if module.env['CXX_NAME'] in ['gcc', 'icc'] and module.env['WL_SONAME_SUPPORTED']:
|
||||
# Get the module library name without any relative paths
|
||||
# at its beginning because all of the libraries will end
|
||||
# up in the same directory.
|
||||
module_library_name = os.path.basename(ccroot.get_target_name(module))
|
||||
module.env.append_value('LINKFLAGS', '-Wl,--soname=%s' % module_library_name)
|
||||
elif module.env['CXX_NAME'] in ['gcc', 'icc'] and \
|
||||
os.uname()[4] == 'x86_64' and \
|
||||
module.env['ENABLE_PYTHON_BINDINGS']:
|
||||
# enable that flag for static builds only on x86-64 platforms
|
||||
# when gcc is present and only when we want python bindings
|
||||
# (it's more efficient to not use this option if we can avoid it)
|
||||
module.env.append_value('CXXFLAGS', '-mcmodel=large')
|
||||
module.env.append_value('CCFLAGS', '-mcmodel=large')
|
||||
module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION")
|
||||
module.env.append_value('CCDEFINES', "NS3_MODULE_COMPILATION")
|
||||
|
||||
module.install_path = "${LIBDIR}"
|
||||
|
||||
return module
|
||||
|
||||
|
||||
def create_ns3_module(bld, name, dependencies=(), test=False):
|
||||
module = bld.new_task_gen('ns3module')
|
||||
module.bld = bld
|
||||
module.name = "ns3-" + name
|
||||
module.dependencies = dependencies
|
||||
# Initially create an empty value for this because the pcfile
|
||||
# writing task assumes every module has a uselib attribute.
|
||||
module.uselib = ''
|
||||
|
||||
module.is_ns3_module = True
|
||||
module.name = 'ns3-' + name
|
||||
module.vnum = wutils.VNUM
|
||||
# Add the proper path to the module's name.
|
||||
module.target = '%s/ns3-%s' % (bld.srcnode.relpath_gen(bld.path), name)
|
||||
# Set the libraries this module depends on.
|
||||
module.uselib_local = ['ns3-' + dep for dep in dependencies]
|
||||
module.module_deps = list(dependencies)
|
||||
if not module.env['ENABLE_STATIC_NS3']:
|
||||
module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS'])
|
||||
module.env.append_value('CCFLAGS', module.env['shlib_CXXFLAGS'])
|
||||
# Turn on the link flags for shared libraries if we have the
|
||||
# proper compiler and platform.
|
||||
if module.env['CXX_NAME'] in ['gcc', 'icc'] and module.env['WL_SONAME_SUPPORTED']:
|
||||
# Get the module library name without any relative paths
|
||||
# at its beginning because all of the libraries will end
|
||||
# up in the same directory.
|
||||
module_library_name = os.path.basename(ccroot.get_target_name(module))
|
||||
module.env.append_value('LINKFLAGS', '-Wl,--soname=%s' % module_library_name)
|
||||
elif module.env['CXX_NAME'] in ['gcc', 'icc'] and \
|
||||
os.uname()[4] == 'x86_64' and \
|
||||
module.env['ENABLE_PYTHON_BINDINGS']:
|
||||
# enable that flag for static builds only on x86-64 platforms
|
||||
# when gcc is present and only when we want python bindings
|
||||
# (it's more efficient to not use this option if we can avoid it)
|
||||
module.env.append_value('CXXFLAGS', '-mcmodel=large')
|
||||
module.env.append_value('CCFLAGS', '-mcmodel=large')
|
||||
|
||||
module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION")
|
||||
module.env.append_value('CCDEFINES', "NS3_MODULE_COMPILATION")
|
||||
module.test = test
|
||||
module.is_ns3_module = True
|
||||
|
||||
return module
|
||||
|
||||
|
||||
def create_ns3_module_test_library(bld, name):
|
||||
# Create an ns3 module for the test library that depends only on
|
||||
# the module being tested.
|
||||
@@ -258,15 +332,17 @@ def ns3_python_bindings(bld):
|
||||
pymod.source = ['bindings/ns3module.cc']
|
||||
pymod.target = '%s/%s' % (module_target_dir, extension_name)
|
||||
pymod.name = 'ns3module_%s' % module
|
||||
pymod.uselib_local = pymod.env['NS3_ENABLED_MODULES'] # Should be '"ns3-"+module', but see bug 1117
|
||||
pymod.uselib_local = ["%s--lib" % mod for mod in pymod.env['NS3_ENABLED_MODULES']] # Should be '"ns3-"+module', but see bug 1117
|
||||
if pymod.env['ENABLE_STATIC_NS3']:
|
||||
if sys.platform == 'darwin':
|
||||
pymod.env.append_value('LINKFLAGS', '-Wl,-all_load')
|
||||
for mod in pymod.uselib_local:
|
||||
mod = mod.split("--lib")[0]
|
||||
pymod.env.append_value('LINKFLAGS', '-l' + mod)
|
||||
else:
|
||||
pymod.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic')
|
||||
for mod in pymod.uselib_local:
|
||||
mod = mod.split("--lib")[0]
|
||||
pymod.env.append_value('LINKFLAGS', '-l' + mod)
|
||||
pymod.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive')
|
||||
defines = list(pymod.env['CXXDEFINES'])
|
||||
@@ -416,7 +492,6 @@ class ns3header_taskgen(TaskGen.task_gen):
|
||||
def apply(self):
|
||||
for filename in set(self.to_list(self.source)):
|
||||
src_node = self.path.find_resource(filename)
|
||||
self.bld.install_files('${PREFIX}/include/ns3', [src_node])
|
||||
if self.module is None:
|
||||
raise Utils.WafError("'module' missing on ns3headers object %s" % self)
|
||||
ns3_dir_node = self.bld.path.find_dir("ns3")
|
||||
@@ -431,6 +506,7 @@ class ns3header_taskgen(TaskGen.task_gen):
|
||||
task = self.create_task('ns3header', env=self.env)
|
||||
task.mode = self.mode
|
||||
if self.mode == 'install':
|
||||
self.bld.install_files('${PREFIX}/include/ns3', [src_node])
|
||||
task.set_inputs([src_node])
|
||||
task.set_outputs([dst_node])
|
||||
else:
|
||||
@@ -598,13 +674,13 @@ class ns3moduleheader_taskgen(TaskGen.task_gen):
|
||||
raise Utils.WscriptError("error finding headers for module %s" % self.module)
|
||||
if not all_headers_inputs:
|
||||
return
|
||||
self.bld.install_files('${PREFIX}/include/ns3',
|
||||
ns3_dir_node.find_or_declare("%s-module.h" % self.module))
|
||||
all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self.module)]
|
||||
task = self.create_task('gen_ns3_module_header', env=self.env)
|
||||
task.module = self.module
|
||||
task.mode = self.mode
|
||||
if self.mode == 'install':
|
||||
self.bld.install_files('${PREFIX}/include/ns3',
|
||||
ns3_dir_node.find_or_declare("%s-module.h" % self.module))
|
||||
task.set_inputs(all_headers_inputs)
|
||||
task.set_outputs(all_headers_outputs)
|
||||
module_obj = self.bld.name_to_obj("ns3-" + self.module, self.env)
|
||||
|
||||
74
wscript
74
wscript
@@ -207,6 +207,10 @@ def set_options(opt):
|
||||
help=('Compile NS-3 statically: works only on linux, without python'),
|
||||
dest='enable_static', action='store_true',
|
||||
default=False)
|
||||
opt.add_option('--enable-shared-and-static',
|
||||
help=('Compile NS-3 both shared and static libraries at the same time: static works only on linux'),
|
||||
dest='enable_shared_and_static', action='store_true',
|
||||
default=False)
|
||||
opt.add_option('--enable-mpi',
|
||||
help=('Compile NS-3 with MPI and distributed simulation support'),
|
||||
dest='enable_mpi', action='store_true',
|
||||
@@ -316,12 +320,15 @@ def configure(conf):
|
||||
env['WL_SONAME_SUPPORTED'] = True
|
||||
|
||||
env['ENABLE_STATIC_NS3'] = False
|
||||
if Options.options.enable_static:
|
||||
if Options.options.enable_static or Options.options.enable_shared_and_static:
|
||||
if env['PLATFORM'].startswith('linux') and \
|
||||
env['CXX_NAME'] in ['gcc', 'icc']:
|
||||
if re.match('i[3-6]86', os.uname()[4]):
|
||||
conf.report_optional_feature("static", "Static build", True, '')
|
||||
env['ENABLE_STATIC_NS3'] = True
|
||||
if Options.options.enable_static:
|
||||
env['ENABLE_STATIC_NS3'] = True
|
||||
if Options.options.enable_shared_and_static:
|
||||
env['ENABLE_SHARED_AND_STATIC_NS3'] = True
|
||||
elif os.uname()[4] == 'x86_64':
|
||||
if env['ENABLE_PYTHON_BINDINGS'] and \
|
||||
not conf.check_compilation_flag('-mcmodel=large'):
|
||||
@@ -332,12 +339,18 @@ def configure(conf):
|
||||
"compiler to at least gcc 4.3.x.")
|
||||
else:
|
||||
conf.report_optional_feature("static", "Static build", True, '')
|
||||
env['ENABLE_STATIC_NS3'] = True
|
||||
if Options.options.enable_static:
|
||||
env['ENABLE_STATIC_NS3'] = True
|
||||
if Options.options.enable_shared_and_static:
|
||||
env['ENABLE_SHARED_AND_STATIC_NS3'] = True
|
||||
elif env['CXX_NAME'] == 'gcc' and \
|
||||
(env['PLATFORM'].startswith('darwin') or \
|
||||
env['PLATFORM'].startswith('cygwin')):
|
||||
conf.report_optional_feature("static", "Static build", True, '')
|
||||
env['ENABLE_STATIC_NS3'] = True
|
||||
if Options.options.enable_static:
|
||||
env['ENABLE_STATIC_NS3'] = True
|
||||
if Options.options.enable_shared_and_static:
|
||||
env['ENABLE_SHARED_AND_STATIC_NS3'] = True
|
||||
else:
|
||||
conf.report_optional_feature("static", "Static build", False,
|
||||
"Unsupported platform")
|
||||
@@ -558,18 +571,7 @@ def create_ns3_program(bld, name, dependencies=('core',)):
|
||||
program.name = name
|
||||
program.target = program.name
|
||||
# Each of the modules this program depends on has its own library.
|
||||
program.uselib_local = ['ns3-' + dep for dep in dependencies]
|
||||
program.ns3_module_dependencies = ['ns3-'+dep for dep in dependencies]
|
||||
if program.env['ENABLE_STATIC_NS3']:
|
||||
if sys.platform == 'darwin':
|
||||
program.env.append_value('LINKFLAGS', '-Wl,-all_load')
|
||||
for dep in dependencies:
|
||||
program.env.append_value('LINKFLAGS', '-lns3-' + dep)
|
||||
else:
|
||||
program.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic')
|
||||
for dep in dependencies:
|
||||
program.env.append_value('LINKFLAGS', '-lns3-' + dep)
|
||||
program.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive')
|
||||
return program
|
||||
|
||||
def register_ns3_script(bld, name, dependencies=('core',)):
|
||||
@@ -606,6 +608,22 @@ def add_scratch_programs(bld):
|
||||
obj.name = obj.target
|
||||
|
||||
|
||||
def _add_ns3_program_missing_deps(bld, program):
|
||||
deps_found = program.ns3_module_dependencies
|
||||
program.uselib_local = [dep + "--lib" for dep in deps_found]
|
||||
if program.env['ENABLE_STATIC_NS3'] and not program.env['ENABLE_SHARED_AND_STATIC_NS3']:
|
||||
if sys.platform == 'darwin':
|
||||
program.env.append_value('LINKFLAGS', '-Wl,-all_load')
|
||||
for dep in deps_found:
|
||||
program.env.append_value('LINKFLAGS', '-l' + dep)
|
||||
else:
|
||||
program.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic')
|
||||
for dep in deps_found:
|
||||
program.env.append_value('LINKFLAGS', '-l' + dep)
|
||||
program.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive')
|
||||
|
||||
|
||||
|
||||
def build(bld):
|
||||
# If --enabled-modules option was given, then print a warning
|
||||
# message and exit this function.
|
||||
@@ -751,6 +769,32 @@ def build(bld):
|
||||
|
||||
bld.add_subdirs('bindings/python')
|
||||
|
||||
## do a topological sort on the modules graph
|
||||
dep_graph = []
|
||||
for gen in bld.all_task_gen:
|
||||
if type(gen).__name__ in ['ns3module_taskgen']:
|
||||
for dep in gen.dependencies:
|
||||
dep_graph.append(("ns3-"+dep, gen.name))
|
||||
dep_graph.sort()
|
||||
sys.path.insert(0, "bindings/python")
|
||||
from topsort import topsort
|
||||
sorted_ns3_modules = topsort(dep_graph)
|
||||
#print sorted_ns3_modules
|
||||
|
||||
# we need to post() the ns3 modules, so they create libraries underneath, and programs can list them in uselib_local
|
||||
for module in sorted_ns3_modules:
|
||||
gen = bld.name_to_obj(module, bld.env)
|
||||
if type(gen).__name__ in ['ns3module_taskgen']:
|
||||
gen.post()
|
||||
for lib in gen.libs:
|
||||
lib.post()
|
||||
|
||||
for gen in bld.all_task_gen:
|
||||
if not getattr(gen, "is_ns3_program", False) or not hasattr(gen, "ns3_module_dependencies"):
|
||||
continue
|
||||
_add_ns3_program_missing_deps(bld, gen)
|
||||
|
||||
|
||||
if Options.options.run:
|
||||
# Check that the requested program name is valid
|
||||
program_name, dummy_program_argv = wutils.get_run_program(Options.options.run, wutils.get_command_template(env))
|
||||
|
||||
Reference in New Issue
Block a user