[PATCH v2] sb: Add support to search for a suitable version of python.

Malte Münch mamu at stablerock.de
Tue Oct 23 12:47:14 UTC 2018


Hi,

i have difficulties running the source builder on Archlinux. It worked
fine before commit 13f4c379997b53b204d8534d198da2fa35dd5630 (sb: Add
support to search for a suitable version of python.) Know it stops with
the following error:


[mamu at verstappen rtems]$ ../source-builder/sb-set-builder
--prefix="$HOME/vcs/git/development/rtems/5" 5/rtems-sparc
RTEMS Source Builder - Set Builder, 5 (818f3960325a modified)
Traceback (most recent call last):
  File "../source-builder/sb/cmd-set-builder.py", line 26, in <module>
    setbuilder.run()
  File
"/home/mamu/vcs/git/development/rtems/rsb/source-builder/sb/setbuilder.py",
line 618, in run
    b = buildset(bset, configs, opts)
  File
"/home/mamu/vcs/git/development/rtems/rsb/source-builder/sb/setbuilder.py",
line 82, in __init__
    log.trace(str(self.macros))
  File
"/home/mamu/vcs/git/development/rtems/rsb/source-builder/sb/macros.py",
line 129, in __str__
    text += l[0:text_len]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 7:
ordinal not in range(128)


If i revert back to 8992d20b8c28af7c95c8b95da054aa9d94521426 it works
fine. I wish i could provide a path so it works for arch but i did not
understand the way the wrapper script works.

I am running Archlinux with the following locations (links):

[mamu at verstappen rtems]$ which python
/usr/bin/python
[mamu at verstappen rtems]$ which python2
/usr/bin/python2
[mamu at verstappen rtems]$ which python3
/usr/bin/python3
[mamu at verstappen rtems]$ ls -lah /usr/bin/python
lrwxrwxrwx 1 root root 7 15. Sep 21:13 /usr/bin/python -> python3
[mamu at verstappen rtems]$

Best

Malte


On 10/19/18 12:48 AM, chrisj at rtems.org wrote:
> From: Chris Johns <chrisj at rtems.org>
> 
> The command python has been removed from upstream python and python2
> and python3 is now used. This patch wraps the commands in a shell
> script that locates a suitable python to run.
> 
> Updates #3537
> ---
>  source-builder/config/gdb-common-1.cfg | 105 +++++++++++++-
>  source-builder/defaults.mc             |   6 +-
>  source-builder/pkg-config              | 241 +++------------------------------
>  source-builder/sb-bootstrap            |  24 ++--
>  source-builder/sb-builder              |  24 ++--
>  source-builder/sb-check                |  24 ++--
>  source-builder/sb-defaults             |  24 ++--
>  source-builder/sb-reports              |  24 ++--
>  source-builder/sb-rtems-config         |  24 ++--
>  source-builder/sb-set-builder          |  25 ++--
>  source-builder/sb/build.py             |   8 ++
>  source-builder/sb/cmd-bootstrap.py     |  29 ++++
>  source-builder/sb/cmd-builder.py       |  29 ++++
>  source-builder/sb/cmd-check.py         |  29 ++++
>  source-builder/sb/cmd-defaults.py      |  29 ++++
>  source-builder/sb/cmd-pkg-config.py    | 220 ++++++++++++++++++++++++++++++
>  source-builder/sb/cmd-reports.py       |  29 ++++
>  source-builder/sb/cmd-rtems-config.py  |  29 ++++
>  source-builder/sb/cmd-set-builder.py   |  29 ++++
>  source-builder/sb/config.py            |  48 ++++---
>  source-builder/sb/freebsd.py           |   6 +-
>  source-builder/sb/macros.py            |   9 +-
>  source-builder/sb/options.py           |   7 +-
>  source-builder/sb/path.py              |  11 +-
>  source-builder/sb/python-wrapper.sh    |  39 ++++++
>  source-builder/sb/rtems-build-dep      | 170 +++++++++++++++++++++++
>  source-builder/sb/windows.py           |  46 ++++---
>  27 files changed, 917 insertions(+), 371 deletions(-)
>  create mode 100755 source-builder/sb/cmd-bootstrap.py
>  create mode 100755 source-builder/sb/cmd-builder.py
>  create mode 100755 source-builder/sb/cmd-check.py
>  create mode 100755 source-builder/sb/cmd-defaults.py
>  create mode 100755 source-builder/sb/cmd-pkg-config.py
>  create mode 100755 source-builder/sb/cmd-reports.py
>  create mode 100755 source-builder/sb/cmd-rtems-config.py
>  create mode 100755 source-builder/sb/cmd-set-builder.py
>  create mode 100644 source-builder/sb/python-wrapper.sh
>  create mode 100755 source-builder/sb/rtems-build-dep
> 
> diff --git a/source-builder/config/gdb-common-1.cfg b/source-builder/config/gdb-common-1.cfg
> index fe4dbaf..30fdf90 100644
> --- a/source-builder/config/gdb-common-1.cfg
> +++ b/source-builder/config/gdb-common-1.cfg
> @@ -4,6 +4,103 @@
>  # This configuration file configure's, make's and install's gdb.
>  #
>  
> +#
> +# Python
> +#
> +# GDB uses python internally so we need to link to a suitable python
> +# dev kit. The dev kit for python is the header and a library. These
> +# files are versioned where the header file is located in a directory
> +# based on:
> +#
> +#  pythonM.m/Python.h
> +#
> +# where 'M' is the major version number and 'm' is the minor verison
> +# number. The library is:
> +#
> +#  libpythonM.m.a
> +#
> +# The python command is 'pythonM' which means we need to query it for
> +# the minor number.
> +#
> +# The python running the RSB may not be suitable, for example a MSC,
> +# MSYS or Cygwin version on Windows when we want the MinGW python dev
> +# file. A specific version cannot be forced because older versions of
> +# GDB can only link to 'python2'.
> +#
> +# Host support can perform a complex query of the system, for example
> +# Windows and set '%{gdb_python2}' and '%{gdb_python3}' with the full
> +# path to that version's executable.
> +#
> +# A configuration of GDB can set the version required by setting
> +# '%{gdb-python-version}' to the versions command, eg python2.
> +#
> +# The procedure is:
> +#
> +# 1. If the macros '%{gdb_python2}' or '%{gdb_python3}' are present
> +#    use that path they contain. Assume the path is valid.
> +#
> +# 2. Does the version of gdb specify a version of python that must be
> +#    used. Override with '%define gdb-python-version python2'.
> +#
> +# 3. Search for 'python2' and if not found search for 'python3'.
> +#
> +%if %{defined gdb-python2}
> +  %define gdb-enable-python %{gdb_python2}
> +%else
> +  %if %{defined gdb-python3}
> +    %define gdb-enable-python %{gdb_python3}
> +  %else
> +    %if %{defined gdb-python-version}
> +      %define gdb-enable-python %(command -v %{gdb-python-version || true})
> +    %else
> +      %define gdb-enable-python %(command -v python2 || true)
> +      %if %{gdb-enable-python} == %{nil}
> +        %define gdb-enable-python %(command -v python3 || true)
> +      %endif
> +      %if %{gdb-enable-python} == %{nil}
> +          %define gdb-enable-python %(command -v python || true})
> +      %endif
> +    %endif
> +    %if %{gdb-enable-python} == %{nil}
> +      %error "gdb: python: no valid version of python found"
> +    %endif
> +  %endif
> +%endif
> +
> +#
> +# Get the Python's major and minor version from the python
> +# command. The headers and libraries are installed under a major/minor
> +# (mm) version path and name.
> +#
> +# The library file name can vary across the hosts so wildcard the search.
> +#
> +%define gdb-python-ver-mm %(%{gdb-enable-python} --version 2>&1 | sed -e 's/.* //g' | rev | cut -d'.' -f2- | rev)
> +%define gdb-python-ver-header python%{gdb-python-ver-mm}/Python.h
> +%define gdb-python-ver-lib libpython%{gdb-python-ver-mm}.*
> +%if %{host_includes} == %{nil}
> +  %define gdb-host-incs %{nil}
> +%else
> +  %define gdb-host-incs -I '%{host_includes}'
> +%endif
> +%define gdb-python-header-check %(%{_sbdir}/sb/rtems-build-dep -c %{__cc} %{gdb-host-incs} -H %{gdb-python-ver-header})
> +%if %{gdb-python-header-check} == not-found
> +  %error "gdb: python: header file not found: %{gdb-python-ver-header}, please install"
> +%endif
> +#
> +# Too hard to find on MacOS (darwin), the header is good enough.
> +#
> +%ifnos darwin
> +  %if %{host_ldflags} == %{nil}
> +    %define gdb-host-libs %{nil}
> +  %else
> +    %define gdb-host-libs -L '%{host_ldflags}'
> +  %endif
> +  %define gdb-python-lib-check %(%{_sbdir}/sb/rtems-build-dep -c %{__cc} %{gdb-host-libs} -l %{gdb-python-ver-lib})
> +  %if %{gdb-python-lib-check} == not-found
> +    %error "gdb: python: library file not found: %{gdb-python-ver-lib}, please install"
> +  %endif
> +%endif
> +
>  #
>  # See if the simulator has been disabled for Windows.
>  #
> @@ -41,7 +138,7 @@ Name:      %{_target}-gdb-%{gdb_version}-%{_host}-%{release}
>  Summary:   GDB v%{gdb_version} for target %{_target} on host %{_host}
>  Version:   %{gdb_version}
>  Release:   %{release}
> -URL: 	   http://www.gnu.org/software/gdb/
> +URL:       http://www.gnu.org/software/gdb/
>  BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
>  
>  #
> @@ -70,7 +167,11 @@ BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
>  %if %{defined with_python_path}
>    %define with_python_option --with-python=%{with_python_path}
>  %else
> -  %define with_python_option --with-python
> +  %if %{defined gdb-enable-python}
> +    %define with_python_option --with-python=%{gdb-enable-python}
> +  %else
> +    %define with_python_option --with-python
> +  %endif
>  %endif
>  
>  #
> diff --git a/source-builder/defaults.mc b/source-builder/defaults.mc
> index 3f9ff9f..aa1a5e6 100644
> --- a/source-builder/defaults.mc
> +++ b/source-builder/defaults.mc
> @@ -65,9 +65,11 @@ _uid:                none,    convert,  '%(%{__id_u} -n)'
>  # the tools will run on and build is the host building the tools.
>  host_cflags:         none,    convert,  '-O2 -pipe'
>  host_cxxflags:       none,    convert,  '-O2 -pipe'
> +host_ldflags:        none,    convert,  ''
>  host_includes:       none,    convert,  ''
>  build_cflags:        none,    convert,  '-O2 -pipe'
>  build_cxxflags:      none,    convert,  '-O2 -pipe'
> +build_ldflags:       none,    convert,  ''
>  build_includes:      none,    convert,  ''
>  
>  # Extra path a platform can override.
> @@ -202,10 +204,10 @@ SB_BUILD_DIR="%{_builddir}"
>  SB_HOST_CPPFLAGS="%{host_includes}"
>  SB_HOST_CFLAGS="%{host_cflags} %{host_includes}"
>  SB_HOST_CXXFLAGS="%{host_cxxflags} %{host_includes}"
> -SB_HOST_LDFLAGS="%{?host_ldflags:%{host_ldflags}} %{?_tmproot:-L%{_tmproot}/${SB_PREFIX_CLEAN}/lib}"
> +SB_HOST_LDFLAGS="%{host_ldflags} %{?_tmproot:-L%{_tmproot}/${SB_PREFIX_CLEAN}/lib}"
>  SB_BUILD_CFLAGS="%{build_cflags} %{?_tmproot:-I%{_tmproot}/${SB_PREFIX_CLEAN}/include}"
>  SB_BUILD_CXXFLAGS="%{build_cxxflags} %{?_tmproot:-I%{_tmproot}/${SB_PREFIX_CLEAN}/include}"
> -SB_BUILD_LDFLAGS="%{?build_ldflags:%{build_ldflags}} %{?_tmproot:-L%{_tmproot}/${SB_PREFIX_CLEAN}/lib}"
> +SB_BUILD_LDFLAGS="%{build_ldflags} %{?_tmproot:-L%{_tmproot}/${SB_PREFIX_CLEAN}/lib}"
>  SB_CFLAGS="${SB_BUILD_CFLAGS} %{build_includes}"
>  SB_CXXFLAGS="${SB_BUILD_CXXFLAGS} %{build_includes}"
>  SB_ARCH="%{_arch}"
> diff --git a/source-builder/pkg-config b/source-builder/pkg-config
> index fa251e5..65ee307 100755
> --- a/source-builder/pkg-config
> +++ b/source-builder/pkg-config
> @@ -1,226 +1,27 @@
> -#! /usr/bin/env python
> +#! /bin/sh
>  #
>  # RTEMS Tools Project (http://www.rtems.org/)
> -# Copyright 2014-2016 Chris Johns (chrisj at rtems.org)
> +# Copyright 2018 Chris Johns (chrisj at rtems.org)
>  # All rights reserved.
>  #
>  # This file is part of the RTEMS Tools package in 'rtems-tools'.
>  #
> -# Redistribution and use in source and binary forms, with or without
> -# modification, are permitted provided that the following conditions are met:
> -#
> -# 1. Redistributions of source code must retain the above copyright notice,
> -# this list of conditions and the following disclaimer.
> -#
> -# 2. Redistributions in binary form must reproduce the above copyright notice,
> -# this list of conditions and the following disclaimer in the documentation
> -# and/or other materials provided with the distribution.
> -#
> -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
> -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> -# POSSIBILITY OF SUCH DAMAGE.
> -#
> -
> -from __future__ import print_function
> -
> -import os
> -import sys
> -
> -base = os.path.dirname(sys.argv[0])
> -sys.path.insert(0, base + '/sb')
> -
> -try:
> -    import argparse
> -except:
> -    sys.path.insert(0, base + '/sb/imports')
> -    try:
> -        import argparse
> -    except:
> -        print("Incorrect Source Builder installation", file = sys.stderr)
> -        sys.exit(1)
> -
> -try:
> -    import pkgconfig
> -except ImportError:
> -    print("Incorrect Source Builder installation", file = sys.stderr)
> -    sys.exit(1)
> -
> -#
> -# Make trace true to get a file of what happens and what is being asked.
> -#
> -trace = True
> -trace_stdout = False
> -logfile = 'pkg-config.log'
> -out = None
> -srcfd = None
> -
> -#
> -# Write all the package source parsed to a single file.
> -#
> -trace_src = True
> -if trace_src:
> -    srcfd = open('pkg-src.txt', 'w')
> -
> -def src(text):
> -    if srcfd:
> -        srcfd.writelines(text)
> -
> -def log(s, lf = True):
> -    global trace, logfile, out
> -    if trace:
> -        if out is None:
> -            if logfile:
> -                out = open(logfile, 'a')
> -            else:
> -                out = sys.stdout
> -        if lf:
> -            if out != sys.stdout and trace_stdout:
> -                print(s)
> -            print(s, file = out)
> -        else:
> -            if out != sys.stdout and trace_stdout:
> -                print(s, end = '')
> -                sys.stdout.flush()
> -            print(s, end = '', file = out)
> -
> -def run(argv):
> -
> -    class version_action(argparse.Action):
> -        def __call__(self, parser, namespace, values, option_string = None):
> -            parts = values[0].strip().split('.')
> -            for p in parts:
> -                if not p.isdigit():
> -                    raise error('invalid version value: %s' % (values))
> -            setattr(namespace, self.dest, '.'.join(parts))
> -
> -    ec = 0
> -
> -    opts = argparse.ArgumentParser(prog = 'pkg-config', description = 'Package Configuration.')
> -    opts.add_argument('libraries', metavar='lib', type = str,  help = 'a library', nargs = '*')
> -    opts.add_argument('--modversion', dest = 'modversion', action = 'store', default = None,
> -                      help = 'Requests that the version information of the libraries.')
> -    opts.add_argument('--print-errors', dest = 'print_errors', action = 'store_true',
> -                      default = False,
> -                      help = 'Print any errors.')
> -    opts.add_argument('--short-errors', dest = 'short_errors', action = 'store_true',
> -                      default = False,
> -                      help = 'Make error messages short.')
> -    opts.add_argument('--silence-errors', dest = 'silence_errors', action = 'store_true',
> -                      default = False,
> -                      help = 'Do not print any errors.')
> -    opts.add_argument('--errors-to-stdout', dest = 'errors_to_stdout', action = 'store_true',
> -                      default = False,
> -                      help = 'Print errors to stdout rather than stderr.')
> -    opts.add_argument('--cflags', dest = 'cflags', action = 'store_true',
> -                      default = False,
> -                      help = 'This prints pre-processor and compile flags required to' \
> -                             ' compile the package(s)')
> -    opts.add_argument('--libs', dest = 'libs', action = 'store_true',
> -                      default = False,
> -                      help = 'This option is identical to "--cflags", only it prints the' \
> -                             ' link flags.')
> -    opts.add_argument('--libs-only-L', dest = 'libs_only_L', action = 'store_true',
> -                      default = False,
> -                      help = 'This prints the -L/-R part of "--libs".')
> -    opts.add_argument('--libs-only-l', dest = 'libs_only_l', action = 'store_true',
> -                      default = False,
> -                      help = 'This prints the -l part of "--libs".')
> -    opts.add_argument('--variable', dest = 'variable', action = 'store',
> -                      nargs = 1, default = None,
> -                      help = 'This returns the value of a variable.')
> -    opts.add_argument('--define-variable', dest = 'define_variable', action = 'store',
> -                      nargs = 1, default = None,
> -                      help = 'This sets a global value for a variable')
> -    opts.add_argument('--uninstalled', dest = 'uninstalled', action = 'store_true',
> -                      default = False,
> -                      help = 'Ignored')
> -    opts.add_argument('--atleast-pkgconfig-version', dest = 'atleast_pkgconfig_version',
> -                      action = 'store', nargs = 1, default = None,
> -                      help = 'Check the version of package config. Always ok.')
> -    opts.add_argument('--exists', dest = 'exists', action = 'store_true',
> -                      default = False,
> -                      help = 'Test if a library is present')
> -    opts.add_argument('--atleast-version', dest = 'atleast_version',
> -                      action = version_action, nargs = 1, default = None,
> -                      help = 'The package is at least this version.')
> -    opts.add_argument('--exact-version', dest = 'exact_version', action = version_action,
> -                       nargs = 1, default = None,
> -                        help = 'The package is the exact version.')
> -    opts.add_argument('--max-version', dest = 'max_version', action = version_action,
> -                      nargs = 1, default = None,
> -                      help = 'The package is no later than this version.')
> -    opts.add_argument('--msvc-syntax', dest = 'msvc_syntax', action = 'store_true',
> -                      default = False,
> -                      help = 'Ignored')
> -    opts.add_argument('--dont-define-prefix', dest = 'dont_define_prefix', action = 'store_true',
> -                      default = False,
> -                      help = 'Ignored')
> -    opts.add_argument('--prefix-variable', dest = 'prefix', action = 'store',
> -                      nargs = 1, default = pkgconfig.default_prefix(),
> -                      help = 'Define the prefix.')
> -    opts.add_argument('--static', dest = 'static', action = 'store_true',
> -                      default = False,
> -                      help = 'Output libraries suitable for static linking')
> -    opts.add_argument('--dump', dest = 'dump', action = 'store_true',
> -                      default = False,
> -                      help = 'Dump the package if one is found.')
> -
> -    args = opts.parse_args(argv[1:])
> -
> -    if (args.exists and (args.exact_version or args.max_version)) or \
> -            (args.exact_version and (args.exists or args.max_version)) or \
> -            (args.max_version and (args.exists or args.exact_version)):
> -        raise error('only one of --exists, --exact-version, or --max-version')
> -
> -    if args.dont_define_prefix:
> -        args.prefix = pkgconfig.default_prefix(False)
> -
> -    exists = False
> -
> -    ec = 1
> -
> -    if args.atleast_pkgconfig_version:
> -        ec = 0
> -    else:
> -        ec, pkg, flags = pkgconfig.check_package(args.libraries, args, log, src)
> -        if ec == 0:
> -            if args.cflags:
> -                if len(flags['cflags']):
> -                    print(flags['cflags'])
> -                    log('cflags: %s' % (flags['cflags']))
> -                else:
> -                    log('cflags: empty')
> -            if args.libs:
> -                if len(flags['libs']):
> -                    print(flags['libs'])
> -                    log('libs: %s' % (flags['libs']))
> -                else:
> -                    log('libs: empty')
> -
> -    #pkgconfig.package.dump_loaded()
> -
> -    return ec
> -
> -try:
> -    log('-' * 40)
> -    log('pkg-config', lf = False)
> -    for a in sys.argv[1:]:
> -        log(' "%s"' % (a), lf = False)
> -    log('')
> -    ec = run(sys.argv)
> -    log('ec = %d' % (ec))
> -except ImportError:
> -    print("incorrect package config installation", file = sys.stderr)
> -    sys.exit(1)
> -except pkgconfig.error as e:
> -    print('error: %s' % (e), file = sys.stderr)
> -    sys.exit(1)
> -sys.exit(ec)
> +# Permission to use, copy, modify, and/or distribute this software for any
> +# purpose with or without fee is hereby granted, provided that the above
> +# copyright notice and this permission notice appear in all copies.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +#
> +set -e
> +base=$(dirname $0)
> +PYTHON_CMD=${base}/sb/cmd-pkg-config.py
> +if test -f ${base}/sb/python-wrapper.sh; then
> +  . ${base}/sb/python-wrapper.sh
> +fi
> +echo "error: python wrapper not found"
> diff --git a/source-builder/sb-bootstrap b/source-builder/sb-bootstrap
> index a1ee9a7..618e2bb 100755
> --- a/source-builder/sb-bootstrap
> +++ b/source-builder/sb-bootstrap
> @@ -1,7 +1,7 @@
> -#! /usr/bin/env python
> +#! /bin/sh
>  #
>  # RTEMS Tools Project (http://www.rtems.org/)
> -# Copyright 2013 Chris Johns (chrisj at rtems.org)
> +# Copyright 2018 Chris Johns (chrisj at rtems.org)
>  # All rights reserved.
>  #
>  # This file is part of the RTEMS Tools package in 'rtems-tools'.
> @@ -17,15 +17,11 @@
>  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
>  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>  # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> -
> -from __future__ import print_function
> -
> -import sys, os
> -base = os.path.dirname(sys.argv[0])
> -sys.path.insert(0, base + '/sb')
> -try:
> -    import bootstrap
> -    bootstrap.run(sys.argv)
> -except ImportError:
> -    print("Incorrect Source Builder installation", file = sys.stderr)
> -    sys.exit(1)
> +#
> +set -e
> +base=$(dirname $0)
> +PYTHON_CMD=${base}/sb/cmd-bootstrap.py
> +if test -f ${base}/sb/python-wrapper.sh; then
> +  . ${base}/sb/python-wrapper.sh
> +fi
> +echo "error: python wrapper not found"
> diff --git a/source-builder/sb-builder b/source-builder/sb-builder
> index 8721b56..be3d205 100755
> --- a/source-builder/sb-builder
> +++ b/source-builder/sb-builder
> @@ -1,7 +1,7 @@
> -#! /usr/bin/env python
> +#! /bin/sh
>  #
>  # RTEMS Tools Project (http://www.rtems.org/)
> -# Copyright 2010-2012 Chris Johns (chrisj at rtems.org)
> +# Copyright 2018 Chris Johns (chrisj at rtems.org)
>  # All rights reserved.
>  #
>  # This file is part of the RTEMS Tools package in 'rtems-tools'.
> @@ -17,15 +17,11 @@
>  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
>  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>  # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> -
> -from __future__ import print_function
> -
> -import sys, os
> -base = os.path.dirname(sys.argv[0])
> -sys.path.insert(0, base + '/sb')
> -try:
> -    import build
> -    build.run(sys.argv)
> -except ImportError:
> -    print("Incorrect Source Builder installation", file = sys.stderr)
> -    sys.exit(1)
> +#
> +set -e
> +base=$(dirname $0)
> +PYTHON_CMD=${base}/sb/cmd-builder.py
> +if test -f ${base}/sb/python-wrapper.sh; then
> +  . ${base}/sb/python-wrapper.sh
> +fi
> +echo "error: python wrapper not found"
> diff --git a/source-builder/sb-check b/source-builder/sb-check
> index d23b799..b092697 100755
> --- a/source-builder/sb-check
> +++ b/source-builder/sb-check
> @@ -1,7 +1,7 @@
> -#! /usr/bin/env python
> +#! /bin/sh
>  #
>  # RTEMS Tools Project (http://www.rtems.org/)
> -# Copyright 2010-2012 Chris Johns (chrisj at rtems.org)
> +# Copyright 2018 Chris Johns (chrisj at rtems.org)
>  # All rights reserved.
>  #
>  # This file is part of the RTEMS Tools package in 'rtems-tools'.
> @@ -17,15 +17,11 @@
>  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
>  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>  # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> -
> -from __future__ import print_function
> -
> -import sys, os
> -base = os.path.dirname(sys.argv[0])
> -sys.path.insert(0, base + '/sb')
> -try:
> -    import check
> -    check.run()
> -except ImportError:
> -    print("Incorrect Source Builder installation", file = sys.stderr)
> -    sys.exit(1)
> +#
> +set -e
> +base=$(dirname $0)
> +PYTHON_CMD=${base}/sb/cmd-check.py
> +if test -f ${base}/sb/python-wrapper.sh; then
> +  . ${base}/sb/python-wrapper.sh
> +fi
> +echo "error: python wrapper not found"
> diff --git a/source-builder/sb-defaults b/source-builder/sb-defaults
> index 790a5e5..25437ba 100755
> --- a/source-builder/sb-defaults
> +++ b/source-builder/sb-defaults
> @@ -1,7 +1,7 @@
> -#! /usr/bin/env python
> +#! /bin/sh
>  #
>  # RTEMS Tools Project (http://www.rtems.org/)
> -# Copyright 2010-2013 Chris Johns (chrisj at rtems.org)
> +# Copyright 2018 Chris Johns (chrisj at rtems.org)
>  # All rights reserved.
>  #
>  # This file is part of the RTEMS Tools package in 'rtems-tools'.
> @@ -17,15 +17,11 @@
>  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
>  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>  # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> -
> -from __future__ import print_function
> -
> -import sys, os
> -base = os.path.dirname(sys.argv[0])
> -sys.path.insert(0, base + '/sb')
> -try:
> -    import options
> -    options.run(sys.argv)
> -except ImportError:
> -    print("Incorrect Source Builder installation", file = sys.stderr)
> -    sys.exit(1)
> +#
> +set -e
> +base=$(dirname $0)
> +PYTHON_CMD=${base}/sb/cmd-defaults.py
> +if test -f ${base}/sb/python-wrapper.sh; then
> +  . ${base}/sb/python-wrapper.sh
> +fi
> +echo "error: python wrapper not found"
> diff --git a/source-builder/sb-reports b/source-builder/sb-reports
> index 3330be3..5fb02d1 100755
> --- a/source-builder/sb-reports
> +++ b/source-builder/sb-reports
> @@ -1,7 +1,7 @@
> -#! /usr/bin/env python
> +#! /bin/sh
>  #
>  # RTEMS Tools Project (http://www.rtems.org/)
> -# Copyright 2010-2013 Chris Johns (chrisj at rtems.org)
> +# Copyright 2018 Chris Johns (chrisj at rtems.org)
>  # All rights reserved.
>  #
>  # This file is part of the RTEMS Tools package in 'rtems-tools'.
> @@ -17,15 +17,11 @@
>  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
>  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>  # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> -
> -from __future__ import print_function
> -
> -import sys, os
> -base = os.path.dirname(sys.argv[0])
> -sys.path.insert(0, base + '/sb')
> -try:
> -    import reports
> -    reports.run(sys.argv)
> -except ImportError:
> -    print("Incorrect Source Builder installation", file = sys.stderr)
> -    sys.exit(1)
> +#
> +set -e
> +base=$(dirname $0)
> +PYTHON_CMD=${base}/sb/cmd-reports.py
> +if test -f ${base}/sb/python-wrapper.sh; then
> +  . ${base}/sb/python-wrapper.sh
> +fi
> +echo "error: python wrapper not found"
> diff --git a/source-builder/sb-rtems-config b/source-builder/sb-rtems-config
> index 1633b6b..66a95f7 100755
> --- a/source-builder/sb-rtems-config
> +++ b/source-builder/sb-rtems-config
> @@ -1,7 +1,7 @@
> -#! /usr/bin/env python
> +#! /bin/sh
>  #
>  # RTEMS Tools Project (http://www.rtems.org/)
> -# Copyright 2010-2012 Chris Johns (chrisj at rtems.org)
> +# Copyright 2018 Chris Johns (chrisj at rtems.org)
>  # All rights reserved.
>  #
>  # This file is part of the RTEMS Tools package in 'rtems-tools'.
> @@ -17,15 +17,11 @@
>  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
>  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>  # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> -
> -from __future__ import print_function
> -
> -import sys, os
> -base = os.path.dirname(sys.argv[0])
> -sys.path.insert(0, base + '/sb')
> -try:
> -    import rtemsconfig
> -    rtemsconfig.run(sys.argv)
> -except ImportError:
> -    print("Incorrect Source Builder installation", file = sys.stderr)
> -    sys.exit(1)
> +#
> +set -e
> +base=$(dirname $0)
> +PYTHON_CMD=${base}/sb/cmd-rtems-config.py
> +if test -f ${base}/sb/python-wrapper.sh; then
> +  . ${base}/sb/python-wrapper.sh
> +fi
> +echo "error: python wrapper not found"
> diff --git a/source-builder/sb-set-builder b/source-builder/sb-set-builder
> index 561199e..6a196fe 100755
> --- a/source-builder/sb-set-builder
> +++ b/source-builder/sb-set-builder
> @@ -1,7 +1,7 @@
> -#! /usr/bin/env python
> +#! /bin/sh
>  #
>  # RTEMS Tools Project (http://www.rtems.org/)
> -# Copyright 2010-2012 Chris Johns (chrisj at rtems.org)
> +# Copyright 2018 Chris Johns (chrisj at rtems.org)
>  # All rights reserved.
>  #
>  # This file is part of the RTEMS Tools package in 'rtems-tools'.
> @@ -17,16 +17,11 @@
>  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
>  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>  # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> -
> -from __future__ import print_function
> -
> -import sys, os
> -base = os.path.dirname(sys.argv[0])
> -sys.path.insert(0, base + '/sb')
> -
> -try:
> -    import setbuilder
> -    setbuilder.run()
> -except ImportError:
> -    print("Incorrect Source Builder installation", file = sys.stderr)
> -    sys.exit(1)
> +#
> +set -e
> +base=$(dirname $0)
> +PYTHON_CMD=${base}/sb/cmd-set-builder.py
> +if test -f ${base}/sb/python-wrapper.sh; then
> +  . ${base}/sb/python-wrapper.sh
> +fi
> +echo "error: python wrapper not found"
> diff --git a/source-builder/sb/build.py b/source-builder/sb/build.py
> index 88446bb..a17bfe2 100644
> --- a/source-builder/sb/build.py
> +++ b/source-builder/sb/build.py
> @@ -69,7 +69,15 @@ class script:
>          self.lc = 0
>  
>      def append(self, text):
> +        is_str = False
>          if type(text) is str:
> +            is_str = True
> +        try:
> +            if type(text) is unicode:
> +                is_str = True
> +        except:
> +            pass
> +        if is_str:
>              text = text.splitlines()
>          if not log.quiet:
>              i = 0
> diff --git a/source-builder/sb/cmd-bootstrap.py b/source-builder/sb/cmd-bootstrap.py
> new file mode 100755
> index 0000000..0243237
> --- /dev/null
> +++ b/source-builder/sb/cmd-bootstrap.py
> @@ -0,0 +1,29 @@
> +#
> +# RTEMS Tools Project (http://www.rtems.org/)
> +# Copyright 2013 Chris Johns (chrisj at rtems.org)
> +# All rights reserved.
> +#
> +# This file is part of the RTEMS Tools package in 'rtems-tools'.
> +#
> +# Permission to use, copy, modify, and/or distribute this software for any
> +# purpose with or without fee is hereby granted, provided that the above
> +# copyright notice and this permission notice appear in all copies.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +
> +from __future__ import print_function
> +
> +import sys, os
> +
> +try:
> +    import bootstrap
> +    bootstrap.run(sys.argv)
> +except ImportError:
> +    print("Incorrect Source Builder installation", file = sys.stderr)
> +    sys.exit(1)
> diff --git a/source-builder/sb/cmd-builder.py b/source-builder/sb/cmd-builder.py
> new file mode 100755
> index 0000000..437b81a
> --- /dev/null
> +++ b/source-builder/sb/cmd-builder.py
> @@ -0,0 +1,29 @@
> +#
> +# RTEMS Tools Project (http://www.rtems.org/)
> +# Copyright 2010-2012 Chris Johns (chrisj at rtems.org)
> +# All rights reserved.
> +#
> +# This file is part of the RTEMS Tools package in 'rtems-tools'.
> +#
> +# Permission to use, copy, modify, and/or distribute this software for any
> +# purpose with or without fee is hereby granted, provided that the above
> +# copyright notice and this permission notice appear in all copies.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +
> +from __future__ import print_function
> +
> +import sys, os
> +
> +try:
> +    import build
> +    build.run(sys.argv)
> +except ImportError:
> +    print("Incorrect Source Builder installation", file = sys.stderr)
> +    sys.exit(1)
> diff --git a/source-builder/sb/cmd-check.py b/source-builder/sb/cmd-check.py
> new file mode 100755
> index 0000000..4525dbb
> --- /dev/null
> +++ b/source-builder/sb/cmd-check.py
> @@ -0,0 +1,29 @@
> +#
> +# RTEMS Tools Project (http://www.rtems.org/)
> +# Copyright 2010-2012 Chris Johns (chrisj at rtems.org)
> +# All rights reserved.
> +#
> +# This file is part of the RTEMS Tools package in 'rtems-tools'.
> +#
> +# Permission to use, copy, modify, and/or distribute this software for any
> +# purpose with or without fee is hereby granted, provided that the above
> +# copyright notice and this permission notice appear in all copies.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +
> +from __future__ import print_function
> +
> +import sys, os
> +
> +try:
> +    import check
> +    check.run()
> +except ImportError:
> +    print("Incorrect Source Builder installation", file = sys.stderr)
> +    sys.exit(1)
> diff --git a/source-builder/sb/cmd-defaults.py b/source-builder/sb/cmd-defaults.py
> new file mode 100755
> index 0000000..0b2b357
> --- /dev/null
> +++ b/source-builder/sb/cmd-defaults.py
> @@ -0,0 +1,29 @@
> +#
> +# RTEMS Tools Project (http://www.rtems.org/)
> +# Copyright 2010-2013 Chris Johns (chrisj at rtems.org)
> +# All rights reserved.
> +#
> +# This file is part of the RTEMS Tools package in 'rtems-tools'.
> +#
> +# Permission to use, copy, modify, and/or distribute this software for any
> +# purpose with or without fee is hereby granted, provided that the above
> +# copyright notice and this permission notice appear in all copies.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +
> +from __future__ import print_function
> +
> +import sys, os
> +
> +try:
> +    import options
> +    options.run(sys.argv)
> +except ImportError:
> +    print("Incorrect Source Builder installation", file = sys.stderr)
> +    sys.exit(1)
> diff --git a/source-builder/sb/cmd-pkg-config.py b/source-builder/sb/cmd-pkg-config.py
> new file mode 100755
> index 0000000..c2f485c
> --- /dev/null
> +++ b/source-builder/sb/cmd-pkg-config.py
> @@ -0,0 +1,220 @@
> +#
> +# RTEMS Tools Project (http://www.rtems.org/)
> +# Copyright 2014-2016 Chris Johns (chrisj at rtems.org)
> +# All rights reserved.
> +#
> +# This file is part of the RTEMS Tools package in 'rtems-tools'.
> +#
> +# Redistribution and use in source and binary forms, with or without
> +# modification, are permitted provided that the following conditions are met:
> +#
> +# 1. Redistributions of source code must retain the above copyright notice,
> +# this list of conditions and the following disclaimer.
> +#
> +# 2. Redistributions in binary form must reproduce the above copyright notice,
> +# this list of conditions and the following disclaimer in the documentation
> +# and/or other materials provided with the distribution.
> +#
> +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
> +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +# POSSIBILITY OF SUCH DAMAGE.
> +#
> +
> +from __future__ import print_function
> +
> +import os
> +import sys
> +
> +base = os.path.dirname(sys.argv[0])
> +
> +try:
> +    import argparse
> +except:
> +    sys.path.insert(0, base + '/sb/imports')
> +    try:
> +        import argparse
> +    except:
> +        print("Incorrect Source Builder installation", file = sys.stderr)
> +        sys.exit(1)
> +
> +import pkgconfig
> +
> +#
> +# Make trace true to get a file of what happens and what is being asked.
> +#
> +trace = True
> +trace_stdout = False
> +logfile = 'pkg-config.log'
> +out = None
> +srcfd = None
> +
> +#
> +# Write all the package source parsed to a single file.
> +#
> +trace_src = True
> +if trace_src:
> +    srcfd = open('pkg-src.txt', 'w')
> +
> +def src(text):
> +    if srcfd:
> +        srcfd.writelines(text)
> +
> +def log(s, lf = True):
> +    global trace, logfile, out
> +    if trace:
> +        if out is None:
> +            if logfile:
> +                out = open(logfile, 'a')
> +            else:
> +                out = sys.stdout
> +        if lf:
> +            if out != sys.stdout and trace_stdout:
> +                print(s)
> +            print(s, file = out)
> +        else:
> +            if out != sys.stdout and trace_stdout:
> +                print(s, end = '')
> +                sys.stdout.flush()
> +            print(s, end = '', file = out)
> +
> +def run(argv):
> +
> +    class version_action(argparse.Action):
> +        def __call__(self, parser, namespace, values, option_string = None):
> +            parts = values[0].strip().split('.')
> +            for p in parts:
> +                if not p.isdigit():
> +                    raise error('invalid version value: %s' % (values))
> +            setattr(namespace, self.dest, '.'.join(parts))
> +
> +    ec = 0
> +
> +    opts = argparse.ArgumentParser(prog = 'pkg-config', description = 'Package Configuration.')
> +    opts.add_argument('libraries', metavar='lib', type = str,  help = 'a library', nargs = '*')
> +    opts.add_argument('--modversion', dest = 'modversion', action = 'store', default = None,
> +                      help = 'Requests that the version information of the libraries.')
> +    opts.add_argument('--print-errors', dest = 'print_errors', action = 'store_true',
> +                      default = False,
> +                      help = 'Print any errors.')
> +    opts.add_argument('--short-errors', dest = 'short_errors', action = 'store_true',
> +                      default = False,
> +                      help = 'Make error messages short.')
> +    opts.add_argument('--silence-errors', dest = 'silence_errors', action = 'store_true',
> +                      default = False,
> +                      help = 'Do not print any errors.')
> +    opts.add_argument('--errors-to-stdout', dest = 'errors_to_stdout', action = 'store_true',
> +                      default = False,
> +                      help = 'Print errors to stdout rather than stderr.')
> +    opts.add_argument('--cflags', dest = 'cflags', action = 'store_true',
> +                      default = False,
> +                      help = 'This prints pre-processor and compile flags required to' \
> +                             ' compile the package(s)')
> +    opts.add_argument('--libs', dest = 'libs', action = 'store_true',
> +                      default = False,
> +                      help = 'This option is identical to "--cflags", only it prints the' \
> +                             ' link flags.')
> +    opts.add_argument('--libs-only-L', dest = 'libs_only_L', action = 'store_true',
> +                      default = False,
> +                      help = 'This prints the -L/-R part of "--libs".')
> +    opts.add_argument('--libs-only-l', dest = 'libs_only_l', action = 'store_true',
> +                      default = False,
> +                      help = 'This prints the -l part of "--libs".')
> +    opts.add_argument('--variable', dest = 'variable', action = 'store',
> +                      nargs = 1, default = None,
> +                      help = 'This returns the value of a variable.')
> +    opts.add_argument('--define-variable', dest = 'define_variable', action = 'store',
> +                      nargs = 1, default = None,
> +                      help = 'This sets a global value for a variable')
> +    opts.add_argument('--uninstalled', dest = 'uninstalled', action = 'store_true',
> +                      default = False,
> +                      help = 'Ignored')
> +    opts.add_argument('--atleast-pkgconfig-version', dest = 'atleast_pkgconfig_version',
> +                      action = 'store', nargs = 1, default = None,
> +                      help = 'Check the version of package config. Always ok.')
> +    opts.add_argument('--exists', dest = 'exists', action = 'store_true',
> +                      default = False,
> +                      help = 'Test if a library is present')
> +    opts.add_argument('--atleast-version', dest = 'atleast_version',
> +                      action = version_action, nargs = 1, default = None,
> +                      help = 'The package is at least this version.')
> +    opts.add_argument('--exact-version', dest = 'exact_version', action = version_action,
> +                       nargs = 1, default = None,
> +                        help = 'The package is the exact version.')
> +    opts.add_argument('--max-version', dest = 'max_version', action = version_action,
> +                      nargs = 1, default = None,
> +                      help = 'The package is no later than this version.')
> +    opts.add_argument('--msvc-syntax', dest = 'msvc_syntax', action = 'store_true',
> +                      default = False,
> +                      help = 'Ignored')
> +    opts.add_argument('--dont-define-prefix', dest = 'dont_define_prefix', action = 'store_true',
> +                      default = False,
> +                      help = 'Ignored')
> +    opts.add_argument('--prefix-variable', dest = 'prefix', action = 'store',
> +                      nargs = 1, default = pkgconfig.default_prefix(),
> +                      help = 'Define the prefix.')
> +    opts.add_argument('--static', dest = 'static', action = 'store_true',
> +                      default = False,
> +                      help = 'Output libraries suitable for static linking')
> +    opts.add_argument('--dump', dest = 'dump', action = 'store_true',
> +                      default = False,
> +                      help = 'Dump the package if one is found.')
> +
> +    args = opts.parse_args(argv[1:])
> +
> +    if (args.exists and (args.exact_version or args.max_version)) or \
> +            (args.exact_version and (args.exists or args.max_version)) or \
> +            (args.max_version and (args.exists or args.exact_version)):
> +        raise error('only one of --exists, --exact-version, or --max-version')
> +
> +    if args.dont_define_prefix:
> +        args.prefix = pkgconfig.default_prefix(False)
> +
> +    exists = False
> +
> +    ec = 1
> +
> +    if args.atleast_pkgconfig_version:
> +        ec = 0
> +    else:
> +        ec, pkg, flags = pkgconfig.check_package(args.libraries, args, log, src)
> +        if ec == 0:
> +            if args.cflags:
> +                if len(flags['cflags']):
> +                    print(flags['cflags'])
> +                    log('cflags: %s' % (flags['cflags']))
> +                else:
> +                    log('cflags: empty')
> +            if args.libs:
> +                if len(flags['libs']):
> +                    print(flags['libs'])
> +                    log('libs: %s' % (flags['libs']))
> +                else:
> +                    log('libs: empty')
> +
> +    #pkgconfig.package.dump_loaded()
> +
> +    return ec
> +
> +try:
> +    log('-' * 40)
> +    log('pkg-config', lf = False)
> +    for a in sys.argv[1:]:
> +        log(' "%s"' % (a), lf = False)
> +    log('')
> +    ec = run(sys.argv)
> +    log('ec = %d' % (ec))
> +except ImportError:
> +    print("incorrect package config installation", file = sys.stderr)
> +    sys.exit(1)
> +except pkgconfig.error as e:
> +    print('error: %s' % (e), file = sys.stderr)
> +    sys.exit(1)
> +sys.exit(ec)
> diff --git a/source-builder/sb/cmd-reports.py b/source-builder/sb/cmd-reports.py
> new file mode 100755
> index 0000000..4c41e33
> --- /dev/null
> +++ b/source-builder/sb/cmd-reports.py
> @@ -0,0 +1,29 @@
> +#
> +# RTEMS Tools Project (http://www.rtems.org/)
> +# Copyright 2010-2013 Chris Johns (chrisj at rtems.org)
> +# All rights reserved.
> +#
> +# This file is part of the RTEMS Tools package in 'rtems-tools'.
> +#
> +# Permission to use, copy, modify, and/or distribute this software for any
> +# purpose with or without fee is hereby granted, provided that the above
> +# copyright notice and this permission notice appear in all copies.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +
> +from __future__ import print_function
> +
> +import sys, os
> +
> +try:
> +    import reports
> +    reports.run(sys.argv)
> +except ImportError:
> +    print("Incorrect Source Builder installation", file = sys.stderr)
> +    sys.exit(1)
> diff --git a/source-builder/sb/cmd-rtems-config.py b/source-builder/sb/cmd-rtems-config.py
> new file mode 100755
> index 0000000..f29ef04
> --- /dev/null
> +++ b/source-builder/sb/cmd-rtems-config.py
> @@ -0,0 +1,29 @@
> +#
> +# RTEMS Tools Project (http://www.rtems.org/)
> +# Copyright 2010-2012 Chris Johns (chrisj at rtems.org)
> +# All rights reserved.
> +#
> +# This file is part of the RTEMS Tools package in 'rtems-tools'.
> +#
> +# Permission to use, copy, modify, and/or distribute this software for any
> +# purpose with or without fee is hereby granted, provided that the above
> +# copyright notice and this permission notice appear in all copies.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +
> +from __future__ import print_function
> +
> +import sys, os
> +
> +try:
> +    import rtemsconfig
> +    rtemsconfig.run(sys.argv)
> +except ImportError:
> +    print("Incorrect Source Builder installation", file = sys.stderr)
> +    sys.exit(1)
> diff --git a/source-builder/sb/cmd-set-builder.py b/source-builder/sb/cmd-set-builder.py
> new file mode 100755
> index 0000000..56114cd
> --- /dev/null
> +++ b/source-builder/sb/cmd-set-builder.py
> @@ -0,0 +1,29 @@
> +#
> +# RTEMS Tools Project (http://www.rtems.org/)
> +# Copyright 2010-2012 Chris Johns (chrisj at rtems.org)
> +# All rights reserved.
> +#
> +# This file is part of the RTEMS Tools package in 'rtems-tools'.
> +#
> +# Permission to use, copy, modify, and/or distribute this software for any
> +# purpose with or without fee is hereby granted, provided that the above
> +# copyright notice and this permission notice appear in all copies.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +
> +from __future__ import print_function
> +
> +import sys, os
> +
> +try:
> +    import setbuilder
> +    setbuilder.run()
> +except ImportError:
> +    print("Incorrect Source Builder installation", file = sys.stderr)
> +    sys.exit(1)
> diff --git a/source-builder/sb/config.py b/source-builder/sb/config.py
> index a901038..b7bf403 100644
> --- a/source-builder/sb/config.py
> +++ b/source-builder/sb/config.py
> @@ -557,7 +557,7 @@ class file:
>                  elif m.startswith('%{expand'):
>                      colon = m.find(':')
>                      if colon < 8:
> -                        log.warning('malformed expand macro, no colon found')
> +                        log.warning(self._name_line_msg('malformed expand macro, no colon found'))
>                      else:
>                          e = self._expand(m[colon + 1:-1].strip())
>                          s = s.replace(m, self._label(e))
> @@ -576,7 +576,7 @@ class file:
>                      mn = None
>                  elif m.startswith('%{echo'):
>                      if not m.endswith('}'):
> -                        log.warning("malformed conditional macro '%s'" % (m))
> +                        log.warning(self._name_line_msg("malformed conditional macro '%s'" % (m)))
>                          mn = None
>                      else:
>                          e = self._expand(m[6:-1].strip())
> @@ -648,7 +648,7 @@ class file:
>                      colon = m[start:].find(':')
>                      if colon < 0:
>                          if not m.endswith('}'):
> -                            log.warning("malformed conditional macro '%s'" % (m))
> +                            log.warning(self._name_line_msg("malformed conditional macro '%s'" % (m)))
>                              mn = None
>                          else:
>                              mn = self._label(m[start:-1])
> @@ -690,18 +690,18 @@ class file:
>  
>      def _disable(self, config, ls):
>          if len(ls) != 2:
> -            log.warning('invalid disable statement')
> +            log.warning(self._name_line_msg('invalid disable statement'))
>          else:
>              if ls[1] == 'select':
>                  self.macros.lock_read_map()
>                  log.trace('config: %s: %3d: _disable_select: %s' % (self.name, self.lc,
>                                                                       ls[1]))
>              else:
> -                log.warning('invalid disable statement: %s' % (ls[1]))
> +                log.warning(self._name_line_msg('invalid disable statement: %s' % (ls[1])))
>  
>      def _select(self, config, ls):
>          if len(ls) != 2:
> -            log.warning('invalid select statement')
> +            log.warning(self._name_line_msg('invalid select statement'))
>          else:
>              r = self.macros.set_read_map(ls[1])
>              log.trace('config: %s: %3d: _select: %s %s %r' % \
> @@ -716,7 +716,7 @@ class file:
>  
>      def _define(self, config, ls):
>          if len(ls) <= 1:
> -            log.warning('invalid macro definition')
> +            log.warning(self._name_line_msg('invalid macro definition'))
>          else:
>              d = self._label(ls[1])
>              if self.disable_macro_reassign:
> @@ -727,7 +727,7 @@ class file:
>                      else:
>                          self.macros[d] = ' '.join([f.strip() for f in ls[2:]])
>                  else:
> -                    log.warning("macro '%s' already defined" % (d))
> +                    log.warning(self._name_line_msg("macro '%s' already defined" % (d)))
>              else:
>                  if len(ls) == 2:
>                      self.macros[d] = '1'
> @@ -736,7 +736,7 @@ class file:
>  
>      def _undefine(self, config, ls):
>          if len(ls) <= 1:
> -            log.warning('invalid macro definition')
> +            log.warning(self._name_line_msg('invalid macro definition'))
>          else:
>              mn = self._label(ls[1])
>              if mn in self.macros:
> @@ -841,7 +841,7 @@ class file:
>                      i = andi
>                  log.trace('config: %s: %3d: _if[%i]: next OP found at %i' % (self.name, self.lc,
>                                                                               self.if_depth,
> -                i))
> +                                                                             i))
>              ls = cls[:i]
>              if len(ls) == 0:
>                  self._error('invalid if expression: ' + reduce(add, sls, ''))
> @@ -965,6 +965,16 @@ class file:
>                      break
>          return self._ifs(config, ls, '%ifos', isos, isvalid, dir, info)
>  
> +    def _ifnos(self, config, ls, isvalid, dir, info):
> +        isnos = True
> +        if isvalid:
> +            os = self.define('_os')
> +            for l in ls:
> +                if l in os:
> +                    isnos = False
> +                    break
> +        return self._ifs(config, ls, '%ifnos', isnos, isvalid, dir, info)
> +
>      def _ifarch(self, config, positive, ls, isvalid, dir, info):
>          isarch = False
>          if isvalid:
> @@ -1063,6 +1073,10 @@ class file:
>                      d = self._ifos(config, ls, isvalid, dir, info)
>                      if len(d):
>                          return ('data', d)
> +                elif ls[0] == '%ifnos':
> +                    d = self._ifnos(config, ls, isvalid, dir, info)
> +                    if len(d):
> +                        return ('data', d)
>                  elif ls[0] == '%ifarch':
>                      d = self._ifarch(config, True, ls, isvalid, dir, info)
>                      if len(d):
> @@ -1074,11 +1088,11 @@ class file:
>                  elif ls[0] == '%endif':
>                      if roc:
>                          return ('control', '%endif', '%endif')
> -                    log.warning("unexpected '" + ls[0] + "'")
> +                    log.warning(self._name_line_msg("unexpected '" + ls[0] + "'"))
>                  elif ls[0] == '%else':
>                      if roc:
>                          return ('control', '%else', '%else')
> -                    log.warning("unexpected '" + ls[0] + "'")
> +                    log.warning(self._name_line_msg("unexpected '" + ls[0] + "'"))
>                  elif ls[0].startswith('%defattr'):
>                      return ('data', [l])
>                  elif ls[0] == '%bcond_with':
> @@ -1103,7 +1117,7 @@ class file:
>                                  log.trace('config: %s: %0d: _parse: directive: %s' % \
>                                            (self.name, self.lc, ls[0].strip()))
>                                  return ('directive', ls[0].strip(), ls[1:])
> -                        log.warning("unknown directive: '" + ls[0] + "'")
> +                        log.warning(self._name_line_msg("unknown directive: '" + ls[0] + "'"))
>                          return ('data', [lo])
>              else:
>                  return ('data', [lo])
> @@ -1124,7 +1138,7 @@ class file:
>                  _package = results[2][0]
>              else:
>                  if results[2][0].strip() != '-n':
> -                    log.warning("unknown directive option: '%s'" % (' '.join(results[2])))
> +                    log.warning(self._name_line_msg("unknown directive option: '%s'" % (' '.join(results[2]))))
>                  _package = results[2][1].strip()
>              self._set_package(_package)
>          if directive and directive != results[1]:
> @@ -1146,7 +1160,7 @@ class file:
>                  log.output(l[4:])
>              elif l.startswith('%warning'):
>                  l = self._expand(l)
> -                log.warning(l[9:])
> +                log.warning(self._name_line_msg(l[9:]))
>              if not directive:
>                  l = self._expand(l)
>                  ls = self.tags.split(l, 1)
> @@ -1161,7 +1175,7 @@ class file:
>                  if info is not None:
>                      self._info_append(info, info_data)
>                  else:
> -                    log.warning("invalid format: '%s'" % (info_data[:-1]))
> +                    log.warning(self._name_line_msg("invalid format: '%s'" % (info_data[:-1])))
>              else:
>                  l = self._expand(l)
>                  log.trace('config: %s: %3d: _data: %s %s' % (self.name, self.lc, l, new_data))
> @@ -1275,7 +1289,7 @@ class file:
>                  elif r[0] == 'control':
>                      if r[1] == '%end':
>                          break
> -                    log.warning("unexpected '%s'" % (r[1]))
> +                    log.warning(self._name_line_msg("unexpected '%s'" % (r[1])))
>                  elif r[0] == 'directive':
>                      if r[1] == '%include':
>                          self.load(r[2][0])
> diff --git a/source-builder/sb/freebsd.py b/source-builder/sb/freebsd.py
> index 2c519a1..e207d00 100644
> --- a/source-builder/sb/freebsd.py
> +++ b/source-builder/sb/freebsd.py
> @@ -57,6 +57,8 @@ def load():
>          '_host_cpu':        ('none',    'none',     cpu),
>          '_host_alias':      ('none',    'none',     '%{nil}'),
>          '_host_arch':       ('none',    'none',     cpu),
> +        'host_includes':    ('none',    'convert',  '-I%{_usr}/include'),
> +        'host_ldflags':     ('none',    'convert',  '-L%{_usr}/lib'),
>          '_usr':             ('dir',     'required', '/usr/local'),
>          '_var':             ('dir',     'optional', '/usr/local/var'),
>          '__bash':           ('exe',     'optional', '/usr/local/bin/bash'),
> @@ -67,7 +69,7 @@ def load():
>          '__xz':             ('exe',     'optional', '/usr/bin/xz'),
>          '__make':           ('exe',     'required', 'gmake'),
>          '__patch_opts':     ('none',     'none',    '-E')
> -        }
> +    }
>  
>      defines['_build']        = defines['_host']
>      defines['_build_vendor'] = defines['_host_vendor']
> @@ -110,7 +112,7 @@ def load():
>          #
>          # Fix the mess iconv is on FreeBSD 10.0.
>          #
> -        defines['iconv_includes'] = ('none', 'none', '-I/usr/local/include -L/usr/local/lib')
> +        defines['iconv_includes'] = ('none', 'none', '%{_host_includes} %{_host_ldflags}')
>  
>          #
>          # On 11.0+ makeinfo and install-info have moved to /usr/local/...
> diff --git a/source-builder/sb/macros.py b/source-builder/sb/macros.py
> index cf25783..2abe386 100644
> --- a/source-builder/sb/macros.py
> +++ b/source-builder/sb/macros.py
> @@ -53,7 +53,8 @@ class macros:
>          def iterkeys(self):
>              return self.keys
>  
> -    def _unicode_to_str(self, us):
> +    @staticmethod
> +    def _unicode_to_str(us):
>          try:
>              if type(us) == unicode:
>                  return us.encode('ascii', 'replace')
> @@ -174,14 +175,14 @@ class macros:
>                              'override', 'undefine', 'convert']:
>              raise TypeError('bad value tuple (attrib field): %s' % (value[1]))
>          if value[1] == 'convert':
> -            value = self.expand(value)
> +            value = (value[0], value[1], self.expand(value[2]))
>          self.macros[self.write_map][self.key_filter(key)] = value
>  
>      def __delitem__(self, key):
>          self.undefine(key)
>  
>      def __contains__(self, key):
> -        return self.has_key(key)
> +        return self.has_key(self._unicode_to_str(key))
>  
>      def __len__(self):
>          return len(list(self.keys()))
> @@ -201,6 +202,7 @@ class macros:
>          return sorted(set(keys))
>  
>      def has_key(self, key):
> +        key = self._unicode_to_str(key)
>          if type(key) is not str:
>              raise TypeError('bad key type (want str): %s' % (type(key)))
>          if self.key_filter(key) not in list(self.keys()):
> @@ -452,6 +454,7 @@ class macros:
>  
>      def expand(self, _str):
>          """Simple basic expander of config file macros."""
> +        _str = self._unicode_to_str(_str)
>          expanded = True
>          while expanded:
>              expanded = False
> diff --git a/source-builder/sb/options.py b/source-builder/sb/options.py
> index 7312285..c5fcabe 100644
> --- a/source-builder/sb/options.py
> +++ b/source-builder/sb/options.py
> @@ -601,10 +601,15 @@ def load(args, optargs = None, defaults = '%{_sbdir}/defaults.mc', logfile = Tru
>      global host_windows
>      global host_posix
>  
> +    #
> +    # Adjust the args to remove the wrapper.
> +    #
> +    args = args[1:]
> +
>      #
>      # The path to this command.
>      #
> -    command_path = path.dirname(args[0])
> +    command_path = path.dirname(path.abspath(args[0]))
>      if len(command_path) == 0:
>          command_path = '.'
>  
> diff --git a/source-builder/sb/path.py b/source-builder/sb/path.py
> index 984f3d7..93852c8 100644
> --- a/source-builder/sb/path.py
> +++ b/source-builder/sb/path.py
> @@ -30,10 +30,13 @@ import os
>  import shutil
>  import stat
>  import string
> +import sys
>  
>  import error
>  
> +windows_posix = sys.platform == 'msys'
>  windows = os.name == 'nt'
> +
>  win_maxpath = 254
>  
>  def host(path):
> @@ -54,13 +57,15 @@ def host(path):
>      return path
>  
>  def shell(path):
> +    if isinstance(path, bytes):
> +        path = path.decode('ascii')
>      if path is not None:
> -        if windows:
> -            path = path.encode('ascii', 'ignore')
> +        if windows or windows_posix:
> +            path = path.encode('ascii', 'ignore').decode('ascii')
>              if path.startswith('\\\\?\\'):
>                  path = path[4:]
>              if len(path) > 1 and path[1] == ':':
> -                path = '/%s%s' % (path[0], path[2:])
> +                path = '/%s%s' % (path[0].lower(), path[2:])
>              path = path.replace('\\', '/')
>          while '//' in path:
>              path = path.replace('//', '/')
> diff --git a/source-builder/sb/python-wrapper.sh b/source-builder/sb/python-wrapper.sh
> new file mode 100644
> index 0000000..c1b62d2
> --- /dev/null
> +++ b/source-builder/sb/python-wrapper.sh
> @@ -0,0 +1,39 @@
> +#
> +# RTEMS Tools Project (http://www.rtems.org/)
> +# Copyright 2018 Chris Johns (chrisj at rtems.org)
> +# All rights reserved.
> +#
> +# This file is part of the RTEMS Tools package in 'rtems-tools'.
> +#
> +# Permission to use, copy, modify, and/or distribute this software for any
> +# purpose with or without fee is hereby granted, provided that the above
> +# copyright notice and this permission notice appear in all copies.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +set -e
> +if test ! -f $PYTHON_CMD; then
> +  echo "error: python command not found: $PYTHON_CMD"
> +  exit 5
> +fi
> +for py in python2 python3 python
> +do
> +  set +e
> +  py_cmd=$(command -v $py)
> +  set -e
> +  if test -n "$RTEMS_PYTHON_OVERRIDE"; then
> +    if test "$RTEMS_PYTHON_OVERRIDE" != "$py"; then
> +      py_cmd=""
> +    fi
> +  fi
> +  if test -n "$py_cmd"; then
> +    exec $py_cmd $PYTHON_CMD $0 $*
> +  fi
> +done
> +echo "error: no valid python found"
> +exit 5
> diff --git a/source-builder/sb/rtems-build-dep b/source-builder/sb/rtems-build-dep
> new file mode 100755
> index 0000000..94bb566
> --- /dev/null
> +++ b/source-builder/sb/rtems-build-dep
> @@ -0,0 +1,170 @@
> +#! /bin/sh
> +#
> +# RTEMS Tools Project (http://www.rtems.org/)
> +# Copyright 2018 Chris Johns (chrisj at rtems.org)
> +# All rights reserved.
> +#
> +# This file is part of the RTEMS Tools package in 'rtems-tools'.
> +#
> +# Permission to use, copy, modify, and/or distribute this software for any
> +# purpose with or without fee is hereby granted, provided that the above
> +# copyright notice and this permission notice appear in all copies.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +
> +#
> +# Host Build Dependence
> +#
> +# This script finds a file that is part of the compiler's default
> +# build environment. The file can be header or a library.
> +#
> +# Header files:
> +#  - Get the list of include directories from the compiler.
> +#  - Search the include paths for the header file.
> +#
> +# Library:
> +#  - Ask the compiler to print the library paths, add on any user
> +#    paths and search with a wilecard.
> +#
> +
> +set -e
> +
> +op=
> +name=
> +includes=
> +libraries=
> +compile=
> +verbose=no
> +debug=no
> +
> +if [ $# == 0 ]
> +then
> +    echo 'Usage: rtems-build-dep [-c compiler] [-H header] [-I header-paths]
> +                       [-l library] [-L library-paths] [-v] [-d]'
> +    exit 2
> +fi
> +while [ $# > 0 ]
> +do
> +    case "$1"
> +    in
> +	-c)
> +	    if [ $# == 1 ]; then
> +		echo 'error: no compiler (-c) provided'
> +		exit 2
> +	    fi
> +	    compiler="$2"; shift;
> +            shift;;
> +	-H)
> +	    if [ $# == 1 ]; then
> +		echo 'error: no header (-H) provided'
> +		exit 2
> +	    fi
> +	    op="header"
> +            name="$2"; shift;
> +            shift;;
> +	-I)
> +	    if [ $# == 1 ]; then
> +		echo 'error: no header path (-I) provided'
> +		exit 2
> +	    fi
> +            includes="$2"; shift;
> +            shift;;
> +	-l)
> +	    if [ $# == 1 ]; then
> +		echo 'error: no library (-l) provided'
> +		exit 2
> +	    fi
> +	    op="library"
> +            name="$2"; shift;
> +            shift;;
> +	-L)
> +	    if [ $# == 1 ]; then
> +		echo 'error: no library path (-L) provided'
> +		exit 2
> +	    fi
> +            libraries="$2"; shift;
> +            shift;;
> +	-v)
> +	    verbose=yes
> +            shift;;
> +	-d)
> +	    debug=yes
> +            shift;;
> +	*)
> +	    break;
> +    esac
> +done
> +
> +if [ ${debug} = yes ]; then
> +    set -x
> +fi
> +
> +if [ -z "${op}" ]; then
> +    echo "error: no header or library file to find found."
> +    exit 2
> +fi
> +if [ -z "${compiler}" ]; then
> +    echo "error: no compiler provided."
> +    exit 2
> +fi
> +if [ -z "${name}" ]; then
> +    echo "error: no name found."
> +    exit 2
> +fi
> +
> +#
> +# Header file.
> +#
> +if [ ${op} = "header" ]; then
> +    inc_paths=$(echo | ${compiler} ${includes} -xc -E -v - 2>&1 | \
> +	       awk 'BEGIN {flag=0;} /starts here/{flag=1;next}/End/{flag=0}flag')
> +    for p in ${inc_paths}
> +    do
> +	if [ ${verbose} = yes ]; then
> +	    echo "Include: ${p}"
> +	fi
> +	if [ -f "${p}/${name}" ]; then
> +	    echo "found"
> +	    exit 0
> +	fi
> +    done
> +    echo "not-found"
> +    exit 0
> +fi
> +
> +#
> +# Library file
> +#
> +if [ ${op} = "library" ]; then
> +    if [ "${OS}" = "Windows_NT" ]; then
> +	sep=';'
> +    else
> +	sep=':'
> +    fi
> +    lib_paths_1=$(${compiler} -print-search-dirs 2>&1 | \
> +		      grep libraries | \
> +		      sed -e 's/libraries:.*=//' | \
> +		      awk 'BEGIN {FS="'${sep}'"} {for (i=0;++i<=NF;) print $i;}')
> +    lib_paths_2=$(echo ${libraries} | \
> +		      awk 'BEGIN {FS="-L"} {for (i=0;++i<=NF;) if (length($i) > 0) print $i;}')
> +    for p in ${lib_paths_1} ${lib_paths_2}
> +    do
> +	if [ ${verbose} = yes ]; then
> +	    echo "Library: ${p}/${name}"
> +	fi
> +	if ls ${p}/${name} 1> /dev/null 2>&1; then
> +	    echo "found"
> +	    exit 0
> +	fi
> +    done
> +    echo "not-found"
> +    exit 0
> +fi
> +
> +exit 1
> diff --git a/source-builder/sb/windows.py b/source-builder/sb/windows.py
> index f4eb85c..0eabf9c 100644
> --- a/source-builder/sb/windows.py
> +++ b/source-builder/sb/windows.py
> @@ -1,6 +1,6 @@
>  #
>  # RTEMS Tools Project (http://www.rtems.org/)
> -# Copyright 2010-2013 Chris Johns (chrisj at rtems.org)
> +# Copyright 2010-2018 Chris Johns (chrisj at rtems.org)
>  # All rights reserved.
>  #
>  # This file is part of the RTEMS Tools package in 'rtems-tools'.
> @@ -21,12 +21,12 @@
>  # Windows specific support and overrides.
>  #
>  
> -import error
> -import pprint
>  import os
>  import sys
>  
> +import error
>  import execute
> +import path
>  
>  def load():
>      # Default to the native Windows Python.
> @@ -146,13 +146,19 @@ def load():
>      #  6. W64/Python2 - Ok if machsize is 32
>      #  7. W64/Python3 - gdb-7.9 needs python2.
>      #
> -    if sys.platform == 'win32' and 'MSC' in sys.version:
> -        raise error.general('python.org Pythons are built with MSC and cannot be linked with GDB')
> -
> +    # Find a suitable python2 and python3.
> +    #
> +    for p in os.environ['PATH'].split(os.pathsep):
> +        sh = os.path.join(p, 'sh.exe')
> +        if os.path.exists(sh) and os.path.isfile(sh):
> +            break
> +        sh = None
> +    if sh is None:
> +        raise error.general('cannot find a shell (sh.exe) in the PATH')
>      #
>      # Search the MSYS2 install tree for a suitable python.
>      #
> -    if sys.platform == 'msys':
> +    if sys.platform == 'msys' or True:
>          e = execute.capture_execution()
>          exit_code, proc, output = e.shell("sh -c mount")
>          if exit_code != 0:
> @@ -166,23 +172,19 @@ def load():
>              raise error.general('cannot locate MSYS root mount point')
>          if install_point[1] != ':':
>              raise error.general('invalid MSYS root mount point: %s' % install_point)
> -        install_point = '/%s%s' % (install_point[0], install_point[2:])
> -        bin = '/mingw%s/bin' % (machsize)
> -        bin_list = os.listdir(bin)
> -        exe = None
> -        for python in ['python2.exe']:
> -            for f in bin_list:
> -                if f == python:
> -                    exe = install_point + os.path.join(bin, f)
> -                    break;
> -            if exe is not None:
> -                break
> -        if exe is None:
> -            raise error.general('no valid python found; you need a mingw%s python2 installed' % (machsize))
> -        defines['with_python_path'] = exe
> -
> +        install_point = path.shell(install_point)
> +        mingw = path.join(install_point, 'mingw%s' % (machsize))
> +        if not path.exists(mingw) or not path.isdir(mingw):
> +            raise error.general('cannot find MinGW install: %s' % (path.host(mingw)))
> +        for version in ['2', '3']:
> +            python = 'python%s' % (version)
> +            exe = path.join(mingw, 'bin', '%s.exe' % (python))
> +            if not path.exists(exe) or not path.isdir(exe):
> +                defines['gdb_python%s' % (version)] = exe
> +                header = path.join(mingw, python)
>  
>      return defines
>  
>  if __name__ == '__main__':
> +    import pprint
>      pprint.pprint(load())
> 



More information about the devel mailing list