You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

516 lines
20 KiB

#!/usr/bin/env python
# -*- python -*-
# BEGIN_LEGAL
#
# Copyright (c) 2021 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# END_LEGAL
import sys
import os
import re
import shutil
import copy
import time
import types
import optparse
# sys.path is set up by calling script (mfile.py ususally)
import mbuild
import xed_build_common as xbc
def ex_compile_and_link(env, dag, src, objs):
"""Return the exe name - used for the examples"""
basename = os.path.basename(src)
exe = env.build_dir_join(env.resuffix(basename, env['EXEEXT']))
all_obj = []
# first_example_lib and last_example_lib are for supporting
# compilations using custom C runtimes.
if 'first_example_lib' in env:
all_obj.append(env['first_example_lib'])
all_obj.extend(env.compile(dag, [src]))
all_obj.extend(objs)
if 'last_example_lib' in env:
all_obj.append(env['last_example_lib'])
lc = env.link(all_obj, exe)
cmd = dag.add(env,lc)
return cmd.targets[0]
###########################################################################
def mkenv():
"""External entry point: create the environment"""
if sys.version_info[0] == 3 and sys.version_info[1] < 4:
_fatal("Need python version 3.4 or later.")
elif sys.version_info[0] == 2 and sys.version_info[1] < 7:
_fatal("Need python version 2.7 or later.")
# create an environment, parse args
env = mbuild.env_t()
standard_defaults = dict( doxygen_install='',
doxygen='',
clean=False,
die_on_errors=True,
xed_messages=False,
xed_asserts=False,
pedantic=True,
clr=False,
use_werror=True,
dbghelp=False,
install_dir='',
kit_kind='base',
win=False,
dev=False,
legal_header=None,
encoder=True,
enc2=True,
decoder=True,
ld_library_path=[],
ld_library_path_for_tests=[],
use_elf_dwarf=False,
use_elf_dwarf_precompiled=False,
strip='strip',
verbose = 1,
example_linkflags='',
example_flags='',
example_rpaths=[],
android=False,
xed_inc_dir=[],
xed_lib_dir='',
xed_enc2_libs=[],
xed_dir='',
build_cpp_examples=False,
set_copyright=False,
pin_crt='')
env['xed_defaults'] = standard_defaults
env.set_defaults(env['xed_defaults'])
return env
def xed_args(env):
"""For command line invocation: parse the arguments"""
env.parser.add_option("--no-encoder",
dest="encoder",
action="store_false",
help="No encoder")
env.parser.add_option("--no-enc2",
dest="enc2",
action="store_false",
help="No enc2 encoder")
env.parser.add_option("--no-decoder",
dest="decoder",
action="store_false",
help="No decoder")
env.parser.add_option("--android",
dest="android",
action="store_true",
help="Android build (avoid rpath for examples)")
env.parser.add_option("--example-linkflags",
dest="example_linkflags",
action="store",
help="Extra link flags for the examples")
env.parser.add_option("--example-flags",
dest="example_flags",
action="store",
help="Extra compilation flags for the examples")
env.parser.add_option("--example-rpath",
dest="example_rpaths",
action="append",
help="Extra rpath dirs for examples")
env.parser.add_option("-c","--clean",
dest="clean",
action="store_true",
help="Clean targets")
env.parser.add_option("--keep-going", '-k',
action="store_false",
dest="die_on_errors",
help="Keep going after errors occur when building")
env.parser.add_option("--messages",
action="store_true",
dest="xed_messages",
help="Enable use xed's debug messages")
env.parser.add_option("--no-pedantic",
action="store_false",
dest="pedantic",
help="Disable -pedantic (gnu/clang compilers).")
env.parser.add_option("--asserts",
action="store_true",
dest="xed_asserts",
help="Enable use xed's asserts")
env.parser.add_option("--clr",
action="store_true",
dest="clr",
help="Compile for Microsoft CLR")
env.parser.add_option("--no-werror",
action="store_false",
dest="use_werror",
help="Disable use of -Werror on GNU compiles")
env.parser.add_option("--dbghelp",
action="store_true",
dest="dbghelp",
help="Use dbghelp.dll on windows.")
env.parser.add_option("--install-dir",
dest="install_dir",
action="store",
help="XED Install directory. " +
"Default: kits/xed-install-date-os-cpu")
env.parser.add_option("--kit-kind",
dest="kit_kind",
action="store",
help="Kit version string. " +
"The default is 'base'")
env.parser.add_option("--win",
action="store_true",
dest="win",
help="Add -mno-cygwin to GCC-on-windows compilation")
env.parser.add_option("--ld-library-path",
action="append",
dest="ld_library_path",
help="Specify additions to LD_LIBRARY_PATH " +
"for use when running ldd and making kits")
env.parser.add_option("--ld-library-path-for-tests",
action="append",
dest="ld_library_path_for_tests",
help="Specify additions to LD_LIBRARY_PATH " +
"for use when running the tests")
# elf.h is different than libelf.h.
env.parser.add_option("--elf-dwarf", "--dwarf",
action="store_true",
dest="use_elf_dwarf",
help="Use libelf/libdwarf. (Linux only)")
env.parser.add_option("--elf-dwarf-precompiled",
action="store_true",
dest="use_elf_dwarf_precompiled",
help="Use precompiled libelf/libdwarf from " +
" the XED source distribution." +
" This is the currently required" +
" if you are installing a kit." +
" Implies the --elf-dwarf knob."
" (Linux only)")
env.parser.add_option("--strip",
action="store",
dest="strip",
help="Path to strip binary. (Linux only)")
env.parser.add_option("--pin-crt",
action="store",
dest="pin_crt",
help="Compile for the Pin C-runtime. Specify" +
" path to pin kit")
env.parser.add_option("--lib-dir",
action='store',
dest="xed_lib_dir",
help="directory where libxed* is located.")
env.parser.add_option("--enc2-lib",
action='append',
dest="xed_enc2_libs",
help="Filenames (with paths) of the XED enc2 libraries.")
env.parser.add_option("--inc-dir",
action="append",
dest="xed_inc_dir",
help="directory where xed generated headers are located.")
env.parser.add_option("--xed-dir",
action="store",
dest="xed_dir",
help="directory where xed sources are located.")
env.parser.add_option("--build-cpp-examples",
action="store_true",
dest="build_cpp_examples",
help="Build the C++ examples default: False.")
env.parser.add_option("--set-copyright",
action="store_true",
dest="set_copyright",
help="Set the Intel copyright on Windows XED executable")
env.parse_args(env['xed_defaults'])
def nchk(env,s):
#null string check or not set check
if s not in env or len(env[s]) == 0:
return True
return False
def init(env):
xbc.init(env)
if nchk(env,'xed_lib_dir'):
env['xed_lib_dir'] = '../lib'
if nchk(env,'xed_enc2_libs'):
env['xed_enc2_libs'] = ( mbuild.glob(env['xed_lib_dir'],'*xed-chk-enc2-*') +
mbuild.glob(env['xed_lib_dir'],'*xed-enc2-*') )
if nchk(env,'xed_enc2_libs'):
# do not build enc2 examples if libraries are missing
env['enc2'] = False
if nchk(env,'xed_inc_dir'):
env['xed_inc_dir'] = ['../include']
if nchk(env,'xed_dir'):
env['xed_dir'] = '..'
env.add_include_dir( env['src_dir'] ) # examples dir
for inc in env['xed_inc_dir']:
env.add_include_dir( inc )
def _wk_show_errors_only():
#True means show errors only when building.
if mbuild.verbose(2):
return False # show output
return True # show errors only.
def _add_libxed_rpath(env):
"""Make example tools refer to the libxed.so from the lib directory"""
if env['shared'] and env.on_linux() and not env['android']:
env['LINKFLAGS'] += " -Wl,-rpath,'$ORIGIN/../lib'"
def build_asmparse(env, dag, otherobj):
srcs = env.src_dir_join(['xed-asmparse.c'])
objs = env.compile(dag, srcs)
exe = ex_compile_and_link(env,
dag,
env.src_dir_join('xed-asmparse-main.c'),
objs + otherobj + [env['link_libxed']])
return exe
def build_examples(env, work_queue):
"""Build the examples"""
example_exes = []
env['example_exes'] = [] # used by install
examples_dag = mbuild.dag_t('xedexamples', env=env)
if not env.on_windows():
for d in env['example_rpaths']:
env.add_to_var('example_linkflags',
'-Wl,-rpath,{}'.format(d))
env.add_to_var('LINKFLAGS', env['example_linkflags'])
env.add_to_var('CCFLAGS', env['example_flags'])
env.add_to_var('CXXFLAGS', env['example_flags'])
mbuild.cmkdir(env['build_dir'])
link_libxed = env['link_libxed']
if env['shared']:
_add_libxed_rpath(env)
# C vs C++: env is for C++ and env_c is for C programs.
if env['compiler'] in ['gnu','clang', 'icc']:
env['LINK'] = env['CXX']
env_c = copy.deepcopy(env)
if env_c['compiler'] in ['gnu','clang']:
env_c['LINK'] = '%(CC)s'
if env['pin_crt']:
xbc.compile_with_pin_crt_lin_mac_common_cplusplus(env)
# shared files
cc_shared_files = env.src_dir_join([
'xed-examples-util.c'])
if env['decoder']:
cc_shared_files.extend(env.src_dir_join([
'xed-dot.c',
'xed-dot-prep.c']))
if env['encoder']:
cc_shared_files += env.src_dir_join([ 'xed-enc-lang.c'])
cc_shared_objs = env.compile( examples_dag, cc_shared_files)
# the XED command line tool
xed_cmdline_files = [ 'xed-disas-raw.c',
'avltree.c',
'xed-disas-hex.c',
'xed-symbol-table.c']
if env.on_windows() and env['set_copyright']:
# AUTOMATICALLY UPDATE YEAR IN THE RC FILE
year = time.strftime("%Y")
lines = open(env.src_dir_join('xed-rc-template.txt')).readlines()
lines = [ re.sub('%%YEAR%%',year,x) for x in lines ]
xbc.write_file(env.src_dir_join('xed.rc'), lines)
xed_cmdline_files.append("xed.rc")
extra_libs = []
if env['decoder']:
if env.on_linux() or env.on_freebsd() or env.on_netbsd():
xed_cmdline_files.append('xed-disas-filter.c')
xed_cmdline_files.append('xed-nm-symtab.c')
elif env.on_mac():
xed_cmdline_files.append('xed-disas-macho.c')
elif env.on_windows():
xed_cmdline_files.append('xed-disas-pecoff.cpp')
if ( env['dbghelp'] and
env['msvs_version'] not in ['6','7'] ):
env.add_define("XED_DBGHELP")
xed_cmdline_files.append('udhelp.cpp')
extra_libs = ['dbghelp.lib', 'version.lib' ]
xed_cmdline_files = env.src_dir_join(xed_cmdline_files)
xed_cmdline_obj = copy.deepcopy(cc_shared_objs)
# Env for cmdline tool (with libelf/dwarf on linux.)
if env.on_windows(): # still C++
cenv = copy.deepcopy(env)
else: # lin/mac are C code only.
cenv = copy.deepcopy(env_c)
if env.on_linux():
xbc.cond_add_elf_dwarf(cenv)
if env.on_linux() or env.on_freebsd() or env.on_netbsd():
src_elf = env.src_dir_join('xed-disas-elf.c')
if env['use_elf_dwarf_precompiled']:
cenv2 = copy.deepcopy(cenv)
# need to remove -pedantic because of redundant typedef Elf in dwarf header file
cenv2.remove_from_var('CCFLAGS','-pedantic')
xed_cmdline_obj += cenv2.compile(examples_dag, [src_elf])
else:
xed_cmdline_files.append(src_elf)
xed_cmdline_obj += cenv.compile(examples_dag, xed_cmdline_files)
xed_cmdline = ex_compile_and_link(cenv, examples_dag,
env.src_dir_join('xed.c'),
xed_cmdline_obj + [link_libxed] +
extra_libs)
mbuild.msgb("CMDLINE", xed_cmdline)
example_exes.append(xed_cmdline)
if env['encoder']:
exe = build_asmparse(cenv, examples_dag, cc_shared_objs)
example_exes.append(exe)
ild_examples = []
other_c_examples = []
enc2_examples = []
small_examples = ['xed-size.c']
if env['enc2']:
enc2_examples += [ 'xed-enc2-1.c',
'xed-enc2-2.c',
'xed-enc2-3.c' ]
if env['encoder']:
small_examples += ['xed-ex5-enc.c']
other_c_examples += ['xed-ex3.c']
if env['decoder'] and env['encoder']:
other_c_examples += ['xed-ex6.c',
'xed-ex9-patch.c' ]
if env['decoder']:
ild_examples += [ 'xed-ex-ild.c' ]
other_c_examples += ['xed-ex1.c',
'xed-ex-ild2.c',
'xed-min.c',
'xed-reps.c',
'xed-ex4.c',
'xed-tester.c',
'xed-dec-print.c',
'xed-ex-agen.c',
'xed-ex7.c',
'xed-ex8.c',
'xed-ex-cpuid.c',
'xed-tables.c',
'xed-find-special.c',
'xed-dll-discovery.c']
# compile & link other_c_examples
for example in env.src_dir_join(other_c_examples):
example_exes.append(ex_compile_and_link(env_c,
examples_dag,
example,
cc_shared_objs + [ link_libxed ]))
# compile & link ild_examples
if os.path.exists(env['link_libild']):
for example in env.src_dir_join(ild_examples):
example_exes.append(ex_compile_and_link(env_c,
examples_dag,
example,
[ env['link_libild'] ]))
# compile & link small_examples
for example in env.src_dir_join(small_examples):
example_exes.append(ex_compile_and_link(env_c,
examples_dag,
example,
[ link_libxed ]))
for example in env.src_dir_join(enc2_examples):
example_exes.append(ex_compile_and_link( env_c,
examples_dag,
example,
env['xed_enc2_libs'] + [link_libxed] ))
mbuild.vmsgb(4, "ALL EXAMPLES", "\n\t".join(example_exes))
examples_to_build = example_exes
env['example_exes'] = example_exes
mbuild.msgb("BUILDING EXAMPLES")
okay = work_queue.build(examples_dag,
targets=examples_to_build,
die_on_errors=env['die_on_errors'],
show_progress=True,
show_output=True,
show_errors_only=_wk_show_errors_only())
if not okay:
xbc.cdie( "XED EXAMPLES build failed")
mbuild.vmsgb(3, "XED EXAMPLES", "build succeeded")
return 0
def verify_args(env):
if env['use_elf_dwarf_precompiled']:
env['use_elf_dwarf'] = True
def examples_work(env):
"""External entry point for non-command line invocations.
Initialize the environment, build libxed, the examples, the kit
and run the tests"""
xbc.prep(env)
verify_args(env)
start_time=mbuild.get_time()
xbc.init_once(env)
init(env)
if 'clean' in env['targets'] or env['clean']:
xbc.xed_remove_files_glob(env)
if len(env['targets'])<=1:
xbc.cexit(0)
mbuild.cmkdir(env['build_dir'])
work_queue = mbuild.work_queue_t(env['jobs'])
xbc.get_libxed_names(env)
retval = build_examples(env, work_queue)
end_time=mbuild.get_time()
mbuild.msgb("EXAMPLES BUILD ELAPSED TIME",
mbuild.get_elapsed_time(start_time, end_time))
return retval
def execute():
"""Main external entry point for command line invocations"""
import mbuild
env = mkenv()
# xed_args() is skip-able for remote (import) invocation. The env
# from mkenv can be updated programmatically. One must call
# xbc.set_xed_defaults(env) if not calling xed_args(env)
xed_args(env) # parse command line knobs
retval = examples_work(env)
return retval