Adding a module to NS3

1,867 views
Skip to first unread message

Syd

unread,
Feb 4, 2011, 7:11:24 PM2/4/11
to ns-3-users
Hi All,
I am attempting to add a model to NS3. As per the documentation on
the NS3 manual, I copied the .cc and .h files to my NS3 home directory
(src/common) and updated the "wscript" folder in this same directory.
However, my model depends on other packages such as lapack. Lets say I
were to compile a design using this model in Linux (ubuntu 10.04), I
would do the following:

g++ -Wall -O3 -fopenmp -DLAPACK -DLUSOLVER=LAPACK GenrFail.o sim.o -
L../../src -lthyme -llapack -L/usr/local/src/GotoBLAS2 -lblas

However, WAF is based on python and I am unable to locate the file
where I need to insert the necessary flags. Can someone kindly provide
some feedback?

Best Regards,
Syd

Tom Henderson

unread,
Feb 4, 2011, 7:21:00 PM2/4/11
to ns-3-...@googlegroups.com


An example of this can be found in the wifi device, and the approach
could be copied. Some files in src/devices/wifi depend on GNU
Scientific Library (GSL), and when GSL is installed, we want to use it.
We want -lgsl -lm -lgslcblas to be appended. In the
src/devices/wifi/wscript, you can see this:

> if bld.env['ENABLE_GSL']:
> obj.uselib = 'GSL GSLCBLAS M'
>

where ENABLE_GSL is set in the top-level wscript (search for "have_gsl"
in the top wscript where the configuration check is done).

Syd

unread,
Feb 4, 2011, 8:20:26 PM2/4/11
to ns-3-users
Thanks for your help.

One other thing, how do I set the other flags like:
-Wall -O3 -fopenmp -DLAPACK -DLUSOLVER=LAPACK



Tom Henderson

unread,
Feb 5, 2011, 12:33:16 AM2/5/11
to ns-3-...@googlegroups.com
On 02/04/2011 05:20 PM, Syd wrote:
> Thanks for your help.
>
> One other thing, how do I set the other flags like:
> -Wall -O3 -fopenmp -DLAPACK -DLUSOLVER=LAPACK
>

I think that these can be changed by environment variables at configure
time:
http://code.google.com/p/waf/wiki/EnvironmentVariables

- Tom

Syd

unread,
Feb 6, 2011, 4:42:18 PM2/6/11
to ns-3-users
Hi Tom,
Unlike gsl, apparently lapack does not come with a pkgconfig
file (i.e. a corresponding ".pc" file). Using the following link, I
was able to get lapack up and running (i.e. sudo ./waf configure was
successful with no errors). Thank you.

http://cblfs.cross-lfs.org/index.php/ATLAS

With reference to your previous link, I assumed that these flags
should be set in the top level "wscript (near line 387)" file (NB. I
have no experience with flags in WAF). I added the 5 following lines,
but my source files are not able to locate the LUSOLVER macro defined
in the top level wscript file.


# append user defined flags after all our ones
1 CXXFLAGS = "-Wall -O3 -fopenmp"
2 CPPFLAGS = "-DLAPACK -DLUSOLVER=LAPACK"
3 LINKFLAGS ="-llapack -L/home/asydney/local -lblas -Lsrc/common -
lthyme"

for (confvar, envvar) in [['CCFLAGS', 'CCFLAGS_EXTRA'],
['CXXFLAGS', 'CXXFLAGS_EXTRA'],
['LINKFLAGS', 'LINKFLAGS_EXTRA'],
4 ['LINKFLAGS', 'LDFLAGS_EXTRA'],
5 ['CPPFLAGS', 'CPPFLAGS_EXTRA']]:

if envvar in os.environ:
value = shlex.split(os.environ[envvar])
conf.env.append_value(confvar, value)


First of all, am I inserting these flags correctly? Secondly, am I
inserting them in the right file?

Thanks Tom!
Syd

Gustavo Carneiro

unread,
Feb 7, 2011, 6:22:44 AM2/7/11
to ns-3-...@googlegroups.com
On Sun, Feb 6, 2011 at 21:42, Syd <asydn...@gmail.com> wrote:
Hi Tom,
      Unlike gsl, apparently lapack does not come with a pkgconfig
file (i.e. a corresponding ".pc" file). Using the following link, I
was able to get lapack up and running (i.e. sudo ./waf configure was
successful with no errors). Thank you.

http://cblfs.cross-lfs.org/index.php/ATLAS

With reference to your previous link, I assumed that these flags
should be set in the top level "wscript (near line 387)" file (NB. I
have no experience with flags in WAF). I added the 5 following lines,
but my source files are not able to locate the LUSOLVER macro defined
in the top level wscript file.


   # append user defined flags after all our ones
1   CXXFLAGS = "-Wall -O3 -fopenmp"

The correct way is: conf.env.append_value("CXXFLAGS", ["-Wall", "-O3", "-fopenmp"])
 
2   CPPFLAGS = "-DLAPACK -DLUSOLVER=LAPACK"

The correct way is: conf.env.append_value("CXXDEFINES", ["LAPACK", "LUSOLVER=LAPACK"])
 
3   LINKFLAGS ="-llapack -L/home/asydney/local -lblas -Lsrc/common -
lthyme"

The correct way is: conf.env.append_value("LINKFLAGS", ["-llapack", "-L/home/asydney/local", "-lblas", "-Lsrc/common", "-lthyme"])
 
Make sure to replace CXX with CC if you are compiling C sources instead of C++ ones.


   for (confvar, envvar) in [['CCFLAGS', 'CCFLAGS_EXTRA'],
                             ['CXXFLAGS', 'CXXFLAGS_EXTRA'],
                             ['LINKFLAGS', 'LINKFLAGS_EXTRA'],
4                             ['LINKFLAGS', 'LDFLAGS_EXTRA'],
5                             ['CPPFLAGS', 'CPPFLAGS_EXTRA']]:

       if envvar in os.environ:
           value = shlex.split(os.environ[envvar])
           conf.env.append_value(confvar, value)


First of all, am I inserting these flags correctly? Secondly, am I
inserting them in the right file?

Thanks Tom!
Syd

On Feb 4, 11:33 pm, Tom Henderson <t...@tomh.org> wrote:
> On 02/04/2011 05:20 PM, Syd wrote:
>
> > Thanks for your help.
>
> > One other thing, how do I set the other flags like:
> > -Wall -O3 -fopenmp -DLAPACK -DLUSOLVER=LAPACK
>
> I think that these can be changed by environment variables at configure
> time:http://code.google.com/p/waf/wiki/EnvironmentVariables
>
> - Tom

--
You received this message because you are subscribed to the Google Groups "ns-3-users" group.
To post to this group, send email to ns-3-...@googlegroups.com.
To unsubscribe from this group, send email to ns-3-users+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/ns-3-users?hl=en.




--
Gustavo J. A. M. Carneiro
INESC Porto, UTM, WiN, http://win.inescporto.pt/gjc
"The universe is always one step beyond logic." -- Frank Herbert

Syd

unread,
Feb 7, 2011, 5:50:33 PM2/7/11
to ns-3-users
Hi Gustavo,
Thanks for your previous response. With reference to your
previous reply, my source files are ".cpp" and below is the setup for
my "LINKFLAGS" within "wscript". My model included additional headers
in the following directory and so I added "-I/home/asydney/adevs/trunk/
include" to "LINKFLAGS" below.

conf.env.append_value("LINKFLAGS", ["-llapack", "-L/usr/local/src/
GotoBLAS2", "-lblas", "-L/home/asydney/ns-allinone-3.10/ns-3.10/src/
common", "-lthyme", "-I/home/asydney/adevs/trunk/include"])

However, when I run "sudo ./waf --check" WAF is unable to locate the
headers within the "adevs" directory that I specified above. For this
reason, I get a list of errors like the following:

debug/ns3/adevs.h:23:29: error: adevs_exception.h: No such file or
directory

PS. I have ensured that all the header files indeed exist in the
specified directory above.

Can you kindly point out my errors? Do I have to copy all the header
files from the "include" directory into "ns-3.10/src/common" and then
update the "wscript" file within this folder with the header names?
Thank you.

Cheers!
Syd

On Feb 7, 5:22 am, Gustavo Carneiro <gjcarne...@gmail.com> wrote:
> INESC Porto, UTM, WiN,http://win.inescporto.pt/gjc

Gustavo Carneiro

unread,
Feb 7, 2011, 7:21:58 PM2/7/11
to ns-3-...@googlegroups.com
On Mon, Feb 7, 2011 at 22:50, Syd <asydn...@gmail.com> wrote:
Hi Gustavo,
          Thanks for your previous response.  With reference to your
previous reply, my source files are ".cpp" and below is the setup for
my "LINKFLAGS" within "wscript". My model included additional headers
in the following directory and so I added "-I/home/asydney/adevs/trunk/
include" to "LINKFLAGS" below.

conf.env.append_value("LINKFLAGS", ["-llapack", "-L/usr/local/src/
GotoBLAS2", "-lblas", "-L/home/asydney/ns-allinone-3.10/ns-3.10/src/
common", "-lthyme", "-I/home/asydney/adevs/trunk/include"])

However, when I run "sudo ./waf --check" WAF is unable to locate the
headers within the "adevs" directory that I specified above. For this
reason, I get a list of errors like the following:

debug/ns3/adevs.h:23:29: error: adevs_exception.h: No such file or
directory

PS. I have ensured that all the header files indeed exist in the
specified directory above.

Can you kindly point out my errors?  Do I have to copy all the header
files from the "include" directory into "ns-3.10/src/common" and then
update the "wscript" file within this folder with the header names?
Thank you.


Sounds like you need to define the include path to point to the location of that header.  IIRC, it's the "CPPPATH" waf env var.  For more information, visit the waf documentation: http://waf.googlecode.com/svn/docs/single.html
INESC Porto, UTM, WiN, http://win.inescporto.pt/gjc

Tom Henderson

unread,
Feb 8, 2011, 9:32:25 AM2/8/11
to ns-3-...@googlegroups.com
I started a new wiki page to capture this info:
http://www.nsnam.org/wiki/index.php/HOWTO_use_ns-3_with_other_libraries

Gustavo, could you also use the extra environment variables such as
CXXFLAGS_EXTRA, LINKFLAGS_EXTRA, as long as you don't care if they are
applied to all of the build?

- Tom

Gustavo Carneiro

unread,
Feb 8, 2011, 9:59:14 AM2/8/11
to ns-3-...@googlegroups.com
Yes, of course.  CXXFLAGS_EXTRA can be set in the shell to have -I/foo/bar, for instance.  It's a quick way to include some external headers.  LINKFLAGS_EXTRA contains extra options to add to the linker command, e.g. libraries to link to.  One could also use CXXFLAGS and LINKFLAGS, without _EXTRA, but those variables completely replace the default ns-3 compilation options (such as -g -Wall).
 


- Tom

--
You received this message because you are subscribed to the Google Groups "ns-3-users" group.
To post to this group, send email to ns-3-...@googlegroups.com.
To unsubscribe from this group, send email to ns-3-users+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/ns-3-users?hl=en.




--
Gustavo J. A. M. Carneiro

Syd

unread,
Feb 9, 2011, 5:41:28 PM2/9/11
to ns-3-users
Hi Tom, Gustavo,
With your instructions, I have been able to add the necessary
flags. However, WAF keeps throwing an "openmp" related error:

sudo CXXFLAGS_EXTRA="-fopenmp" ./waf build

Waf: Entering directory `/home/asydney/ns-allinone-3.10/ns-3.10/build'
[1396/1519] cxx_link: build/debug/src/devices/bridge/examples/csma-
bridge-one-hop_2.o -> build/debug/src/devices/bridge/examples/csma-
bridge-one-hop
debug/libns3.so: undefined reference to `GOMP_parallel_start'
debug/libns3.so: undefined reference to `omp_get_thread_num'
debug/libns3.so: undefined reference to `GOMP_parallel_end'
debug/libns3.so: undefined reference to `omp_get_num_threads'
collect2: ld returned 1 exit status
Waf: Leaving directory `/home/asydney/ns-allinone-3.10/ns-3.10/build'
Build failed: -> task failed (err #1):
{task: cxx_link csma-bridge-one-hop_2.o -> csma-bridge-one-
hop}

As an added precaution (or for redanduncy), I also added the "openmp"
flag in my top-level wscript:

conf.env.append_value("CXXFLAGS", ["-Wall", "-O3", "-fopenmp"])

Finally, I verified that the "openmp" flag is set by printing out
"con.env":
'CXXFLAGS' ['-O0', '-ggdb', '-g3', '-Wall', '-Werror', '-O3', '-
fopenmp']

I have been stuck on this for the past few days. If you guys can
provide any feedback, I would totally appreciate that. Thanks much!

Syd



On Feb 8, 8:59 am, Gustavo Carneiro <gjcarne...@gmail.com> wrote:
> On Tue, Feb 8, 2011 at 14:32, Tom Henderson <t...@tomh.org> wrote:
> > I started a new wiki page to capture this info:
> >http://www.nsnam.org/wiki/index.php/HOWTO_use_ns-3_with_other_libraries
>
> > Gustavo, could you also use the extra environment variables such as
> > CXXFLAGS_EXTRA, LINKFLAGS_EXTRA, as long as you don't care if they are
> > applied to all of the build?
>
> Yes, of course.  CXXFLAGS_EXTRA can be set in the shell to have -I/foo/bar,
> for instance.  It's a quick way to include some external headers.
>  LINKFLAGS_EXTRA contains extra options to add to the linker command, e.g.
> libraries to link to.  One could also use CXXFLAGS and LINKFLAGS, without
> _EXTRA, but those variables completely replace the default ns-3 compilation
> options (such as -g -Wall).
>
>
>
> > - Tom
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "ns-3-users" group.
> > To post to this group, send email to ns-3-...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > ns-3-users+...@googlegroups.com.
> > For more options, visit this group at
> >http://groups.google.com/group/ns-3-users?hl=en.
>
> --
> Gustavo J. A. M. Carneiro
> INESC Porto, UTM, WiN,http://win.inescporto.pt/gjc

Gustavo Carneiro

unread,
Feb 9, 2011, 5:44:28 PM2/9/11
to ns-3-...@googlegroups.com
On Wed, Feb 9, 2011 at 22:41, Syd <asydn...@gmail.com> wrote:
Hi Tom, Gustavo,
       With your instructions, I have been able to add the necessary
flags. However, WAF keeps throwing an "openmp" related error:

sudo CXXFLAGS_EXTRA="-fopenmp" ./waf build

Below sounds like you are missing a library to link to.  Maybe you need LINKFLAGS_EXTRA="-fopenmp" also?  You can combine both in the same command:
 
 CXXFLAGS_EXTRA="-fopenmp" LINKFLAGS_EXTRA="-fopenmp" ./waf build
INESC Porto, UTM, WiN, http://win.inescporto.pt/gjc

Syd

unread,
Feb 9, 2011, 8:59:53 PM2/9/11
to ns-3-users
All,
Thanks to Tom and Gustavo, I was successfully able to add my
module to NS3. I see it only fit to give a brief summary of what I did
to get it up and running.

Goal: Integrate my ".cpp" model with NS3

NB. My original "make" file produced the following output:

g++ -Wall -O3 -fopenmp -DLAPACK -DLUSOLVER=LAPACK GenrFail.o sim.o -
L../../src -lthyme -llapack -L/usr/local/src/GotoBLAS2 -lblas

Below is my experience:

1. I copied my source files (.cpp) and my header files (.h) to ns-3.10/
src/common.

2. I added the name of my source and header files to the "wscript"
file within the directory mentioned in "1." Additionally, I inserted
the following block of code to the very end of this file:

>if bld.env['ENABLE_LAPACK']:
> common.uselib = 'LAPACK THYME BLAS

Similar to what was done in src/devices/wifi/wscript (Thanks to Tom
for this):
> if bld.env['ENABLE_GSL']:
> obj.uselib = 'GSL GSLCBLAS M


3. Then I inserted the following block of code in the top-level
"wscript" file (ns-3.10/wscript) below the block of code which reads
"have_gsl" (As Tom points out again, you can simply search for
"have_gsl"):

>have_lapack = conf.pkg_check_modules('LAPACK', 'lapack', mandatory=False)
> conf.env['ENABLE_LAPACK'] = have_lapack
>
> conf.report_optional_feature("LAPACK", "Linear Algebra Library (LAPACK)",
> conf.env['ENABLE_LAPACK'],
> "LAPACK not found")
> if have_lapack:
> conf.env.append_value('CXXDEFINES', "ENABLE_LAPACK")
> conf.env.append_value('CCDEFINES', "ENABLE_LAPACK")
> conf.env.append_value("CXXFLAGS", ["-Wall", "-O3", "-fopenmp"])
> conf.env.append_value("CXXDEFINES", ["LAPACK", "LUSOLVER=LAPACK"])
> conf.env.append_value("LINKFLAGS", ["-llapack", "-L/usr/local/src/GoToBLAS2", "-lblas", "-L/home/asydney/simulator/thyme-2.0/src", "-lthyme", "-fopenmp"])
> conf.env.append_value("CPPPATH",["/home/asydney/adevs/trunk/include","/home/asydney/simulator/thyme-2.0/src"])
> conf.env.append_value("LINKFLAGS_EXTRA","-fopenmp")

> print ("")
> print (conf.env)

The last line prints out all "env" flags. This is not necessary but
allows one to verify that my flags are set.

4. I run "sudo ./waf configure" and checked to see that all flags were
set.

5. Finally I run "sudo ./waf build" and voila! everything worked just
fine.

I do hope this helps someone. Again, you can always get the details
from the WAF book. However, you can learn quite a bit from other's
experience.

Tom and Gustave, stay awesome! Thanks!
Syd


On Feb 9, 4:44 pm, Gustavo Carneiro <gjcarne...@gmail.com> wrote:

Gevorg Poghosyan

unread,
Oct 17, 2012, 1:45:16 PM10/17/12
to ns-3-...@googlegroups.com
Hello!

I have a similar problem.
I am trying to link "libconfig" library to my ns3, but without success.

I tried to adopt the solution proposed in this post but I still get errors.

scratch/test_intersession.cc.1.o: In function `main':
/home/gevra/repos/ns-3-allinone/ns-3.15/build/../scratch/include_file.inc:36: undefined reference to `libconfig::Config::Config()'
/home/gevra/repos/ns-3-allinone/ns-3.15/build/../scratch/include_file.inc:41: undefined reference to `libconfig::Config::readFile(char const*)'
/home/gevra/repos/ns-3-allinone/ns-3.15/build/../scratch/include_file.inc:44: undefined reference to `libconfig::Config::lookup(char const*) const'

Can you help me to figure out with this?
The library is installed and the files are in /usr/local/lib and /usr/local/include...

As you can notice I use this library for a program in scratch/

Thanks!

Ahmed Zahran

unread,
May 26, 2015, 9:14:56 AM5/26/15
to ns-3-...@googlegroups.com
I was doing something similar to the question related to the last question. So I am sharing what worked for me in case it would be of use for future questions. 
Scratch folder is built in a different way from NS3. Typically, folders containing modules/components would have a wscript file where you can add additional build configurations. On the contrary, scratch configuration is based on add_scratch_programs function defined in the root/main wscript as shown below

def add_scratch_programs(bld):
    all_modules = [mod[len("ns3-"):] for mod in bld.env['NS3_ENABLED_MODULES']]
    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
A simple trick to get an external library work for scratch is the following
1- properly include the needed header files in your code. Typically the files are included from the build directory. So you have multiple options starting from adding the file manually to the build directory or any other folder but make sure that you properly direct the include directive.  
2- tell the compiler/linker where to find relevant libraries by extending the add_scratch_programs function as follows   

            obj.env.append_value("LINKFLAGS", ["-L/path/to/your/libraries/"])
            obj.env.append_value("LIB", ["LIBRARY_NAME"])  
            obj.env.append_value('CCFLAGS', ['-O3', '-m64', 'or whatever flags you would like' ])
NOTE: this would be applied to any app in scratch. So, it may be performed more elegantly by using an additional if statement targeting specific files. 

As a final note, step 2 can be used inside new modules to get the linking step to work but this would be performed in a different way through defining a special configure function to this module 
def configure(conf):
            conf.env.append_value("LINKFLAGS", ["-L/path/to/your/libraries/"])
            conf.env.append_value("LIB", ["LIBRARY_NAME"])  
            conf.env.append_value('CCFLAGS', ['-O3', '-m64', 'or whatever flags you would like' ])

This worked for a new module that I wrote. 

good luck 
Ahmed 
Reply all
Reply to author
Forward
0 new messages