import subprocess
import os
import platform
import waflib
try:
vfile = open('include/protoVersion.h', 'r')
except:
vfile = open('protolib/include/protoVersion.h', 'r')
for line in vfile.readlines():
line = line.split()
if len(line) != 3:
continue
if "#define" == line[0] and "PROTOLIB_VERSION" == line[1]:
VERSION = line[2].strip('"')
if VERSION is None:
print ("Warning: Protolib version not found!?")
waflib.Configure.autoconfig = True
top = '.'
out = 'build'
system = platform.system().lower()
def options(ctx):
ctx.load('compiler_cxx')
ctx.load('python')
ctx.load('java')
bind_opts = ctx.parser.add_option_group('Language Bindings', 'Use during configure step.')
bind_opts.add_option('--build-python', action='store_true',
help='Build Python bindings [default:false]')
bind_opts.add_option('--build-java', action='store_true',
help='Build Java bindings [default:false]')
build_opts = ctx.parser.add_option_group('Compile Options', 'Use during build step.')
build_opts.add_option('--debug', action='store_true',
help='Build in debug mode [default:release]')
build_opts.add_option('--enable-wx', action='store_true',
help='Enable checking for wxWidgets.')
build_opts.add_option('--enable-static-library', action='store_true',
help='Enable installing static library. [default:false]')
def configure(ctx):
if system == 'windows':
ctx.env.MSVC_TARGETS = ['x86']
elif system == 'darwin':
ctx.env.ARCH = ['arm64', 'x86_64']
ctx.load('compiler_cxx')
ctx.env.USE_BUILD_PROTOLIB += ['BUILD_PROTOLIB']
if system in ('linux', 'darwin', 'freebsd', 'gnu', 'gnu/kfreebsd'):
ctx.env.DEFINES_BUILD_PROTOLIB += ['UNIX', 'HAVE_DIRFD', 'HAVE_IPV6',
'HAVE_ASSERT', 'HAVE_GETLOGIN']
ctx.check_cxx(lib='pthread')
ctx.env.USE_BUILD_PROTOLIB += ['PTHREAD']
if ctx.options.enable_wx:
ctx.check_cfg(path='wx-config', args=['--cxxflags', '--libs'],
package='', uselib_store='WX', mandatory=False)
if system == 'linux':
ctx.env.DEFINES_BUILD_PROTOLIB += ['LINUX',
'HAVE_LOCKF', '_FILE_OFFSET_BITS=64', 'HAVE_OLD_SIGNALHANDLER',
'NO_SCM_RIGHTS', 'HAVE_SCHED',
'USE_TIMERFD', 'USE_EVENTFD', 'HAVE_PSELECT', 'USE_SELECT']
ctx.check_cxx(lib='dl rt')
ctx.env.USE_BUILD_PROTOLIB += ['DL', 'RT']
ctx.env.HAVE_NETFILTER_QUEUE = ctx.check_cxx(lib='netfilter_queue',
mandatory=False)
if system == 'darwin':
ctx.env.DEFINES_BUILD_PROTOLIB += ['MACOSX',
'HAVE_FLOCK', '_FILE_OFFSET_BITS=64', 'HAVE_PSELECT', 'USE_SELECT'] ; ctx.check_cxx(lib='resolv')
ctx.env.USE_BUILD_PROTOLIB += ['RESOLV']
if system in ('freebsd'):
ctx.env.DEFINES_BUILD_PROTOLIB += ['HAVE_FLOCK', '_FILE_OFFSET_BITS=64',
'HAVE_PSELECT', 'USE_SELECT']
if system == 'windows':
ctx.env.DEFINES_BUILD_PROTOLIB += ['_CRT_SECURE_NO_WARNINGS',
'HAVE_ASSERT', 'WIN32', 'HAVE_IPV6']
ctx.env.CXXFLAGS += ['/EHsc']
ctx.check_libs_msvc(['ws2_32', 'iphlpapi', 'user32', 'gdi32', 'Advapi32', 'ntdll'])
ctx.env.USE_BUILD_PROTOLIB += ['WS2_32', 'IPHLPAPI', 'USER32', 'GDI32', 'ADVAPI32', 'ntdll.lib']
if system == "gnu":
ctx.check_cxx(lib='pcap')
ctx.env.LDFLAGS += ['-lpcap']
try:
libxml2Include = subprocess.check_output(['xml2-config', '--cflags']).strip().split('I', 1)[1]
ctx.env.append_value('INCLUDES', [libxml2Include])
print ("Added '%s' to INCLUDES" % libxml2Include)
except:
print ("WARNING: libxml2 not found! Some Protolib code may not build. Install 'libxml2-dev' package.")
if ctx.options.build_python:
ctx.load('python')
if 'darwin' == system:
print ("(Note MacOSX requires 'gettext' installation)")
ctx.env.LINKFLAGS += ['-L/opt/local/lib'] ; ctx.check_python_version((2,4))
ctx.check_python_headers()
if ctx.env.PYTHON_VERSION.split('.')[0] != '2':
waflib.Logs.warn('Python bindings currently only support Python 2')
else:
ctx.env.BUILD_PYTHON = True
if ctx.options.build_java:
ctx.load('java')
ctx.check_jni_headers()
for i in ctx.env.DEFINES:
if i == 'HAVE_JNI_H=1':
ctx.env.BUILD_JAVA = True
if ctx.options.debug:
ctx.env.DEFINES_BUILD_PROTOLIB += ['PROTO_DEBUG', 'DEBUG']
else:
ctx.env.DEFINES_BUILD_PROTOLIB += ['NDEBUG', "PROTO_DEBUG"]
if ctx.env.COMPILER_CXX == 'g++' or ctx.env.COMPILER_CXX == 'clang++':
ctx.env.CFLAGS += ['-fPIC']
ctx.env.CXXFLAGS += ['-fPIC']
if ctx.options.debug:
ctx.env.CFLAGS += ['-O0', '-g']
ctx.env.CXXFLAGS += ['-O0', '-g']
else:
ctx.env.CFLAGS += ['-O3']
ctx.env.CXXFLAGS += ['-O3']
if ctx.env.COMPILER_CXX == 'msvc':
if ctx.options.debug:
ctx.env.CFLAGS += ['/Od', '/RTC1', '/ZI']
else:
ctx.env.CXXFLAGS += ['/Ox', '/DNDEBUG']
ctx.env.CFLAGS
def build(ctx):
obj = ctx.objects(
target = 'protoObjs',
includes = ['include', 'include/unix'],
export_includes = ['include', 'include/unix'],
use = ctx.env.USE_BUILD_PROTOLIB,
source = ['src/common/{0}.cpp'.format(x) for x in [
'protoAddress',
'protoApp',
'protoBase64',
'protoBitmask',
'protoCap',
'protoChannel',
'protoDebug',
'protoDispatcher',
'protoEvent',
'protoFile',
'protoFlow',
'protoGraph',
'protoJson',
'protoLFSR',
'protoList',
'protoNet',
'protoPipe',
'protoPkt',
'protoPktARP',
'protoPktETH',
'protoPktGRE',
'protoPktIGMP',
'protoPktIP',
'protoPktRTP',
'protoQueue',
'protoRouteMgr',
'protoRouteTable',
'protoSerial',
'protoSocket',
'protoSpace',
'protoString',
'protoTime',
'protoTimer',
'protoTree',
'protoVif',
]],
)
if system in ('linux', 'darwin', 'freebsd', 'gnu', 'gnu/kfreebsd'):
obj.source.extend(['src/unix/{0}.cpp'.format(x) for x in [
'unixNet',
'unixSerial',
'unixVif',
]])
obj.source.extend(['src/manet/{0}.cpp'.format(x) for x in [
'manetGraph',
'manetMsg',
]])
if system == 'linux':
obj.source.extend(['src/linux/{0}.cpp'.format(x) for x in [
'linuxCap',
'linuxNet',
'linuxRouteMgr',
]])
obj.source.append('src/unix/zebraRouteMgr.cpp')
if ctx.env.HAVE_NETFILTER_QUEUE:
obj.source.append('src/linux/linuxDetour.cpp')
obj.use.append('NETFILTER_QUEUE')
if system in ('darwin', 'freebsd', 'gnu/kfreebsd'):
obj.source.extend(['src/bsd/{0}.cpp'.format(x) for x in [
'bsdDetour',
'bsdRouteMgr',
]])
if system != 'gnu/kfreebsd':
obj.source.append('src/bsd/bsdNet.cpp')
obj.source.append('src/unix/bpfCap.cpp')
if system == 'windows':
obj.source.extend(['src/win32/{0}.cpp'.format(x) for x in [
'win32Net',
'win32RouteMgr',
]])
if system == 'gnu':
obj.source.append('src/common/pcapCap.cpp')
protolib_st = ctx.stlib(
target = 'protokit',
name = 'protolib_st',
vnum = VERSION,
use = ['protoObjs'],
source = [],
features = 'cxx cxxstlib',
install_path = '${LIBDIR}',
)
if ctx.env.HAVE_WX:
protolib_st.source.append('src/wx/wxProtoApp.cpp')
protolib_st.use.append('WX')
if ctx.env.BUILD_PYTHON:
if ctx.env.COMPILER_CXX == 'clang++':
use = ['protoObjs']
else:
use = ['protolib_st']
ctx.shlib(
features = 'pyext',
target = 'protokit',
name = 'pyprotokit',
use = use,
source = ['src/python/protokit.cpp'],
)
if ctx.env.BUILD_JAVA:
if ctx.env.COMPILER_CXX == 'clang++':
use = ['protoObjs', 'JAVA']
else:
use = ['protolib_st', 'JAVA']
ctx.shlib(
target = 'ProtolibJni',
includes = ['include'],
use = use,
source = ['src/java/protoPipeJni.cpp'],
)
ctx(
features = ['javac', 'jar'],
srcdir = 'src/java/src',
outdir = 'src/java/src',
basedir = 'src/java/src',
destfile = 'protolib-jni.jar',
)
protolib_sh = ctx.shlib(
target = 'protokit',
name = 'protolib_sh',
vnum = VERSION,
use = ['protoObjs'],
source = [],
features = 'cxx cxxshlib',
install_path = '${LIBDIR}',
)
for example in (
'base64Example',
'detourExample',
'eventExample',
'fileTest',
'graphExample',
'lfsrExample',
'msg2MsgExample',
'netExample',
'pipe2SockExample',
'pipeExample',
'protoCapExample',
'protoExample',
'protoFileExample',
'queueExample',
'serialExample',
'simpleTcpExample',
'sock2PipeExample',
'threadExample',
'timerTest',
'vifExample',
'vifLan',
'udptest'
):
_make_simple_example(ctx, example)
ctx._parse_targets()
def _make_simple_example(ctx, name):
if ctx.env.COMPILER_CXX == 'clang++':
use = ['protoObjs']
else:
use = ['protolib_st']
ctx.program(
target = name,
use = use,
includes = ['include', 'include/unix'],
source = ['examples/{0}.cpp'.format(name)],
posted = True,
install_path = False,
)
@waflib.Configure.conf
def _parse_targets(ctx):
for task in ctx.get_group(None):
if ctx.targets == '*' or task.target in ctx.targets.split(','):
task.posted = False