# -*- mode: python -*- # OpenPGM build script import os import time import sys EnsureSConsVersion( 0, 97 ) SConsignFile('scons.signatures'); opt = Options(None, ARGUMENTS) opt.AddOptions ( (EnumOption ('BUILD', 'build environment', 'debug', ('release', 'debug', 'profile'))), (EnumOption ('BRANCH', 'branch prediction', 'none', ('none', 'profile', 'seed'))), (EnumOption ('COVERAGE', 'test coverage', 'none', ('none', 'full'))), (EnumOption ('WITH_HISTOGRAMS', 'Runtime statistical information', 'true', ('true', 'false'))), (EnumOption ('WITH_HTTP', 'HTTP administration', 'true', ('true', 'false'))), (EnumOption ('WITH_SNMP', 'SNMP administration', 'true', ('true', 'false'))), (EnumOption ('WITH_CHECK', 'Check test system', 'false', ('true', 'false'))), (EnumOption ('WITH_TEST', 'Network test system', 'false', ('true', 'false'))), (EnumOption ('WITH_EXAMPLES', 'Examples', 'true', ('true', 'false'))), (EnumOption ('WITH_NCURSES', 'NCURSES examples', 'false', ('true', 'false'))), (EnumOption ('WITH_PROTOBUF', 'Google Protocol Buffer examples', 'false', ('true', 'false'))), (EnumOption ('WITH_PLUS', 'libpgmplus GPL library', 'false', ('true', 'false'))), ) #----------------------------------------------------------------------------- # Dependencies env = Environment(); def CheckPKGConfig(context, version): context.Message( 'Checking for pkg-config... ' ) ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0] context.Result( ret ) return ret def CheckPKG(context, name): context.Message( 'Checking for %s... ' % name ) ret = context.TryAction('pkg-config --exists \'%s\'' % name)[0] context.Result( ret ) return ret conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig, 'CheckPKG' : CheckPKG }) if not conf.CheckPKGConfig('0.15.0'): print 'pkg-config >= 0.15.0 not found.' Exit(1) if not conf.CheckPKG('glib-2.0 >= 2.10'): print 'glib-2.0 >= 2.10 not found.' Exit(1) if not conf.CheckPKG('gthread-2.0'): print 'gthread-2.0 not found.' Exit(1) env = conf.Finish(); #----------------------------------------------------------------------------- # Platform specifics env = Environment(ENV = os.environ, CCFLAGS = [ '-pipe', '-Wall', '-Wextra', '-Wfloat-equal', '-Wshadow', '-Wunsafe-loop-optimizations', '-Wpointer-arith', '-Wbad-function-cast', '-Wcast-qual', '-Wcast-align', '-Wwrite-strings', '-Waggregate-return', '-Wstrict-prototypes', '-Wold-style-definition', '-Wmissing-prototypes', '-Wmissing-declarations', '-Wmissing-noreturn', '-Wmissing-format-attribute', '-Wredundant-decls', '-Wnested-externs', '-Winline', '-pedantic', '-std=gnu99', '--param', 'max-inline-insns-single=600', '-D_REENTRANT', '-D_GNU_SOURCE', '-D__need_IOV_MAX', '-DCONFIG_16BIT_CHECKSUM', '-DCONFIG_HAVE_PROC', '-DCONFIG_HAVE_BACKTRACE', '-DCONFIG_HAVE_PSELECT', '-DCONFIG_HAVE_POLL', '-DCONFIG_HAVE_EPOLL', '-DCONFIG_HAVE_CLOCK_GETTIME', '-DCONFIG_HAVE_CLOCK_NANOSLEEP', '-DCONFIG_HAVE_NANOSLEEP', '-DCONFIG_HAVE_USLEEP', '-DCONFIG_HAVE_RTC', '-DCONFIG_HAVE_TSC', '-DCONFIG_HAVE_IFR_NETMASK', '-DCONFIG_HAVE_GETIFADDRS', '-DCONFIG_HAVE_GETHOSTBYNAME2', '-DCONFIG_HAVE_GETPROTOBYNAME_R', '-DCONFIG_HAVE_MCAST_JOIN', '-DCONFIG_HAVE_IP_MREQN', '-DCONFIG_HAVE_DSO_VISIBILITY', '-DCONFIG_BIND_INADDR_ANY', '-DCONFIG_GALOIS_MUL_LUT', ], LINKFLAGS = [ '-pipe', '-lm' ] ) opt.Update (env) # Branch prediction if env['BRANCH'] == 'profile': env.Append(CCFLAGS = '-fprofile-arcs') env.Append(LINKFLAGS = '-fprofile-arcs') elif env['BRANCH'] == 'seed': env.Append(CCFLAGS = '-fbranch-probabilities') # Coverage analysis if env['COVERAGE'] == 'full': env.Append(CCFLAGS = '-fprofile-arcs') env.Append(CCFLAGS = '-ftest-coverage') env.Append(LINKFLAGS = '-fprofile-arcs') env.Append(LINKFLAGS = '-lgcov') # Define separate build environments release = env.Clone(BUILD = 'release') release.Append(CCFLAGS = '-O2') debug = env.Clone(BUILD = 'debug') debug.Append(CCFLAGS = '-ggdb', LINKFLAGS = '-gdb') profile = env.Clone(BUILD = 'profile') profile.Append(CCFLAGS = ['-O2','-pg'], LINKFLAGS = '-pg') thirtytwo = release.Clone(BUILD = 'thirtytwo') thirtytwo.Append(CCFLAGS = '-m32', LINKFLAGS = '-m32') # choose and environment to build if env['BUILD'] == 'release': Export({'env':release}) elif env['BUILD'] == 'profile': Export({'env':profile}) elif env['BUILD'] == 'thirtytwo': Export({'env':thirtytwo}) else: Export({'env':debug}) #----------------------------------------------------------------------------- # Re-analyse dependencies Import('env') # vanilla environment env.ParseConfig('pkg-config --cflags --libs glib-2.0 gthread-2.0'); # instrumentation if env['WITH_HTTP'] == 'true' and env['WITH_HISTOGRAMS'] == 'true': env.Append(CCFLAGS = '-DCONFIG_HISTOGRAMS'); # managed environment for libpgmsnmp, libpgmhttp env['SNMP_FLAGS'] = { 'CCFLAGS' : [], 'LIBS' : [ 'netsnmpagent', 'netsnmpmibs', 'netsnmphelpers', 'netsnmp' ], }; def CheckSNMP(context): context.Message('Checking Net-SNMP...'); lastLIBS = context.env['LIBS']; lastCCFLAGS= context.env['CCFLAGS']; context.env.MergeFlags(env['SNMP_FLAGS']); result = context.TryLink(""" int main(int argc, char**argv) { init_agent("PGM"); return 0; } """, '.c'); context.env.Replace(LIBS = lastLIBS, CCFLAGS=lastCCFLAGS); context.Result(not result); return result; def CheckCheck(context): context.Message('Checking Check unit test framework...'); result = context.TryAction('pkg-config --cflags --libs check')[0]; context.Result(result); return result; def CheckEventFD(context): context.Message('Checking eventfd...'); result = context.TryLink(""" #include int main(int argc, char**argv) { eventfd(0,0); return 0; } """, '.c') context.Result(result); return result; tests = { 'CheckCheck': CheckCheck, 'CheckEventFD': CheckEventFD } if env['WITH_SNMP'] == 'true': tests['CheckSNMP'] = CheckSNMP; conf = Configure(env, custom_tests = tests); if env['WITH_SNMP'] == 'true' and not conf.CheckSNMP(): print 'Enabling extra Red Hat dependencies for Net-SNMP.'; conf.env['SNMP_FLAGS']['LIBS'].append(['librpm', 'libsensors', 'libdl', 'libwrap']); lastLIBS = conf.env['LIBS']; conf.env.ParseConfig('perl -MExtUtils::Embed -e ldopts'); conf.env['SNMP_FLAGS']['LIBS'].append(conf.env['LIBS']); conf.env.Replace(LIBS = lastLIBS); if not conf.CheckSNMP(): print 'Net-SNMP libraries not compatible.'; Exit(1); if env['WITH_CHECK'] == 'true' and conf.CheckCheck(): print 'Enabling Check unit tests.'; conf.env['CHECK'] = 'true'; else: print 'Disabling Check unit tests.'; conf.env['CHECK'] = 'false'; if conf.CheckEventFD(): print 'Enabling kernel eventfd notification mechanism.'; conf.env.Append(CCFLAGS = '-DCONFIG_EVENTFD'); env = conf.Finish(); # DSO visibility flags if '-DCONFIG_HAVE_DSO_VISIBILITY' in env['CCFLAGS']: env.Append(CCFLAGS = '-DPGM_GNUC_INTERNAL=G_GNUC_INTERNAL') else: env.Append(CCFLAGS = '-DPGM_GNUC_INTERNAL=') # add builder to create PIC static libraries for including in shared libraries action_list = [ Action("$ARCOM", "$ARCOMSTR") ]; if env.Detect('ranlib'): ranlib_action = Action("$RANLIBCOM", "$RANLIBCOMSTR"); action_list.append(ranlib_action); pic_lib = Builder( action = action_list, emitter = '$LIBEMITTER', prefix = '$LIBPREFIX', suffix = '$LIBSUFFIX', src_suffix = '$OBJSUFFIX', src_builder = 'SharedObject') env.Append(BUILDERS = {'StaticSharedLibrary': pic_lib}); #----------------------------------------------------------------------------- ref_node = 'ref/' + env['BUILD'] + '/'; BuildDir(ref_node, '.', duplicate=0) env.Append(CPPPATH = os.getcwd() + '/include'); env.Append(LIBPATH = os.getcwd() + '/' + ref_node); SConscript(ref_node + 'SConscript.libpgm'); SConscript(ref_node + 'SConscript.libpgmex'); if env['WITH_HTTP'] == 'true': SConscript(ref_node + 'SConscript.libpgmhttp'); if env['WITH_SNMP'] == 'true': SConscript(ref_node + 'SConscript.libpgmsnmp'); if env['WITH_TEST'] == 'true': SConscript(ref_node + 'test/SConscript'); if env['WITH_EXAMPLES'] == 'true': SConscript(ref_node + 'examples/SConscript'); # end of file