Undefined Reference in a copied, but renamed application

382 views
Skip to first unread message

stefanhe...@googlemail.com

unread,
Feb 26, 2013, 5:18:14 AM2/26/13
to ns-3-...@googlegroups.com
Hello everybody!

I used already existing applications as a basis for my new model, but just after renaming the classes, I get an undefined reference error. In fact I am using the star.cc example, which I renamed to star-example and the onoff-application.{cc,h} and on-off-application.{cc.h}, which I renamed to smartmeter.{cc.h} and smartmeter-helper.{cc.h}. I added everything to the belonging wscript in my self-created modul "smartsim" and I am unable to find the root of the problem.

This is the concrete error:

[1510/1870] cxx: src/smartsim/helper/smartmeter-helper.cc -> build/src/smartsim/helper/smartmeter-helper.cc.1.o
[1512/1870] cxx: src/smartsim/examples/star-example.cc -> build/src/smartsim/examples/star-example.cc.2.o
[1864/1870] cxxprogram: build/src/smartsim/examples/star-example.cc.2.o -> build/src/smartsim/examples/ns3-dev-star-example-debug
src/smartsim/examples/star-example.cc.2.o: In function `main':
/home/user/Documents/ns3/ns-3-allinone/ns-3-dev/build/../src/smartsim/examples/star-example.cc:93: undefined reference to `ns3::SmartmeterHelper::SmartmeterHelper(std::string, ns3::Address)'
/home/stefan/Documents/ns3/ns-3-allinone/ns-3-dev/build/../src/smartsim/examples/star-example.cc:94: undefined reference to `ns3::SmartmeterHelper::SetAttribute(std::string, ns3::AttributeValue const&)'
/home/stefan/Documents/ns3/ns-3-allinone/ns-3-dev/build/../src/smartsim/examples/star-example.cc:95: undefined reference to `ns3::SmartmeterHelper::SetAttribute(std::string, ns3::AttributeValue const&)'
/home/stefan/Documents/ns3/ns-3-allinone/ns-3-dev/build/../src/smartsim/examples/star-example.cc:102: undefined reference to `ns3::SmartmeterHelper::SetAttribute(std::string, ns3::AttributeValue const&)'
/home/stefan/Documents/ns3/ns-3-allinone/ns-3-dev/build/../src/smartsim/examples/star-example.cc:103: undefined reference to `ns3::SmartmeterHelper::Install(ns3::Ptr<ns3::Node>) const'
collect2: error: ld returned 1 exit status
Waf: Leaving directory `/home/stefan/Documents/ns3/ns-3-allinone/ns-3-dev/build'

And here are the actually classes, but I just renamed things a little bit.

star-example.c:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

 //Source: /examples/tcp/star.cc

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/netanim-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/point-to-point-layout-module.h"
#include "../helper/smartmeter-helper.h"

// Network topology (default)
//
//        n2 n3 n4              .
//         \ | /                .
//          \|/                 .
//     n1--- n0---n5            .
//          /|\                 .
//         / | \                .
//        n8 n7 n6              .
//


using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("Star-Example");

int
main (int argc, char *argv[])
{

  //
  // Set up some default values for the simulation.
  //
  Config::SetDefault ("ns3::Smartmeter::PacketSize", UintegerValue (137));

  // ??? try and stick 15kb/s into the data rate
  Config::SetDefault ("ns3::Smartmeter::DataRate", StringValue ("14kb/s"));

  //
  // Default number of nodes in the star.  Overridable by command line argument.
  //
  uint32_t nSpokes = 8;

  CommandLine cmd;
  cmd.AddValue ("nSpokes", "Number of nodes to place in the star", nSpokes);
  cmd.Parse (argc, argv);

  NS_LOG_INFO ("Build star topology.");
  PointToPointHelper pointToPoint;
  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
  PointToPointStarHelper star (nSpokes, pointToPoint);

  NS_LOG_INFO ("Install internet stack on all nodes.");
  InternetStackHelper internet;
  star.InstallStack (internet);

  NS_LOG_INFO ("Assign IP Addresses.");
  star.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.1.0", "255.255.255.0"));

  NS_LOG_INFO ("Create applications.");
  //
  // Create a packet sink on the star "hub" to receive packets.
  //
  uint16_t port = 50000;
  Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress);
  ApplicationContainer hubApp = packetSinkHelper.Install (star.GetHub ());
  hubApp.Start (Seconds (1.0));
  hubApp.Stop (Seconds (10.0));

  //
  // Create OnOff applications to send TCP to the hub, one on each spoke node.
  //
  SmartmeterHelper smartmeterHelper ("ns3::TcpSocketFactory", Address ());
  smartmeterHelper.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
  smartmeterHelper.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));

  ApplicationContainer spokeApps;

  for (uint32_t i = 0; i < star.SpokeCount (); ++i)
    {
      AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i), port));
      smartmeterHelper.SetAttribute ("Remote", remoteAddress);
      spokeApps.Add (smartmeterHelper.Install (star.GetSpokeNode (i)));
    }
  spokeApps.Start (Seconds (1.0));
  spokeApps.Stop (Seconds (10.0));

  NS_LOG_INFO ("Enable static global routing.");
  //
  // Turn on global static routing so we can actually be routed across the star.
  //
  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

  NS_LOG_INFO ("Enable pcap tracing.");
  //
  // Do pcap tracing on all point-to-point devices on all nodes.
  //
  pointToPoint.EnablePcapAll ("starExample");

  NS_LOG_INFO ("Run Simulation.");
  Simulator::Run ();
  Simulator::Destroy ();
  NS_LOG_INFO ("Done.");

  return 0;
}


smartmeter-helper.cc:

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2008 INRIA
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Mathieu Lacage <mathieu...@sophia.inria.fr>
 */

 //Source: /src/application/helper/on-off-helper.cc

#include "smartmeter-helper.h"
#include "ns3/inet-socket-address.h"
#include "ns3/packet-socket-address.h"
#include "ns3/string.h"
#include "ns3/data-rate.h"
#include "ns3/uinteger.h"
#include "ns3/names.h"
#include "ns3/random-variable-stream.h"
#include "ns3/smartmeter.h"

namespace ns3 {

SmartmeterHelper::SmartmeterHelper (std::string protocol, Address address)
{
  m_factory.SetTypeId ("ns3::Smartmeter");
  m_factory.Set ("Protocol", StringValue (protocol));
  m_factory.Set ("Remote", AddressValue (address));
}

void
SmartmeterHelper::SetAttribute (std::string name, const AttributeValue &value)
{
  m_factory.Set (name, value);
}

ApplicationContainer
SmartmeterHelper::Install (Ptr<Node> node) const
{
  return ApplicationContainer (InstallPriv (node));
}

ApplicationContainer
SmartmeterHelper::Install (std::string nodeName) const
{
  Ptr<Node> node = Names::Find<Node> (nodeName);
  return ApplicationContainer (InstallPriv (node));
}

ApplicationContainer
SmartmeterHelper::Install (NodeContainer c) const
{
  ApplicationContainer apps;
  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
    {
      apps.Add (InstallPriv (*i));
    }

  return apps;
}

Ptr<Application>
SmartmeterHelper::InstallPriv (Ptr<Node> node) const
{
  Ptr<Application> app = m_factory.Create<Application> ();
  node->AddApplication (app);

  return app;
}

int64_t
SmartmeterHelper::AssignStreams (NodeContainer c, int64_t stream)
{
  int64_t currentStream = stream;
  Ptr<Node> node;
  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
    {
      node = (*i);
      for (uint32_t j = 0; j < node->GetNApplications (); j++)
        {
          Ptr<Smartmeter> smart = DynamicCast<Smartmeter> (node->GetApplication (j));
          if (smart)
            {
              currentStream += smart->AssignStreams (currentStream);
            }
        }
    }
  return (currentStream - stream);
}

void
SmartmeterHelper::SetConstantRate (DataRate dataRate, uint32_t packetSize)
{
  m_factory.Set ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
  m_factory.Set ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
  m_factory.Set ("DataRate", DataRateValue (dataRate));
  m_factory.Set ("PacketSize", UintegerValue (packetSize));
}

} // namespace ns3
 

smartmeter-helper.h:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2008 INRIA
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Mathieu Lacage <mathieu...@sophia.inria.fr>
 */

 //Source: /src/application/helper/on-off-helper.h

#ifndef SMARTMETER_HELPER_H
#define SMARTMETER_HELPER_H

#include <stdint.h>
#include <string>
#include "ns3/object-factory.h"
#include "ns3/address.h"
#include "ns3/attribute.h"
#include "ns3/net-device.h"
#include "ns3/node-container.h"
#include "ns3/application-container.h"
#include "ns3/smartmeter.h"

namespace ns3 {

class DataRate;

/**
 * \brief A helper to make it easier to instantiate an ns3::OnOffApplication
 * on a set of nodes.
 */
class SmartmeterHelper
{
public:
  /**
   * Create an SmartmeterHelper to make it easier to work with OnOffApplications
   *
   * \param protocol the name of the protocol to use to send traffic
   *        by the applications. This string identifies the socket
   *        factory type used to create sockets for the applications.
   *        A typical value would be ns3::UdpSocketFactory.
   * \param address the address of the remote node to send traffic
   *        to.
   */
  SmartmeterHelper (std::string protocol, Address address);

  /**
   * Helper function used to set the underlying application attributes.
   *
   * \param name the name of the application attribute to set
   * \param value the value of the application attribute to set
   */
  void SetAttribute (std::string name, const AttributeValue &value);

  /**
   * Helper function to set a constant rate source.  Equivalent to
   * setting the attributes OnTime to constant 1000 seconds, OffTime to
   * constant 0 seconds, and the DataRate and PacketSize set accordingly
   *
   * \param dataRate DataRate object for the sending rate
   * \param packetSize size in bytes of the packet payloads generated
   */
  void SetConstantRate (DataRate dataRate, uint32_t packetSize = 512);

  /**
   * Install an ns3::OnOffApplication on each node of the input container
   * configured with all the attributes set with SetAttribute.
   *
   * \param c NodeContainer of the set of nodes on which an OnOffApplication
   * will be installed.
   * \returns Container of Ptr to the applications installed.
   */
  ApplicationContainer Install (NodeContainer c) const;

  /**
   * Install an ns3::OnOffApplication on the node configured with all the
   * attributes set with SetAttribute.
   *
   * \param node The node on which an OnOffApplication will be installed.
   * \returns Container of Ptr to the applications installed.
   */
  ApplicationContainer Install (Ptr<Node> node) const;

  /**
   * Install an ns3::OnOffApplication on the node configured with all the
   * attributes set with SetAttribute.
   *
   * \param nodeName The node on which an OnOffApplication will be installed.
   * \returns Container of Ptr to the applications installed.
   */
  ApplicationContainer Install (std::string nodeName) const;

 /**
  * Assign a fixed random variable stream number to the random variables
  * used by this model.  Return the number of streams (possibly zero) that
  * have been assigned.  The Install() method should have previously been
  * called by the user.
  *
  * \param stream first stream index to use
  * \param c NodeContainer of the set of nodes for which the OnOffApplication
  *          should be modified to use a fixed stream
  * \return the number of stream indices assigned by this helper
  */
  int64_t AssignStreams (NodeContainer c, int64_t stream);

private:
  /**
   * \internal
   * Install an ns3::OnOffApplication on the node configured with all the
   * attributes set with SetAttribute.
   *
   * \param node The node on which an OnOffApplication will be installed.
   * \returns Ptr to the application installed.
   */
  Ptr<Application> InstallPriv (Ptr<Node> node) const;
  std::string m_protocol;
  Address m_remote;
  ObjectFactory m_factory;
};

} // namespace ns3

#endif /* SMARTMETER_HELPER_H */


wscript in the root directory of the modul "smartsim":

# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-

# def options(opt):
#     pass

# def configure(conf):
#     conf.check_nonfatal(header_name='stdint.h', define_name='HAVE_STDINT_H')

def build(bld):
    module = bld.create_ns3_module('smartsim', ['internet', 'config-store', 'tools'])
    module.source = [
        'model/smartsim.cc',
        'model/request-response-server.cc',
        'model/request-response-client.cc',
        'model/smartmeter.cc',
        'helper/smartsim-helper.cc',
        'helper/request-response-helper.cc',
        'helper/smartmeter-helper.cc',
    ]

    module_test = bld.create_ns3_module_test_library('smartsim')
    module_test.source = [
        'test/smartsim-test-suite.cc',
        ]

    headers = bld.new_task_gen(features=['ns3header'])
    headers.module = 'smartsim'
    headers.source = [
        'model/smartsim.h',
        'model/request-response-server.h',
        'model/request-response-client.h',
        'model/smartmeter.h',
        'helper/smartsim-helper.h',
        'helper/request-response-helper.h',
        'helper/smartmeter-helper.h',
        ]

    if bld.env.ENABLE_EXAMPLES:
        bld.add_subdirs('examples')

    # bld.ns3_python_bindings()


I am glad for every help!!
Greets.

Thomas Roberts

unread,
Feb 26, 2013, 7:20:32 AM2/26/13
to ns-3-...@googlegroups.com

Hi there!


You need to use the create module script, then go into src/<yourmodulename>/model and edit the cc and h files, then when they're done, then run ./waf distclean and ./waf build!

Hope this was helpful
Thomas.
Message has been deleted

stefanhe...@googlemail.com

unread,
Feb 26, 2013, 8:01:12 AM2/26/13
to ns-3-...@googlegroups.com
Thanks for your reply,

I used this Tutorial , which includes the use of the create-module.py script, too. Even after a "./waf distclean" the same errors are still existing.

Greets.

stefanhe...@googlemail.com

unread,
Feb 28, 2013, 9:06:48 AM2/28/13
to ns-3-...@googlegroups.com
Found the solution. I forgot to add the own module to the wscript file in the examples folder.
Reply all
Reply to author
Forward
0 new messages