#!/usr/bin/env python # encoding: utf-8 # Hanoh Haim # Cisco Systems, Inc. VERSION='0.0.1' APPNAME='cxx_test' import os; import shutil; import copy; from distutils.version import StrictVersion top = '../' out = 'build' b_path ="./build/linux/" REQUIRED_CC_VERSION = "4.7.0" class SrcGroup: ' group of source by directory ' def __init__(self,dir,src_list): self.dir = dir; self.src_list = src_list; self.group_list = None; assert (type(src_list)==list) assert (type(dir)==str) def file_list (self,top): ' return the long list of the files ' res='' for file in self.src_list: res= res + top+'/'+self.dir+'/'+file+' '; return res; def __str__ (self): return (self.file_list('')); def __repr__ (self): return (self.file_list('')); class SrcGroups: ' group of source groups ' def __init__(self,list_group): self.list_group = list_group; assert (type(list_group)==list) def file_list (self,top): ' return the long list of the files ' res='' for o in self.list_group: res += o.file_list(top); return res; def __str__ (self): return (self.file_list('')); def __repr__ (self): return (self.file_list('')); def options(opt): opt.load('compiler_cxx') def verify_cc_version (env): ver = '.'.join(env['CC_VERSION']) if StrictVersion(ver) < REQUIRED_CC_VERSION: print("\nMachine GCC version too low '{0}' - required at least '{1}'".format(ver, REQUIRED_CC_VERSION)) print( "\n*** please set a compiler using CXX / AR enviorment variables ***\n") exit(-1) def configure(conf): # start from clean if 'RPATH' in os.environ: conf.env.RPATH = os.environ['RPATH'].split(':') else: conf.env.RPATH = [] conf.load('g++') verify_cc_version(conf.env) bp_sim_main = SrcGroup(dir='src', src_list=['main.cpp']) bp_sim_gtest = SrcGroup(dir='src', src_list=[ 'bp_gtest.cpp', 'gtest/bp_timer_gtest.cpp', 'gtest/tuple_gen_test.cpp', 'gtest/client_cfg_test.cpp', 'gtest/nat_test.cpp', 'gtest/trex_stateless_gtest.cpp' ]) main_src = SrcGroup(dir='src', src_list=[ 'inet_pton.cpp', 'bp_sim.cpp', 'os_time.cpp', 'rx_check.cpp', 'tuple_gen.cpp', 'platform_cfg.cpp', 'utl_yaml.cpp', 'tw_cfg.cpp', 'rx_check_header.cpp', 'nat_check.cpp', 'nat_check_flow_table.cpp', 'pkt_gen.cpp', 'timer_wheel_pq.cpp', 'time_histogram.cpp', 'utl_json.cpp', 'utl_cpuu.cpp', 'utl_ip.cpp', 'msg_manager.cpp', 'trex_port_attr.cpp', 'publisher/trex_publisher.cpp', 'stateful_rx_core.cpp', 'flow_stat.cpp', 'flow_stat_parser.cpp', 'trex_watchdog.cpp', 'trex_client_config.cpp', 'pal/linux/pal_utl.cpp', 'pal/linux/mbuf.cpp', 'pal/common/common_mbuf.cpp', 'sim/trex_sim_stateless.cpp', 'sim/trex_sim_stateful.cpp', 'h_timer.cpp' ]); cmn_src = SrcGroup(dir='src/common', src_list=[ 'gtest-all.cc', 'gtest_main.cc', 'basic_utils.cpp', 'captureFile.cpp', 'erf.cpp', 'pcap.cpp', 'base64.cpp' ]); net_src = SrcGroup(dir='src/common/Network/Packet', src_list=[ 'CPktCmn.cpp', 'EthernetHeader.cpp', 'IPHeader.cpp', 'IPv6Header.cpp', 'TCPHeader.cpp', 'TCPOptions.cpp', 'UDPHeader.cpp', 'MacAddress.cpp', 'VLANHeader.cpp']); # stateless code stateless_src = SrcGroup(dir='src/stateless/', src_list=['cp/trex_stream.cpp', 'cp/trex_stream_vm.cpp', 'cp/trex_stateless.cpp', 'cp/trex_stateless_port.cpp', 'cp/trex_streams_compiler.cpp', 'cp/trex_vm_splitter.cpp', 'cp/trex_dp_port_events.cpp', 'dp/trex_stateless_dp_core.cpp', 'messaging/trex_stateless_messaging.cpp', 'rx/trex_stateless_rx_core.cpp', 'rx/trex_stateless_rx_port_mngr.cpp', 'rx/trex_stateless_capture.cpp', 'common/trex_stateless_pkt.cpp' ]) # RPC code rpc_server_src = SrcGroup(dir='src/rpc-server/', src_list=[ 'trex_rpc_server.cpp', 'trex_rpc_req_resp_server.cpp', 'trex_rpc_async_server.cpp', 'trex_rpc_jsonrpc_v2_parser.cpp', 'trex_rpc_cmds_table.cpp', 'trex_rpc_cmd.cpp', 'trex_rpc_zip.cpp', 'commands/trex_rpc_cmd_test.cpp', 'commands/trex_rpc_cmd_general.cpp', 'commands/trex_rpc_cmd_stream.cpp', ]) # JSON package json_src = SrcGroup(dir='external_libs/json', src_list=[ 'jsoncpp.cpp' ]) yaml_src = SrcGroup(dir='external_libs/yaml-cpp/src/', src_list=[ 'aliasmanager.cpp', 'binary.cpp', 'contrib/graphbuilder.cpp', 'contrib/graphbuilderadapter.cpp', 'conversion.cpp', 'directives.cpp', 'emitfromevents.cpp', 'emitter.cpp', 'emitterstate.cpp', 'emitterutils.cpp', 'exp.cpp', 'iterator.cpp', 'node.cpp', 'nodebuilder.cpp', 'nodeownership.cpp', 'null.cpp', 'ostream.cpp', 'parser.cpp', 'regex.cpp', 'scanner.cpp', 'scanscalar.cpp', 'scantag.cpp', 'scantoken.cpp', 'simplekey.cpp', 'singledocparser.cpp', 'stream.cpp', 'tag.cpp']); # stubs stubs = SrcGroup(dir='/src/stub/', src_list=['zmq_stub.c']) bp =SrcGroups([ bp_sim_main, bp_sim_gtest, main_src, cmn_src , stubs, net_src , yaml_src, json_src, stateless_src, rpc_server_src ]); cxxflags_base =['-DWIN_UCODE_SIM', '-DTREX_SIM', '-D_BYTE_ORDER', '-D_LITTLE_ENDIAN', '-DLINUX', '-D__STDC_LIMIT_MACROS', '-D__STDC_FORMAT_MACROS', '-g', '-Wno-deprecated-declarations', '-std=c++0x', ]; includes_path =''' ../src/pal/linux/ ../src/pal/common/ ../src/ ../src/rpc-server/ ../src/stateless/cp/ ../src/stateless/dp/ ../src/stateless/rx/ ../src/stateless/common/ ../src/stateless/messaging/ ../external_libs/json/ ../external_libs/zmq/include/ ../external_libs/yaml-cpp/include/ '''; RELEASE_ = "release" DEBUG_ = "debug" PLATFORM_64 = "64" PLATFORM_32 = "32" class build_option: def __init__(self, name, src, platform, debug_mode, is_pie, use = [], flags = [], rpath = []): self.mode = debug_mode; ##debug,release self.platform = platform; #['32','64'] self.is_pie = is_pie self.name = name self.src = src self.use = use self.flags = flags self.rpath = rpath def __str__(self): s=self.mode+","+self.platform; return (s); def lib_name(self,lib_name_p,full_path): if full_path: return b_path+lib_name_p; else: return lib_name_p; #private functions def toLib (self,name,full_path = True): lib_n = "lib"+name+".a"; return (self.lib_name(lib_n,full_path)); def toExe(self,name,full_path = True): return (self.lib_name(name,full_path)); def is64Platform (self): return ( self.platform == PLATFORM_64); def isRelease (self): return ( self.mode == RELEASE_); def isPIE (self): return self.is_pie def update_executable_name (self,name): return self.update_name(name,"-") def update_non_exe_name (self,name): return self.update_name(name,"_") def update_name (self,name,delimiter): trg = copy.copy(name); if self.is64Platform(): trg += delimiter + "64"; else: trg += delimiter + "32"; if self.isRelease () : trg += ""; else: trg += delimiter + "debug"; if self.isPIE(): trg += delimiter + "pie" return trg; def cxxcomp_flags (self,flags): result = copy.copy(flags); if self.is64Platform () : result+=['-m64']; else: result+=['-m32']; if self.isRelease () : result+=['-O3']; else: result+=['-O0','-DDEBUG','-D_DEBUG','-DSTILE_CPP_ASSERT','-DSTILE_SHIM_ASSERT']; if self.isPIE(): result += ['-fPIE', '-DPATCH_FOR_PIE'] result += self.flags return result; def get_use_libs (self): return self.use def get_target (self): return self.update_executable_name(self.name); def get_flags (self): return self.cxxcomp_flags(cxxflags_base); def get_src (self): return self.src.file_list(top) def get_rpath (self): return self.rpath def get_link_flags(self): # add here basic flags base_flags = []; if self.isPIE(): base_flags.append('-lstdc++') #platform depended flags if self.is64Platform(): base_flags += ['-m64'] else: base_flags += ['-m32'] base_flags += ['-lrt'] if self.isPIE(): base_flags += ['-pie', '-DPATCH_FOR_PIE'] return base_flags; build_types = [ build_option(name = "bp-sim", src = bp, use = [''],debug_mode= DEBUG_, platform = PLATFORM_64, is_pie = False, flags = ['-Wall', '-Werror', '-Wno-sign-compare', '-Wno-strict-aliasing'], rpath = ['.']), build_option(name = "bp-sim", src = bp, use = [''],debug_mode= RELEASE_,platform = PLATFORM_64, is_pie = False, flags = ['-Wall', '-Werror', '-Wno-sign-compare', '-Wno-strict-aliasing'], rpath = ['.']), ] def build_prog (bld, build_obj): bld.program(features='cxx cxxprogram', includes =includes_path, cxxflags =(build_obj.get_flags()+['-std=gnu++11',]), linkflags = build_obj.get_link_flags(), source = build_obj.get_src(), use = build_obj.get_use_libs(), lib = ['pthread', 'z', 'dl'], rpath = bld.env.RPATH + build_obj.get_rpath(), target = build_obj.get_target()) def build_type(bld,build_obj): build_prog(bld, build_obj); def post_build(bld): print("copy objects") exec_p ="../scripts/" for obj in build_types: install_single_system(bld, exec_p, obj); def build(bld): bld.add_post_fun(post_build); for obj in build_types: build_type(bld,obj); def build_info(bld): pass; def install_single_system (bld, exec_p, build_obj): o='build/linux/'; src_file = os.path.realpath(o+build_obj.get_target()) if os.path.exists(src_file): dest_file = exec_p +build_obj.get_target() if not os.path.lexists(dest_file): relative_path = os.path.relpath(src_file, exec_p) os.symlink(relative_path, dest_file);