blob: 955266bbda7e95d7226977bdd74dac68559994d6 [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 Afanasyev7c10b3b2015-01-20 12:24:27 -080026VERSION = "0.3.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 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 Afanasyev613e2a92014-04-15 13:36:58 -0700211 bld(target='bin/nfd',
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -0700212 features='cxx cxxprogram',
213 source='daemon/main.cpp',
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700214 use='daemon-objects',
hilata198cadb2014-02-15 23:46:19 -0600215 )
Steve DiBenedetto84da5bf2014-03-11 14:51:29 -0600216
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700217 rib_objects = bld(
218 target='rib-objects',
219 name='rib-objects',
220 features='cxx',
221 source=bld.path.ant_glob(['rib/**/*.cpp'],
222 excl=['rib/main.cpp']),
223 use='core-objects',
224 )
225
226 bld(target='bin/nrd',
227 features='cxx cxxprogram',
228 source='rib/main.cpp',
229 use='rib-objects',
230 )
231
Alexander Afanasyev262203b2015-01-26 16:39:59 -0800232 bld.recurse("tools")
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700233 bld.recurse("tests")
Ilya Moiseenko96b80bb2014-04-05 20:53:27 -0400234
Alexander Afanasyev97e4cac2014-03-28 10:55:11 -0700235 bld(features="subst",
236 source='nfd.conf.sample.in',
237 target='nfd.conf.sample',
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700238 install_path="${SYSCONFDIR}/ndn",
Wentao Shang53df1632014-04-21 12:01:32 -0700239 IF_HAVE_LIBPCAP="" if bld.env['HAVE_LIBPCAP'] else "; ",
240 IF_HAVE_WEBSOCKET="" if bld.env['HAVE_WEBSOCKET'] else "; ")
Alexander Afanasyev35fc2b72014-02-13 16:56:21 -0800241
Alexander Afanasyev49272f72014-04-06 21:49:46 -0700242 if bld.env['SPHINX_BUILD']:
243 bld(features="sphinx",
244 builder="man",
245 outdir="docs/manpages",
246 config="docs/conf.py",
247 source=bld.path.ant_glob('docs/manpages/**/*.rst'),
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700248 install_path="${MANDIR}/",
249 VERSION=VERSION)
Alexander Afanasyev49272f72014-04-06 21:49:46 -0700250
Alexander Afanasyev284257b2014-04-11 14:16:51 -0700251def docs(bld):
252 from waflib import Options
253 Options.commands = ['doxygen', 'sphinx'] + Options.commands
254
Alexander Afanasyev35fc2b72014-02-13 16:56:21 -0800255def doxygen(bld):
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700256 version(bld)
257
Alexander Afanasyev35fc2b72014-02-13 16:56:21 -0800258 if not bld.env.DOXYGEN:
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700259 Logs.error("ERROR: cannot build documentation (`doxygen' is not found in $PATH)")
260 else:
261 bld(features="subst",
262 name="doxygen-conf",
Alexander Afanasyev20757882014-08-25 22:39:08 -0700263 source=["docs/doxygen.conf.in",
264 "docs/named_data_theme/named_data_footer-with-analytics.html.in"],
265 target=["docs/doxygen.conf",
266 "docs/named_data_theme/named_data_footer-with-analytics.html"],
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700267 VERSION=VERSION_BASE,
Alexander Afanasyev20757882014-08-25 22:39:08 -0700268 HTML_FOOTER="../build/docs/named_data_theme/named_data_footer-with-analytics.html" \
269 if os.getenv('GOOGLE_ANALYTICS', None) \
270 else "../docs/named_data_theme/named_data_footer.html",
271 GOOGLE_ANALYTICS=os.getenv('GOOGLE_ANALYTICS', ""),
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700272 )
273
274 bld(features="doxygen",
275 doxyfile='docs/doxygen.conf',
276 use="doxygen-conf")
Alexander Afanasyev49272f72014-04-06 21:49:46 -0700277
278def sphinx(bld):
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700279 version(bld)
280
Beichuan Zhang55b8ed42014-04-26 22:25:44 -0700281 if not bld.env.SPHINX_BUILD:
282 bld.fatal("ERROR: cannot build documentation (`sphinx-build' is not found in $PATH)")
283 else:
284 bld(features="sphinx",
285 outdir="docs",
286 source=bld.path.ant_glob('docs/**/*.rst'),
287 config="docs/conf.py",
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700288 VERSION=VERSION_BASE)
289
290def version(ctx):
Alexander Afanasyev26181532014-05-07 23:38:51 -0700291 if getattr(Context.g_module, 'VERSION_BASE', None):
292 return
293
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700294 Context.g_module.VERSION_BASE = Context.g_module.VERSION
295 Context.g_module.VERSION_SPLIT = [v for v in VERSION_BASE.split('.')]
296
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700297 didGetVersion = False
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700298 try:
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700299 cmd = ['git', 'describe', '--always', '--match', '%s*' % GIT_TAG_PREFIX]
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700300 p = Utils.subprocess.Popen(cmd, stdout=Utils.subprocess.PIPE,
301 stderr=None, stdin=None)
Alexander Afanasyev3b21fa32014-09-01 13:25:20 -0700302 out = str(p.communicate()[0].strip())
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700303 didGetVersion = (p.returncode == 0 and out != "")
304 if didGetVersion:
305 if out.startswith(GIT_TAG_PREFIX):
306 Context.g_module.VERSION = out[len(GIT_TAG_PREFIX):]
307 else:
308 Context.g_module.VERSION = "%s-commit-%s" % (Context.g_module.VERSION_BASE, out)
309 except OSError:
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700310 pass
311
Alexander Afanasyev48f5a3c2014-08-22 22:33:01 -0700312 versionFile = ctx.path.find_node('VERSION')
313
314 if not didGetVersion and versionFile is not None:
315 try:
316 Context.g_module.VERSION = versionFile.read()
317 return
318 except (OSError, IOError):
319 pass
320
321 # version was obtained from git, update VERSION file if necessary
322 if versionFile is not None:
323 try:
324 version = versionFile.read()
325 if version == Context.g_module.VERSION:
326 return # no need to update
327 except (OSError, IOError):
328 Logs.warn("VERSION file exists, but not readable")
329 else:
330 versionFile = ctx.path.make_node('VERSION')
331
332 if versionFile is None:
333 return
334
335 try:
336 versionFile.write(Context.g_module.VERSION)
337 except (OSError, IOError):
338 Logs.warn("VERSION file is not writeable")
339
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700340def dist(ctx):
341 version(ctx)
342
343def distcheck(ctx):
344 version(ctx)