blob: 53edd43db49fdc408f6effa0e4ef96adcb2fd414 [file] [log] [blame]
Alexander Afanasyev2aa39622014-01-22 11:51:11 -08001# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07002
3"""
4Copyright (c) 2014 Regents of the University of California,
5 Arizona Board of Regents,
6 Colorado State University,
7 University Pierre & Marie Curie, Sorbonne University,
8 Washington University in St. Louis,
9 Beijing Institute of Technology
10
11This file is part of NFD (Named Data Networking Forwarding Daemon).
12See AUTHORS.md for complete list of NFD authors and contributors.
13
14NFD is free software: you can redistribute it and/or modify it under the terms
15of the GNU General Public License as published by the Free Software Foundation,
16either version 3 of the License, or (at your option) any later version.
17
18NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20PURPOSE. See the GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License along with
23NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24"""
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080025
Junxiao Shi6b597e72014-06-29 23:41:17 -070026VERSION = "0.2.0"
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -070027APPNAME = "nfd"
28BUGREPORT = "http://redmine.named-data.net/projects/nfd"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070029URL = "http://named-data.net/doc/NFD/"
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -070030GIT_TAG_PREFIX = "NFD-"
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -070031
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070032from waflib import Logs, Utils, Context
Alexander Afanasyev20757882014-08-25 22:39:08 -070033import os
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080034
35def options(opt):
Alexander Afanasyev5cda2e02014-04-11 13:58:44 -070036 opt.load(['compiler_cxx', 'gnu_dirs'])
Wentao Shang53df1632014-04-21 12:01:32 -070037 opt.load(['boost', 'unix-socket', 'dependency-checker', 'websocket',
Alexander Afanasyeve9186212014-08-23 20:15:48 -070038 'default-compiler-flags', 'coverage', 'pch', 'boost-kqueue',
Junxiao Shi1c93cae2014-12-09 22:52:17 -070039 'doxygen', 'sphinx_build', 'type_traits', 'compiler-features'],
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -070040 tooldir=['.waf-tools'])
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080041
42 nfdopt = opt.add_option_group('NFD Options')
Alexander Afanasyev885a85b2014-04-12 21:01:13 -070043 opt.addUnixOptions(nfdopt)
Wentao Shang53df1632014-04-21 12:01:32 -070044 opt.addWebsocketOptions(nfdopt)
Alexander Afanasyev885a85b2014-04-12 21:01:13 -070045 opt.addDependencyOptions(nfdopt, 'libpcap')
46 nfdopt.add_option('--without-libpcap', action='store_true', default=False,
47 dest='without_libpcap',
48 help='''Disable libpcap (Ethernet face support will be disabled)''')
49
Alexander Afanasyev5cda2e02014-04-11 13:58:44 -070050 opt.addDependencyOptions(nfdopt, 'librt', '(optional)')
51 opt.addDependencyOptions(nfdopt, 'libresolv', '(optional)')
52
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -070053 nfdopt.add_option('--with-tests', action='store_true', default=False,
54 dest='with_tests', help='''Build unit tests''')
Ilya Moiseenko96b80bb2014-04-05 20:53:27 -040055 nfdopt.add_option('--with-other-tests', action='store_true', default=False,
56 dest='with_other_tests', help='''Build other tests''')
Steve DiBenedetto84da5bf2014-03-11 14:51:29 -060057
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080058def configure(conf):
Beichuan Zhang55b8ed42014-04-26 22:25:44 -070059 conf.load(['compiler_cxx', 'gnu_dirs',
Alexander Afanasyeve9186212014-08-23 20:15:48 -070060 'default-compiler-flags', 'pch', 'boost-kqueue',
Wentao Shang53df1632014-04-21 12:01:32 -070061 'boost', 'dependency-checker', 'websocket',
Junxiao Shi1c93cae2014-12-09 22:52:17 -070062 'doxygen', 'sphinx_build', 'type_traits', 'compiler-features'])
Alexander Afanasyevefea8fe2014-03-23 00:00:35 -070063
Davide Pesaventof0ae4422014-05-05 16:32:12 +020064 conf.find_program('bash', var='BASH')
65
Alexander Afanasyev6db058c2014-11-13 16:46:25 -080066 if not os.environ.has_key('PKG_CONFIG_PATH'):
67 os.environ['PKG_CONFIG_PATH'] = ':'.join([
68 '/usr/local/lib/pkgconfig',
69 '/opt/local/lib/pkgconfig'])
Alexander Afanasyev4a771362014-04-24 21:29:33 -070070 conf.check_cfg(package='libndn-cxx', args=['--cflags', '--libs'],
71 uselib_store='NDN_CXX', mandatory=True)
Davide Pesavento44deacc2014-02-19 10:48:07 +010072
Davide Pesaventob499a602014-11-18 22:36:56 +010073 conf.checkDependency(name='librt', lib='rt', mandatory=False)
74 conf.checkDependency(name='libresolv', lib='resolv', mandatory=False)
75
Alexander Afanasyev748e9892015-01-28 15:07:41 -080076 if not conf.check_cxx(msg='Checking if privilege drop/elevation is supported', mandatory=False,
77 define_name='HAVE_PRIVILEGE_DROP_AND_ELEVATE', fragment='''
78#include <unistd.h>
79#include <pwd.h>
80#include <grp.h>
81int
82main(int, char**)
83{
84 ::sysconf(_SC_GETGR_R_SIZE_MAX);
85 group grp;
86 getgrnam_r("nogroup", &grp, nullptr, 0, nullptr);
87 passwd pwd;
88 getpwnam_r("nobody", &pwd, nullptr, 0, nullptr);
89
90 int ret = setegid(grp.gr_gid);
91 ret = seteuid(pwd.pw_uid);
92 (void)(ret);
93 return 0;
94}
95'''):
96 Logs.warn('Dropping privileges is not supported on this platform')
97
Alexander Afanasyev49343f62015-01-26 21:58:07 -080098 conf.check_cxx(header_name='ifaddrs.h', mandatory=False)
Alexander Afanasyev49343f62015-01-26 21:58:07 -080099
Wentao Shang93ef6c92014-06-19 11:59:17 -0400100 boost_libs = 'system chrono program_options random'
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800101 if conf.options.with_tests:
102 conf.env['WITH_TESTS'] = 1
Junxiao Shi88884492014-02-15 15:57:43 -0700103 conf.define('WITH_TESTS', 1);
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -0700104 boost_libs += ' unit_test_framework'
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800105
Ilya Moiseenko96b80bb2014-04-05 20:53:27 -0400106 if conf.options.with_other_tests:
107 conf.env['WITH_OTHER_TESTS'] = 1
108
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800109 conf.check_boost(lib=boost_libs)
Alexander Afanasyeve1724c42014-02-26 22:00:54 -0800110 if conf.env.BOOST_VERSION_NUMBER < 104800:
Junxiao Shiea48d8b2014-03-16 13:53:47 -0700111 Logs.error("Minimum required boost version is 1.48.0")
112 Logs.error("Please upgrade your distribution or install custom boost libraries" +
113 " (http://redmine.named-data.net/projects/nfd/wiki/Boost_FAQ)")
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800114 return
Alexander Afanasyevc78b1412014-02-19 14:08:26 -0800115
116 conf.load('unix-socket')
Wentao Shang53df1632014-04-21 12:01:32 -0700117 conf.checkWebsocket(mandatory=True)
Davide Pesavento44deacc2014-02-19 10:48:07 +0100118
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700119 if not conf.options.without_libpcap:
Alexander Afanasyeve9186212014-08-23 20:15:48 -0700120 conf.check_asio_pcap_support()
121 if conf.env['HAVE_ASIO_PCAP_SUPPORT']:
122 conf.checkDependency(name='libpcap', lib='pcap', mandatory=True,
123 errmsg='not found, but required for Ethernet face support. '
124 'Specify --without-libpcap to disable Ethernet face support.')
125 else:
126 Logs.warn('Warning: Ethernet face support is not supported on this platform with Boost libraries version 1.56. '
127 'See http://redmine.named-data.net/issues/1877 for more details')
Davide Pesaventof0ae4422014-05-05 16:32:12 +0200128 if conf.env['HAVE_LIBPCAP']:
129 conf.check_cxx(function_name='pcap_set_immediate_mode', header_name='pcap/pcap.h',
130 cxxflags='-Wno-error', use='LIBPCAP', mandatory=False)
Alexander Afanasyevefea8fe2014-03-23 00:00:35 -0700131
Alexander Afanasyev689569b2014-02-16 20:20:07 -0800132 conf.load('coverage')
133
Steve DiBenedettofbb40a82014-03-11 19:40:15 -0600134 conf.define('DEFAULT_CONFIG_FILE', '%s/ndn/nfd.conf' % conf.env['SYSCONFDIR'])
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700135
Junxiao Shi759f7062014-11-29 10:19:22 -0700136 # disable assertions in release builds
137 if not conf.options.debug:
138 conf.define('NDEBUG', 1)
139
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700140 conf.write_config_header('config.hpp')
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800141
Junxiao Shi09bf7c42014-01-31 11:10:25 -0700142def build(bld):
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700143 version(bld)
144
145 bld(features="subst",
146 name='version',
147 source='version.hpp.in',
148 target='version.hpp',
149 install_path=None,
150 VERSION_STRING=VERSION_BASE,
151 VERSION_BUILD=VERSION,
152 VERSION=int(VERSION_SPLIT[0]) * 1000000 +
153 int(VERSION_SPLIT[1]) * 1000 +
154 int(VERSION_SPLIT[2]),
155 VERSION_MAJOR=VERSION_SPLIT[0],
156 VERSION_MINOR=VERSION_SPLIT[1],
157 VERSION_PATCH=VERSION_SPLIT[2],
158 )
159
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700160 core = bld(
161 target='core-objects',
162 name='core-objects',
Alexander Afanasyev58ea4582014-05-30 08:38:56 +0300163 features='cxx pch',
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700164 source=bld.path.ant_glob(['core/**/*.cpp']),
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700165 use='version BOOST NDN_CXX LIBRT',
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700166 includes='. core',
167 export_includes='. core',
Alexander Afanasyev58ea4582014-05-30 08:38:56 +0300168 headers='common.hpp',
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700169 )
170
Alexander Afanasyevc78b1412014-02-19 14:08:26 -0800171 nfd_objects = bld(
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700172 target='daemon-objects',
173 name='daemon-objects',
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -0700174 features='cxx',
175 source=bld.path.ant_glob(['daemon/**/*.cpp'],
176 excl=['daemon/face/ethernet-*.cpp',
177 'daemon/face/unix-*.cpp',
Wentao Shang53df1632014-04-21 12:01:32 -0700178 'daemon/face/websocket-*.cpp',
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -0700179 'daemon/main.cpp']),
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600180 use='core-objects WEBSOCKET',
181 includes='daemon',
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700182 export_includes='daemon',
Junxiao Shi0fcb41e2014-01-24 10:29:43 -0700183 )
184
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700185 if bld.env['HAVE_LIBPCAP']:
Davide Pesavento44deacc2014-02-19 10:48:07 +0100186 nfd_objects.source += bld.path.ant_glob('daemon/face/ethernet-*.cpp')
Alexander Afanasyev5cda2e02014-04-11 13:58:44 -0700187 nfd_objects.use += ' LIBPCAP'
Davide Pesavento44deacc2014-02-19 10:48:07 +0100188
Alexander Afanasyevc78b1412014-02-19 14:08:26 -0800189 if bld.env['HAVE_UNIX_SOCKETS']:
Davide Pesavento44deacc2014-02-19 10:48:07 +0100190 nfd_objects.source += bld.path.ant_glob('daemon/face/unix-*.cpp')
Alexander Afanasyevc78b1412014-02-19 14:08:26 -0800191
Wentao Shang53df1632014-04-21 12:01:32 -0700192 if bld.env['HAVE_WEBSOCKET']:
193 nfd_objects.source += bld.path.ant_glob('daemon/face/websocket-*.cpp')
194
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700195 bld(target='bin/nfd',
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -0700196 features='cxx cxxprogram',
197 source='daemon/main.cpp',
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700198 use='daemon-objects',
hilata198cadb2014-02-15 23:46:19 -0600199 )
Steve DiBenedetto84da5bf2014-03-11 14:51:29 -0600200
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700201 rib_objects = bld(
202 target='rib-objects',
203 name='rib-objects',
204 features='cxx',
205 source=bld.path.ant_glob(['rib/**/*.cpp'],
206 excl=['rib/main.cpp']),
207 use='core-objects',
208 )
209
210 bld(target='bin/nrd',
211 features='cxx cxxprogram',
212 source='rib/main.cpp',
213 use='rib-objects',
214 )
215
Alexander Afanasyev262203b2015-01-26 16:39:59 -0800216 bld.recurse("tools")
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700217 bld.recurse("tests")
Ilya Moiseenko96b80bb2014-04-05 20:53:27 -0400218
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -0700219 bld(features="subst",
220 source='nfd.conf.sample.in',
221 target='nfd.conf.sample',
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700222 install_path="${SYSCONFDIR}/ndn",
Wentao Shang53df1632014-04-21 12:01:32 -0700223 IF_HAVE_LIBPCAP="" if bld.env['HAVE_LIBPCAP'] else "; ",
224 IF_HAVE_WEBSOCKET="" if bld.env['HAVE_WEBSOCKET'] else "; ")
Alexander Afanasyev35fc2b72014-02-13 16:56:21 -0800225
Alexander Afanasyev49272f72014-04-06 21:49:46 -0700226 if bld.env['SPHINX_BUILD']:
227 bld(features="sphinx",
228 builder="man",
229 outdir="docs/manpages",
230 config="docs/conf.py",
231 source=bld.path.ant_glob('docs/manpages/**/*.rst'),
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700232 install_path="${MANDIR}/",
233 VERSION=VERSION)
Alexander Afanasyev49272f72014-04-06 21:49:46 -0700234
Alexander Afanasyev284257b2014-04-11 14:16:51 -0700235def docs(bld):
236 from waflib import Options
237 Options.commands = ['doxygen', 'sphinx'] + Options.commands
238
Alexander Afanasyev35fc2b72014-02-13 16:56:21 -0800239def doxygen(bld):
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700240 version(bld)
241
Alexander Afanasyev35fc2b72014-02-13 16:56:21 -0800242 if not bld.env.DOXYGEN:
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700243 Logs.error("ERROR: cannot build documentation (`doxygen' is not found in $PATH)")
244 else:
245 bld(features="subst",
246 name="doxygen-conf",
Alexander Afanasyev20757882014-08-25 22:39:08 -0700247 source=["docs/doxygen.conf.in",
248 "docs/named_data_theme/named_data_footer-with-analytics.html.in"],
249 target=["docs/doxygen.conf",
250 "docs/named_data_theme/named_data_footer-with-analytics.html"],
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700251 VERSION=VERSION_BASE,
Alexander Afanasyev20757882014-08-25 22:39:08 -0700252 HTML_FOOTER="../build/docs/named_data_theme/named_data_footer-with-analytics.html" \
253 if os.getenv('GOOGLE_ANALYTICS', None) \
254 else "../docs/named_data_theme/named_data_footer.html",
255 GOOGLE_ANALYTICS=os.getenv('GOOGLE_ANALYTICS', ""),
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700256 )
257
258 bld(features="doxygen",
259 doxyfile='docs/doxygen.conf',
260 use="doxygen-conf")
Alexander Afanasyev49272f72014-04-06 21:49:46 -0700261
262def sphinx(bld):
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700263 version(bld)
264
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700265 if not bld.env.SPHINX_BUILD:
266 bld.fatal("ERROR: cannot build documentation (`sphinx-build' is not found in $PATH)")
267 else:
268 bld(features="sphinx",
269 outdir="docs",
270 source=bld.path.ant_glob('docs/**/*.rst'),
271 config="docs/conf.py",
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700272 VERSION=VERSION_BASE)
273
274def version(ctx):
Alexander Afanasyev26181532014-05-07 23:38:51 -0700275 if getattr(Context.g_module, 'VERSION_BASE', None):
276 return
277
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700278 Context.g_module.VERSION_BASE = Context.g_module.VERSION
279 Context.g_module.VERSION_SPLIT = [v for v in VERSION_BASE.split('.')]
280
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700281 didGetVersion = False
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700282 try:
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700283 cmd = ['git', 'describe', '--always', '--match', '%s*' % GIT_TAG_PREFIX]
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700284 p = Utils.subprocess.Popen(cmd, stdout=Utils.subprocess.PIPE,
285 stderr=None, stdin=None)
Alexander Afanasyev3b21fa32014-09-01 13:25:20 -0700286 out = str(p.communicate()[0].strip())
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700287 didGetVersion = (p.returncode == 0 and out != "")
288 if didGetVersion:
289 if out.startswith(GIT_TAG_PREFIX):
290 Context.g_module.VERSION = out[len(GIT_TAG_PREFIX):]
291 else:
292 Context.g_module.VERSION = "%s-commit-%s" % (Context.g_module.VERSION_BASE, out)
293 except OSError:
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700294 pass
295
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700296 versionFile = ctx.path.find_node('VERSION')
297
298 if not didGetVersion and versionFile is not None:
299 try:
300 Context.g_module.VERSION = versionFile.read()
301 return
302 except (OSError, IOError):
303 pass
304
305 # version was obtained from git, update VERSION file if necessary
306 if versionFile is not None:
307 try:
308 version = versionFile.read()
309 if version == Context.g_module.VERSION:
310 return # no need to update
311 except (OSError, IOError):
312 Logs.warn("VERSION file exists, but not readable")
313 else:
314 versionFile = ctx.path.make_node('VERSION')
315
316 if versionFile is None:
317 return
318
319 try:
320 versionFile.write(Context.g_module.VERSION)
321 except (OSError, IOError):
322 Logs.warn("VERSION file is not writeable")
323
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700324def dist(ctx):
325 version(ctx)
326
327def distcheck(ctx):
328 version(ctx)