tools: Add nlsrc command line tool
refs: #1834 Change-Id: Ifbe75a3f49e2689930e61ebfd348d9932b04c975
This commit is contained in:
1 parent
d6bb3fa306
commit
c439d66728
6 files changed
+647
-1
No files matched your search
+2
-1
@@ -59,7 +59,7 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'NLSR - Named Data Link State Routing Protocol'
|
||||
copyright = u'2014, Named Data Networking Project'
|
||||
copyright = u'2014-2015, Named Data Networking Project'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@@ -239,6 +239,7 @@ latex_documents = [
|
||||
man_pages = [
|
||||
('manpages/nlsr', 'nlsr', u'Named Data Link State Routing Protocol Daemon', None, 1),
|
||||
('manpages/nlsr.conf', 'nlsr.conf', u'Named Data Link State Routing Protocol Daemon config file', None, 5),
|
||||
('manpages/nlsrc', 'nlsrc', u'Command-line utility to interact with and collect statistics from NLSR', None, 1),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -6,4 +6,5 @@ Manpages
|
||||
.. toctree::
|
||||
manpages/nlsr
|
||||
manpages/nlsr.conf
|
||||
manpages/nlsrc
|
||||
:maxdepth: 1
|
||||
@@ -0,0 +1,55 @@
|
||||
nlsrc
|
||||
=====
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
::
|
||||
|
||||
nlsrc [-h] [-V] COMMAND [<Command Options>]
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
``nlsrc`` is a tool to retrieve link-state database (LSDB) status information from NLSR and
|
||||
announce/withdraw Name prefixes advertised by NLSR.
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
``-h``
|
||||
Print usage information
|
||||
|
||||
``-V``
|
||||
Show NLSRC version information
|
||||
|
||||
``COMMAND``
|
||||
|
||||
``status``
|
||||
Retrieve LSDB status information
|
||||
|
||||
``advertise``
|
||||
Add a Name prefix to be advertised by NLSR
|
||||
|
||||
``advertise <name>``
|
||||
|
||||
``name``
|
||||
The Name prefix to be advertised
|
||||
|
||||
``withdraw``
|
||||
Remove a Name prefix advertised through NLSR
|
||||
|
||||
``withdraw <name>``
|
||||
|
||||
``name``
|
||||
The Name prefix to be withdrawn
|
||||
|
||||
Exit Status
|
||||
-----------
|
||||
|
||||
nlsrc exits with one of the following values:
|
||||
::
|
||||
|
||||
0 nlsrc exited successfully
|
||||
>0 An error occurred
|
||||
+412
@@ -0,0 +1,412 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
* See AUTHORS.md for complete list of NLSR authors and contributors.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR 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
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#include "nlsrc.hpp"
|
||||
|
||||
#include "version.hpp"
|
||||
#include "src/publisher/lsa-publisher.hpp"
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/data.hpp>
|
||||
#include <ndn-cxx/interest.hpp>
|
||||
#include <ndn-cxx/encoding/block.hpp>
|
||||
#include <ndn-cxx/management/nfd-control-parameters.hpp>
|
||||
#include <ndn-cxx/management/nfd-control-response.hpp>
|
||||
#include <ndn-cxx/util/segment-fetcher.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace nlsrc {
|
||||
|
||||
const ndn::Name Nlsrc::LOCALHOST_PREFIX = ndn::Name("/localhost/nlsr");
|
||||
const ndn::Name Nlsrc::LSDB_PREFIX = ndn::Name(Nlsrc::LOCALHOST_PREFIX).append("lsdb");
|
||||
const ndn::Name Nlsrc::NAME_UPDATE_PREFIX = ndn::Name(Nlsrc::LOCALHOST_PREFIX).append("prefix-update");
|
||||
|
||||
const uint32_t Nlsrc::ERROR_CODE_TIMEOUT = 10060;
|
||||
const uint32_t Nlsrc::RESPONSE_CODE_SUCCESS = 200;
|
||||
|
||||
Nlsrc::Nlsrc(ndn::Face& face)
|
||||
: m_face(face)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::printUsage()
|
||||
{
|
||||
std::cout << "Usage:\n" << programName << " [-h] [-V] COMMAND [<Command Options>]\n"
|
||||
" -h print usage and exit\n"
|
||||
" -V print version and exit\n"
|
||||
"\n"
|
||||
" COMMAND can be one of the following:\n"
|
||||
" status\n"
|
||||
" display NLSR status\n"
|
||||
" advertise name\n"
|
||||
" advertise a name prefix through NLSR\n"
|
||||
" withdraw name\n"
|
||||
" remove a name prefix advertised through NLSR"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::getStatus()
|
||||
{
|
||||
m_fetchSteps.push_back(std::bind(&Nlsrc::fetchAdjacencyLsas, this));
|
||||
m_fetchSteps.push_back(std::bind(&Nlsrc::fetchCoordinateLsas, this));
|
||||
m_fetchSteps.push_back(std::bind(&Nlsrc::fetchNameLsas, this));
|
||||
m_fetchSteps.push_back(std::bind(&Nlsrc::printLsdb, this));
|
||||
|
||||
runNextStep();
|
||||
}
|
||||
|
||||
bool
|
||||
Nlsrc::dispatch(const std::string& command)
|
||||
{
|
||||
if (command == "advertise") {
|
||||
if (nOptions != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
advertiseName();
|
||||
return true;
|
||||
}
|
||||
else if (command == "withdraw") {
|
||||
if (nOptions != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
withdrawName();
|
||||
return true;
|
||||
}
|
||||
else if (command == "status") {
|
||||
if (nOptions != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
getStatus();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::runNextStep()
|
||||
{
|
||||
if (m_fetchSteps.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::function<void()> nextStep = m_fetchSteps.front();
|
||||
m_fetchSteps.pop_front();
|
||||
|
||||
nextStep();
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::advertiseName()
|
||||
{
|
||||
ndn::Name name = commandLineArguments[0];
|
||||
ndn::Name::Component verb("advertise");
|
||||
std::string info = "(Advertise: " + name.toUri() + ")";
|
||||
|
||||
sendNamePrefixUpdate(name, verb, info);
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::withdrawName()
|
||||
{
|
||||
ndn::Name name = commandLineArguments[0];
|
||||
ndn::Name::Component verb("withdraw");
|
||||
std::string info = "(Withdraw: " + name.toUri() + ")";
|
||||
|
||||
sendNamePrefixUpdate(name, verb, info);
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::sendNamePrefixUpdate(const ndn::Name& name,
|
||||
const ndn::Name::Component& verb,
|
||||
const std::string& info)
|
||||
{
|
||||
ndn::nfd::ControlParameters parameters;
|
||||
parameters.setName(name);
|
||||
|
||||
ndn::Name commandName = NAME_UPDATE_PREFIX;
|
||||
commandName.append(verb);
|
||||
|
||||
ndn::Interest interest(commandName.append(parameters.wireEncode()));
|
||||
interest.setMustBeFresh(true);
|
||||
m_keyChain.sign(interest);
|
||||
|
||||
m_face.expressInterest(interest,
|
||||
std::bind(&Nlsrc::onControlResponse, this, info, _2),
|
||||
std::bind(&Nlsrc::onTimeout, this, ERROR_CODE_TIMEOUT, "Timeout"));
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::onControlResponse(const std::string& info, const ndn::Data& data)
|
||||
{
|
||||
ndn::nfd::ControlResponse response;
|
||||
|
||||
try {
|
||||
response.wireDecode(data.getContent().blockFromValue());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "ERROR: Control response decoding error" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t code = response.getCode();
|
||||
|
||||
if (code != RESPONSE_CODE_SUCCESS) {
|
||||
std::cerr << "Name prefix update error (code: " << code << ")" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Applied Name prefix update successfully: " << info << std::endl;
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::fetchAdjacencyLsas()
|
||||
{
|
||||
fetchFromLsdb<nlsr::tlv::AdjacencyLsa>(nlsr::AdjacencyLsaPublisher::DATASET_COMPONENT,
|
||||
std::bind(&Nlsrc::recordAdjacencyLsa, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::fetchCoordinateLsas()
|
||||
{
|
||||
fetchFromLsdb<nlsr::tlv::CoordinateLsa>(nlsr::CoordinateLsaPublisher::DATASET_COMPONENT,
|
||||
std::bind(&Nlsrc::recordCoordinateLsa, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::fetchNameLsas()
|
||||
{
|
||||
fetchFromLsdb<nlsr::tlv::NameLsa>(nlsr::NameLsaPublisher::DATASET_COMPONENT,
|
||||
std::bind(&Nlsrc::recordNameLsa, this, _1));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void
|
||||
Nlsrc::fetchFromLsdb(const ndn::Name::Component& datasetType,
|
||||
const std::function<void(const T&)>& recordLsa)
|
||||
{
|
||||
ndn::Name command = LSDB_PREFIX;
|
||||
command.append(datasetType);
|
||||
|
||||
ndn::Interest interest(command);
|
||||
|
||||
ndn::util::SegmentFetcher::fetch(m_face,
|
||||
interest,
|
||||
ndn::util::DontVerifySegment(),
|
||||
std::bind(&Nlsrc::onFetchSuccess<T>,
|
||||
this, _1, recordLsa),
|
||||
std::bind(&Nlsrc::onTimeout, this, _1, _2));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void
|
||||
Nlsrc::onFetchSuccess(const ndn::ConstBufferPtr& data,
|
||||
const std::function<void(const T&)>& recordLsa)
|
||||
{
|
||||
ndn::Block block;
|
||||
size_t offset = 0;
|
||||
|
||||
while (offset < data->size()) {
|
||||
bool isOk = false;
|
||||
std::tie(isOk, block) = ndn::Block::fromBuffer(data, offset);
|
||||
|
||||
if (!isOk) {
|
||||
std::cerr << "ERROR: cannot decode LSA TLV" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
offset += block.size();
|
||||
|
||||
T lsa(block);
|
||||
recordLsa(lsa);
|
||||
}
|
||||
|
||||
runNextStep();
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::onTimeout(uint32_t errorCode, const std::string& error)
|
||||
{
|
||||
std::cerr << "Request timed out (code: " << errorCode
|
||||
<< ", error: " << error << ")" << std::endl;
|
||||
}
|
||||
|
||||
std::string
|
||||
Nlsrc::getLsaInfoString(const nlsr::tlv::LsaInfo& info)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << " info=" << info;
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::recordAdjacencyLsa(const nlsr::tlv::AdjacencyLsa& lsa)
|
||||
{
|
||||
Router& router = getRouter(lsa.getLsaInfo());
|
||||
|
||||
std::ostringstream os;
|
||||
os << " AdjacencyLsa:" << std::endl;
|
||||
|
||||
os << getLsaInfoString(lsa.getLsaInfo()) << std::endl;
|
||||
|
||||
for (const auto& adjacency : lsa.getAdjacencies()) {
|
||||
os << " adjacency=" << adjacency << std::endl;
|
||||
}
|
||||
|
||||
router.adjacencyLsaString = os.str();
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::recordCoordinateLsa(const nlsr::tlv::CoordinateLsa& lsa)
|
||||
{
|
||||
Router& router = getRouter(lsa.getLsaInfo());
|
||||
|
||||
std::ostringstream os;
|
||||
os << " Coordinate LSA:" << std::endl;
|
||||
|
||||
os << getLsaInfoString(lsa.getLsaInfo()) << std::endl;
|
||||
|
||||
os << " angle=" << lsa.getHyperbolicAngle() << std::endl;
|
||||
os << " radius=" << lsa.getHyperbolicRadius() << std::endl;
|
||||
|
||||
router.coordinateLsaString = os.str();
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::recordNameLsa(const nlsr::tlv::NameLsa& lsa)
|
||||
{
|
||||
Router& router = getRouter(lsa.getLsaInfo());
|
||||
|
||||
std::ostringstream os;
|
||||
os << " Name LSA:" << std::endl;
|
||||
|
||||
os << getLsaInfoString(lsa.getLsaInfo()) << std::endl;
|
||||
|
||||
for (const auto& name : lsa.getNames()) {
|
||||
os << " name=" << name << std::endl;
|
||||
}
|
||||
|
||||
router.nameLsaString = os.str();
|
||||
}
|
||||
|
||||
void
|
||||
Nlsrc::printLsdb()
|
||||
{
|
||||
std::cout << "NLSR Status" << std::endl;
|
||||
std::cout << "LSDB:" << std::endl;
|
||||
|
||||
for (const auto& item : m_routers) {
|
||||
std::cout << " OriginRouter: " << item.first << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
const Router& router = item.second;
|
||||
|
||||
if (!router.adjacencyLsaString.empty()) {
|
||||
std::cout << router.adjacencyLsaString << std::endl;
|
||||
}
|
||||
|
||||
if (!router.coordinateLsaString.empty()) {
|
||||
std::cout << router.coordinateLsaString << std::endl;
|
||||
}
|
||||
|
||||
if (!router.nameLsaString.empty()) {
|
||||
std::cout << router.nameLsaString << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Nlsrc::Router&
|
||||
Nlsrc::getRouter(const nlsr::tlv::LsaInfo& info)
|
||||
{
|
||||
const ndn::Name& originRouterName = info.getOriginRouter();
|
||||
|
||||
const auto& pair =
|
||||
m_routers.insert(std::make_pair(originRouterName, std::move(Router())));
|
||||
|
||||
return pair.first->second;
|
||||
}
|
||||
|
||||
} // namespace nlsrc
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
ndn::Face face;
|
||||
nlsrc::Nlsrc nlsrc(face);
|
||||
|
||||
nlsrc.programName = argv[0];
|
||||
|
||||
if (argc < 2) {
|
||||
nlsrc.printUsage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opt;
|
||||
while ((opt = ::getopt(argc, argv, "hV")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
nlsrc.printUsage();
|
||||
return 0;
|
||||
case 'V':
|
||||
std::cout << NLSR_VERSION_BUILD_STRING << std::endl;
|
||||
return 0;
|
||||
default:
|
||||
nlsrc.printUsage();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc == ::optind) {
|
||||
nlsrc.printUsage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
::optind = 2; // Set ::optind to the command's index
|
||||
|
||||
nlsrc.commandLineArguments = argv + ::optind;
|
||||
nlsrc.nOptions = argc - ::optind;
|
||||
|
||||
// argv[1] points to the command, so pass it to the dispatch
|
||||
bool isOk = nlsrc.dispatch(argv[1]);
|
||||
if (!isOk) {
|
||||
nlsrc.printUsage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
face.processEvents();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "ERROR: " << e.what() << std::endl;
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
* See AUTHORS.md for complete list of NLSR authors and contributors.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR 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
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#include "tlv/adjacency-lsa.hpp"
|
||||
#include "tlv/coordinate-lsa.hpp"
|
||||
#include "tlv/name-lsa.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifndef NLSR_TOOLS_NLSRC_HPP
|
||||
#define NLSR_TOOLS_NLSRC_HPP
|
||||
|
||||
namespace nlsrc {
|
||||
|
||||
class Nlsrc : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Nlsrc(ndn::Face& face);
|
||||
|
||||
void
|
||||
printUsage();
|
||||
|
||||
void
|
||||
getStatus();
|
||||
|
||||
bool
|
||||
dispatch(const std::string& cmd);
|
||||
|
||||
private:
|
||||
void
|
||||
runNextStep();
|
||||
|
||||
/**
|
||||
* \brief Adds a name prefix to be advertised in NLSR's Name LSA
|
||||
*
|
||||
* cmd format:
|
||||
* name
|
||||
*
|
||||
*/
|
||||
void
|
||||
advertiseName();
|
||||
|
||||
/**
|
||||
* \brief Removes a name prefix from NLSR's Name LSA
|
||||
*
|
||||
* cmd format:
|
||||
* name
|
||||
*
|
||||
*/
|
||||
void
|
||||
withdrawName();
|
||||
|
||||
void
|
||||
sendNamePrefixUpdate(const ndn::Name& name,
|
||||
const ndn::Name::Component& verb,
|
||||
const std::string& info);
|
||||
|
||||
void
|
||||
onControlResponse(const std::string& info, const ndn::Data& data);
|
||||
|
||||
private:
|
||||
void
|
||||
fetchAdjacencyLsas();
|
||||
|
||||
void
|
||||
fetchCoordinateLsas();
|
||||
|
||||
void
|
||||
fetchNameLsas();
|
||||
|
||||
template <class T>
|
||||
void
|
||||
fetchFromLsdb(const ndn::Name::Component& datasetType,
|
||||
const std::function<void(const T&)>& recordLsa);
|
||||
|
||||
template <class T>
|
||||
void
|
||||
onFetchSuccess(const ndn::ConstBufferPtr& data,
|
||||
const std::function<void(const T&)>& recordLsa);
|
||||
|
||||
void
|
||||
onTimeout(uint32_t errorCode, const std::string& error);
|
||||
|
||||
private:
|
||||
std::string
|
||||
getLsaInfoString(const nlsr::tlv::LsaInfo& info);
|
||||
|
||||
void
|
||||
recordAdjacencyLsa(const nlsr::tlv::AdjacencyLsa& lsa);
|
||||
|
||||
void
|
||||
recordCoordinateLsa(const nlsr::tlv::CoordinateLsa& lsa);
|
||||
|
||||
void
|
||||
recordNameLsa(const nlsr::tlv::NameLsa& lsa);
|
||||
|
||||
void
|
||||
printLsdb();
|
||||
|
||||
public:
|
||||
const char* programName;
|
||||
|
||||
// command parameters without leading 'cmd' component
|
||||
const char* const* commandLineArguments;
|
||||
int nOptions;
|
||||
|
||||
private:
|
||||
struct Router
|
||||
{
|
||||
std::string adjacencyLsaString;
|
||||
std::string coordinateLsaString;
|
||||
std::string nameLsaString;
|
||||
};
|
||||
|
||||
Router&
|
||||
getRouter(const nlsr::tlv::LsaInfo& info);
|
||||
|
||||
typedef std::map<const ndn::Name, Router> RouterMap;
|
||||
RouterMap m_routers;
|
||||
|
||||
private:
|
||||
ndn::KeyChain m_keyChain;
|
||||
ndn::Face& m_face;
|
||||
|
||||
std::deque<std::function<void()>> m_fetchSteps;
|
||||
|
||||
static const ndn::Name LOCALHOST_PREFIX;
|
||||
static const ndn::Name LSDB_PREFIX;
|
||||
static const ndn::Name NAME_UPDATE_PREFIX;
|
||||
|
||||
static const uint32_t ERROR_CODE_TIMEOUT;
|
||||
static const uint32_t RESPONSE_CODE_SUCCESS;
|
||||
};
|
||||
|
||||
} // namespace nlsrc
|
||||
|
||||
#endif // NLSR_TOOLS_NLSRC_HPP
|
||||
@@ -128,10 +128,25 @@ def build(bld):
|
||||
use='nlsr-objects',
|
||||
)
|
||||
|
||||
nlsrc = bld(
|
||||
target='bin/nlsrc',
|
||||
features='cxx cxxprogram',
|
||||
source='tools/nlsrc.cpp',
|
||||
use='nlsr-objects BOOST',
|
||||
)
|
||||
|
||||
if bld.env['WITH_TESTS']:
|
||||
bld.recurse('tests')
|
||||
bld.recurse('tests-integrated')
|
||||
|
||||
if bld.env['SPHINX_BUILD']:
|
||||
bld(features="sphinx",
|
||||
builder="man",
|
||||
outdir="docs/manpages",
|
||||
config="docs/conf.py",
|
||||
source=bld.path.ant_glob('docs/manpages/**/*.rst'),
|
||||
install_path="${MANDIR}/",
|
||||
VERSION=VERSION)
|
||||
|
||||
def docs(bld):
|
||||
from waflib import Options
|
||||
|
||||
Reference in new issue
Block a user