# -*- mode: python -*- # OpenPGM build script import platform import os import time import sys EnsureSConsVersion( 0, 97 ) SConsignFile('scons.signatures'+ '-' + platform.system() + '-' + platform.machine() + '-sunstudio'); opt = Options(None, ARGUMENTS) opt.AddOptions ( (EnumOption ('BUILD', 'build environment', 'debug', ('release', 'debug', 'profile'))), (EnumOption ('BRANCH', 'branch prediction', 'none', ('none', 'profile', 'seed'))), (EnumOption ('WITH_GETTEXT', 'l10n support via libintl', 'false', ('true', 'false'))), (EnumOption ('WITH_GLIB', 'Build GLib dependent modules', 'false', ('true', 'false'))), (EnumOption ('COVERAGE', 'test coverage', 'none', ('none', 'full'))), (EnumOption ('WITH_HISTOGRAMS', 'Runtime statistical information', 'true', ('true', 'false'))), (EnumOption ('WITH_HTTP', 'HTTP administration', 'false', ('true', 'false'))), (EnumOption ('WITH_SNMP', 'SNMP administration', 'false', ('true', 'false'))), (EnumOption ('WITH_CHECK', 'Check test system', 'false', ('true', 'false'))), (EnumOption ('WITH_TEST', 'Network test system', 'false', ('true', 'false'))), (EnumOption ('WITH_CC', 'C++ Examples', 'true', ('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'))), ) #----------------------------------------------------------------------------- # Dependencies def force_sunstudio(env): env.PrependENVPath('PATH', '/opt/sun/sunstudio12.1/bin'); env.Tool('sunc++'); env.Tool('suncc'); env.Tool('sunlink'); env.Tool('sunar'); env = Environment(); force_sunstudio(env); 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 = [ '-v', # C99 '-xc99=all', '-D_XOPEN_SOURCE=600', '-D__EXTENSIONS__', '-DBSD_COMP', '-D_BSD_SOURCE', # re-entrant libc '-D_REENTRANT', # '-DCONFIG_HAVE_GETPROTOBYNAME_R', '-DCONFIG_HAVE_GETPROTOBYNAME_R2', # variadic macros '-DCONFIG_HAVE_ISO_VARARGS', # '-DCONFIG_HAVE_GNUC_VARARGS', # stack memory api header '-DCONFIG_HAVE_ALLOCA_H', # optimium checksum implementation # '-DCONFIG_8BIT_CHECKSUM', '-DCONFIG_16BIT_CHECKSUM', # '-DCONFIG_32BIT_CHECKSUM', # '-DCONFIG_64BIT_CHECKSUM', # '-DCONFIG_VECTOR_CHECKSUM', # useful /proc system '-DCONFIG_HAVE_PROC', # example: crash handling '-DCONFIG_HAVE_BACKTRACE', # timing '-DCONFIG_HAVE_PSELECT', '-DCONFIG_HAVE_RTC', '-DCONFIG_HAVE_TSC', # event handling '-DCONFIG_HAVE_POLL', '-DCONFIG_HAVE_EPOLL', # interface enumeration '-DCONFIG_HAVE_GETIFADDRS', '-DCONFIG_HAVE_IFR_NETMASK', # win32 cmsg # '-DCONFIG_HAVE_WSACMSGHDR', # multicast '-DCONFIG_HAVE_MCAST_JOIN', '-DCONFIG_HAVE_IP_MREQN', # sprintf '-DCONFIG_HAVE_SPRINTF_GROUPING', '-DCONFIG_HAVE_VASPRINTF', # symbol linking scope '-DCONFIG_HAVE_DSO_VISIBILITY', # socket binding '-DCONFIG_BIND_INADDR_ANY', # IP header order as per IP(4) on FreeBSD # '-DCONFIG_HOST_ORDER_IP_LEN', # '-DCONFIG_HOST_ORDER_IP_OFF', # optimum galois field multiplication '-DCONFIG_GALOIS_MUL_LUT', # Wine limited API support # '-DCONFIG_TARGET_WINE', # GNU getopt '-DCONFIG_HAVE_GETOPT' ], LINKFLAGS = [ ], LIBS = [ # histogram math 'm', # clock_gettime() 'rt' ], PROTOBUF_CCFLAGS = '-I/miru/projects/protobuf/protobuf-2.1.0/src', PROTOBUF_LIBS = '/miru/projects/protobuf/protobuf-2.1.0/src/.libs/libprotobuf.a', PROTOBUF_PROTOC = '/miru/projects/protobuf/protobuf-2.1.0/src/protoc' ) opt.Update (env) force_sunstudio(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 = ['-DPGM_DEBUG','-g'], LINKFLAGS = '-g') profile = env.Clone(BUILD = 'profile') profile.Append(CCFLAGS = ['-O0','-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 if env['WITH_GLIB'] == 'true': env['GLIB_FLAGS'] = env.ParseFlags('!pkg-config --cflags --libs glib-2.0 gthread-2.0'); else: env['GLIB_FLAGS'] = ''; # l10n if env['WITH_GETTEXT'] == 'true': env.Append(CCFLAGS = '-DCONFIG_HAVE_GETTEXT'); # instrumentation if env['WITH_HTTP'] == 'true' and env['WITH_HISTOGRAMS'] == 'true': env.Append(CCFLAGS = '-DCONFIG_HISTOGRAMS'); def list_remove(list, target): newlist = []; for item in str(list).split(' '): if item != target: newlist.append(item); return newlist; # managed environment for libpgmsnmp, libpgmhttp if env['WITH_SNMP'] == 'true': env['SNMP_FLAGS'] = env.ParseFlags('!net-snmp-config --cflags --agent-libs'); # strip out GCC only flags ccflags = env['SNMP_FLAGS'].get('CCFLAGS', ''); env['SNMP_FLAGS']['CCFLAGS'] = list_remove(ccflags, '-Wall'); def CheckSNMP(context): context.Message('Checking Net-SNMP...'); # backup = context.env.Clone().Dictionary(); lastASFLAGS = context.env.get('ASFLAGS', ''); lastCCFLAGS = context.env.get('CCFLAGS', ''); lastCFLAGS = context.env.get('CFLAGS', ''); lastCPPDEFINES = context.env.get('CPPDEFINES', ''); lastCPPFLAGS = context.env.get('CPPFLAGS', ''); lastCPPPATH = context.env.get('CPPPATH', ''); lastLIBPATH = context.env.get('LIBPATH', ''); lastLIBS = context.env.get('LIBS', ''); lastLINKFLAGS = context.env.get('LINKFLAGS', ''); lastRPATH = context.env.get('RPATH', ''); context.env.MergeFlags(env['SNMP_FLAGS']); result = context.TryLink(""" int main(int argc, char**argv) { init_agent("PGM"); return 0; } """, '.c'); # context.env.Replace(**backup); context.env.Replace(ASFLAGS = lastASFLAGS, CCFLAGS = lastCCFLAGS, CFLAGS = lastCFLAGS, CPPDEFINES = lastCPPDEFINES, CPPFLAGS = lastCPPFLAGS, CPPPATH = lastCPPPATH, LIBPATH = lastLIBPATH, LIBS = lastLIBS, LINKFLAGS = lastLINKFLAGS, RPATH = lastRPATH); 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 '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(); # 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'] + '-' + platform.system() + '-' + platform.machine() + '-sunstudio/'; BuildDir(ref_node, '.', duplicate=0) env.Append(CPPPATH = os.getcwd() + '/include'); env.Append(LIBPATH = os.getcwd() + '/' + ref_node); if env['WITH_GLIB'] == 'true': SConscript(ref_node + 'SConscript.libpgmex'); SConscript(ref_node + 'SConscript.libpgm'); 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