blob: abc04358f8d324a31ebad9c094215efee795681e [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
Alexander Afanasyev88964782015-03-03 14:28:19 -080026VERSION = "0.3.1"
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 Afanasyev8269a052015-02-09 16:25:36 -080058 nfdopt.add_option('--with-custom-logger', type='string', default=None,
59 dest='with_custom_logger',
60 help='''Path to custom-logger.hpp and custom-logger-factory.hpp '''
61 '''implementing Logger and LoggerFactory interfaces''')
62
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080063def configure(conf):
Beichuan Zhang55b8ed42014-04-26 22:25:44 -070064 conf.load(['compiler_cxx', 'gnu_dirs',
Alexander Afanasyeve9186212014-08-23 20:15:48 -070065 'default-compiler-flags', 'pch', 'boost-kqueue',
Wentao Shang53df1632014-04-21 12:01:32 -070066 'boost', 'dependency-checker', 'websocket',
Junxiao Shi1c93cae2014-12-09 22:52:17 -070067 'doxygen', 'sphinx_build', 'type_traits', 'compiler-features'])
Alexander Afanasyevefea8fe2014-03-23 00:00:35 -070068
Davide Pesaventof0ae4422014-05-05 16:32:12 +020069 conf.find_program('bash', var='BASH')
70
Alexander Afanasyev6db058c2014-11-13 16:46:25 -080071 if not os.environ.has_key('PKG_CONFIG_PATH'):
72 os.environ['PKG_CONFIG_PATH'] = ':'.join([
73 '/usr/local/lib/pkgconfig',
74 '/opt/local/lib/pkgconfig'])
Alexander Afanasyev4a771362014-04-24 21:29:33 -070075 conf.check_cfg(package='libndn-cxx', args=['--cflags', '--libs'],
76 uselib_store='NDN_CXX', mandatory=True)
Davide Pesavento44deacc2014-02-19 10:48:07 +010077
Davide Pesaventob499a602014-11-18 22:36:56 +010078 conf.checkDependency(name='librt', lib='rt', mandatory=False)
79 conf.checkDependency(name='libresolv', lib='resolv', mandatory=False)
80
Alexander Afanasyev748e9892015-01-28 15:07:41 -080081 if not conf.check_cxx(msg='Checking if privilege drop/elevation is supported', mandatory=False,
82 define_name='HAVE_PRIVILEGE_DROP_AND_ELEVATE', fragment='''
83#include <unistd.h>
84#include <pwd.h>
85#include <grp.h>
86int
87main(int, char**)
88{
89 ::sysconf(_SC_GETGR_R_SIZE_MAX);
90 group grp;
91 getgrnam_r("nogroup", &grp, nullptr, 0, nullptr);
92 passwd pwd;
93 getpwnam_r("nobody", &pwd, nullptr, 0, nullptr);
94
95 int ret = setegid(grp.gr_gid);
96 ret = seteuid(pwd.pw_uid);
97 (void)(ret);
98 return 0;
99}
100'''):
101 Logs.warn('Dropping privileges is not supported on this platform')
102
Alexander Afanasyev49343f62015-01-26 21:58:07 -0800103 conf.check_cxx(header_name='ifaddrs.h', mandatory=False)
Alexander Afanasyev49343f62015-01-26 21:58:07 -0800104
Alexander Afanasyev5d57f972015-02-11 21:04:29 -0800105 boost_libs = 'system chrono program_options random thread'
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800106 if conf.options.with_tests:
107 conf.env['WITH_TESTS'] = 1
Junxiao Shi88884492014-02-15 15:57:43 -0700108 conf.define('WITH_TESTS', 1);
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -0700109 boost_libs += ' unit_test_framework'
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800110
Ilya Moiseenko96b80bb2014-04-05 20:53:27 -0400111 if conf.options.with_other_tests:
112 conf.env['WITH_OTHER_TESTS'] = 1
113
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800114 conf.check_boost(lib=boost_libs)
Alexander Afanasyeve1724c42014-02-26 22:00:54 -0800115 if conf.env.BOOST_VERSION_NUMBER < 104800:
Junxiao Shiea48d8b2014-03-16 13:53:47 -0700116 Logs.error("Minimum required boost version is 1.48.0")
117 Logs.error("Please upgrade your distribution or install custom boost libraries" +
118 " (http://redmine.named-data.net/projects/nfd/wiki/Boost_FAQ)")
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800119 return
Alexander Afanasyevc78b1412014-02-19 14:08:26 -0800120
121 conf.load('unix-socket')
Wentao Shang53df1632014-04-21 12:01:32 -0700122 conf.checkWebsocket(mandatory=True)
Davide Pesavento44deacc2014-02-19 10:48:07 +0100123
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700124 if not conf.options.without_libpcap:
Alexander Afanasyeve9186212014-08-23 20:15:48 -0700125 conf.check_asio_pcap_support()
126 if conf.env['HAVE_ASIO_PCAP_SUPPORT']:
127 conf.checkDependency(name='libpcap', lib='pcap', mandatory=True,
128 errmsg='not found, but required for Ethernet face support. '
129 'Specify --without-libpcap to disable Ethernet face support.')
130 else:
131 Logs.warn('Warning: Ethernet face support is not supported on this platform with Boost libraries version 1.56. '
132 'See http://redmine.named-data.net/issues/1877 for more details')
Davide Pesaventof0ae4422014-05-05 16:32:12 +0200133 if conf.env['HAVE_LIBPCAP']:
134 conf.check_cxx(function_name='pcap_set_immediate_mode', header_name='pcap/pcap.h',
135 cxxflags='-Wno-error', use='LIBPCAP', mandatory=False)
Alexander Afanasyevefea8fe2014-03-23 00:00:35 -0700136
Alexander Afanasyev8269a052015-02-09 16:25:36 -0800137 if conf.options.with_custom_logger:
138 conf.define('HAVE_CUSTOM_LOGGER', 1)
139 conf.env['INCLUDES_CUSTOM_LOGGER'] = [conf.options.with_custom_logger]
140 conf.env['HAVE_CUSTOM_LOGGER'] = 1
141
Alexander Afanasyev689569b2014-02-16 20:20:07 -0800142 conf.load('coverage')
143
Steve DiBenedettofbb40a82014-03-11 19:40:15 -0600144 conf.define('DEFAULT_CONFIG_FILE', '%s/ndn/nfd.conf' % conf.env['SYSCONFDIR'])
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700145
Junxiao Shi759f7062014-11-29 10:19:22 -0700146 # disable assertions in release builds
147 if not conf.options.debug:
148 conf.define('NDEBUG', 1)
149
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700150 conf.write_config_header('config.hpp')
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800151
Junxiao Shi09bf7c42014-01-31 11:10:25 -0700152def build(bld):
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700153 version(bld)
154
155 bld(features="subst",
156 name='version',
157 source='version.hpp.in',
158 target='version.hpp',
159 install_path=None,
160 VERSION_STRING=VERSION_BASE,
161 VERSION_BUILD=VERSION,
162 VERSION=int(VERSION_SPLIT[0]) * 1000000 +
163 int(VERSION_SPLIT[1]) * 1000 +
164 int(VERSION_SPLIT[2]),
165 VERSION_MAJOR=VERSION_SPLIT[0],
166 VERSION_MINOR=VERSION_SPLIT[1],
167 VERSION_PATCH=VERSION_SPLIT[2],
168 )
169
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700170 core = bld(
171 target='core-objects',
172 name='core-objects',
Alexander Afanasyev58ea4582014-05-30 08:38:56 +0300173 features='cxx pch',
Alexander Afanasyev8269a052015-02-09 16:25:36 -0800174 source=bld.path.ant_glob(['core/**/*.cpp'],
175 excl=['core/logger*.cpp']),
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700176 use='version BOOST NDN_CXX LIBRT',
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700177 includes='. core',
178 export_includes='. core',
Alexander Afanasyev58ea4582014-05-30 08:38:56 +0300179 headers='common.hpp',
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700180 )
181
Alexander Afanasyev8269a052015-02-09 16:25:36 -0800182 if bld.env['HAVE_CUSTOM_LOGGER']:
183 core.use += " CUSTOM_LOGGER"
184 else:
185 core.source += bld.path.ant_glob(['core/logger*.cpp'])
186
Alexander Afanasyevc78b1412014-02-19 14:08:26 -0800187 nfd_objects = bld(
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700188 target='daemon-objects',
189 name='daemon-objects',
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -0700190 features='cxx',
191 source=bld.path.ant_glob(['daemon/**/*.cpp'],
192 excl=['daemon/face/ethernet-*.cpp',
193 'daemon/face/unix-*.cpp',
Wentao Shang53df1632014-04-21 12:01:32 -0700194 'daemon/face/websocket-*.cpp',
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -0700195 'daemon/main.cpp']),
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600196 use='core-objects WEBSOCKET',
197 includes='daemon',
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700198 export_includes='daemon',
Junxiao Shi0fcb41e2014-01-24 10:29:43 -0700199 )
200
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700201 if bld.env['HAVE_LIBPCAP']:
Davide Pesavento44deacc2014-02-19 10:48:07 +0100202 nfd_objects.source += bld.path.ant_glob('daemon/face/ethernet-*.cpp')
Alexander Afanasyev5cda2e02014-04-11 13:58:44 -0700203 nfd_objects.use += ' LIBPCAP'
Davide Pesavento44deacc2014-02-19 10:48:07 +0100204
Alexander Afanasyevc78b1412014-02-19 14:08:26 -0800205 if bld.env['HAVE_UNIX_SOCKETS']:
Davide Pesavento44deacc2014-02-19 10:48:07 +0100206 nfd_objects.source += bld.path.ant_glob('daemon/face/unix-*.cpp')
Alexander Afanasyevc78b1412014-02-19 14:08:26 -0800207
Wentao Shang53df1632014-04-21 12:01:32 -0700208 if bld.env['HAVE_WEBSOCKET']:
209 nfd_objects.source += bld.path.ant_glob('daemon/face/websocket-*.cpp')
210
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700211 rib_objects = bld(
212 target='rib-objects',
213 name='rib-objects',
214 features='cxx',
Alexander Afanasyevf08a7372015-02-09 21:28:19 -0800215 source=bld.path.ant_glob(['rib/**/*.cpp']),
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700216 use='core-objects',
217 )
218
Alexander Afanasyevf08a7372015-02-09 21:28:19 -0800219 bld(target='bin/nfd',
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700220 features='cxx cxxprogram',
Alexander Afanasyevf08a7372015-02-09 21:28:19 -0800221 source='daemon/main.cpp',
222 use='daemon-objects rib-objects',
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700223 )
224
Alexander Afanasyev262203b2015-01-26 16:39:59 -0800225 bld.recurse("tools")
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700226 bld.recurse("tests")
Ilya Moiseenko96b80bb2014-04-05 20:53:27 -0400227
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -0700228 bld(features="subst",
229 source='nfd.conf.sample.in',
230 target='nfd.conf.sample',
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700231 install_path="${SYSCONFDIR}/ndn",
Wentao Shang53df1632014-04-21 12:01:32 -0700232 IF_HAVE_LIBPCAP="" if bld.env['HAVE_LIBPCAP'] else "; ",
233 IF_HAVE_WEBSOCKET="" if bld.env['HAVE_WEBSOCKET'] else "; ")
Alexander Afanasyev35fc2b72014-02-13 16:56:21 -0800234
Alexander Afanasyev49272f72014-04-06 21:49:46 -0700235 if bld.env['SPHINX_BUILD']:
236 bld(features="sphinx",
237 builder="man",
238 outdir="docs/manpages",
239 config="docs/conf.py",
240 source=bld.path.ant_glob('docs/manpages/**/*.rst'),
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700241 install_path="${MANDIR}/",
242 VERSION=VERSION)
Alexander Afanasyev49272f72014-04-06 21:49:46 -0700243
Alexander Afanasyev284257b2014-04-11 14:16:51 -0700244def docs(bld):
245 from waflib import Options
246 Options.commands = ['doxygen', 'sphinx'] + Options.commands
247
Alexander Afanasyev35fc2b72014-02-13 16:56:21 -0800248def doxygen(bld):
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700249 version(bld)
250
Alexander Afanasyev35fc2b72014-02-13 16:56:21 -0800251 if not bld.env.DOXYGEN:
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700252 Logs.error("ERROR: cannot build documentation (`doxygen' is not found in $PATH)")
253 else:
254 bld(features="subst",
255 name="doxygen-conf",
Alexander Afanasyev20757882014-08-25 22:39:08 -0700256 source=["docs/doxygen.conf.in",
257 "docs/named_data_theme/named_data_footer-with-analytics.html.in"],
258 target=["docs/doxygen.conf",
259 "docs/named_data_theme/named_data_footer-with-analytics.html"],
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700260 VERSION=VERSION_BASE,
Alexander Afanasyev20757882014-08-25 22:39:08 -0700261 HTML_FOOTER="../build/docs/named_data_theme/named_data_footer-with-analytics.html" \
262 if os.getenv('GOOGLE_ANALYTICS', None) \
263 else "../docs/named_data_theme/named_data_footer.html",
264 GOOGLE_ANALYTICS=os.getenv('GOOGLE_ANALYTICS', ""),
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700265 )
266
267 bld(features="doxygen",
268 doxyfile='docs/doxygen.conf',
269 use="doxygen-conf")
Alexander Afanasyev49272f72014-04-06 21:49:46 -0700270
271def sphinx(bld):
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700272 version(bld)
273
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700274 if not bld.env.SPHINX_BUILD:
275 bld.fatal("ERROR: cannot build documentation (`sphinx-build' is not found in $PATH)")
276 else:
277 bld(features="sphinx",
278 outdir="docs",
279 source=bld.path.ant_glob('docs/**/*.rst'),
280 config="docs/conf.py",
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700281 VERSION=VERSION_BASE)
282
283def version(ctx):
Alexander Afanasyev26181532014-05-07 23:38:51 -0700284 if getattr(Context.g_module, 'VERSION_BASE', None):
285 return
286
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700287 Context.g_module.VERSION_BASE = Context.g_module.VERSION
288 Context.g_module.VERSION_SPLIT = [v for v in VERSION_BASE.split('.')]
289
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700290 didGetVersion = False
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700291 try:
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700292 cmd = ['git', 'describe', '--always', '--match', '%s*' % GIT_TAG_PREFIX]
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700293 p = Utils.subprocess.Popen(cmd, stdout=Utils.subprocess.PIPE,
294 stderr=None, stdin=None)
Alexander Afanasyev3b21fa32014-09-01 13:25:20 -0700295 out = str(p.communicate()[0].strip())
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700296 didGetVersion = (p.returncode == 0 and out != "")
297 if didGetVersion:
298 if out.startswith(GIT_TAG_PREFIX):
299 Context.g_module.VERSION = out[len(GIT_TAG_PREFIX):]
300 else:
301 Context.g_module.VERSION = "%s-commit-%s" % (Context.g_module.VERSION_BASE, out)
302 except OSError:
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700303 pass
304
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700305 versionFile = ctx.path.find_node('VERSION')
306
307 if not didGetVersion and versionFile is not None:
308 try:
309 Context.g_module.VERSION = versionFile.read()
310 return
311 except (OSError, IOError):
312 pass
313
314 # version was obtained from git, update VERSION file if necessary
315 if versionFile is not None:
316 try:
317 version = versionFile.read()
318 if version == Context.g_module.VERSION:
319 return # no need to update
320 except (OSError, IOError):
321 Logs.warn("VERSION file exists, but not readable")
322 else:
323 versionFile = ctx.path.make_node('VERSION')
324
325 if versionFile is None:
326 return
327
328 try:
329 versionFile.write(Context.g_module.VERSION)
330 except (OSError, IOError):
331 Logs.warn("VERSION file is not writeable")
332
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700333def dist(ctx):
334 version(ctx)
335
336def distcheck(ctx):
337 version(ctx)