Merge branch 'master' of ssh://kiwi/opt/work/sw/rtems/tb/source-builder
Merge the separate repo into a single master with the RTEMS source builder.
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*~
|
||||
*.pyc
|
69
config/autoconf-2-1.cfg
Normal file
@ -0,0 +1,69 @@
|
||||
#
|
||||
# Autoconf 2.xx Version 1.
|
||||
#
|
||||
# This configuration file configure's, make's and install's autoconf
|
||||
#
|
||||
|
||||
ifn %{defined _internal_autotools}
|
||||
%define _internal_autotools no
|
||||
%endfi
|
||||
|
||||
Name: autoconf-%{autoconf_version}-%{_host}-%{release}
|
||||
Summary: Autoconf v%{autoconf_version} for host %{_host}
|
||||
Version: %{autoconf_version}
|
||||
Release: %{release}
|
||||
URL: http://www.gnu.org/software/autoconf/
|
||||
BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
|
||||
|
||||
#
|
||||
# Source
|
||||
#
|
||||
Source0: ftp://ftp.gnu.org/gnu/autoconf/autoconf-%{autoconf_version}.tar.gz
|
||||
VersionControl0: git clone git://git.sv.gnu.org/autoconf
|
||||
|
||||
#
|
||||
# Prepare the source code.
|
||||
#
|
||||
%prep
|
||||
%setup -q -c -T -n %{name}-%{version}
|
||||
cd autoconf-%{autoconf_version}
|
||||
%{?patch0:%patch0 -p1}
|
||||
cd ..
|
||||
|
||||
%build
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
cd autoconf-%{autoconf_version}
|
||||
|
||||
if "%{_internal_autotools}" == "yes"; then
|
||||
ac_prefix=$SB_TMPPREFIX
|
||||
else
|
||||
ac_prefix=%{_prefix}
|
||||
fi
|
||||
|
||||
%if "%{_build}" != "%{_host}"
|
||||
CFLAGS_FOR_BUILD="-g -O2 -Wall" \
|
||||
%endif
|
||||
CFLAGS="$SB_OPT_FLAGS" \
|
||||
./configure \
|
||||
--build=%{_build} --host=%{_host} \
|
||||
--verbose --disable-nls \
|
||||
--without-included-gettext \
|
||||
--prefix=${ac_prefix}
|
||||
|
||||
%{__make} %{?_smp_mflags} all
|
||||
|
||||
cd ..
|
||||
|
||||
%install
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
rm -rf $SB_BUILD_ROOT
|
||||
|
||||
cd autoconf-%{autoconf_version}
|
||||
|
||||
if "%{_internal_autotools}" == "yes"; then
|
||||
%{__make} install
|
||||
else
|
||||
%{__make} DESTDIR=$SB_BUILD_ROOT install
|
||||
fi
|
||||
|
||||
cd ..
|
16
config/autoconf-2.68-1.cfg
Normal file
@ -0,0 +1,16 @@
|
||||
#
|
||||
# Autoconf 2.68.
|
||||
#
|
||||
|
||||
%if %{release} == %{nil}
|
||||
%define release 1
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/base.cfg
|
||||
|
||||
%define autoconf_version 2.68
|
||||
|
||||
#
|
||||
# The autoconf build instructions. We use 2.xx Release 1.
|
||||
#
|
||||
%include %{_configdir}/autoconf-2-1.cfg
|
16
config/autoconf-2.69-1.cfg
Normal file
@ -0,0 +1,16 @@
|
||||
#
|
||||
# Autoconf 2.22.
|
||||
#
|
||||
|
||||
%if %{release} == %{nil}
|
||||
%define release 1
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/base.cfg
|
||||
|
||||
%define autoconf_version 2.69
|
||||
|
||||
#
|
||||
# The autoconf build instructions. We use 2.xx Release 1.
|
||||
#
|
||||
%include %{_configdir}/autoconf-2-1.cfg
|
8
config/autoconf-internal-2.68-1.cfg
Normal file
@ -0,0 +1,8 @@
|
||||
#
|
||||
# Internal Autoconf 2.68.
|
||||
#
|
||||
|
||||
%warning This autoconf build is for internal bootstraps, no package created
|
||||
|
||||
%define _internal_autotools yes
|
||||
%include %{_configdir}/autoconf-2.68-1.cfg
|
69
config/automake-1-1.cfg
Normal file
@ -0,0 +1,69 @@
|
||||
#
|
||||
# Automake 1.xx Version 1.
|
||||
#
|
||||
# This configuration file configure's, make's and install's automake
|
||||
#
|
||||
|
||||
ifn %{defined _internal_autotools}
|
||||
%define _internal_autotools no
|
||||
%endfi
|
||||
|
||||
Name: automake-%{automake_version}-%{_host}-%{release}
|
||||
Summary: Automake v%{automake_version} for host %{_host}
|
||||
Version: %{automake_version}
|
||||
Release: %{release}
|
||||
URL: http://www.gnu.org/software/automake/
|
||||
BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
|
||||
|
||||
#
|
||||
# Source
|
||||
#
|
||||
Source0: ftp://ftp.gnu.org/gnu/automake/automake-%{automake_version}.tar.gz
|
||||
VersionControl0: git clone git://git.savannah.gnu.org/automake.git
|
||||
|
||||
#
|
||||
# Prepare the source code.
|
||||
#
|
||||
%prep
|
||||
%setup -q -c -T -n %{name}-%{version}
|
||||
cd automake-%{automake_version}
|
||||
%{?patch0:%patch0 -p1}
|
||||
cd ..
|
||||
|
||||
%build
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
|
||||
cd automake-%{automake_version}
|
||||
|
||||
if "%{_internal_autotools}" == "yes"; then
|
||||
am_prefix=$SB_TMPPREFIX
|
||||
else
|
||||
am_prefix=%{_prefix}
|
||||
fi
|
||||
|
||||
%if "%{_build}" != "%{_host}"
|
||||
CFLAGS_FOR_BUILD="-g -O2 -Wall" \
|
||||
%endif
|
||||
CFLAGS="$SB_OPT_FLAGS" \
|
||||
./configure \
|
||||
--build=%{_build} --host=%{_host} \
|
||||
--verbose \
|
||||
--prefix=${am_prefix}
|
||||
|
||||
%{__make} %{?_smp_mflags} all
|
||||
|
||||
cd ..
|
||||
|
||||
%install
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
rm -rf $SB_BUILD_ROOT
|
||||
|
||||
cd automake-%{automake_version}
|
||||
|
||||
if "%{_internal_autotools}" == "yes"; then
|
||||
%{__make} install
|
||||
else
|
||||
%{__make} DESTDIR=$SB_BUILD_ROOT install
|
||||
fi
|
||||
|
||||
cd ..
|
16
config/automake-1.12-1.cfg
Normal file
@ -0,0 +1,16 @@
|
||||
#
|
||||
# Automake 1.12
|
||||
#
|
||||
|
||||
%if %{release} == %{nil}
|
||||
%define release 1
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/base.cfg
|
||||
|
||||
%define automake_version 1.12
|
||||
|
||||
#
|
||||
# The automake build instructions. We use 1.xx Release 1.
|
||||
#
|
||||
%include %{_configdir}/automake-1-1.cfg
|
8
config/automake-internal-1.12-1.cfg
Normal file
@ -0,0 +1,8 @@
|
||||
#
|
||||
# Internal Automake 1.12
|
||||
#
|
||||
|
||||
%warning This automake build is for internal bootstraps, no package created
|
||||
|
||||
%define _internal_autotools yes
|
||||
%include %{_configdir}/automake-1.12-1.cfg
|
34
config/base.cfg
Normal file
@ -0,0 +1,34 @@
|
||||
#
|
||||
# Base set up for all configurations.
|
||||
#
|
||||
|
||||
# _prefix is set in the tool
|
||||
|
||||
%define _exec_prefix %{_prefix}
|
||||
%define _bindir %{_exec_prefix}/bin
|
||||
%define _sbindir %{_exec_prefix}/sbin
|
||||
%define _libexecdir %{_exec_prefix}/libexec
|
||||
%define _datarootdir %{_prefix}/share
|
||||
%define _datadir %{_datarootdir}
|
||||
%define _sysconfdir %{_prefix}/etc
|
||||
%define _sharedstatedir %{_prefix}/com
|
||||
%define _localstatedir %{_prefix}/var
|
||||
%define _includedir %{_prefix}/include
|
||||
%define _libdir %{_exec_prefix}/%{_lib}
|
||||
%define _mandir %{_datarootdir}/man
|
||||
%define _infodir %{_datarootdir}/info
|
||||
%define _localedir %{_datarootdir}/locale
|
||||
|
||||
%ifos mingw mingw32
|
||||
%define _exeext .exe
|
||||
%define debug_package %{nil}
|
||||
%define _libdir %{_exec_prefix}/lib
|
||||
%else
|
||||
%define _exeext %{nil}
|
||||
%endif
|
||||
|
||||
%if "%{_build}" != "%{_host}"
|
||||
%define _host_prefix %{_host}-
|
||||
%else
|
||||
%define _host_prefix %{nil}
|
||||
%endif
|
88
config/binutils-2-1.cfg
Normal file
@ -0,0 +1,88 @@
|
||||
#
|
||||
# Binutils 2.xx Version 1.
|
||||
#
|
||||
# This configuration file configure's, make's and install's binutils.
|
||||
#
|
||||
|
||||
%include %{_configdir}/checks.cfg
|
||||
|
||||
Name: %{_target}-binutils-%{binutils_version}-%{release}
|
||||
Summary: Binutils v%{binutils_version} for target %{_target} on host %{_host}
|
||||
Version: %{binutils_version}
|
||||
Release: %{release}
|
||||
URL: http://sources.redhat.com/binutils
|
||||
BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
|
||||
|
||||
#
|
||||
# Source
|
||||
#
|
||||
Source0: ftp://ftp.gnu.org/gnu/binutils/binutils-%{binutils_version}.tar.bz2
|
||||
VersionControl0: cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co binutils
|
||||
|
||||
#
|
||||
# Prepare the source code.
|
||||
#
|
||||
%prep
|
||||
%setup -q -c -T -n %{name}-%{version}
|
||||
%setup -q -D -T -n %{name}-%{version} -a0
|
||||
cd binutils-%{binutils_version}
|
||||
%{?patch0:%patch0 -p1}
|
||||
cd ..
|
||||
|
||||
%build
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
mkdir -p build
|
||||
cd build
|
||||
%if "%{_build}" != "%{_host}"
|
||||
CFLAGS_FOR_BUILD="-g -O2 -Wall" \
|
||||
%endif
|
||||
CFLAGS="$SB_OPT_FLAGS" \
|
||||
../binutils-%{binutils_version}/configure \
|
||||
--build=%{_build} --host=%{_host} \
|
||||
--target=%{_target} \
|
||||
--verbose --disable-nls \
|
||||
--without-included-gettext \
|
||||
--disable-win32-registry \
|
||||
--disable-werror \
|
||||
--prefix=%{_prefix} --bindir=%{_bindir} \
|
||||
--exec-prefix=%{_exec_prefix} \
|
||||
--includedir=%{_includedir} --libdir=%{_libdir} \
|
||||
--mandir=%{_mandir} --infodir=%{_infodir}
|
||||
|
||||
%{__make} %{?_smp_mflags} all
|
||||
cd ..
|
||||
|
||||
%install
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
rm -rf $SB_BUILD_ROOT
|
||||
|
||||
cd build
|
||||
%{__make} DESTDIR=$SB_BUILD_ROOT install
|
||||
|
||||
# Dropped in FSF-binutils-2.9.5, but Cygwin still ships it.
|
||||
rm -rf $SB_BUILD_ROOT%{_infodir}/configure.info*
|
||||
|
||||
rm -f $SB_BUILD_ROOT%{_infodir}/dir
|
||||
touch $SB_BUILD_ROOT%{_infodir}/dir
|
||||
|
||||
# binutils does not install share/locale, however it uses it
|
||||
mkdir -p $SB_BUILD_ROOT%{_prefix}/share/locale
|
||||
|
||||
# We don't ship host files
|
||||
rm -f ${SB_BUILD_ROOT}%{_libdir}/libiberty*
|
||||
|
||||
# manpages without corresponding tools
|
||||
if test ! -f ${SB_BUILD_ROOT}%{_bindir}/%{_target}-dlltool%{_exeext}; then
|
||||
rm -f ${SB_BUILD_ROOT}%{_mandir}/man1/%{_target}-dlltool*
|
||||
fi
|
||||
if test ! -f ${SB_BUILD_ROOT}%{_bindir}/%{_target}-nlmconv%{_exeext}; then
|
||||
rm -f ${SB_BUILD_ROOT}%{_mandir}/man1/%{_target}-nlmconv*
|
||||
fi
|
||||
if test ! -f ${SB_BUILD_ROOT}%{_bindir}/%{_target}-windres%{_exeext}; then
|
||||
rm -f ${SB_BUILD_ROOT}%{_mandir}/man1/%{_target}-windres*
|
||||
fi
|
||||
if test ! -f ${SB_BUILD_ROOT}%{_bindir}/%{_target}-windmc%{_exeext}; then
|
||||
rm -f ${SB_BUILD_ROOT}%{_mandir}/man1/%{_target}-windmc*
|
||||
fi
|
||||
|
||||
cd ..
|
17
config/binutils-2.22-1.cfg
Normal file
@ -0,0 +1,17 @@
|
||||
#
|
||||
# Binutils 2.22.
|
||||
#
|
||||
|
||||
%if %{release} == %{nil}
|
||||
%define release 1
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/checks.cfg
|
||||
%include %{_configdir}/base.cfg
|
||||
|
||||
%define binutils_version 2.22
|
||||
|
||||
#
|
||||
# The binutils build instructions. We use 2.xx Release 1.
|
||||
#
|
||||
%include %{_configdir}/binutils-2-1.cfg
|
11
config/checks.cfg
Normal file
@ -0,0 +1,11 @@
|
||||
#
|
||||
# Standard checks.
|
||||
#
|
||||
|
||||
%if %{_target} == %{nil}
|
||||
%error No 'target' defined
|
||||
%endif
|
||||
|
||||
%ifn %{defined release}
|
||||
%error No 'release' defined
|
||||
%endif
|
60
config/expat-2-1.cfg
Normal file
@ -0,0 +1,60 @@
|
||||
#
|
||||
# Expat 2.xx Version 1.
|
||||
#
|
||||
# This configuration file configure's, make's and install's expat.
|
||||
#
|
||||
|
||||
%if %{release} == %{nil}
|
||||
%define release 1
|
||||
%endif
|
||||
|
||||
Name: expat-%{expat_version}-%{_host}-%{release}
|
||||
Summary: Expat XML Parser v%{expat_version} for target %{_target} on host %{_host}
|
||||
Version: %{expat_version}
|
||||
Release: %{release}
|
||||
URL: http://expat.sourceforge.net/
|
||||
BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
|
||||
|
||||
#
|
||||
# Source
|
||||
#
|
||||
Source0: http://downloads.sourceforge.net/project/expat/expat/%{expat_version}/expat-%{expat_version}.tar.gz
|
||||
|
||||
#
|
||||
# Prepare the source code.
|
||||
#
|
||||
%prep
|
||||
%setup -q -c -T -n %{name}-%{version}
|
||||
cd expat-%{expat_version}
|
||||
%{?patch0:%patch0 -p1}
|
||||
cd ..
|
||||
|
||||
%build
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
cd expat-%{expat_version}
|
||||
|
||||
%if "%{_build}" != "%{_host}"
|
||||
CFLAGS_FOR_BUILD="-g -O2 -Wall" \
|
||||
%endif
|
||||
CFLAGS="$SB_OPT_FLAGS" \
|
||||
./configure \
|
||||
--build=%{_build} --host=%{_host} \
|
||||
--verbose --disable-nls \
|
||||
--without-included-gettext \
|
||||
--prefix=%{_prefix} --bindir=%{_bindir} \
|
||||
--exec-prefix=%{_exec_prefix} \
|
||||
--includedir=%{_includedir} --libdir=%{_libdir} \
|
||||
--mandir=%{_mandir} --infodir=%{_infodir}
|
||||
|
||||
%{__make} %{?_smp_mflags} all
|
||||
|
||||
cd ..
|
||||
|
||||
%install
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
rm -rf $SB_BUILD_ROOT
|
||||
|
||||
cd expat-%{expat_version}
|
||||
%{__make} DESTDIR=$SB_BUILD_ROOT install
|
||||
|
||||
cd ..
|
16
config/expat-2.1.0-1.cfg
Normal file
@ -0,0 +1,16 @@
|
||||
#
|
||||
# Expat 2.1.0
|
||||
#
|
||||
|
||||
%if %{release} == %{nil}
|
||||
%define release 1
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/base.cfg
|
||||
|
||||
%define expat_version 2.1.0
|
||||
|
||||
#
|
||||
# The Expat build instructions. We use 2.xx Release 1.
|
||||
#
|
||||
%include %{_configdir}/expat-2-1.cfg
|
186
config/gcc-4.4-1.cfg
Normal file
@ -0,0 +1,186 @@
|
||||
#
|
||||
# GCC 4.6 Version 1.
|
||||
#
|
||||
# This configuration file configure's, make's and install's gcc. It uses
|
||||
# newlib, MPFR, MPC, and GMP in a one-tree build configuration.
|
||||
#
|
||||
|
||||
#
|
||||
# Default to C++ on.
|
||||
#
|
||||
%ifn %{defined enable_cxx}
|
||||
%define enable_cxx 1
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/checks.cfg
|
||||
|
||||
%ifn %{defined gcc_version_message}
|
||||
%error No GCC Version message defined.
|
||||
%endif
|
||||
|
||||
Name: %{_target}-gcc-%{gcc_version}-newlib-%{newlib_version}-%{release}
|
||||
Summary: GCC v%{gcc_version} and Newlib v%{newlib_version} for target %{_target} on host %{_host}
|
||||
Version: %{gcc_version}
|
||||
Release: %{release}
|
||||
URL: http://gcc.gnu.org/
|
||||
BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
|
||||
|
||||
#
|
||||
# Source
|
||||
#
|
||||
#
|
||||
# GCC core and G++
|
||||
#
|
||||
Source0: ftp://ftp.gnu.org/gnu/gcc/gcc-%{gcc_version}/gcc-core-%{gcc_version}.tar.bz2
|
||||
VersionContro0: git clone git://gcc.gnu.org/git/gcc.git
|
||||
|
||||
%if %{enable_cxx}
|
||||
Source1: ftp://ftp.gnu.org/gnu/gcc/gcc-%{gcc_version}/gcc-g++-%{gcc_version}.tar.gz
|
||||
%endif
|
||||
|
||||
#
|
||||
# Newlib
|
||||
#
|
||||
Source10: ftp://sourceware.org/pub/newlib/newlib-%{newlib_version}.tar.gz
|
||||
VersionControl10: cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src co newlib
|
||||
|
||||
#
|
||||
# Packages GCC requires
|
||||
#
|
||||
Source20: http://www.mpfr.org/mpfr-%{mpfr_version}/mpfr-%{mpfr_version}.tar.bz2
|
||||
Source21: http://www.multiprecision.org/mpc/download/mpc-%{mpc_version}.tar.gz
|
||||
Source22: ftp://ftp.gnu.org/gnu/gmp/gmp-%{gmp_version}.tar.bz2
|
||||
|
||||
#
|
||||
# The GCC library directory
|
||||
#
|
||||
%global _gcclibdir %{_prefix}/lib
|
||||
|
||||
#
|
||||
# Prepare the source code.
|
||||
#
|
||||
%prep
|
||||
%setup -q -c -T -n %{name}-%{version}
|
||||
|
||||
# gcc core
|
||||
%setup -q -T -D -n %{name}-%{version} -a0
|
||||
cd gcc-%{gcc_version}
|
||||
%{?patch0:%patch0 -p1}
|
||||
cd ..
|
||||
|
||||
# g++
|
||||
%{?source1:%setup -q -T -D -n %{name}-%{version} -a1}
|
||||
cd gcc-%{gcc_version}
|
||||
%{?patch1:%patch1 -p1}
|
||||
cd ..
|
||||
|
||||
# newlib
|
||||
%setup -q -T -D -n %{name}-%{version} -a10
|
||||
cd newlib-%{newlib_version}
|
||||
%{?patch10:%patch10 -p1}
|
||||
cd ..
|
||||
# Link newlib into the gcc source tree
|
||||
ln -s ../newlib-%{newlib_version}/newlib gcc-%{gcc_version}
|
||||
|
||||
# MPFR
|
||||
%setup -q -T -D -n %{name}-%{version} -a20
|
||||
cd mpfr-%{mpfr_version}
|
||||
%{?patch20:%patch20 -p1}
|
||||
cd ..
|
||||
# Build MPFR one-tree style
|
||||
ln -s ../mpfr-%{mpfr_version} gcc-%{gcc_version}/mpfr
|
||||
|
||||
# MPC
|
||||
%setup -q -T -D -n %{name}-%{version} -a21
|
||||
cd mpc-%{mpc_version}
|
||||
%{?patch21:%patch21 -p1}
|
||||
cd ..
|
||||
# Build MPC one-tree style
|
||||
ln -s ../mpc-%{mpc_version} gcc-%{gcc_version}/mpc
|
||||
|
||||
# GMP
|
||||
%setup -q -T -D -n %{name}-%{version} -a22
|
||||
cd gmp-%{gmp_version}
|
||||
%{?patch22:%patch22 -p1}
|
||||
cd ..
|
||||
# Build GMP one-tree style
|
||||
ln -s ../gmp-%{gmp_version} gcc-%{gcc_version}/gmp
|
||||
|
||||
echo "%{gcc_version_message}" > gcc-%{gcc_version}/gcc/DEV-PHASE
|
||||
|
||||
# Fix timestamps
|
||||
cd gcc-%{gcc_version}
|
||||
contrib/gcc_update --touch
|
||||
cd ..
|
||||
|
||||
%build
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
mkdir -p build
|
||||
cd build
|
||||
languages="c"
|
||||
%if %{enable_cxx}
|
||||
languages="$languages,c++"
|
||||
%endif
|
||||
%if "%{_build}" != "%{_host}"
|
||||
CFLAGS_FOR_BUILD="-g -O2 -Wall" \
|
||||
CC="%{_host}-gcc ${SB_OPT_FLAGS}" \
|
||||
%else
|
||||
# gcc is not ready to be compiled with -std=gnu99
|
||||
CC=$(echo "%{__cc} ${SB_OPT_FLAGS}" | sed -e 's,-std=gnu99 ,,') \
|
||||
%endif
|
||||
../gcc-%{gcc_version}/configure \
|
||||
--prefix=%{_prefix} \
|
||||
--bindir=%{_bindir} \
|
||||
--exec_prefix=%{_exec_prefix} \
|
||||
--includedir=%{_includedir} \
|
||||
--libdir=%{_gcclibdir} \
|
||||
--libexecdir=%{_libexecdir} \
|
||||
--mandir=%{_mandir} \
|
||||
--infodir=%{_infodir} \
|
||||
--datadir=%{_datadir} \
|
||||
--build=%_build --host=%_host \
|
||||
--target=%{_target} \
|
||||
--disable-libstdcxx-pch \
|
||||
--with-gnu-as --with-gnu-ld --verbose \
|
||||
--with-newlib \
|
||||
--with-system-zlib \
|
||||
--disable-nls --without-included-gettext \
|
||||
--disable-win32-registry \
|
||||
--enable-version-specific-runtime-libs \
|
||||
--disable-lto \
|
||||
%{?with_threads:--enable-threads}%{!?with_threads:--disable-threads} \
|
||||
%{?with_plugin:--enable-plugin}%{!?with_plugin:--disable-plugin} \
|
||||
--enable-newlib-io-c99-formats \
|
||||
%{?with_iconv:--enable-newlib-iconv} \
|
||||
--enable-languages="$languages"
|
||||
|
||||
%if "%_host" != "%_build"
|
||||
# Bug in gcc-3.2.1:
|
||||
# Somehow, gcc doesn't get syslimits.h right for Cdn-Xs
|
||||
mkdir -p gcc/include
|
||||
cp ../gcc-%{gcc_version}/gcc/gsyslimits.h gcc/include/syslimits.h
|
||||
%endif
|
||||
|
||||
%{__make} %{?_smp_mflags} all
|
||||
cd ..
|
||||
|
||||
%install
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
rm -rf $SB_BUILD_ROOT
|
||||
|
||||
cd build
|
||||
%{__make} DESTDIR=$SB_BUILD_ROOT install
|
||||
cd ..
|
||||
|
||||
# libiberty doesn't honor --libdir, but always installs to a
|
||||
# magically guessed _libdir
|
||||
rm -f ${SB_BUILD_ROOT}%{_libdir}/libiberty.a
|
||||
|
||||
# We use the version from binutils
|
||||
rm -f $SB_BUILD_ROOT%{_bindir}/%{_target}-c++filt%{_exeext}
|
||||
|
||||
# We don't ship info/dir
|
||||
rm -f $SB_BUILD_ROOT%{_infodir}/dir
|
||||
|
||||
# Don't want libffi's man-pages
|
||||
rm -f $SB_BUILD_ROOT%{_mandir}/man3/*ffi*
|
186
config/gcc-4.6-1.cfg
Normal file
@ -0,0 +1,186 @@
|
||||
#
|
||||
# GCC 4.6 Version 1.
|
||||
#
|
||||
# This configuration file configure's, make's and install's gcc. It uses
|
||||
# newlib, MPFR, MPC, and GMP in a one-tree build configuration.
|
||||
#
|
||||
|
||||
#
|
||||
# Default to C++ on.
|
||||
#
|
||||
%ifn %{defined enable_cxx}
|
||||
%define enable_cxx 1
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/checks.cfg
|
||||
|
||||
%ifn %{defined gcc_version_message}
|
||||
%error No GCC Version message defined.
|
||||
%endif
|
||||
|
||||
Name: %{_target}-gcc-%{gcc_version}-newlib-%{newlib_version}-%{release}
|
||||
Summary: GCC v%{gcc_version} and Newlib v%{newlib_version} for target %{_target} on host %{_host}
|
||||
Version: %{gcc_version}
|
||||
Release: %{release}
|
||||
URL: http://gcc.gnu.org/
|
||||
BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
|
||||
|
||||
#
|
||||
# Source
|
||||
#
|
||||
#
|
||||
# GCC core and G++
|
||||
#
|
||||
Source0: ftp://ftp.gnu.org/gnu/gcc/gcc-%{gcc_version}/gcc-core-%{gcc_version}.tar.bz2
|
||||
VersionContro0: git clone git://gcc.gnu.org/git/gcc.git
|
||||
|
||||
%if %{enable_cxx}
|
||||
Source1: ftp://ftp.gnu.org/gnu/gcc/gcc-%{gcc_version}/gcc-g++-%{gcc_version}.tar.gz
|
||||
%endif
|
||||
|
||||
#
|
||||
# Newlib
|
||||
#
|
||||
Source10: ftp://sourceware.org/pub/newlib/newlib-%{newlib_version}.tar.gz
|
||||
VersionControl10: cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src co newlib
|
||||
|
||||
#
|
||||
# Packages GCC requires
|
||||
#
|
||||
Source20: http://www.mpfr.org/mpfr-%{mpfr_version}/mpfr-%{mpfr_version}.tar.bz2
|
||||
Source21: http://www.multiprecision.org/mpc/download/mpc-%{mpc_version}.tar.gz
|
||||
Source22: ftp://ftp.gnu.org/gnu/gmp/gmp-%{gmp_version}.tar.bz2
|
||||
|
||||
#
|
||||
# The GCC library directory
|
||||
#
|
||||
%global _gcclibdir %{_prefix}/lib
|
||||
|
||||
#
|
||||
# Prepare the source code.
|
||||
#
|
||||
%prep
|
||||
%setup -q -c -T -n %{name}-%{version}
|
||||
|
||||
# gcc core
|
||||
%setup -q -T -D -n %{name}-%{version} -a0
|
||||
cd gcc-%{gcc_version}
|
||||
%{?patch0:%patch0 -p1}
|
||||
cd ..
|
||||
|
||||
# g++
|
||||
%{?source1:%setup -q -T -D -n %{name}-%{version} -a1}
|
||||
cd gcc-%{gcc_version}
|
||||
%{?patch1:%patch1 -p1}
|
||||
cd ..
|
||||
|
||||
# newlib
|
||||
%setup -q -T -D -n %{name}-%{version} -a10
|
||||
cd newlib-%{newlib_version}
|
||||
%{?patch10:%patch10 -p1}
|
||||
cd ..
|
||||
# Link newlib into the gcc source tree
|
||||
ln -s ../newlib-%{newlib_version}/newlib gcc-%{gcc_version}
|
||||
|
||||
# MPFR
|
||||
%setup -q -T -D -n %{name}-%{version} -a20
|
||||
cd mpfr-%{mpfr_version}
|
||||
%{?patch20:%patch20 -p1}
|
||||
cd ..
|
||||
# Build MPFR one-tree style
|
||||
ln -s ../mpfr-%{mpfr_version} gcc-%{gcc_version}/mpfr
|
||||
|
||||
# MPC
|
||||
%setup -q -T -D -n %{name}-%{version} -a21
|
||||
cd mpc-%{mpc_version}
|
||||
%{?patch21:%patch21 -p1}
|
||||
cd ..
|
||||
# Build MPC one-tree style
|
||||
ln -s ../mpc-%{mpc_version} gcc-%{gcc_version}/mpc
|
||||
|
||||
# GMP
|
||||
%setup -q -T -D -n %{name}-%{version} -a22
|
||||
cd gmp-%{gmp_version}
|
||||
%{?patch22:%patch22 -p1}
|
||||
cd ..
|
||||
# Build GMP one-tree style
|
||||
ln -s ../gmp-%{gmp_version} gcc-%{gcc_version}/gmp
|
||||
|
||||
echo "%{gcc_version_message}" > gcc-%{gcc_version}/gcc/DEV-PHASE
|
||||
|
||||
# Fix timestamps
|
||||
cd gcc-%{gcc_version}
|
||||
contrib/gcc_update --touch
|
||||
cd ..
|
||||
|
||||
%build
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
mkdir -p build
|
||||
cd build
|
||||
languages="c"
|
||||
%if %{enable_cxx}
|
||||
languages="$languages,c++"
|
||||
%endif
|
||||
%if "%{_build}" != "%{_host}"
|
||||
CFLAGS_FOR_BUILD="-g -O2 -Wall" \
|
||||
CC="%{_host}-gcc ${SB_OPT_FLAGS}" \
|
||||
%else
|
||||
# gcc is not ready to be compiled with -std=gnu99
|
||||
CC=$(echo "%{__cc} ${SB_OPT_FLAGS}" | sed -e 's,-std=gnu99 ,,') \
|
||||
%endif
|
||||
../gcc-%{gcc_version}/configure \
|
||||
--prefix=%{_prefix} \
|
||||
--bindir=%{_bindir} \
|
||||
--exec_prefix=%{_exec_prefix} \
|
||||
--includedir=%{_includedir} \
|
||||
--libdir=%{_gcclibdir} \
|
||||
--libexecdir=%{_libexecdir} \
|
||||
--mandir=%{_mandir} \
|
||||
--infodir=%{_infodir} \
|
||||
--datadir=%{_datadir} \
|
||||
--build=%_build --host=%_host \
|
||||
--target=%{_target} \
|
||||
--disable-libstdcxx-pch \
|
||||
--with-gnu-as --with-gnu-ld --verbose \
|
||||
--with-newlib \
|
||||
--with-system-zlib \
|
||||
--disable-nls --without-included-gettext \
|
||||
--disable-win32-registry \
|
||||
--enable-version-specific-runtime-libs \
|
||||
--disable-lto \
|
||||
%{?with_threads:--enable-threads}%{!?with_threads:--disable-threads} \
|
||||
%{?with_plugin:--enable-plugin}%{!?with_plugin:--disable-plugin} \
|
||||
--enable-newlib-io-c99-formats \
|
||||
%{?with_iconv:--enable-newlib-iconv} \
|
||||
--enable-languages="$languages"
|
||||
|
||||
%if "%_host" != "%_build"
|
||||
# Bug in gcc-3.2.1:
|
||||
# Somehow, gcc doesn't get syslimits.h right for Cdn-Xs
|
||||
mkdir -p gcc/include
|
||||
cp ../gcc-%{gcc_version}/gcc/gsyslimits.h gcc/include/syslimits.h
|
||||
%endif
|
||||
|
||||
%{__make} %{?_smp_mflags} all
|
||||
cd ..
|
||||
|
||||
%install
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
rm -rf $SB_BUILD_ROOT
|
||||
|
||||
cd build
|
||||
%{__make} DESTDIR=$SB_BUILD_ROOT install
|
||||
cd ..
|
||||
|
||||
# libiberty doesn't honor --libdir, but always installs to a
|
||||
# magically guessed _libdir
|
||||
rm -f ${SB_BUILD_ROOT}%{_libdir}/libiberty.a
|
||||
|
||||
# We use the version from binutils
|
||||
rm -f $SB_BUILD_ROOT%{_bindir}/%{_target}-c++filt%{_exeext}
|
||||
|
||||
# We don't ship info/dir
|
||||
rm -f $SB_BUILD_ROOT%{_infodir}/dir
|
||||
|
||||
# Don't want libffi's man-pages
|
||||
rm -f $SB_BUILD_ROOT%{_mandir}/man3/*ffi*
|
21
config/gcc-4.6-newlib-1.20-1.cfg
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# GCC 2.6, Newlib 1.20
|
||||
#
|
||||
|
||||
%if %{release} == %{nil}
|
||||
%define release 1
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/checks.cfg
|
||||
%include %{_configdir}/base.cfg
|
||||
|
||||
%define gcc_version 4.6.3
|
||||
%define newlib_version 1.20.0
|
||||
%define mpfr_version 3.0.1
|
||||
%define mpc_version 0.8.2
|
||||
%define gmp_version 5.0.1
|
||||
|
||||
#
|
||||
# The gcc/newlib build instructions. We use 4.6 Release 1.
|
||||
#
|
||||
%include %{_configdir}/gcc-4.6-1.cfg
|
70
config/gdb-7-1.cfg
Normal file
@ -0,0 +1,70 @@
|
||||
#
|
||||
# GDB 7.xx Version 1.
|
||||
#
|
||||
# This configuration file configure's, make's and install's gdb.
|
||||
#
|
||||
|
||||
%include %{_configdir}/checks.cfg
|
||||
|
||||
Name: %{_target}-gdb-%{gdb_version}-%{release}
|
||||
Summary: GDB v%{gdb_version} for target %{_target} on host %{_host}
|
||||
Version: %{gdb_version}
|
||||
Release: %{release}
|
||||
URL: http://www.gnu.org/software/gdb/
|
||||
BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
|
||||
|
||||
#
|
||||
# Source
|
||||
#
|
||||
Source0: http://ftp.gnu.org/gnu/gdb/gdb-%{gdb_version}.tar.bz2
|
||||
VersionControl0 git clone git://sourceware.org/git/gdb.git
|
||||
|
||||
#
|
||||
# Prepare the source code.
|
||||
#
|
||||
%prep
|
||||
%setup -q -c -T -n %{name}-%{version}
|
||||
cd gdb-%{gdb_version}
|
||||
%{?patch0:%patch0 -p1}
|
||||
cd ..
|
||||
|
||||
%build
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
mkdir -p build
|
||||
cd build
|
||||
%if "%{_build}" != "%{_host}"
|
||||
CFLAGS_FOR_BUILD="-g -O2 -Wall" \
|
||||
%endif
|
||||
CFLAGS="$SB_OPT_FLAGS" \
|
||||
../gdb-%{gdb_version}/configure \
|
||||
--build=%{_build} --host=%{_host} \
|
||||
--target=%{_target} \
|
||||
--verbose --disable-nls \
|
||||
--without-included-gettext \
|
||||
--disable-win32-registry \
|
||||
--disable-werror \
|
||||
--enable-sim \
|
||||
--with-expat \
|
||||
--with-python \
|
||||
--prefix=%{_prefix} --bindir=%{_bindir} \
|
||||
--exec-prefix=%{_exec_prefix} \
|
||||
--includedir=%{_includedir} --libdir=%{_libdir} \
|
||||
--mandir=%{_mandir} --infodir=%{_infodir}
|
||||
|
||||
%{__make} %{?_smp_mflags} all
|
||||
cd ..
|
||||
|
||||
%install
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
rm -rf $SB_BUILD_ROOT
|
||||
|
||||
cd build
|
||||
%{__make} DESTDIR=$SB_BUILD_ROOT install
|
||||
|
||||
# Dropped in FSF-binutils-2.9.5, but Cygwin still ships it.
|
||||
rm -rf $SB_BUILD_ROOT%{_infodir}/configure.info*
|
||||
|
||||
rm -f $SB_BUILD_ROOT%{_infodir}/dir
|
||||
touch $SB_BUILD_ROOT%{_infodir}/dir
|
||||
|
||||
cd ..
|
17
config/gdb-7.5-1.cfg
Normal file
@ -0,0 +1,17 @@
|
||||
#
|
||||
# GDB 7.5.
|
||||
#
|
||||
|
||||
%if %{release} == %{nil}
|
||||
%define release 1
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/checks.cfg
|
||||
%include %{_configdir}/base.cfg
|
||||
|
||||
%define gdb_version 7.5
|
||||
|
||||
#
|
||||
# The gdb build instructions. We use 7.xx Release 1.
|
||||
#
|
||||
%include %{_configdir}/gdb-7-1.cfg
|
24
config/gnu-tools-4.6.bset
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# GNU Tools Set
|
||||
#
|
||||
|
||||
%define release 1
|
||||
|
||||
package: gnu-tool-%{_target}-%{release}
|
||||
|
||||
#
|
||||
# Project custom message
|
||||
#
|
||||
%define gcc_version_message SB-%{release},gcc-%{gcc_version}/newlib-%{newlib_version}
|
||||
|
||||
#
|
||||
# Enable G++
|
||||
#
|
||||
%define enable_cxx 1
|
||||
|
||||
#
|
||||
# Tool configuration.
|
||||
#
|
||||
binutils-2.22-1
|
||||
gcc-4.6-newlib-1.20-1
|
||||
gdb-7.5-1
|
61
config/libusb-1-1.cfg
Normal file
@ -0,0 +1,61 @@
|
||||
#
|
||||
# LibUSB 1.xx Version 1.
|
||||
#
|
||||
# This configuration file configure's, make's and install's libusb.
|
||||
#
|
||||
|
||||
%if %{release} == %{nil}
|
||||
%define release 1
|
||||
%endif
|
||||
|
||||
Summary: LibUSB v%{libusb_version} for target %{_target} on host %{_host}
|
||||
Version: %{libusb_version}
|
||||
Release: %{release}
|
||||
URL: http://libusb.org/
|
||||
BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
|
||||
|
||||
#
|
||||
# Source
|
||||
#
|
||||
Source0: http://downloads.sourceforge.net/project/libusb/libusb-1.0/libusb-%{libusb_version}/libusb-%{libusb_version}.tar.bz2
|
||||
VersionControl0: git clone git://git.libusb.org/libusb.git
|
||||
|
||||
#
|
||||
# Prepare the source code.
|
||||
#
|
||||
%prep
|
||||
%setup -q -c -T -n %{name}-%{version}
|
||||
%setup -q -D -T -n %{name}-%{version} -a0
|
||||
cd libusb-%{libusb_version}
|
||||
%{?patch0:%patch0 -p1}
|
||||
cd ..
|
||||
|
||||
%build
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
cd libusb-%{libusb_version}
|
||||
|
||||
%if "%{_build}" != "%{_host}"
|
||||
CFLAGS_FOR_BUILD="-g -O2 -Wall" \
|
||||
%endif
|
||||
CFLAGS="$SB_OPT_FLAGS" \
|
||||
./configure \
|
||||
--build=%{_build} --host=%{_host} \
|
||||
--verbose --disable-nls \
|
||||
--without-included-gettext \
|
||||
--prefix=%{_prefix} --bindir=%{_bindir} \
|
||||
--exec-prefix=%{_exec_prefix} \
|
||||
--includedir=%{_includedir} --libdir=%{_libdir} \
|
||||
--mandir=%{_mandir} --infodir=%{_infodir}
|
||||
|
||||
%{__make} %{?_smp_mflags} all
|
||||
|
||||
cd ..
|
||||
|
||||
%install
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
rm -rf $SB_BUILD_ROOT
|
||||
|
||||
cd libusb-%{libusb_version}
|
||||
%{__make} DESTDIR=$SB_BUILD_ROOT install
|
||||
|
||||
cd ..
|
21
config/libusb-1.0.9-1.cfg
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# LibUSB 1.0.9
|
||||
#
|
||||
|
||||
%ifn %{defined release}
|
||||
%error No 'release' defined
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/base.cfg
|
||||
|
||||
%define libusb_version 1.0.9
|
||||
|
||||
Name: libusb-%{libusb_version}-%{_host}-%{release}
|
||||
|
||||
%description
|
||||
LibUSB for host %{_host}.
|
||||
|
||||
#
|
||||
# The Libuxb build instructions. We use 1.xx Release 1.
|
||||
#
|
||||
%include %{_configdir}/libusb-1-1.cfg
|
56
config/m4-1-1.cfg
Normal file
@ -0,0 +1,56 @@
|
||||
#
|
||||
# M4 1.xx Version 1.
|
||||
#
|
||||
# This configuration file configure's, make's and install's m4
|
||||
#
|
||||
# Warning: this package is only for bootstrapping within a build.
|
||||
#
|
||||
|
||||
|
||||
Name: m4-%{m4_version}-%{_host}-%{release}
|
||||
Summary: M4 v%{m4_version} for host %{_host}
|
||||
Version: %{m4_version}
|
||||
Release: %{release}
|
||||
URL: http://www.gnu.org/software/m4/
|
||||
BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
|
||||
|
||||
#
|
||||
# Source
|
||||
#
|
||||
Source0: ftp://ftp.gnu.org/gnu/m4/m4-%{m4_version}.tar.gz
|
||||
|
||||
#
|
||||
# Prepare the source code.
|
||||
#
|
||||
%prep
|
||||
%setup -q -c -T -n %{name}-%{version}
|
||||
cd m4-%{m4_version}
|
||||
%{?patch0:%patch0 -p1}
|
||||
cd ..
|
||||
|
||||
%build
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
cd m4-%{m4_version}
|
||||
|
||||
%if "%{_build}" != "%{_host}"
|
||||
CFLAGS_FOR_BUILD="-g -O2 -Wall" \
|
||||
%endif
|
||||
CFLAGS="$SB_OPT_FLAGS" \
|
||||
./configure \
|
||||
--build=%{_build} --host=%{_host} \
|
||||
--verbose --disable-nls \
|
||||
--without-included-gettext \
|
||||
--prefix=$SB_TMPPREFIX
|
||||
|
||||
%{__make} %{?_smp_mflags} all
|
||||
|
||||
cd ..
|
||||
|
||||
%install
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
rm -rf $SB_BUILD_ROOT
|
||||
|
||||
cd m4-%{m4_version}
|
||||
%{__make} install
|
||||
|
||||
cd ..
|
16
config/m4-1.4.16-1.cfg
Normal file
@ -0,0 +1,16 @@
|
||||
#
|
||||
# M4 1.4.16
|
||||
#
|
||||
|
||||
%if %{release} == %{nil}
|
||||
%define release 1
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/base.cfg
|
||||
|
||||
%define m4_version 1.4.16
|
||||
|
||||
#
|
||||
# The m4 build instructions. We use 1.x.x Release 1.
|
||||
#
|
||||
%include %{_configdir}/m4-1-1.cfg
|
71
config/texane-stlink-1.cfg
Normal file
@ -0,0 +1,71 @@
|
||||
#
|
||||
# ST-Link Version 1.
|
||||
#
|
||||
# This configuration file configure's, make's and install's SL-Link.
|
||||
#
|
||||
|
||||
%if %{release} == %{nil}
|
||||
%define release 1
|
||||
%endif
|
||||
|
||||
%include %{_configdir}/base.cfg
|
||||
|
||||
%define stlink_version 3494c11
|
||||
|
||||
Name: texane-stlink-%{stlink_version}-%{release}
|
||||
Summary: ST-Link v%{stlink_version} for host %{_host}
|
||||
Version: %{stlink_version}
|
||||
Release: %{release}
|
||||
URL: https://github.com/texane/stlink/
|
||||
BuildRoot: %{_tmppath}/%{name}-root-%(%{__id_u} -n)
|
||||
|
||||
#
|
||||
# Source
|
||||
#
|
||||
Source0: https://api.github.com/repos/texane/stlink/texane-stlink-%{stlink_version}.tar.gz
|
||||
VersionControl0: git clone https://github.com/texane/stlink.git
|
||||
Patch0: texane-stlink-3494c11-1.diff
|
||||
|
||||
#
|
||||
# Prepare the source code.
|
||||
#
|
||||
%prep
|
||||
%setup -q -c -T -n %{name}-%{version}
|
||||
%setup -q -D -T -n %{name}-%{version} -a0
|
||||
cd texane-stlink-%{stlink_version}
|
||||
%{?patch0:%patch0 -p1}
|
||||
cd ..
|
||||
|
||||
%build
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
|
||||
cd texane-stlink-%{stlink_version}
|
||||
|
||||
./autogen.sh
|
||||
|
||||
%if "%{_build}" != "%{_host}"
|
||||
CFLAGS_FOR_BUILD="-g -O2 -Wall" \
|
||||
%endif
|
||||
CPPFLAGS="-I $SB_TMPPREFIX/include/libusb-1.0" \
|
||||
CFLAGS="$SB_OPT_FLAGS" \
|
||||
LDFLAGS="-L $SB_TMPPREFIX/lib" \
|
||||
./configure \
|
||||
--build=%{_build} --host=%{_host} \
|
||||
--verbose \
|
||||
--prefix=%{_prefix} --bindir=%{_bindir} \
|
||||
--exec-prefix=%{_exec_prefix} \
|
||||
--includedir=%{_includedir} --libdir=%{_libdir} \
|
||||
--mandir=%{_mandir} --infodir=%{_infodir}
|
||||
|
||||
%{__make} %{?_smp_mflags} all
|
||||
|
||||
cd ..
|
||||
|
||||
%install
|
||||
export PATH="%{_bindir}:${PATH}"
|
||||
rm -rf $TB_BUILD_ROOT
|
||||
|
||||
cd texane-stlink-%{stlink_version}
|
||||
%{__make} DESTDIR=$TB_BUILD_ROOT install
|
||||
|
||||
cd ..
|
2
doc/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.lock-*
|
||||
build
|
5
doc/images/icons/README
Normal file
@ -0,0 +1,5 @@
|
||||
Replaced the plain DocBook XSL admonition icons with Jimmac's DocBook
|
||||
icons (http://jimmac.musichall.cz/ikony.php3). I dropped transparency
|
||||
from the Jimmac icons to get round MS IE and FOP PNG incompatibilies.
|
||||
|
||||
Stuart Rackham
|
BIN
doc/images/icons/callouts/1.png
Normal file
After Width: | Height: | Size: 329 B |
BIN
doc/images/icons/callouts/10.png
Normal file
After Width: | Height: | Size: 361 B |
BIN
doc/images/icons/callouts/11.png
Normal file
After Width: | Height: | Size: 565 B |
BIN
doc/images/icons/callouts/12.png
Normal file
After Width: | Height: | Size: 617 B |
BIN
doc/images/icons/callouts/13.png
Normal file
After Width: | Height: | Size: 623 B |
BIN
doc/images/icons/callouts/14.png
Normal file
After Width: | Height: | Size: 411 B |
BIN
doc/images/icons/callouts/15.png
Normal file
After Width: | Height: | Size: 640 B |
BIN
doc/images/icons/callouts/2.png
Normal file
After Width: | Height: | Size: 353 B |
BIN
doc/images/icons/callouts/3.png
Normal file
After Width: | Height: | Size: 350 B |
BIN
doc/images/icons/callouts/4.png
Normal file
After Width: | Height: | Size: 345 B |
BIN
doc/images/icons/callouts/5.png
Normal file
After Width: | Height: | Size: 348 B |
BIN
doc/images/icons/callouts/6.png
Normal file
After Width: | Height: | Size: 355 B |
BIN
doc/images/icons/callouts/7.png
Normal file
After Width: | Height: | Size: 344 B |
BIN
doc/images/icons/callouts/8.png
Normal file
After Width: | Height: | Size: 357 B |
BIN
doc/images/icons/callouts/9.png
Normal file
After Width: | Height: | Size: 357 B |
BIN
doc/images/icons/caution.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
doc/images/icons/example.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
doc/images/icons/home.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
doc/images/icons/important.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
doc/images/icons/next.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
doc/images/icons/note.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
doc/images/icons/prev.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
doc/images/icons/tip.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
doc/images/icons/up.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
doc/images/icons/warning.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
doc/images/rtemswhitebg.jpg
Normal file
After Width: | Height: | Size: 115 KiB |
214
doc/source-builder.txt
Normal file
@ -0,0 +1,214 @@
|
||||
Source Builder
|
||||
==============
|
||||
Chris Johns <chrisj@rtems.org>
|
||||
1.0, November 2012
|
||||
:doctype: book
|
||||
:toc:
|
||||
:icons:
|
||||
:numbered:
|
||||
|
||||
image:images/rtemswhitebg.jpg["RTEMS",width="20%"]
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The Source Builder is a tool to aid building packages from source. It is not a
|
||||
package manager. It is just helps consolidate the details that you need to know
|
||||
to build a package from source. The tool is mainly aimed at those users who
|
||||
need to maintain tool sets for embedded type development, that is
|
||||
cross-compiled compiled tool chains, debuggers, and debugging aids. It is not
|
||||
limited to this role but designed to fit with-in that specific niche.
|
||||
|
||||
The Source Builder attempts to support any host environment that runs Python
|
||||
and you can build the package on. It is not some sort of magic that can take
|
||||
any piece of source code and make it build. Someone at some point in time has
|
||||
figured out how to build that package from source and taught this tool.
|
||||
|
||||
The Source Builder has two types configuration data. The first is configuration
|
||||
files and these are scripts based on the RPM spec file format that detail the
|
||||
steps needed to build a package. The steps are 'preparation', 'building', and
|
||||
'installing'. The second set of configuration files are 'build sets'. A build
|
||||
set describes a collection of packages you want built together. For example the
|
||||
GNU tool set is autoconf, automake, binutils, gcc, and gdb. This is the typical
|
||||
suite of tools you need for an embedded cross-development type project.
|
||||
|
||||
The Source Builder does not interact with any host package management
|
||||
system. There is no automatic dependence checking between various packages you
|
||||
build or your host system may have installed. We assume you know what are doing
|
||||
or the build sets and configuration files you are using have been created by
|
||||
developers who do. A buld set should provide a known working configuration.
|
||||
|
||||
Why build from source ?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you are developing a system or product that has a long shelf life or is used
|
||||
in a critical piece of infastructure that has a long life cycle being able to
|
||||
build from source is important. It insulates the project from the fast ever
|
||||
changing world of the host development machines. If your tool set is binary and
|
||||
you have lost the ability to build it you have lost a degree of control and
|
||||
flexibility open source gives you. Fast moving host environments are
|
||||
fantastic. We have powerful multi-core computers with huge amounts of memory
|
||||
and state of the art operating systems to running on them. The product or
|
||||
project you are part of may need to be maintained well past the life time of
|
||||
these host. Being able to build from source an important and critical part of
|
||||
this process because you can move to a newer host and create an equivalent tool
|
||||
set.
|
||||
|
||||
Building from source provides you with control over the configuration of the
|
||||
package you are building. If all or the most important dependent parts are
|
||||
built from source you limit the exposure to host variations. For example the
|
||||
GNU C compiler (gcc) currently uses a number of 3rd party libraries internally
|
||||
(gmp, mpfr, etc). If your validated compiler generating code for your target
|
||||
processor is dynamically linked against the host's version of these libraries
|
||||
any change in the host's configuration may effect you. The changes the host's
|
||||
package management system makes may be perfectly reasonible in relation to the
|
||||
distribution being managed how-ever this may not extend to you and your
|
||||
tools. Building your tools from source and controlling the specific version of
|
||||
these dependent parts means you are not exposing yourself to unexpected and
|
||||
often difficult to resolve problems. On the other side you need to make sure
|
||||
your tools build and work with newer versions of the host operating
|
||||
sytem. Given the stability of standards based libraries like 'libc' and ever
|
||||
improving support for standard header file locations this task is becoming
|
||||
easier.
|
||||
|
||||
History
|
||||
~~~~~~~
|
||||
|
||||
The Source Builder is a stand alone tool based on another tool called the
|
||||
'SpecBuilder'. The SpecBuilder was written for the RTEMS project too give me a
|
||||
way to build tools on hosts that did not support RPMs. At the time the RTEMS
|
||||
tools maintainer only used spec files to create various packages. This meant I
|
||||
had either spec files, RPM files or SRPM files. The RPM and SPRM files where
|
||||
useless because you needed an 'rpm' type tool to extract and manage them. There
|
||||
are versions of 'rpm' for a number of non-RPM hosts how-ever these proved to be
|
||||
in various broken states and randomally maintained. The solution I settled on
|
||||
was to use spec files so I wrote a Python based tool that parsed the spec file
|
||||
format and allowed me to create a shell script I could run to build the
|
||||
package. This approach proved successful and I was able to track the RPM
|
||||
version of the RTEMS tools on a non-RPM host over a number of years. How-ever
|
||||
the SpecBuilder tool did not help me build tools or other packages not related
|
||||
to the RTEMS project where there was no spec file I could use so I needed
|
||||
another tool. Rather than start again I decided to take the parsing code for
|
||||
the spec file format and build a new tool called the Source Builder.
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
|
||||
Check out the Source Builder tool from git:
|
||||
|
||||
-------------------------------------------------------------
|
||||
$ git clone git://git.rtems.org/source-builder.git
|
||||
-------------------------------------------------------------
|
||||
|
||||
The first step is to check if your host is set up correctly:
|
||||
|
||||
-------------------------------------------------------------
|
||||
$ source-builder/sb-check
|
||||
warning: exe: absolute exe found in path: (__objcopy) /usr/local/bin/objcopy <1>
|
||||
warning: exe: absolute exe found in path: (__objdump) /usr/local/bin/objdump
|
||||
error: exe: not found: (_xz) /usr/local/bin/xz <2>
|
||||
Source Builder environent is not correctly set up
|
||||
$ source-builder/sb-check
|
||||
Source Builder environent is ok <3>
|
||||
-------------------------------------------------------------
|
||||
|
||||
<1> A tool is in the environment path but does not match the shown path.
|
||||
<2> The executable 'xz' is not found.
|
||||
<3> The host's environment is set up correct.
|
||||
|
||||
If there are problems you are given a list of executables that cannot be
|
||||
found. You may also be given a list of warnings about executables not in the
|
||||
expected location how-ever the executable was located somewhere in your
|
||||
environment's path. You will need to check the specific host section to resolve
|
||||
these issues.
|
||||
|
||||
Create a suitable build directory away from the Source Builder source change
|
||||
into that directory and build a GNU tool set:
|
||||
|
||||
-------------------------------------------------------------
|
||||
$ mkdir gnu-tools <1>
|
||||
$ cd gnu-tools
|
||||
$ ../source-builder/sb-set-builder <2> --log=l.txt <3> --force <4> \
|
||||
--prefix=$HOME/gnu-tools-1 <5> --target=arm-eabi <6> gnu-toolset-4.6 <7>
|
||||
-------------------------------------------------------------
|
||||
|
||||
<1> Make a build directory you can delete when finished.
|
||||
<2> The Source Builder command to build a set of tools.
|
||||
<3> Capture the output to a log file.
|
||||
<4> The force option will create any needed directories and allow the build to
|
||||
proceed if your host is not set up.
|
||||
<5> Give the tools a suitable prefix. This is the location you install the
|
||||
tools into once they have built.
|
||||
<6> The gnu-toolset requires you set a target. In this case the tool set will
|
||||
be a generic unpatched version of GCC 4.6 for a bare metal the ARM processor.
|
||||
<7> The build set.
|
||||
|
||||
To view the build sets lets change to the RTEMS project's source builder
|
||||
configuration and then list the build sets:
|
||||
|
||||
-------------------------------------------------------------
|
||||
$ cd ../rtems-source-builder
|
||||
$ ../source-builder/sb-set-builder --list-bsets
|
||||
Source Builder - Set Builder, v0.1
|
||||
Examining: /usr/home/chris/development/rtems/src/rtems-source-builder/config <1>
|
||||
Examining: /usr/home/chris/development/rtems/src/source-builder/config <2>
|
||||
gnu-tools-4.6 <3>
|
||||
rtems-tools-4.10 <4>
|
||||
-------------------------------------------------------------
|
||||
|
||||
<1> The local RTEMS configuration directory. Searched first.
|
||||
<2> The Source Builder configuration directory.
|
||||
<3> The Source Builder provided GNU tools GCC 4.6 build set.
|
||||
<4> The RTEMS Source Builder provided RTEMS 4.10 build set.
|
||||
|
||||
And to view the configurations you can:
|
||||
|
||||
-------------------------------------------------------------
|
||||
$ ../source-builder/sb-set-builder --list-configs
|
||||
Source Builder - Set Builder, v0.1
|
||||
Examining: /usr/home/chris/development/rtems/src/rtems-source-builder/config
|
||||
Examining: /usr/home/chris/development/rtems/src/source-builder/config
|
||||
autoconf-2-1 <1>
|
||||
autoconf-2.68-1
|
||||
autoconf-2.69-1
|
||||
autoconf-internal-2.68-1
|
||||
automake-1-1
|
||||
automake-1.12-1
|
||||
automake-internal-1.12-1
|
||||
base
|
||||
binutils-2-1
|
||||
binutils-2.22-1
|
||||
checks
|
||||
expat-2-1
|
||||
expat-2.1.0-1
|
||||
gcc-4.4-1
|
||||
gcc-4.6-1
|
||||
gcc-4.6-newlib-1.20-1
|
||||
gdb-7-1
|
||||
gdb-7.5-1
|
||||
libusb-1-1
|
||||
libusb-1.0.9-1
|
||||
m4-1-1
|
||||
m4-1.4.16-1
|
||||
texane-stlink-1
|
||||
rtems-binutils-2.20.1-1
|
||||
rtems-gcc-4.4.7-newlib-1.18.0-1
|
||||
rtems-gdb-7.3.1-1
|
||||
-------------------------------------------------------------
|
||||
|
||||
<1> Configurations are built by using the builder. This creates a stand alone
|
||||
package.
|
||||
|
||||
The Source Builder
|
||||
------------------
|
||||
|
||||
The Source Builder provides a few generic build sets and the configuration
|
||||
support to build a number of packages. A project that uses the Source Builder
|
||||
can create a specialised set of configuration files that provides the specific
|
||||
configurations thet project uses.
|
||||
|
||||
For example the RTEMS project provides its own set of configuration files. In
|
||||
the build set list in the 'Quick Start' section you can see a build set
|
||||
+rtems-tools-4.10+. This build set defines the extact configration to use for
|
||||
the RTEMS 4.10 release.
|
||||
|
20
doc/wscript
Normal file
@ -0,0 +1,20 @@
|
||||
#
|
||||
# Waf build script to build the Source Builder Documentation.
|
||||
#
|
||||
|
||||
version = "1.0.0"
|
||||
|
||||
def configure(ctx):
|
||||
ctx.env.ASCIIDOC = ctx.find_program(['asciidoc.py'], mandatory = True)
|
||||
ctx.env.ASCIIDOC_FLAGS = ['-b', 'html', '-a', 'data-uri', '-a', 'icons', '-a', 'max-width=55em-a']
|
||||
|
||||
def build(ctx):
|
||||
ctx(target = 'source-builder.html', source = 'source-builder.txt')
|
||||
|
||||
import waflib.TaskGen
|
||||
waflib.TaskGen.declare_chain(name = 'html',
|
||||
rule = '${ASCIIDOC} ${ASCIIDOC_FLAGS} -o ${TGT} ${SRC}',
|
||||
shell = False,
|
||||
ext_in = '.txt',
|
||||
ext_out = '.html',
|
||||
reentrant = False)
|
13
patches/texane-stlink-3494c11-1.diff
Normal file
@ -0,0 +1,13 @@
|
||||
--- texane-stlink-3494c11.orig/configure.ac 2012-10-31 11:40:49.000000000 +1100
|
||||
+++ texane-stlink-3494c11/configure.ac 2012-10-31 10:34:57.000000000 +1100
|
||||
@@ -21,9 +21,7 @@
|
||||
AC_REPLACE_FUNCS(mmap)
|
||||
|
||||
# Checks for libraries.
|
||||
-PKG_CHECK_MODULES(USB, libusb-1.0 >= 1.0.0,,
|
||||
- AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***]))
|
||||
-AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb)
|
||||
+AC_CHECK_HEADER([libusb.h], [USB_LIBS="-lusb-1.0"])
|
||||
|
||||
LIBS="$LIBS $USB_LIBS"
|
||||
CFLAGS="$CFLAGS $USB_CFLAGS"
|
577
patches/texane-stlink-3494c11-2.diff
Normal file
@ -0,0 +1,577 @@
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 1f00f3a..eb140e5 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -21,9 +21,7 @@ AC_CHECK_HEADERS(sys/poll.h)
|
||||
AC_REPLACE_FUNCS(mmap)
|
||||
|
||||
# Checks for libraries.
|
||||
-PKG_CHECK_MODULES(USB, libusb-1.0 >= 1.0.0,,
|
||||
- AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***]))
|
||||
-AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb)
|
||||
+AC_CHECK_HEADER([libusb.h], [USB_LIBS="-lusb-1.0"])
|
||||
|
||||
LIBS="$LIBS $USB_LIBS"
|
||||
CFLAGS="$CFLAGS $USB_CFLAGS"
|
||||
diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c
|
||||
index 9d27ae4..fd25e8b 100644
|
||||
--- a/gdbserver/gdb-server.c
|
||||
+++ b/gdbserver/gdb-server.c
|
||||
@@ -1,11 +1,12 @@
|
||||
/* -*- tab-width:8 -*- */
|
||||
-#define DEBUG 0
|
||||
+
|
||||
/*
|
||||
Copyright (C) 2011 Peter Zotov <whitequark@whitequark.org>
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
+#include <stdarg.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -18,14 +19,15 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
-#include <signal.h>
|
||||
#endif
|
||||
+#include <signal.h>
|
||||
|
||||
#include <stlink-common.h>
|
||||
|
||||
#include "gdb-remote.h"
|
||||
|
||||
-#define DEFAULT_LOGGING_LEVEL 50
|
||||
+#define DEFAULT_LOGGING_LEVEL 0
|
||||
+#define LOGGING_LEVEL_GDBSERVER 2
|
||||
#define DEFAULT_GDB_LISTEN_PORT 4242
|
||||
|
||||
#define STRINGIFY_inner(name) #name
|
||||
@@ -40,24 +42,47 @@ static const char hex[] = "0123456789abcdef";
|
||||
|
||||
static const char* current_memory_map = NULL;
|
||||
|
||||
+FILE *my_stderr;
|
||||
+FILE *my_stdout;
|
||||
+
|
||||
typedef struct _st_state_t {
|
||||
- // things from command line, bleh
|
||||
- int stlink_version;
|
||||
- // "/dev/serial/by-id/usb-FTDI_TTL232R-3V3_FTE531X6-if00-port0" is only 58 chars
|
||||
- char devicename[100];
|
||||
- int logging_level;
|
||||
+ // things from command line, bleh
|
||||
+ int pipe;
|
||||
+ int stlink_version;
|
||||
+ // "/dev/serial/by-id/usb-FTDI_TTL232R-3V3_FTE531X6-if00-port0" is only 58 chars
|
||||
+ char devicename[100];
|
||||
+ int logging_level;
|
||||
int listen_port;
|
||||
} st_state_t;
|
||||
|
||||
+int logging_level = DEFAULT_LOGGING_LEVEL;
|
||||
+
|
||||
+int remote_desc = -1;
|
||||
+int remote_piping = 0;
|
||||
|
||||
-int serve(stlink_t *sl, int port);
|
||||
+int remote_open(int port);
|
||||
+int serve(stlink_t *sl);
|
||||
char* make_memory_map(stlink_t *sl);
|
||||
|
||||
+/*
|
||||
+ * Own printf and redirect when piping.
|
||||
+ */
|
||||
+int
|
||||
+printf (const char *format,...)
|
||||
+{
|
||||
+ int ret;
|
||||
+ va_list args;
|
||||
+ va_start (args, format);
|
||||
+ ret = vfprintf (my_stdout, format, args);
|
||||
+ fflush (my_stdout);
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
int parse_options(int argc, char** argv, st_state_t *st) {
|
||||
static struct option long_options[] = {
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"verbose", optional_argument, NULL, 'v'},
|
||||
+ {"pipe", no_argument, NULL, 'P'},
|
||||
{"device", required_argument, NULL, 'd'},
|
||||
{"stlink_version", required_argument, NULL, 's'},
|
||||
{"stlinkv1", no_argument, NULL, '1'},
|
||||
@@ -78,11 +103,10 @@ int parse_options(int argc, char** argv, st_state_t *st) {
|
||||
"(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n"
|
||||
;
|
||||
|
||||
-
|
||||
int option_index = 0;
|
||||
int c;
|
||||
int q;
|
||||
- while ((c = getopt_long(argc, argv, "hv::d:s:1p:", long_options, &option_index)) != -1) {
|
||||
+ while ((c = getopt_long(argc, argv, "hv::d:s:1Pp:", long_options, &option_index)) != -1) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n");
|
||||
@@ -96,12 +120,16 @@ int parse_options(int argc, char** argv, st_state_t *st) {
|
||||
printf(help_str, argv[0]);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
+ case 'P':
|
||||
+ st->pipe = 1;
|
||||
+ break;
|
||||
case 'v':
|
||||
if (optarg) {
|
||||
st->logging_level = atoi(optarg);
|
||||
} else {
|
||||
st->logging_level = DEFAULT_LOGGING_LEVEL;
|
||||
}
|
||||
+ logging_level = st->logging_level;
|
||||
break;
|
||||
case 'd':
|
||||
if (strlen(optarg) > sizeof (st->devicename)) {
|
||||
@@ -149,10 +177,21 @@ int main(int argc, char** argv) {
|
||||
st_state_t state;
|
||||
memset(&state, 0, sizeof(state));
|
||||
// set defaults...
|
||||
+ state.pipe = 0;
|
||||
state.stlink_version = 2;
|
||||
state.logging_level = DEFAULT_LOGGING_LEVEL;
|
||||
state.listen_port = DEFAULT_GDB_LISTEN_PORT;
|
||||
parse_options(argc, argv, &state);
|
||||
+
|
||||
+ my_stdout = stdout;
|
||||
+ my_stderr = stderr;
|
||||
+
|
||||
+ if (state.pipe) {
|
||||
+ my_stdout = my_stderr = stderr;
|
||||
+ state.listen_port = 0;
|
||||
+ remote_piping = 1;
|
||||
+ }
|
||||
+
|
||||
switch (state.stlink_version) {
|
||||
case 2:
|
||||
sl = stlink_open_usb(state.logging_level);
|
||||
@@ -162,7 +201,18 @@ int main(int argc, char** argv) {
|
||||
sl = stlink_v1_open(state.logging_level);
|
||||
if(sl == NULL) return 1;
|
||||
break;
|
||||
- }
|
||||
+ }
|
||||
+
|
||||
+#ifdef __MINGW32__
|
||||
+ if (!remote_piping) {
|
||||
+ WSADATA wsadata;
|
||||
+ if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) {
|
||||
+ goto winsock_error;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ remote_open(state.listen_port);
|
||||
|
||||
printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id);
|
||||
|
||||
@@ -170,18 +220,13 @@ int main(int argc, char** argv) {
|
||||
|
||||
current_memory_map = make_memory_map(sl);
|
||||
|
||||
-#ifdef __MINGW32__
|
||||
- WSADATA wsadata;
|
||||
- if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) {
|
||||
- goto winsock_error;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- while(serve(sl, state.listen_port) == 0);
|
||||
+ while(serve(sl) == 0);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
+ if (!remote_piping) {
|
||||
winsock_error:
|
||||
- WSACleanup();
|
||||
+ WSACleanup();
|
||||
+ }
|
||||
#endif
|
||||
|
||||
/* Switch back to mass storage mode before closing. */
|
||||
@@ -342,9 +387,8 @@ struct code_hw_watchpoint {
|
||||
struct code_hw_watchpoint data_watches[DATA_WATCH_NUM];
|
||||
|
||||
static void init_data_watchpoints(stlink_t *sl) {
|
||||
- #ifdef DEBUG
|
||||
- printf("init watchpoints\n");
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("init watchpoints\n");
|
||||
|
||||
// set trcena in debug command to turn on dwt unit
|
||||
stlink_write_debug32(sl, 0xE000EDFC,
|
||||
@@ -377,9 +421,8 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr
|
||||
for(i = 0; i < DATA_WATCH_NUM; i++) {
|
||||
// is this an empty slot ?
|
||||
if(data_watches[i].fun == WATCHDISABLED) {
|
||||
- #ifdef DEBUG
|
||||
- printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len);
|
||||
|
||||
data_watches[i].fun = wf;
|
||||
data_watches[i].addr = addr;
|
||||
@@ -401,9 +444,10 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr
|
||||
}
|
||||
}
|
||||
|
||||
- #ifdef DEBUG
|
||||
- printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len);
|
||||
- #endif
|
||||
+
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len);
|
||||
+
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -413,9 +457,8 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr)
|
||||
|
||||
for(i = 0 ; i < DATA_WATCH_NUM; i++) {
|
||||
if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) {
|
||||
- #ifdef DEBUG
|
||||
- printf("delete watchpoint %d addr %x\n", i, addr);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("delete watchpoint %d addr %x\n", i, addr);
|
||||
|
||||
data_watches[i].fun = WATCHDISABLED;
|
||||
stlink_write_debug32(sl, 0xe0001028 + i * 16, 0);
|
||||
@@ -424,9 +467,8 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr)
|
||||
}
|
||||
}
|
||||
|
||||
- #ifdef DEBUG
|
||||
- printf("failure: delete watchpoint addr %x\n", addr);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("failure: delete watchpoint addr %x\n", addr);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -485,20 +527,19 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) {
|
||||
else brk->type &= ~type;
|
||||
|
||||
if(brk->type == 0) {
|
||||
- #ifdef DEBUG
|
||||
- printf("clearing hw break %d\n", id);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("clearing hw break %d\n", id);
|
||||
|
||||
stlink_write_debug32(sl, 0xe0002008 + id * 4, 0);
|
||||
} else {
|
||||
uint32_t mask = (brk->addr) | 1 | (brk->type << 30);
|
||||
|
||||
- #ifdef DEBUG
|
||||
- printf("setting hw break %d at %08x (%d)\n",
|
||||
- id, brk->addr, brk->type);
|
||||
- printf("reg %08x \n",
|
||||
- mask);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER) {
|
||||
+ printf("setting hw break %d at %08x (%d)\n",
|
||||
+ id, brk->addr, brk->type);
|
||||
+ printf("reg %08x \n",
|
||||
+ mask);
|
||||
+ }
|
||||
|
||||
stlink_write_debug32(sl, 0xe0002008 + id * 4, mask);
|
||||
}
|
||||
@@ -589,9 +630,8 @@ static int flash_go(stlink_t *sl) {
|
||||
stlink_reset(sl);
|
||||
|
||||
for(struct flash_block* fb = flash_root; fb; fb = fb->next) {
|
||||
- #ifdef DEBUG
|
||||
- printf("flash_do: block %08x -> %04x\n", fb->addr, fb->length);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("flash_do: block %08x -> %04x\n", fb->addr, fb->length);
|
||||
|
||||
unsigned length = fb->length;
|
||||
for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) {
|
||||
@@ -599,9 +639,8 @@ static int flash_go(stlink_t *sl) {
|
||||
//Update FLASH_PAGE
|
||||
stlink_calculate_pagesize(sl, page);
|
||||
|
||||
- #ifdef DEBUG
|
||||
- printf("flash_do: page %08x\n", page);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("flash_do: page %08x\n", page);
|
||||
|
||||
if(stlink_write_flash(sl, page, fb->data + (page - fb->addr),
|
||||
length > FLASH_PAGE ? FLASH_PAGE : length) < 0)
|
||||
@@ -625,50 +664,74 @@ error:
|
||||
return error;
|
||||
}
|
||||
|
||||
-int serve(stlink_t *sl, int port) {
|
||||
- int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
- if(sock < 0) {
|
||||
- perror("socket");
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- unsigned int val = 1;
|
||||
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
|
||||
+int remote_open(int port) {
|
||||
+ int sock = -1;
|
||||
+ if (port == 0) {
|
||||
+ remote_desc = STDOUT_FILENO;
|
||||
+ remote_piping = 1;
|
||||
+ signal(SIGINT, SIG_IGN);
|
||||
+#ifdef __MINGW32__
|
||||
+ if (_setmode (_fileno( stdout ), _O_BINARY) < 0)
|
||||
+ fprintf(stderr, "cannot change stdout mode to binary");
|
||||
+ if (_setmode (_fileno( stdin ), _O_BINARY) < 0)
|
||||
+ fprintf(stderr, "cannot change stdin mode to binary");
|
||||
+#else
|
||||
+ signal(SIGIO, SIG_IGN);
|
||||
+ signal(SIGCHLD, SIG_IGN);
|
||||
+#endif
|
||||
+ }
|
||||
+ else {
|
||||
+ sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
+ if(sock < 0) {
|
||||
+ perror("socket");
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
- struct sockaddr_in serv_addr;
|
||||
- memset(&serv_addr,0,sizeof(struct sockaddr_in));
|
||||
- serv_addr.sin_family = AF_INET;
|
||||
- serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
- serv_addr.sin_port = htons(port);
|
||||
+ unsigned int val = 1;
|
||||
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
|
||||
|
||||
- if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
- perror("bind");
|
||||
- return 1;
|
||||
- }
|
||||
+ struct sockaddr_in serv_addr;
|
||||
+ memset(&serv_addr,0,sizeof(struct sockaddr_in));
|
||||
+ serv_addr.sin_family = AF_INET;
|
||||
+ serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
+ serv_addr.sin_port = htons(port);
|
||||
|
||||
- if(listen(sock, 5) < 0) {
|
||||
- perror("listen");
|
||||
- return 1;
|
||||
- }
|
||||
+ if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
+ perror("bind");
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
- stlink_force_debug(sl);
|
||||
- stlink_reset(sl);
|
||||
- init_code_breakpoints(sl);
|
||||
- init_data_watchpoints(sl);
|
||||
+ if(listen(sock, 5) < 0) {
|
||||
+ perror("listen");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- printf("Listening at *:%d...\n", port);
|
||||
+ if (!remote_piping) {
|
||||
+ printf("Listening at *:%d...\n", port);
|
||||
|
||||
- int client = accept(sock, NULL, NULL);
|
||||
- //signal (SIGINT, SIG_DFL);
|
||||
- if(client < 0) {
|
||||
- perror("accept");
|
||||
- return 1;
|
||||
- }
|
||||
+ remote_desc = accept(sock, NULL, NULL);
|
||||
+ //signal (SIGINT, SIG_DFL);
|
||||
+ if(remote_desc < 0) {
|
||||
+ perror("accept");
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
- close(sock);
|
||||
+ close(sock);
|
||||
+ }
|
||||
|
||||
printf("GDB connected.\n");
|
||||
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int serve(stlink_t *sl) {
|
||||
+
|
||||
+ stlink_force_debug(sl);
|
||||
+ stlink_reset(sl);
|
||||
+ init_code_breakpoints(sl);
|
||||
+ init_data_watchpoints(sl);
|
||||
+
|
||||
/*
|
||||
* To allow resetting the chip from GDB it is required to
|
||||
* emulate attaching and detaching to target.
|
||||
@@ -678,15 +741,14 @@ int serve(stlink_t *sl, int port) {
|
||||
while(1) {
|
||||
char* packet;
|
||||
|
||||
- int status = gdb_recv_packet(client, &packet);
|
||||
+ int status = gdb_recv_packet(remote_desc, &packet);
|
||||
if(status < 0) {
|
||||
fprintf(stderr, "cannot recv: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
|
||||
- #ifdef DEBUG
|
||||
- printf("recv: %s\n", packet);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("recv: %s\n", packet);
|
||||
|
||||
char* reply = NULL;
|
||||
reg regp;
|
||||
@@ -709,9 +771,8 @@ int serve(stlink_t *sl, int port) {
|
||||
char* queryName = calloc(queryNameLength + 1, 1);
|
||||
strncpy(queryName, &packet[1], queryNameLength);
|
||||
|
||||
- #ifdef DEBUG
|
||||
- printf("query: %s;%s\n", queryName, params);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("query: %s;%s\n", queryName, params);
|
||||
|
||||
if(!strcmp(queryName, "Supported")) {
|
||||
if(sl->chip_id==STM32_CHIPID_F4) {
|
||||
@@ -734,10 +795,9 @@ int serve(stlink_t *sl, int port) {
|
||||
unsigned addr = strtoul(__s_addr, NULL, 16),
|
||||
length = strtoul(s_length, NULL, 16);
|
||||
|
||||
- #ifdef DEBUG
|
||||
- printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n",
|
||||
- type, op, annex, addr, length);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n",
|
||||
+ type, op, annex, addr, length);
|
||||
|
||||
const char* data = NULL;
|
||||
|
||||
@@ -771,9 +831,8 @@ int serve(stlink_t *sl, int port) {
|
||||
|
||||
|
||||
if (!strncmp(params,"726573756d65",12)) {// resume
|
||||
-#ifdef DEBUG
|
||||
- printf("Rcmd: resume\n");
|
||||
-#endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("Rcmd: resume\n");
|
||||
stlink_run(sl);
|
||||
|
||||
reply = strdup("OK");
|
||||
@@ -782,9 +841,9 @@ int serve(stlink_t *sl, int port) {
|
||||
|
||||
stlink_force_debug(sl);
|
||||
|
||||
-#ifdef DEBUG
|
||||
- printf("Rcmd: halt\n");
|
||||
-#endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("Rcmd: halt\n");
|
||||
+
|
||||
} else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset
|
||||
reply = strdup("OK");
|
||||
|
||||
@@ -792,9 +851,9 @@ int serve(stlink_t *sl, int port) {
|
||||
stlink_jtag_reset(sl, 0);
|
||||
stlink_force_debug(sl);
|
||||
|
||||
-#ifdef DEBUG
|
||||
- printf("Rcmd: jtag_reset\n");
|
||||
-#endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("Rcmd: jtag_reset\n");
|
||||
+
|
||||
} else if (!strncmp(params,"7265736574",10)) { //reset
|
||||
reply = strdup("OK");
|
||||
|
||||
@@ -803,14 +862,12 @@ int serve(stlink_t *sl, int port) {
|
||||
init_code_breakpoints(sl);
|
||||
init_data_watchpoints(sl);
|
||||
|
||||
-#ifdef DEBUG
|
||||
- printf("Rcmd: reset\n");
|
||||
-#endif
|
||||
- } else {
|
||||
-#ifdef DEBUG
|
||||
- printf("Rcmd: %s\n", params);
|
||||
-#endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("Rcmd: reset\n");
|
||||
|
||||
+ } else {
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("Rcmd: %s\n", params);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -839,10 +896,9 @@ int serve(stlink_t *sl, int port) {
|
||||
unsigned addr = strtoul(__s_addr, NULL, 16),
|
||||
length = strtoul(s_length, NULL, 16);
|
||||
|
||||
- #ifdef DEBUG
|
||||
- printf("FlashErase: addr:%08x,len:%04x\n",
|
||||
- addr, length);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("FlashErase: addr:%08x,len:%04x\n",
|
||||
+ addr, length);
|
||||
|
||||
if(flash_add_block(addr, length, sl) < 0) {
|
||||
reply = strdup("E00");
|
||||
@@ -877,9 +933,8 @@ int serve(stlink_t *sl, int port) {
|
||||
if(dec_index % 2 != 0)
|
||||
dec_index++;
|
||||
|
||||
- #ifdef DEBUG
|
||||
- printf("binary packet %d -> %d\n", data_length, dec_index);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("binary packet %d -> %d\n", data_length, dec_index);
|
||||
|
||||
if(flash_populate(addr, decoded, dec_index) < 0) {
|
||||
reply = strdup("E00");
|
||||
@@ -908,7 +963,7 @@ int serve(stlink_t *sl, int port) {
|
||||
stlink_run(sl);
|
||||
|
||||
while(1) {
|
||||
- int status = gdb_check_for_interrupt(client);
|
||||
+ int status = gdb_check_for_interrupt(remote_desc);
|
||||
if(status < 0) {
|
||||
fprintf(stderr, "cannot check for int: %d\n", status);
|
||||
return 1;
|
||||
@@ -1190,11 +1245,10 @@ int serve(stlink_t *sl, int port) {
|
||||
}
|
||||
|
||||
if(reply) {
|
||||
- #ifdef DEBUG
|
||||
- printf("send: %s\n", reply);
|
||||
- #endif
|
||||
+ if (logging_level >= LOGGING_LEVEL_GDBSERVER)
|
||||
+ printf("send: %s\n", reply);
|
||||
|
||||
- int result = gdb_send_packet(client, reply);
|
||||
+ int result = gdb_send_packet(remote_desc, reply);
|
||||
if(result != 0) {
|
||||
fprintf(stderr, "cannot send: %d\n", result);
|
||||
return 1;
|
29
sb-builder
Executable file
@ -0,0 +1,29 @@
|
||||
#! /usr/bin/env python
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
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 >> sys.stderr, "Incorrect Source Builder installation"
|
||||
sys.exit(1)
|
29
sb-check
Executable file
@ -0,0 +1,29 @@
|
||||
#! /usr/bin/env python
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
import sys, os
|
||||
base = os.path.dirname(sys.argv[0])
|
||||
sys.path.insert(0, base + '/sb')
|
||||
try:
|
||||
import check
|
||||
check.run()
|
||||
except ImportError:
|
||||
print >> sys.stderr, "Incorrect Set Bulder installation"
|
||||
sys.exit(1)
|
29
sb-set-builder
Executable file
@ -0,0 +1,29 @@
|
||||
#! /usr/bin/env python
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
import sys, os
|
||||
base = os.path.dirname(sys.argv[0])
|
||||
sys.path.insert(0, base + '/sb')
|
||||
try:
|
||||
import setbuilder
|
||||
setbuilder.run()
|
||||
except ImportError:
|
||||
print >> sys.stderr, "Incorrect Set Bulder installation"
|
||||
sys.exit(1)
|
483
sb/build.py
Normal file
@ -0,0 +1,483 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
#
|
||||
# This code builds a package given a config file. It only builds to be
|
||||
# installed not to be package unless you run a packager around this.
|
||||
#
|
||||
|
||||
import getopt
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import stat
|
||||
import sys
|
||||
import urllib2
|
||||
import urlparse
|
||||
|
||||
import check
|
||||
import config
|
||||
import defaults
|
||||
import error
|
||||
import execute
|
||||
import log
|
||||
import path
|
||||
|
||||
#
|
||||
# Version of Sourcer Builder Build.
|
||||
#
|
||||
version = '0.1'
|
||||
|
||||
def _notice(opts, text):
|
||||
if not opts.quiet() and not log.default.has_stdout():
|
||||
print text
|
||||
log.output(text)
|
||||
log.flush()
|
||||
|
||||
class script:
|
||||
"""Create and manage a shell script."""
|
||||
|
||||
def __init__(self, quiet = True):
|
||||
self.quiet = quiet
|
||||
self.reset()
|
||||
|
||||
def reset(self):
|
||||
self.body = []
|
||||
self.lc = 0
|
||||
|
||||
def append(self, text):
|
||||
if type(text) is str:
|
||||
text = text.splitlines()
|
||||
if not self.quiet:
|
||||
i = 0
|
||||
for l in text:
|
||||
i += 1
|
||||
log.output('script:%3d: ' % (self.lc + i) + l)
|
||||
self.lc += len(text)
|
||||
self.body.extend(text)
|
||||
|
||||
def write(self, name, check_for_errors = False):
|
||||
s = None
|
||||
try:
|
||||
s = open(path.host(name), 'w')
|
||||
s.write('\n'.join(self.body))
|
||||
s.close()
|
||||
os.chmod(path.host(name), stat.S_IRWXU | \
|
||||
stat.S_IRGRP | stat.S_IXGRP | \
|
||||
stat.S_IROTH | stat.S_IXOTH)
|
||||
except IOError, err:
|
||||
raise error.general('creating script: ' + name)
|
||||
except:
|
||||
if s is not None:
|
||||
s.close()
|
||||
raise
|
||||
if s is not None:
|
||||
s.close()
|
||||
|
||||
class build:
|
||||
"""Build a package given a config file."""
|
||||
|
||||
def __init__(self, name, _defaults, opts):
|
||||
self.opts = opts
|
||||
_notice(opts, 'building: ' + name)
|
||||
self.config = config.file(name, _defaults = _defaults, opts = opts)
|
||||
self.script = script(quiet = opts.quiet())
|
||||
|
||||
def _output(self, text):
|
||||
if not self.opts.quiet():
|
||||
log.output(text)
|
||||
|
||||
def rmdir(self, rmpath):
|
||||
self._output('removing: %s' % (path.host(rmpath)))
|
||||
if not self.opts.dry_run():
|
||||
if path.exists(rmpath):
|
||||
try:
|
||||
shutil.rmtree(path.host(rmpath))
|
||||
except IOError, err:
|
||||
raise error.error('error removing: %s' % (rmpath))
|
||||
except WindowsError, err:
|
||||
_notice(self.opts, 'warning: cannot remove: %s' % (rmpath))
|
||||
|
||||
def mkdir(self, mkpath):
|
||||
self._output('making dir: %s' % (path.host(mkpath)))
|
||||
if not self.opts.dry_run():
|
||||
try:
|
||||
os.makedirs(path.host(mkpath))
|
||||
except IOError, err:
|
||||
_notice(self.opts, 'warning: cannot make directory: %s' % (mkpath))
|
||||
except WindowsError, err:
|
||||
_notice(self.opts, 'warning: cannot make directory: %s' % (mkpath))
|
||||
|
||||
def get_file(self, url, local):
|
||||
if local is None:
|
||||
raise error.general('source/patch path invalid')
|
||||
if not path.isdir(path.dirname(local)):
|
||||
if not self.opts.force():
|
||||
raise error.general('source path not found: %s; (--force to create)' \
|
||||
% (path.host(path.dirname(local))))
|
||||
self.mkdir(path.host(path.dirname(local)))
|
||||
if not path.exists(local):
|
||||
#
|
||||
# Not localy found so we need to download it. Check if a URL has
|
||||
# been provided on the command line.
|
||||
#
|
||||
url_bases = self.opts.urls()
|
||||
urls = []
|
||||
if url_bases is not None:
|
||||
for base in url_bases:
|
||||
if base[-1:] != '/':
|
||||
base += '/'
|
||||
url_path = urlparse.urlsplit(url)[2]
|
||||
slash = url_path.rfind('/')
|
||||
if slash < 0:
|
||||
url_file = url_path
|
||||
else:
|
||||
url_file = url_path[slash + 1:]
|
||||
urls.append(urlparse.urljoin(base, url_file))
|
||||
urls.append(url)
|
||||
if self.opts.trace():
|
||||
print '_url:', ','.join(urls), '->', local
|
||||
for url in urls:
|
||||
#
|
||||
# Hack for GitHub.
|
||||
#
|
||||
if url.startswith('https://api.github.com'):
|
||||
url = urlparse.urljoin(url, self.config.expand('tarball/%{version}'))
|
||||
_notice(self.opts, 'download: %s -> %s' % (url, path.host(local)))
|
||||
if not self.opts.dry_run():
|
||||
failed = False
|
||||
_in = None
|
||||
_out = None
|
||||
try:
|
||||
_in = urllib2.urlopen(url)
|
||||
_out = open(path.host(local), 'wb')
|
||||
_out.write(_in.read())
|
||||
except IOError, err:
|
||||
msg = 'download: %s: error: %s' % (url, str(err))
|
||||
_notice(self.opts, msg)
|
||||
if path.exists(local):
|
||||
os.remove(path.host(local))
|
||||
failed = True
|
||||
except:
|
||||
print >> sys.stderr, msg
|
||||
if _out is not None:
|
||||
_out.close()
|
||||
raise
|
||||
if _out is not None:
|
||||
_out.close()
|
||||
if _in is not None:
|
||||
del _in
|
||||
if not failed:
|
||||
if not path.isfile(local):
|
||||
raise error.general('source is not a file: %s' % (path.host(local)))
|
||||
return
|
||||
if not self.opts.dry_run():
|
||||
raise error.general('downloading %s: all paths have failed, giving up' % (url))
|
||||
|
||||
def parse_url(self, url, pathkey):
|
||||
#
|
||||
# Split the source up into the parts we need.
|
||||
#
|
||||
source = {}
|
||||
source['url'] = url
|
||||
source['path'] = path.dirname(url)
|
||||
source['file'] = path.basename(url)
|
||||
source['name'], source['ext'] = path.splitext(source['file'])
|
||||
#
|
||||
# Get the file. Checks the local source directory first.
|
||||
#
|
||||
source['local'] = None
|
||||
for p in self.config.define(pathkey).split(':'):
|
||||
local = path.join(path.abspath(p), source['file'])
|
||||
if source['local'] is None or path.exists(local):
|
||||
source['local'] = local
|
||||
break
|
||||
#
|
||||
# Is the file compressed ?
|
||||
#
|
||||
esl = source['ext'].split('.')
|
||||
if esl[-1:][0] == 'gz':
|
||||
source['compressed'] = '%{__gzip} -dc'
|
||||
elif esl[-1:][0] == 'bz2':
|
||||
source['compressed'] = '%{__bzip2} -dc'
|
||||
elif esl[-1:][0] == 'bz2':
|
||||
source['compressed'] = '%{__zip} -u'
|
||||
elif esl[-1:][0] == 'xz':
|
||||
source['compressed'] = '%{__xz} -dc'
|
||||
source['script'] = ''
|
||||
return source
|
||||
|
||||
def source(self, package, source_tag):
|
||||
#
|
||||
# Scan the sources found in the config file for the one we are
|
||||
# after. Infos or tags are lists.
|
||||
#
|
||||
sources = package.sources()
|
||||
url = None
|
||||
for s in sources:
|
||||
tag = s[len('source'):]
|
||||
if tag.isdigit():
|
||||
if int(tag) == source_tag:
|
||||
url = sources[s][0]
|
||||
break
|
||||
if url is None:
|
||||
raise error.general('source tag not found: source%d' % (source_tag))
|
||||
source = self.parse_url(url, '_sourcedir')
|
||||
self.get_file(source['url'], source['local'])
|
||||
if 'compressed' in source:
|
||||
source['script'] = source['compressed'] + ' ' + \
|
||||
source['local'] + ' | %{__tar_extract} -'
|
||||
else:
|
||||
source['script'] = '%{__tar_extract} ' + source['local']
|
||||
return source
|
||||
|
||||
def patch(self, package, args):
|
||||
#
|
||||
# Scan the patches found in the config file for the one we are
|
||||
# after. Infos or tags are lists.
|
||||
#
|
||||
patches = package.patches()
|
||||
url = None
|
||||
for p in patches:
|
||||
if args[0][1:].lower() == p:
|
||||
url = patches[p][0]
|
||||
break
|
||||
if url is None:
|
||||
raise error.general('patch tag not found: %s' % (args[0]))
|
||||
#
|
||||
# Parse the URL first in the source builder's patch directory.
|
||||
#
|
||||
patch = self.parse_url(url, '_patchdir')
|
||||
#
|
||||
# If not in the source builder package check the source directory.
|
||||
#
|
||||
if not path.exists(patch['local']):
|
||||
patch = self.parse_url(url, '_sourcedir')
|
||||
self.get_file(patch['url'], patch['local'])
|
||||
if 'compressed' in patch:
|
||||
patch['script'] = patch['compressed'] + ' ' + patch['local']
|
||||
else:
|
||||
patch['script'] = '%{__cat} ' + patch['local']
|
||||
patch['script'] += ' | %{__patch} ' + ' '.join(args[1:])
|
||||
self.script.append(self.config.expand(patch['script']))
|
||||
|
||||
def setup(self, package, args):
|
||||
self._output('prep: %s: %s' % (package.name(), ' '.join(args)))
|
||||
opts, args = getopt.getopt(args[1:], 'qDcTn:b:a:')
|
||||
source_tag = 0
|
||||
quiet = False
|
||||
unpack_default_source = True
|
||||
delete_before_unpack = True
|
||||
create_dir = False
|
||||
name = None
|
||||
unpack_before_chdir = True
|
||||
for o in opts:
|
||||
if o[0] == '-q':
|
||||
quiet = True
|
||||
elif o[0] == '-D':
|
||||
delete_before_unpack = False
|
||||
elif o[0] == '-c':
|
||||
create_dir = True
|
||||
elif o[0] == '-T':
|
||||
unpack_default_source = False
|
||||
elif o[0] == '-n':
|
||||
name = o[1]
|
||||
elif o[0] == '-b':
|
||||
unpack_before_chdir = True
|
||||
if not o[1].isdigit():
|
||||
raise error.general('setup source tag no a number: %s' % (o[1]))
|
||||
source_tag = int(o[1])
|
||||
elif o[0] == '-a':
|
||||
unpack_before_chdir = False
|
||||
source_tag = int(o[1])
|
||||
source0 = None
|
||||
source = self.source(package, source_tag)
|
||||
if name is None:
|
||||
if source:
|
||||
name = source['name']
|
||||
else:
|
||||
name = source0['name']
|
||||
self.script.append(self.config.expand('cd %{_builddir}'))
|
||||
if delete_before_unpack:
|
||||
self.script.append(self.config.expand('%{__rm} -rf ' + name))
|
||||
if create_dir:
|
||||
self.script.append(self.config.expand('%{__mkdir_p} ' + name))
|
||||
#
|
||||
# If -a? then change directory before unpacking.
|
||||
#
|
||||
if not unpack_before_chdir:
|
||||
self.script.append(self.config.expand('cd ' + name))
|
||||
#
|
||||
# Unpacking the source. Note, treated the same as -a0.
|
||||
#
|
||||
if unpack_default_source and source_tag != 0:
|
||||
source0 = self.source(package, 0)
|
||||
if source0 is None:
|
||||
raise error.general('no setup source0 tag found')
|
||||
self.script.append(self.config.expand(source0['script']))
|
||||
self.script.append(self.config.expand(source['script']))
|
||||
if unpack_before_chdir:
|
||||
self.script.append(self.config.expand('cd ' + name))
|
||||
self.script.append(self.config.expand('%{__setup_post}'))
|
||||
if create_dir:
|
||||
self.script.append(self.config.expand('cd ..'))
|
||||
|
||||
def run(self, command, shell_opts = '', cwd = None):
|
||||
e = execute.capture_execution(log = log.default, dump = self.opts.quiet())
|
||||
cmd = self.config.expand('%{___build_shell} -ex ' + shell_opts + ' ' + command)
|
||||
self._output('run: ' + cmd)
|
||||
exit_code, proc, output = e.shell(cmd, cwd = path.host(cwd))
|
||||
if exit_code != 0:
|
||||
raise error.general('shell cmd failed: ' + cmd)
|
||||
|
||||
def builddir(self):
|
||||
builddir = self.config.abspath('_builddir')
|
||||
self.rmdir(builddir)
|
||||
if not self.opts.dry_run():
|
||||
self.mkdir(builddir)
|
||||
|
||||
def prep(self, package):
|
||||
self.script.append('echo "==> %prep:"')
|
||||
_prep = package.prep()
|
||||
for l in _prep:
|
||||
args = l.split()
|
||||
if args[0] == '%setup':
|
||||
self.setup(package, args)
|
||||
elif args[0].startswith('%patch'):
|
||||
self.patch(package, args)
|
||||
else:
|
||||
self.script.append(' '.join(args))
|
||||
|
||||
def build(self, package):
|
||||
self.script.append('echo "==> %build:"')
|
||||
_build = package.build()
|
||||
for l in _build:
|
||||
args = l.split()
|
||||
self.script.append(' '.join(args))
|
||||
|
||||
def install(self, package):
|
||||
self.script.append('echo "==> %install:"')
|
||||
_install = package.install()
|
||||
for l in _install:
|
||||
args = l.split()
|
||||
self.script.append(' '.join(args))
|
||||
|
||||
def files(self, package):
|
||||
self.script.append('echo "==> %files:"')
|
||||
prefixbase = self.opts.prefixbase()
|
||||
if prefixbase is None:
|
||||
prefixbase = ''
|
||||
inpath = path.join('%{buildroot}', prefixbase)
|
||||
tardir = path.abspath(self.config.expand('%{_tardir}'))
|
||||
self.script.append(self.config.expand('if test -d %s; then' % (inpath)))
|
||||
self.script.append(' mkdir -p %s' % tardir)
|
||||
self.script.append(self.config.expand(' cd ' + inpath))
|
||||
tar = path.join(tardir, package.long_name() + '.tar.bz2')
|
||||
cmd = self.config.expand(' %{__tar} -cf - . ' + '| %{__bzip2} > ' + tar)
|
||||
self.script.append(cmd)
|
||||
self.script.append(self.config.expand(' cd %{_builddir}'))
|
||||
self.script.append('fi')
|
||||
|
||||
def clean(self, package):
|
||||
self.script.append('echo "==> %clean:"')
|
||||
_clean = package.clean()
|
||||
if _clean is not None:
|
||||
for l in _clean:
|
||||
args = l.split()
|
||||
self.script.append(' '.join(args))
|
||||
|
||||
def cleanup(self):
|
||||
if not self.opts.no_clean():
|
||||
buildroot = self.config.abspath('buildroot')
|
||||
builddir = self.config.abspath('_builddir')
|
||||
_notice(self.opts, 'cleanup: %s' % (buildroot))
|
||||
self.rmdir(buildroot)
|
||||
_notice(self.opts, 'cleanup: %s' % (builddir))
|
||||
self.rmdir(builddir)
|
||||
|
||||
def make(self):
|
||||
packages = self.config.packages()
|
||||
package = packages['main']
|
||||
name = package.name()
|
||||
_notice(self.opts, 'package: %s' % (name))
|
||||
self.script.reset()
|
||||
self.script.append(self.config.expand('%{___build_template}'))
|
||||
self.script.append('echo "=> ' + name + ':"')
|
||||
self.prep(package)
|
||||
self.build(package)
|
||||
self.install(package)
|
||||
self.files(package)
|
||||
if not self.opts.no_clean():
|
||||
self.clean(package)
|
||||
if not self.opts.dry_run():
|
||||
self.builddir()
|
||||
sn = path.join(self.config.expand('%{_builddir}'), 'doit')
|
||||
self._output('write script: ' + sn)
|
||||
self.script.write(sn)
|
||||
_notice(self.opts, 'building: ' + name)
|
||||
self.run(sn)
|
||||
|
||||
def name(self):
|
||||
packages = self.config.packages()
|
||||
package = packages['main']
|
||||
return package.name()
|
||||
|
||||
def list_configs(opts, _defaults, ext = '.cfg'):
|
||||
configs = []
|
||||
for cp in opts.expand('%{_configdir}', _defaults).split(':'):
|
||||
print 'Examining: %s' % (path.host(path.abspath(cp)))
|
||||
configs += glob.glob(path.host(path.join(cp, '*%s' % (ext))))
|
||||
for c in sorted(configs):
|
||||
config = path.basename(c)
|
||||
if config.endswith(ext):
|
||||
config = config[:0 - len(ext)]
|
||||
print ' ', config
|
||||
|
||||
def run(args):
|
||||
try:
|
||||
optargs = { '--list-configs': 'List available configurations' }
|
||||
opts, _defaults = defaults.load(args, optargs)
|
||||
log.default = log.log(opts.logfiles())
|
||||
_notice(opts, 'Source Builder, Package Builder v%s' % (version))
|
||||
if not check.host_setup(opts, _defaults):
|
||||
if not opts.force():
|
||||
raise error.general('host build environment is not set up correctly (use --force to proceed)')
|
||||
_notice(opts, 'warning: forcing build with known host setup problems')
|
||||
if opts.get_arg('--list-configs'):
|
||||
list_configs(opts, _defaults)
|
||||
else:
|
||||
for config_file in opts.config_files():
|
||||
b = build(config_file, _defaults = _defaults, opts = opts)
|
||||
b.make()
|
||||
del b
|
||||
except error.general, gerr:
|
||||
print gerr
|
||||
sys.exit(1)
|
||||
except error.internal, ierr:
|
||||
print ierr
|
||||
sys.exit(1)
|
||||
except error.exit, eerr:
|
||||
pass
|
||||
except KeyboardInterrupt:
|
||||
_notice(opts, 'user terminated')
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run(sys.argv)
|
157
sb/check.py
Normal file
@ -0,0 +1,157 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
#
|
||||
# Check the defaults for a specific host.
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
import defaults
|
||||
import error
|
||||
import execute
|
||||
import log
|
||||
import path
|
||||
|
||||
#
|
||||
# Version of Sourcer Builder Check.
|
||||
#
|
||||
version = '0.1'
|
||||
|
||||
def _notice(opts, text):
|
||||
if not opts.quiet() and log.default and not log.default.has_stdout():
|
||||
print text
|
||||
log.output(text)
|
||||
log.flush()
|
||||
|
||||
|
||||
def _check_none(_opts, macro, value, constraint):
|
||||
return True
|
||||
|
||||
|
||||
def _check_triplet(_opts, macro, value, constraint):
|
||||
return True
|
||||
|
||||
|
||||
def _check_dir(_opts, macro, value, constraint):
|
||||
if constraint != 'none' and not path.isdir(value):
|
||||
if constraint == 'required':
|
||||
_notice(_opts, 'error: dir: not found: (%s) %s' % (macro, value))
|
||||
return False
|
||||
if _opts.warn_all():
|
||||
_notice(_opts, 'warning: dir: not found: (%s) %s' % (macro, value))
|
||||
return True
|
||||
|
||||
|
||||
def _check_exe(_opts, macro, value, constraint):
|
||||
|
||||
if len(value) == 0 or constraint == 'none':
|
||||
return True
|
||||
|
||||
orig_value = value
|
||||
|
||||
if path.isabspath(value):
|
||||
if path.isfile(value):
|
||||
return True
|
||||
if os.name == 'nt':
|
||||
if path.isfile('%s.exe' % (value)):
|
||||
return True
|
||||
value = path.basename(value)
|
||||
absexe = True
|
||||
else:
|
||||
absexe = False
|
||||
|
||||
paths = os.environ['PATH'].split(os.pathsep)
|
||||
|
||||
if _check_paths(value, paths):
|
||||
if absexe:
|
||||
_notice(_opts,
|
||||
'warning: exe: absolute exe found in path: (%s) %s' % (macro, orig_value))
|
||||
return True
|
||||
|
||||
if constraint == 'optional':
|
||||
if _opts.trace():
|
||||
_notice(_opts, 'warning: exe: optional exe not found: (%s) %s' % (macro, orig_value))
|
||||
return True
|
||||
|
||||
_notice(_opts, 'error: exe: not found: (%s) %s' % (macro, orig_value))
|
||||
return False
|
||||
|
||||
|
||||
def _check_paths(name, paths):
|
||||
for p in paths:
|
||||
exe = path.join(p, name)
|
||||
if path.isfile(exe):
|
||||
return True
|
||||
if os.name == 'nt':
|
||||
if path.isfile('%s.exe' % (exe)):
|
||||
return True
|
||||
return False
|
||||
|
||||
def host_setup(_opts, _defaults):
|
||||
""" Basic sanity check. All executables and directories must exist."""
|
||||
|
||||
checks = { 'none': _check_none,
|
||||
'triplet': _check_triplet,
|
||||
'dir': _check_dir,
|
||||
'exe': _check_exe }
|
||||
|
||||
sane = True
|
||||
|
||||
for d in sorted(_defaults.iterkeys()):
|
||||
try:
|
||||
(test, constraint, value) = _defaults[d]
|
||||
except:
|
||||
raise error.general('invalid default: %s [%r]' % (d, _defaults[d]))
|
||||
if test != 'none':
|
||||
value = _opts.expand(value, _defaults)
|
||||
if test not in checks:
|
||||
raise error.general('invalid check test: %s [%r]' % (test, _defaults[d]))
|
||||
ok = checks[test](_opts, d, value, constraint)
|
||||
if _opts.trace():
|
||||
if ok:
|
||||
tag = ' '
|
||||
else:
|
||||
tag = '*'
|
||||
_notice(_opts, '%c %15s: %r -> "%s"' % (tag, d, _defaults[d], value))
|
||||
if sane and not ok:
|
||||
sane = False
|
||||
|
||||
return sane
|
||||
|
||||
|
||||
def run():
|
||||
import sys
|
||||
try:
|
||||
_opts, _defaults = defaults.load(args = sys.argv)
|
||||
if host_setup(_opts, _defaults):
|
||||
print 'Source Builder environent is ok'
|
||||
else:
|
||||
print 'Source Builder environent is not correctly set up'
|
||||
except error.general, gerr:
|
||||
print gerr
|
||||
sys.exit(1)
|
||||
except error.internal, ierr:
|
||||
print ierr
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
873
sb/config.py
Normal file
@ -0,0 +1,873 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
#
|
||||
# This code is based on a tool I wrote to parse RPM spec files in the RTEMS
|
||||
# project. This is now a configuration file format that has moved away from the
|
||||
# spec file format to support the specific needs of cross-compiling GCC. This
|
||||
# module parses a configuration file into Python data types that can be used by
|
||||
# other software modules.
|
||||
#
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
import defaults
|
||||
import error
|
||||
import execute
|
||||
import log
|
||||
import path
|
||||
|
||||
class package:
|
||||
|
||||
def __init__(self, name, arch):
|
||||
self._name = name
|
||||
self._arch = arch
|
||||
self.directives = {}
|
||||
self.infos = {}
|
||||
|
||||
def __str__(self):
|
||||
|
||||
def _dictlist(dl):
|
||||
s = ''
|
||||
dll = dl.keys()
|
||||
dll.sort()
|
||||
for d in dll:
|
||||
if d:
|
||||
s += ' ' + d + ':\n'
|
||||
for l in dl[d]:
|
||||
s += ' ' + l + '\n'
|
||||
return s
|
||||
|
||||
s = '\npackage: ' + self._name + \
|
||||
'\n directives:\n' + _dictlist(self.directives) + \
|
||||
'\n infos:\n' + _dictlist(self.infos)
|
||||
|
||||
return s
|
||||
|
||||
def directive_extend(self, dir, data):
|
||||
if dir not in self.directives:
|
||||
self.directives[dir] = []
|
||||
for i in range(0, len(data)):
|
||||
data[i] = data[i].strip()
|
||||
self.directives[dir].extend(data)
|
||||
|
||||
def info_append(self, info, data):
|
||||
if info not in self.infos:
|
||||
self.infos[info] = []
|
||||
self.infos[info].append(data)
|
||||
|
||||
def get_info(self, info):
|
||||
if not info in self.infos:
|
||||
raise error.general('no %s in package "%s"' % (info, self.name))
|
||||
return self.info
|
||||
|
||||
def version(self):
|
||||
return self.get_info('Version')
|
||||
|
||||
def extract_info(self, label):
|
||||
infos = {}
|
||||
for i in self.infos:
|
||||
il = i.lower()
|
||||
if il.startswith(label):
|
||||
if il == label:
|
||||
il = label + '0'
|
||||
elif not il[len(label):].isdigit():
|
||||
continue
|
||||
infos[il] = self.infos[i]
|
||||
return infos
|
||||
|
||||
def find_info(self, label):
|
||||
for i in self.infos:
|
||||
if i.lower() == label:
|
||||
return self.infos[i]
|
||||
return None
|
||||
|
||||
def find_directive(self, label):
|
||||
for d in self.directives:
|
||||
if d.lower() == label:
|
||||
return self.directives[d]
|
||||
return None
|
||||
|
||||
def name(self):
|
||||
info = self.find_info('name')
|
||||
if info:
|
||||
return info[0]
|
||||
return self._name
|
||||
|
||||
def version(self):
|
||||
info = self.find_info('version')
|
||||
if not info:
|
||||
return None
|
||||
return info[0]
|
||||
|
||||
def release(self):
|
||||
info = self.find_info('release')
|
||||
if not info:
|
||||
return None
|
||||
return info[0]
|
||||
|
||||
def buildarch(self):
|
||||
info = self.find_info('buildarch')
|
||||
if not info:
|
||||
return self._arch
|
||||
return info[0]
|
||||
|
||||
def sources(self):
|
||||
return self.extract_info('source');
|
||||
|
||||
def patches(self):
|
||||
return self.extract_info('patch')
|
||||
|
||||
def prep(self):
|
||||
return self.find_directive('%prep')
|
||||
|
||||
def build(self):
|
||||
return self.find_directive('%build')
|
||||
|
||||
def install(self):
|
||||
return self.find_directive('%install')
|
||||
|
||||
def clean(self):
|
||||
return self.find_directive('%clean')
|
||||
|
||||
def post(self):
|
||||
return self.find_directive('%post')
|
||||
|
||||
def include(self):
|
||||
return self.find_directive('%include')
|
||||
|
||||
def long_name(self):
|
||||
return self.name()
|
||||
|
||||
class file:
|
||||
"""Parse a config file."""
|
||||
|
||||
_directive = [ '%description',
|
||||
'%changelog',
|
||||
'%prep',
|
||||
'%build',
|
||||
'%check',
|
||||
'%include',
|
||||
'%install',
|
||||
'%clean',
|
||||
'%post',
|
||||
'%preun',
|
||||
'%files' ]
|
||||
|
||||
_ignore = [ re.compile('%setup'),
|
||||
re.compile('%configure'),
|
||||
re.compile('%source[0-9]*'),
|
||||
re.compile('%patch[0-9]*') ]
|
||||
|
||||
def __init__(self, name, _defaults, opts):
|
||||
self.opts = opts
|
||||
if self.opts.trace():
|
||||
print 'config: %s' % (name)
|
||||
self.configpath = []
|
||||
self.wss = re.compile(r'\s+')
|
||||
self.tags = re.compile(r':+')
|
||||
self.sf = re.compile(r'%\([^\)]+\)')
|
||||
self.default_defines = {}
|
||||
for d in _defaults:
|
||||
self.default_defines[self._label(d)] = _defaults[d][2]
|
||||
for arg in self.opts.args:
|
||||
if arg.startswith('--with-') or arg.startswith('--without-'):
|
||||
label = arg[2:].lower().replace('-', '_')
|
||||
self.default_defines[self._label(label)] = label
|
||||
self.load_depth = 0
|
||||
self.load(name)
|
||||
|
||||
def __str__(self):
|
||||
|
||||
def _dict(dd):
|
||||
s = ''
|
||||
ddl = dd.keys()
|
||||
ddl.sort()
|
||||
for d in ddl:
|
||||
s += ' ' + d + ': ' + dd[d] + '\n'
|
||||
return s
|
||||
|
||||
s = 'config: %s' % ('.'.join(self.configpath)) + \
|
||||
'\n' + str(self.opts) + \
|
||||
'\nlines parsed: %d' % (self.lc) + \
|
||||
'\nname: ' + self.name + \
|
||||
'\ndefines:\n' + _dict(self.defines)
|
||||
for _package in self._packages:
|
||||
s += str(self._packages[_package])
|
||||
return s
|
||||
|
||||
def _name_line_msg(self, msg):
|
||||
return '%s:%d: %s' % (path.basename(self.name), self.lc, msg)
|
||||
|
||||
def _output(self, text):
|
||||
if not self.opts.quiet():
|
||||
log.output(text)
|
||||
|
||||
def _warning(self, msg):
|
||||
self._output('warning: %s' % (self._name_line_msg(msg)))
|
||||
|
||||
def _error(self, msg):
|
||||
err = 'error: %s' % (self._name_line_msg(msg))
|
||||
print >> sys.stderr, err
|
||||
self._output(err)
|
||||
self.in_error = True
|
||||
if not self.opts.dry_run():
|
||||
print >> sys.stderr, 'warning: switched to dry run due to errors'
|
||||
self.opts.set_dry_run()
|
||||
|
||||
def _label(self, name):
|
||||
return '%{' + name.lower() + '}'
|
||||
|
||||
def _macro_split(self, s):
|
||||
'''Split the string (s) up by macros. Only split on the
|
||||
outter level. Nested levels will need to split with futher calls.'''
|
||||
trace_me = False
|
||||
macros = []
|
||||
nesting = []
|
||||
has_braces = False
|
||||
c = 0
|
||||
while c < len(s):
|
||||
if trace_me:
|
||||
print 'ms:', c, '"' + s[c:] + '"', has_braces, len(nesting), nesting
|
||||
#
|
||||
# We need to watch for shell type variables or the form '${var}' because
|
||||
# they can upset the brace matching.
|
||||
#
|
||||
if s[c] == '%' or s[c] == '$':
|
||||
start = s[c]
|
||||
c += 1
|
||||
if c == len(s):
|
||||
continue
|
||||
#
|
||||
# Do we have '%%' or '%(' or '$%' or '$(' or not '${' ?
|
||||
#
|
||||
if s[c] == '%' or s[c] == '(' or (start == '$' and s[c] != '{'):
|
||||
continue
|
||||
elif not s[c].isspace():
|
||||
#
|
||||
# If this is a shell macro and we are at the outter
|
||||
# level or is '$var' forget it and move on.
|
||||
#
|
||||
if start == '$' and (s[c] != '{' or len(nesting) == 0):
|
||||
continue
|
||||
if s[c] == '{':
|
||||
this_has_braces = True
|
||||
else:
|
||||
this_has_braces = False
|
||||
nesting.append((c - 1, has_braces))
|
||||
has_braces = this_has_braces
|
||||
elif len(nesting) > 0:
|
||||
if s[c] == '}' or (s[c].isspace() and not has_braces):
|
||||
#
|
||||
# Can have '%{?test: something %more}' where the
|
||||
# nested %more ends with the '}' which also ends
|
||||
# the outter macro.
|
||||
#
|
||||
if not has_braces:
|
||||
if s[c] == '}':
|
||||
macro_start, has_braces = nesting[len(nesting) - 1]
|
||||
nesting = nesting[:-1]
|
||||
if len(nesting) == 0:
|
||||
macros.append(s[macro_start:c].strip())
|
||||
if len(nesting) > 0:
|
||||
macro_start, has_braces = nesting[len(nesting) - 1]
|
||||
nesting = nesting[:-1]
|
||||
if len(nesting) == 0:
|
||||
macros.append(s[macro_start:c + 1].strip())
|
||||
c += 1
|
||||
if trace_me:
|
||||
print 'ms:', macros
|
||||
return macros
|
||||
|
||||
def _shell(self, line):
|
||||
sl = self.sf.findall(line)
|
||||
if len(sl):
|
||||
e = execute.capture_execution()
|
||||
for s in sl:
|
||||
exit_code, proc, output = e.shell(s[2:-1])
|
||||
if exit_code == 0:
|
||||
line = line.replace(s, output)
|
||||
else:
|
||||
raise error.general('shell macro failed: %s: %s' % (s, output))
|
||||
return line
|
||||
|
||||
def _expand(self, s):
|
||||
expanded = True
|
||||
while expanded:
|
||||
expanded = False
|
||||
ms = self._macro_split(s)
|
||||
for m in ms:
|
||||
mn = m
|
||||
#
|
||||
# A macro can be '%{macro}' or '%macro'. Turn the later into
|
||||
# the former.
|
||||
#
|
||||
show_warning = True
|
||||
if mn[1] != '{':
|
||||
for r in self._ignore:
|
||||
if r.match(mn) is not None:
|
||||
mn = None
|
||||
break
|
||||
else:
|
||||
mn = self._label(mn[1:])
|
||||
show_warning = False
|
||||
elif m.startswith('%{expand'):
|
||||
colon = m.find(':')
|
||||
if colon < 8:
|
||||
self._warning('malformed expand macro, no colon found')
|
||||
else:
|
||||
e = self._expand(m[colon + 1:-1].strip())
|
||||
s = s.replace(m, e)
|
||||
expanded = True
|
||||
mn = None
|
||||
elif m.startswith('%{with '):
|
||||
#
|
||||
# Change the ' ' to '_' because the macros have no spaces.
|
||||
#
|
||||
n = self._label('with_' + m[7:-1].strip())
|
||||
if n in self.defines:
|
||||
s = s.replace(m, '1')
|
||||
else:
|
||||
s = s.replace(m, '0')
|
||||
expanded = True
|
||||
mn = None
|
||||
elif m.startswith('%{echo'):
|
||||
mn = None
|
||||
elif m.startswith('%{defined'):
|
||||
n = self._label(m[9:-1].strip())
|
||||
if n in self.defines:
|
||||
s = s.replace(m, '1')
|
||||
else:
|
||||
s = s.replace(m, '0')
|
||||
expanded = True
|
||||
mn = None
|
||||
elif m.startswith('%{?') or m.startswith('%{!?'):
|
||||
if m[2] == '!':
|
||||
start = 4
|
||||
else:
|
||||
start = 3
|
||||
colon = m[start:].find(':')
|
||||
if colon < 0:
|
||||
if not m.endswith('}'):
|
||||
self._warning("malform conditional macro '%s'" % (m))
|
||||
mn = None
|
||||
else:
|
||||
mn = self._label(m[start:-1])
|
||||
else:
|
||||
mn = self._label(m[start:start + colon])
|
||||
if mn:
|
||||
if m.startswith('%{?'):
|
||||
if mn in self.defines:
|
||||
if colon >= 0:
|
||||
s = s.replace(m, m[start + colon + 1:-1])
|
||||
expanded = True
|
||||
mn = None
|
||||
else:
|
||||
mn = '%{nil}'
|
||||
else:
|
||||
if mn not in self.defines:
|
||||
if colon >= 0:
|
||||
s = s.replace(m, m[start + colon + 1:-1])
|
||||
expanded = True
|
||||
mn = None
|
||||
else:
|
||||
mn = '%{nil}'
|
||||
if mn:
|
||||
if mn.lower() in self.defines:
|
||||
s = s.replace(m, self.defines[mn.lower()])
|
||||
expanded = True
|
||||
elif show_warning:
|
||||
self._error("macro '%s' not found" % (mn))
|
||||
return self._shell(s)
|
||||
|
||||
def _define(self, config, ls):
|
||||
if len(ls) <= 1:
|
||||
self._warning('invalid macro definition')
|
||||
else:
|
||||
d = self._label(ls[1])
|
||||
if (d not in self.defines) or \
|
||||
(d in self.defines and len(self.defines[d]) == 0):
|
||||
if len(ls) == 2:
|
||||
self.defines[d] = '1'
|
||||
else:
|
||||
self.defines[d] = ls[2].strip()
|
||||
else:
|
||||
if self.opts.warn_all():
|
||||
self._warning("macro '%s' already defined" % (d))
|
||||
|
||||
def _undefine(self, config, ls):
|
||||
if len(ls) <= 1:
|
||||
self._warning('invalid macro definition')
|
||||
else:
|
||||
mn = self._label(ls[1])
|
||||
if mn in self.defines:
|
||||
self._error("macro '%s' not defined" % (mn))
|
||||
del self.defines[mn]
|
||||
|
||||
def _ifs(self, config, ls, label, iftrue, isvalid):
|
||||
text = []
|
||||
in_iftrue = True
|
||||
while True:
|
||||
if isvalid and \
|
||||
((iftrue and in_iftrue) or (not iftrue and not in_iftrue)):
|
||||
this_isvalid = True
|
||||
else:
|
||||
this_isvalid = False
|
||||
r = self._parse(config, roc = True, isvalid = this_isvalid)
|
||||
if r[0] == 'control':
|
||||
if r[1] == '%end':
|
||||
self._error(label + ' without %endif')
|
||||
raise error.general('terminating build')
|
||||
if r[1] == '%endif':
|
||||
return text
|
||||
if r[1] == '%else':
|
||||
in_iftrue = False
|
||||
elif r[0] == 'data':
|
||||
if this_isvalid:
|
||||
text.extend(r[1])
|
||||
|
||||
def _if(self, config, ls, isvalid, invert = False):
|
||||
|
||||
def add(x, y):
|
||||
return x + ' ' + str(y)
|
||||
|
||||
def check_bool(value):
|
||||
if value.isdigit():
|
||||
if int(value) == 0:
|
||||
istrue = False
|
||||
else:
|
||||
istrue = True
|
||||
else:
|
||||
istrue = None
|
||||
return istrue
|
||||
|
||||
istrue = False
|
||||
if isvalid:
|
||||
if len(ls) == 2:
|
||||
s = ls[1]
|
||||
else:
|
||||
s = (ls[1] + ' ' + ls[2])
|
||||
ifls = s.split()
|
||||
if len(ifls) == 1:
|
||||
#
|
||||
# Check if '%if %{x} == %{nil}' has both parts as nothing
|
||||
# which means '%if ==' is always True and '%if !=' is always false.
|
||||
#
|
||||
if ifls[0] == '==':
|
||||
istrue = True
|
||||
elif ifls[0] == '==':
|
||||
istrue = False
|
||||
else:
|
||||
istrue = check_bool(ifls[0])
|
||||
if istrue == None:
|
||||
self._error('invalid if bool value: ' + reduce(add, ls, ''))
|
||||
istrue = False
|
||||
elif len(ifls) == 2:
|
||||
if ifls[0] == '!':
|
||||
istrue = check_bool(ifls[1])
|
||||
if istrue == None:
|
||||
self._error('invalid if bool value: ' + reduce(add, ls, ''))
|
||||
istrue = False
|
||||
else:
|
||||
istrue = not istrue
|
||||
else:
|
||||
#
|
||||
# Check is something is being checked against empty,
|
||||
# ie '%if %{x} == %{nil}'
|
||||
# The logic is 'something == nothing' is False and
|
||||
# 'something != nothing' is True.
|
||||
#
|
||||
if ifls[1] == '==':
|
||||
istrue = False
|
||||
elif ifls[1] == '!=':
|
||||
istrue = True
|
||||
else:
|
||||
self._error('invalid if bool operator: ' + reduce(add, ls, ''))
|
||||
elif len(ifls) == 3:
|
||||
if ifls[1] == '==':
|
||||
if ifls[0] == ifls[2]:
|
||||
istrue = True
|
||||
else:
|
||||
istrue = False
|
||||
elif ifls[1] == '!=' or ifls[1] == '=!':
|
||||
if ifls[0] != ifls[2]:
|
||||
istrue = True
|
||||
else:
|
||||
istrue = False
|
||||
elif ifls[1] == '>':
|
||||
if ifls[0] > ifls[2]:
|
||||
istrue = True
|
||||
else:
|
||||
istrue = False
|
||||
elif ifls[1] == '>=' or ifls[1] == '=>':
|
||||
if ifls[0] >= ifls[2]:
|
||||
istrue = True
|
||||
else:
|
||||
istrue = False
|
||||
elif ifls[1] == '<=' or ifls[1] == '=<':
|
||||
if ifls[0] <= ifls[2]:
|
||||
istrue = True
|
||||
else:
|
||||
istrue = False
|
||||
elif ifls[1] == '<':
|
||||
if ifls[0] < ifls[2]:
|
||||
istrue = True
|
||||
else:
|
||||
istrue = False
|
||||
else:
|
||||
self._error('invalid %if operator: ' + reduce(add, ls, ''))
|
||||
else:
|
||||
self._error('malformed if: ' + reduce(add, ls, ''))
|
||||
if invert:
|
||||
istrue = not istrue
|
||||
if self.opts.trace():
|
||||
print '_if: ', ifls, istrue
|
||||
return self._ifs(config, ls, '%if', istrue, isvalid)
|
||||
|
||||
def _ifos(self, config, ls, isvalid):
|
||||
isos = False
|
||||
if isvalid:
|
||||
os = self.define('_os')
|
||||
if ls[0].find(os) >= 0 or ls[1].find(os) >= 0:
|
||||
isos = True
|
||||
else:
|
||||
isos = False
|
||||
return self._ifs(config, ls, '%ifos', isos, isvalid)
|
||||
|
||||
def _ifarch(self, config, positive, ls, isvalid):
|
||||
isarch = False
|
||||
if isvalid:
|
||||
arch = self.define('_arch')
|
||||
if ls[0].find(arch) >= 0 or ls[1].find(arch) >= 0:
|
||||
isarch = True
|
||||
else:
|
||||
isarch = False
|
||||
if not positive:
|
||||
isarch = not isarch
|
||||
return self._ifs(config, ls, '%ifarch', isarch, isvalid)
|
||||
|
||||
def _parse(self, config, roc = False, isvalid = True):
|
||||
# roc = return on control
|
||||
|
||||
def _clean(line):
|
||||
line = line[0:-1]
|
||||
b = line.find('#')
|
||||
if b >= 0:
|
||||
line = line[1:b]
|
||||
return line.strip()
|
||||
|
||||
#
|
||||
# Need to add code to count matching '{' and '}' and if they
|
||||
# do not match get the next line and add to the string until
|
||||
# they match. This closes an opening '{' that is on another
|
||||
# line.
|
||||
#
|
||||
|
||||
for l in config:
|
||||
self.lc += 1
|
||||
l = _clean(l)
|
||||
if len(l) == 0:
|
||||
continue
|
||||
if self.opts.trace():
|
||||
print '%03d: %d %s' % (self.lc, isvalid, l)
|
||||
if isvalid:
|
||||
l = self._expand(l)
|
||||
if len(l) == 0:
|
||||
continue
|
||||
if l[0] == '%':
|
||||
ls = self.wss.split(l, 2)
|
||||
if ls[0] == '%package':
|
||||
if isvalid:
|
||||
if ls[1] == '-n':
|
||||
name = ls[2]
|
||||
else:
|
||||
name = self.name + '-' + ls[1]
|
||||
return ('package', name)
|
||||
elif ls[0] == '%error':
|
||||
if isvalid:
|
||||
return ('data', ['%%error %s' % (self._name_line_msg(l[7:]))])
|
||||
elif ls[0] == '%warning':
|
||||
if isvalid:
|
||||
return ('data', ['%%warning %s' % (self._name_line_msg(l[9:]))])
|
||||
elif ls[0] == '%define' or ls[0] == '%global':
|
||||
if isvalid:
|
||||
self._define(config, ls)
|
||||
elif ls[0] == '%undefine':
|
||||
if isvalid:
|
||||
self._undefine(config, ls)
|
||||
elif ls[0] == '%if':
|
||||
d = self._if(config, ls, isvalid)
|
||||
if len(d):
|
||||
return ('data', d)
|
||||
elif ls[0] == '%ifn':
|
||||
d = self._if(config, ls, isvalid, True)
|
||||
if len(d):
|
||||
return ('data', d)
|
||||
elif ls[0] == '%ifos':
|
||||
d = self._ifos(config, ls, isvalid)
|
||||
if len(d):
|
||||
return ('data', d)
|
||||
elif ls[0] == '%ifarch':
|
||||
d = self._ifarch(config, True, ls, isvalid)
|
||||
if len(d):
|
||||
return ('data', d)
|
||||
elif ls[0] == '%ifnarch':
|
||||
d = self._ifarch(config, False, ls, isvalid)
|
||||
if len(d):
|
||||
return ('data', d)
|
||||
elif ls[0] == '%endif':
|
||||
if roc:
|
||||
return ('control', '%endif')
|
||||
self._warning("unexpected '" + ls[0] + "'")
|
||||
elif ls[0] == '%else':
|
||||
if roc:
|
||||
return ('control', '%else')
|
||||
self._warning("unexpected '" + ls[0] + "'")
|
||||
elif ls[0].startswith('%defattr'):
|
||||
return ('data', [l])
|
||||
elif ls[0] == '%bcond_with':
|
||||
if isvalid:
|
||||
#
|
||||
# Check if already defined. Would be by the command line or
|
||||
# even a host specific default.
|
||||
#
|
||||
if self._label('with_' + ls[1]) not in self.defines:
|
||||
self._define(config, (ls[0], 'without_' + ls[1]))
|
||||
elif ls[0] == '%bcond_without':
|
||||
if isvalid:
|
||||
if self._label('without_' + ls[1]) not in self.defines:
|
||||
self._define(config, (ls[0], 'with_' + ls[1]))
|
||||
else:
|
||||
for r in self._ignore:
|
||||
if r.match(ls[0]) is not None:
|
||||
return ('data', [l])
|
||||
if isvalid:
|
||||
for d in self._directive:
|
||||
if ls[0].strip() == d:
|
||||
return ('directive', ls[0].strip(), ls[1:])
|
||||
self._warning("unknown directive: '" + ls[0] + "'")
|
||||
return ('data', [l])
|
||||
else:
|
||||
return ('data', [l])
|
||||
return ('control', '%end')
|
||||
|
||||
def _set_package(self, _package):
|
||||
if self.package == 'main' and \
|
||||
self._packages[self.package].name() != None:
|
||||
if self._packages[self.package].name() == _package:
|
||||
return
|
||||
if _package not in self._packages:
|
||||
self._packages[_package] = package(_package,
|
||||
self.define('%{_arch}'))
|
||||
self.package = _package
|
||||
|
||||
def _directive_extend(self, dir, data):
|
||||
self._packages[self.package].directive_extend(dir, data)
|
||||
|
||||
def _info_append(self, info, data):
|
||||
self._packages[self.package].info_append(info, data)
|
||||
|
||||
def load(self, name):
|
||||
|
||||
if self.load_depth == 0:
|
||||
self.in_error = False
|
||||
self.lc = 0
|
||||
self.name = name
|
||||
self.defines = self.default_defines
|
||||
self.conditionals = {}
|
||||
self._packages = {}
|
||||
self.package = 'main'
|
||||
self._packages[self.package] = package(self.package,
|
||||
self.define('%{_arch}'))
|
||||
|
||||
self.load_depth += 1
|
||||
|
||||
save_name = self.name
|
||||
save_lc = self.lc
|
||||
|
||||
self.name = name
|
||||
self.lc = 0
|
||||
|
||||
#
|
||||
# Locate the config file. Expand any macors then Add the
|
||||
# extension. Check if the file exists, therefore directly
|
||||
# referenced. If not see if the file contains ':' or the path
|
||||
# separator. If it does split the path else use the standard config dir
|
||||
# path in the defaults.
|
||||
#
|
||||
|
||||
exname = self.expand(name)
|
||||
|
||||
if exname.endswith('.cfg'):
|
||||
configname = exname
|
||||
else:
|
||||
configname = '%s.cfg' % (exname)
|
||||
|
||||
cfgname = path.basename(configname)
|
||||
|
||||
if not path.exists(configname):
|
||||
if ':' in configname:
|
||||
configdirs = path.dirname(configname).split(':')
|
||||
else:
|
||||
configdirs = self.define('_configdir').split(':')
|
||||
for cp in configdirs:
|
||||
configname = path.join(path.abspath(cp), cfgname)
|
||||
if path.exists(configname):
|
||||
break
|
||||
configname = None
|
||||
if configname is None:
|
||||
raise error.general('no config file found: %s' % (cfgname))
|
||||
|
||||
try:
|
||||
if self.opts.trace():
|
||||
print '_open: %s' % (path.host(configname))
|
||||
config = open(path.host(configname), 'r')
|
||||
except IOError, err:
|
||||
raise error.general('error opening config file: %s' % (path.host(configname)))
|
||||
self.configpath += [configname]
|
||||
|
||||
try:
|
||||
dir = None
|
||||
data = []
|
||||
while True:
|
||||
r = self._parse(config)
|
||||
if r[0] == 'package':
|
||||
self._set_package(r[1])
|
||||
dir = None
|
||||
elif r[0] == 'control':
|
||||
if r[1] == '%end':
|
||||
break
|
||||
self._warning("unexpected '" + r[1] + "'")
|
||||
elif r[0] == 'directive':
|
||||
new_data = []
|
||||
if r[1] == '%description':
|
||||
new_data = [' '.join(r[2])]
|
||||
elif r[1] == '%include':
|
||||
self.load(r[2][0])
|
||||
continue
|
||||
else:
|
||||
if len(r[2]) == 0:
|
||||
_package = 'main'
|
||||
elif len(r[2]) == 1:
|
||||
_package = r[2][0]
|
||||
else:
|
||||
if r[2][0].strip() != '-n':
|
||||
self._warning("unknown directive option: '%s'" % (' '.join(r[2])))
|
||||
_package = r[2][1].strip()
|
||||
self._set_package(_package)
|
||||
if dir and dir != r[1]:
|
||||
self._directive_extend(dir, data)
|
||||
dir = r[1]
|
||||
data = new_data
|
||||
elif r[0] == 'data':
|
||||
for l in r[1]:
|
||||
l = self._expand(l)
|
||||
if l.startswith('%error'):
|
||||
raise error.general('config error: %s' % (l[7:]))
|
||||
elif l.startswith('%warning'):
|
||||
print >> sys.stderr, 'warning: %s' % (l[9:])
|
||||
self._warning(l[9:])
|
||||
if not dir:
|
||||
ls = self.tags.split(l, 1)
|
||||
if self.opts.trace():
|
||||
print '_tag: ', l, ls
|
||||
if len(ls) > 1:
|
||||
i = ls[0]
|
||||
self._info_append(i, ls[1].strip())
|
||||
# It seems like the info's also appear as
|
||||
# defines or can be accessed via macros.
|
||||
if ls[0][len(ls[0]) - 1] == ':':
|
||||
ls[0] = ls[0][:-1]
|
||||
ls[0] = ls[0].lower()
|
||||
self._define(None, ('', ls[0], ls[1]))
|
||||
else:
|
||||
self._warning("invalid format: '" + l[:-1] + "'")
|
||||
else:
|
||||
data.append(l)
|
||||
else:
|
||||
self._error("invalid parse state: '" + r[0] + "'")
|
||||
if dir is not None:
|
||||
self._directive_extend(dir, data)
|
||||
except:
|
||||
config.close()
|
||||
raise
|
||||
|
||||
config.close()
|
||||
|
||||
self.name = save_name
|
||||
self.lc = save_lc
|
||||
|
||||
self.load_depth -= 1
|
||||
|
||||
def define(self, name):
|
||||
if name.lower() in self.defines:
|
||||
d = self.defines[name.lower()]
|
||||
else:
|
||||
n = self._label(name)
|
||||
if n in self.defines:
|
||||
d = self.defines[n]
|
||||
else:
|
||||
raise error.general('macro "' + name + '" not found')
|
||||
return self._expand(d)
|
||||
|
||||
def set_define(self, name, value):
|
||||
self.defines[name.lower()] = value
|
||||
|
||||
def expand(self, line):
|
||||
return self._expand(line)
|
||||
|
||||
def directive(self, _package, name):
|
||||
if _package not in self._packages:
|
||||
raise error.general('package "' + _package + '" not found')
|
||||
if name not in self._packages[_package].directives:
|
||||
raise error.general('directive "' + name + \
|
||||
'" not found in package "' + _package + '"')
|
||||
return self._packages[_package].directives[name]
|
||||
|
||||
def abspath(self, rpath):
|
||||
return path.abspath(self.define(rpath))
|
||||
|
||||
def packages(self):
|
||||
return self._packages
|
||||
|
||||
def run():
|
||||
import sys
|
||||
try:
|
||||
opts, _defaults = defaults.load(sys.argv)
|
||||
if opts.trace():
|
||||
print 'config: count %d' % (len(opts.config_files()))
|
||||
for config_file in opts.config_files():
|
||||
s = file(config_file, _defaults = _defaults, opts = opts)
|
||||
print s
|
||||
del s
|
||||
except error.general, gerr:
|
||||
print gerr
|
||||
sys.exit(1)
|
||||
except error.internal, ierr:
|
||||
print ierr
|
||||
sys.exit(1)
|
||||
except KeyboardInterrupt:
|
||||
print 'user terminated'
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
59
sb/darwin.py
Normal file
@ -0,0 +1,59 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
#
|
||||
# This code is based on what ever doco about spec files I could find and
|
||||
# RTEMS project's spec files.
|
||||
#
|
||||
|
||||
import pprint
|
||||
import os
|
||||
|
||||
import execute
|
||||
|
||||
def load():
|
||||
uname = os.uname()
|
||||
sysctl = '/usr/sbin/sysctl '
|
||||
e = execute.capture_execution()
|
||||
exit_code, proc, output = e.shell(sysctl + 'hw.ncpu')
|
||||
if exit_code == 0:
|
||||
smp_mflags = '-j' + output.split(' ')[1].strip()
|
||||
else:
|
||||
smp_mflags = ''
|
||||
defines = {
|
||||
'_os': ('none', 'none', 'darwin'),
|
||||
'_host': ('triplet', 'required', uname[4] + '-apple-darwin' + uname[2]),
|
||||
'_host_vendor': ('none', 'none', 'apple'),
|
||||
'_host_os': ('none', 'none', 'darwin'),
|
||||
'_host_cpu': ('none', 'none', uname[4]),
|
||||
'_host_alias': ('none', 'none', '%{nil}'),
|
||||
'_host_arch': ('none', 'none', uname[4]),
|
||||
'_usr': ('dir', 'optional', '/usr/local'),
|
||||
'_var': ('dir', 'optional', '/usr/local/var'),
|
||||
'_prefix': ('dir', 'optional', '%{_usr}'),
|
||||
'optflags': ('none', 'none', '-O2'),
|
||||
'_smp_mflags': ('none', 'none', smp_mflags),
|
||||
'__ldconfig': ('exe', 'none', ''),
|
||||
'__xz': ('exe', 'required', '%{_usr}/bin/xz'),
|
||||
'with_zlib': ('none', 'none', '--with-zlib=no')
|
||||
}
|
||||
return defines
|
||||
|
||||
if __name__ == '__main__':
|
||||
pprint.pprint(load())
|
575
sb/defaults.py
Normal file
@ -0,0 +1,575 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
#
|
||||
# Determine the defaults and load the specific file.
|
||||
#
|
||||
|
||||
import glob
|
||||
import pprint
|
||||
import re
|
||||
import os
|
||||
|
||||
import error
|
||||
import execute
|
||||
import path
|
||||
|
||||
basepath = 'sb'
|
||||
|
||||
#
|
||||
# All paths in defaults must be Unix format. Do not store any Windows format
|
||||
# paths in the defaults.
|
||||
#
|
||||
# Every entry must describe the type of checking a host must pass.
|
||||
#
|
||||
|
||||
defaults = {
|
||||
# Nothing
|
||||
'nil': ('none', 'none', ''),
|
||||
|
||||
# Set to invalid values.
|
||||
'_bset': ('none', 'none', ''),
|
||||
'name': ('none', 'none', ''),
|
||||
'version': ('none', 'none', ''),
|
||||
'release': ('none', 'none', ''),
|
||||
|
||||
# GNU triples needed to build packages
|
||||
'_host': ('triplet', 'required', ''),
|
||||
'_build': ('triplet', 'required', '%{_host}'),
|
||||
'_target': ('none', 'optional', ''),
|
||||
|
||||
# Paths
|
||||
'_host_platform': ('none', 'none', '%{_host_cpu}-%{_host_vendor}-%{_host_os}%{?_gnu}'),
|
||||
'_build': ('none', 'none', '%{_host}'),
|
||||
'_arch': ('none', 'none', '%{_host_arch}'),
|
||||
'_sbdir': ('none', 'none', ''),
|
||||
'_topdir': ('dir', 'required', path.shell(os.getcwd())),
|
||||
'_configdir': ('dir', 'optional', '%{_topdir}/config:%{_sbdir}/config'),
|
||||
'_tardir': ('dir', 'optional', '%{_topdir}/tar'),
|
||||
'_sourcedir': ('dir', 'optional', '%{_topdir}/sources'),
|
||||
'_patchdir': ('dir', 'optional', '%{_topdir}/patches:%{_sbdir}/patches'),
|
||||
'_builddir': ('dir', 'optional', '%{_topdir}/build/%{name}-%{version}-%{release}'),
|
||||
'_docdir': ('dir', 'none', '%{_defaultdocdir}'),
|
||||
'_tmppath': ('dir', 'none', '%{_topdir}/build/tmp'),
|
||||
'_tmproot': ('dir', 'none', '%{_tmppath}/source-build-%(%{__id_u} -n)/%{_bset}'),
|
||||
'buildroot:': ('dir', 'none', '%{_tmppath}/%{name}-root-%(%{__id_u} -n)'),
|
||||
'_datadir': ('dir', 'none', '%{_prefix}/share'),
|
||||
'_defaultdocdir': ('dir', 'none', '%{_prefix}/share/doc'),
|
||||
'_exeext': ('none', 'none', ''),
|
||||
'_exec_prefix': ('dir', 'none', '%{_prefix}'),
|
||||
'_bindir': ('dir', 'none', '%{_exec_prefix}/bin'),
|
||||
'_sbindir': ('dir', 'none', '%{_exec_prefix}/sbin'),
|
||||
'_libexecdir': ('dir', 'none', '%{_exec_prefix}/libexec'),
|
||||
'_datarootdir': ('dir', 'none', '%{_prefix}/share'),
|
||||
'_datadir': ('dir', 'none', '%{_datarootdir}'),
|
||||
'_sysconfdir': ('dir', 'none', '%{_prefix}/etc'),
|
||||
'_sharedstatedir': ('dir', 'none', '%{_prefix}/com'),
|
||||
'_localstatedir': ('dir', 'none', '%{prefix}/var'),
|
||||
'_includedir': ('dir', 'none', '%{_prefix}/include'),
|
||||
'_lib': ('dir', 'none', 'lib'),
|
||||
'_libdir': ('dir', 'none', '%{_exec_prefix}/%{_lib}'),
|
||||
'_libexecdir': ('dir', 'none', '%{_exec_prefix}/libexec'),
|
||||
'_mandir': ('dir', 'none', '%{_datarootdir}/man'),
|
||||
'_infodir': ('dir', 'none', '%{_datarootdir}/info'),
|
||||
'_localedir': ('dir', 'none', '%{_datarootdir}/locale'),
|
||||
'_localedir': ('dir', 'none', '%{_datadir}/locale'),
|
||||
'_localstatedir': ('dir', 'none', '%{_prefix}/var'),
|
||||
'_prefix': ('dir', 'none', '%{_usr}'),
|
||||
'_usr': ('dir', 'none', '/usr/local'),
|
||||
'_usrsrc': ('dir', 'none', '%{_usr}/src'),
|
||||
'_var': ('dir', 'none', '/usr/local/var'),
|
||||
'_varrun': ('dir', 'none', '%{_var}/run'),
|
||||
|
||||
# Defaults, override in platform specific modules.
|
||||
'___setup_shell': ('exe', 'required', '/bin/sh'),
|
||||
'__aclocal': ('exe', 'optional', 'aclocal'),
|
||||
'__ar': ('exe', 'required', 'ar'),
|
||||
'__arch_install_post': ('exe', 'none', '%{nil}'),
|
||||
'__as': ('exe', 'required', 'as'),
|
||||
'__autoconf': ('exe', 'required', 'autoconf'),
|
||||
'__autoheader': ('exe', 'required', 'autoheader'),
|
||||
'__automake': ('exe', 'required', 'automake'),
|
||||
'__awk': ('exe', 'required', 'awk'),
|
||||
'__bash': ('exe', 'optional', '/bin/bash'),
|
||||
'__bzip2': ('exe', 'required', '/usr/bin/bzip2'),
|
||||
'__cat': ('exe', 'required', '/bin/cat'),
|
||||
'__cc': ('exe', 'required', '/usr/bin/gcc'),
|
||||
'__chgrp': ('exe', 'required', '/usr/bin/chgrp'),
|
||||
'__chmod': ('exe', 'required', '/bin/chmod'),
|
||||
'__chown': ('exe', 'required', '/usr/sbin/chown'),
|
||||
'__cp': ('exe', 'required', '/bin/cp'),
|
||||
'__cpp': ('exe', 'none', '%{__cc} -E'),
|
||||
'__cxx': ('exe', 'required', '/usr/bin/g++'),
|
||||
'__grep': ('exe', 'required', '/usr/bin/grep'),
|
||||
'__gzip': ('exe', 'required', '/usr/bin/gzip'),
|
||||
'__id': ('exe', 'required', '/usr/bin/id'),
|
||||
'__id_u': ('exe', 'none', '%{__id} -u'),
|
||||
'__install': ('exe', 'required', '/usr/bin/install'),
|
||||
'__install_info': ('exe', 'optional', '/usr/bin/install-info'),
|
||||
'__ld': ('exe', 'required', '/usr/bin/ld'),
|
||||
'__ldconfig': ('exe', 'required', '/sbin/ldconfig'),
|
||||
'__ln_s': ('exe', 'none', 'ln -s'),
|
||||
'__make': ('exe', 'required', 'make'),
|
||||
'__mkdir': ('exe', 'required', '/bin/mkdir'),
|
||||
'__mkdir_p': ('exe', 'none', '/bin/mkdir -p'),
|
||||
'__mv': ('exe', 'required', '/bin/mv'),
|
||||
'__nm': ('exe', 'required', '/usr/bin/nm'),
|
||||
'__objcopy': ('exe', 'optional', '/usr/bin//objcopy'),
|
||||
'__objdump': ('exe', 'optional', '/usr/bin/objdump'),
|
||||
'__patch': ('exe', 'required', '/usr/bin/patch'),
|
||||
'__perl': ('exe', 'optional', 'perl'),
|
||||
'__ranlib': ('exe', 'required', 'ranlib'),
|
||||
'__rm': ('exe', 'required', '/bin/rm'),
|
||||
'__sed': ('exe', 'required', '/usr/bin/sed'),
|
||||
'__setup_post': ('exe', 'none', '%{__chmod} -R a+rX,g-w,o-w .'),
|
||||
'__sh': ('exe', 'required', '/bin/sh'),
|
||||
'__tar': ('exe', 'required', '/usr/bin/tar'),
|
||||
'__tar_extract': ('exe', 'none', '%{__tar} -xvvf'),
|
||||
'__unzip': ('exe', 'required', '/usr/bin/unzip'),
|
||||
'__xz': ('exe', 'required', '/usr/bin/xz'),
|
||||
|
||||
# Shell Build Settings.
|
||||
'___build_args': ('none', 'none', '-e'),
|
||||
'___build_cmd': ('none', 'none', '%{?_sudo:%{_sudo} }%{?_remsh:%{_remsh} %{_remhost} }%{?_remsudo:%{_remsudo} }%{?_remchroot:%{_remchroot} %{_remroot} }%{___build_shell} %{___build_args}'),
|
||||
'___build_post': ('none', 'none', 'exit 0'),
|
||||
|
||||
# Prebuild set up script.
|
||||
'___build_pre': ('none', 'none', '''# ___build_pre in as set up in defaults.py
|
||||
# Directories
|
||||
SB_SOURCE_DIR="%{_sourcedir}"
|
||||
SB_BUILD_DIR="%{_builddir}"
|
||||
SB_OPT_FLAGS="%{optflags}"
|
||||
SB_ARCH="%{_arch}"
|
||||
SB_OS="%{_os}"
|
||||
export SB_SOURCE_DIR SB_BUILD_DIR SB_OPT_FLAGS SB_ARCH SB_OS
|
||||
# Documentation
|
||||
SB_DOC_DIR="%{_docdir}"
|
||||
export SB_DOC_DIR
|
||||
# Packages
|
||||
SB_PACKAGE_NAME="%{name}"
|
||||
SB_PACKAGE_VERSION="%{version}"
|
||||
SB_PACKAGE_RELEASE="%{release}"
|
||||
export SBPACKAGE_NAME SB_PACKAGE_VERSION SB_PACKAGE_RELEASE
|
||||
# Build root directory
|
||||
%{?buildroot:SB_BUILD_ROOT="%{buildroot}"}
|
||||
export SB_BUILD_ROOT
|
||||
# The compiler flags
|
||||
%{?_targetcflags:CFLAGS_FOR_TARGET="%{_targetcflags}"}
|
||||
%{?_targetcxxflags:CXXFLAGS_FOR_TARGET="%{_targetcxxflags}"}
|
||||
export CFLAGS_FOR_TARGET
|
||||
# Default environment set up.
|
||||
LANG=C
|
||||
export LANG
|
||||
unset DISPLAY || :
|
||||
umask 022
|
||||
cd "%{_builddir}"'''),
|
||||
'___build_shell': ('none', 'none', '%{?_buildshell:%{_buildshell}}%{!?_buildshell:/bin/sh}'),
|
||||
'___build_template': ('none', 'none', '''#!%{___build_shell}
|
||||
%{___build_pre}
|
||||
%{nil}'''),
|
||||
|
||||
# Configure command
|
||||
'configure': ('none', 'none', '''
|
||||
CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS ;
|
||||
CXXFLAGS="${CXXFLAGS:-%optflags}" ; export CXXFLAGS ;
|
||||
FFLAGS="${FFLAGS:-%optflags}" ; export FFLAGS ;
|
||||
./configure --build=%{_build} --host=%{_host} \
|
||||
--target=%{_target_platform} \
|
||||
--program-prefix=%{?_program_prefix} \
|
||||
--prefix=%{_prefix} \
|
||||
--exec-prefix=%{_exec_prefix} \
|
||||
--bindir=%{_bindir} \
|
||||
--sbindir=%{_sbindir} \
|
||||
--sysconfdir=%{_sysconfdir} \
|
||||
--datadir=%{_datadir} \
|
||||
--includedir=%{_includedir} \
|
||||
--libdir=%{_libdir} \
|
||||
--libexecdir=%{_libexecdir} \
|
||||
--localstatedir=%{_localstatedir} \
|
||||
--sharedstatedir=%{_sharedstatedir} \
|
||||
--mandir=%{_mandir} \
|
||||
--infodir=%{_infodir}''')
|
||||
}
|
||||
|
||||
class command_line:
|
||||
"""Process the command line in a common way for all Tool Builder commands."""
|
||||
|
||||
_defaults = { 'params' : [],
|
||||
'warn-all' : '0',
|
||||
'quiet' : '0',
|
||||
'force' : '0',
|
||||
'trace' : '0',
|
||||
'dry-run' : '0',
|
||||
'no-clean' : '0',
|
||||
'no-smp' : '0',
|
||||
'rebuild' : '0' }
|
||||
|
||||
#
|
||||
# The define and if it is a path and needs conversion.
|
||||
#
|
||||
_long_opts = { '--prefix' : ('_prefix', True),
|
||||
'--prefixbase' : ('_prefixbase', True),
|
||||
'--topdir' : ('_topdir', True),
|
||||
'--configdir' : ('_configdir', True),
|
||||
'--builddir' : ('_builddir', True),
|
||||
'--sourcedir' : ('_sourcedir', True),
|
||||
'--tmppath' : ('_tmppath', True),
|
||||
'--log' : ('_logfile', False),
|
||||
'--url' : ('_url_base', False),
|
||||
'--targetcflags' : ('_targetcflags', False),
|
||||
'--targetcxxflags' : ('_targetcxxflags', False),
|
||||
'--libstdcxxflags' : ('_libstdcxxflags', False) }
|
||||
|
||||
_long_true_opts = { '--force' : '_force',
|
||||
'--trace' : '_trace',
|
||||
'--dry-run' : '_dry_run',
|
||||
'--warn-all' : '_warn_all',
|
||||
'--no-clean' : '_no_clean',
|
||||
'--no-smp' : '_no_smp',
|
||||
'--rebuild' : '_rebuild' }
|
||||
|
||||
_target_triplets = { '--host' : '_host',
|
||||
'--build' : '_build',
|
||||
'--target' : '_target' }
|
||||
|
||||
def _help(self):
|
||||
print '%s: [options] [args]' % (self.command_name)
|
||||
print 'Source Builder, an RTEMS Tools Project (c) 2012 Chris Johns'
|
||||
print 'Options and arguments:'
|
||||
print '--force : Create directories that are not present'
|
||||
print '--trace : Trace the execution (not current used)'
|
||||
print '--dry-run : Do everything but actually run the build'
|
||||
print '--warn-all : Generate warnings'
|
||||
print '--no-clean : Do not clean up the build tree'
|
||||
print '--no-smp : Run with 1 job and not as many as CPUs'
|
||||
print '--rebuild : Rebuild (not used)'
|
||||
print '--host : Set the host triplet'
|
||||
print '--build : Set the build triplet'
|
||||
print '--target : Set the target triplet'
|
||||
print '--prefix path : Tools build prefix, ie where they are installed'
|
||||
print '--prefixbase path : '
|
||||
print '--topdir path : Top of the build tree, default is $PWD'
|
||||
print '--configdir path : Path to the configuration directory, default: ./config'
|
||||
print '--builddir path : Path to the build directory, default: ./build'
|
||||
print '--sourcedir path : Path to the source directory, default: ./source'
|
||||
print '--tmppath path : Path to the temp directory, default: ./tmp'
|
||||
print '--log file : Log file where all build out is written too'
|
||||
print '--url url : URL to look for source'
|
||||
print '--targetcflags flags : List of C flags for the target code'
|
||||
print '--targetcxxflags flags : List of C++ flags for the target code'
|
||||
print '--libstdcxxflags flags : List of C++ flags to build the target libstdc++ code'
|
||||
print '--with-<label> : Add the --with-<label> to the build'
|
||||
print '--without-<label> : Add the --without-<label> to the build'
|
||||
if self.optargs:
|
||||
for a in self.optargs:
|
||||
print '%-22s : %s' % (a, self.optargs[a])
|
||||
raise error.exit()
|
||||
|
||||
def __init__(self, argv, optargs):
|
||||
self.command_path = path.dirname(argv[0])
|
||||
if len(self.command_path) == 0:
|
||||
self.command_path = '.'
|
||||
self.command_name = path.basename(argv[0])
|
||||
self.args = argv[1:]
|
||||
self.optargs = optargs
|
||||
self.defaults = {}
|
||||
for to in command_line._long_true_opts:
|
||||
self.defaults[command_line._long_true_opts[to]] = ('none', 'none', '0')
|
||||
self.defaults['_sbdir'] = ('dir', 'required', path.shell(self.command_path))
|
||||
self._process()
|
||||
|
||||
def __str__(self):
|
||||
def _dict(dd):
|
||||
s = ''
|
||||
ddl = dd.keys()
|
||||
ddl.sort()
|
||||
for d in ddl:
|
||||
s += ' ' + d + ': ' + str(dd[d]) + '\n'
|
||||
return s
|
||||
|
||||
s = 'command: ' + self.command() + \
|
||||
'\nargs: ' + str(self.args) + \
|
||||
'\nopts:\n' + _dict(self.opts)
|
||||
|
||||
return s
|
||||
|
||||
def _process(self):
|
||||
|
||||
def _process_lopt(opt, arg, long_opts, args, values = False):
|
||||
for lo in long_opts:
|
||||
if values and opt.startswith(lo):
|
||||
equals = opt.find('=')
|
||||
if equals < 0:
|
||||
if arg == len(args) - 1:
|
||||
raise error.general('missing option value: ' + lo)
|
||||
arg += 1
|
||||
value = args[arg]
|
||||
else:
|
||||
value = opt[equals + 1:]
|
||||
if type(long_opts[lo]) is tuple:
|
||||
if long_opts[lo][1]:
|
||||
value = path.shell(value)
|
||||
macro = long_opts[lo][0]
|
||||
else:
|
||||
macro = long_opts[lo]
|
||||
return lo, macro, value, arg
|
||||
elif opt == lo:
|
||||
return lo, long_opts[lo], True, arg
|
||||
return None, None, None, arg
|
||||
|
||||
self.opts = command_line._defaults
|
||||
i = 0
|
||||
while i < len(self.args):
|
||||
a = self.args[i]
|
||||
if a.startswith('-'):
|
||||
if a.startswith('--'):
|
||||
if a.startswith('--warn-all'):
|
||||
self.opts['warn-all'] = True
|
||||
elif a == '--help':
|
||||
self._help()
|
||||
else:
|
||||
lo, macro, value, i = _process_lopt(a, i,
|
||||
command_line._long_true_opts,
|
||||
self.args)
|
||||
if lo:
|
||||
self.defaults[macro] = ('none', 'none', '1')
|
||||
self.opts[lo[2:]] = '1'
|
||||
else:
|
||||
lo, macro, value, i = _process_lopt(a, i,
|
||||
command_line._long_opts,
|
||||
self.args, True)
|
||||
if lo:
|
||||
self.defaults[macro] = ('none', 'none', value)
|
||||
self.opts[lo[2:]] = value
|
||||
else:
|
||||
#
|
||||
# The target triplet is 'cpu-vendor-os'.
|
||||
#
|
||||
lo, macro, value, i = _process_lopt(a, i,
|
||||
command_line._target_triplets,
|
||||
self.args, True)
|
||||
if lo:
|
||||
#
|
||||
# This is a target triplet. Run it past config.sub to make
|
||||
# make sure it is ok.
|
||||
#
|
||||
e = execute.capture_execution()
|
||||
config_sub = path.join(self.command_path,
|
||||
basepath, 'config.sub')
|
||||
exit_code, proc, output = e.shell(config_sub + ' ' + value)
|
||||
if exit_code == 0:
|
||||
value = output
|
||||
self.defaults[macro] = ('triplet', 'none', value)
|
||||
self.opts[lo[2:]] = value
|
||||
_arch = macro + '_cpu'
|
||||
_vendor = macro + '_vendor'
|
||||
_os = macro + '_os'
|
||||
_arch_value = ''
|
||||
_vendor_value = ''
|
||||
_os_value = ''
|
||||
dash = value.find('-')
|
||||
if dash >= 0:
|
||||
_arch_value = value[:dash]
|
||||
value = value[dash + 1:]
|
||||
dash = value.find('-')
|
||||
if dash >= 0:
|
||||
_vendor_value = value[:dash]
|
||||
value = value[dash + 1:]
|
||||
if len(value):
|
||||
_os_value = value
|
||||
self.defaults[_arch] = ('none', 'none', _arch_value)
|
||||
self.defaults[_vendor] = ('none', 'none', _vendor_value)
|
||||
self.defaults[_os] = ('none', 'none', _os_value)
|
||||
if not lo and a not in self.optargs:
|
||||
raise error.general('invalid argument (try --help): %s' % (a))
|
||||
else:
|
||||
if a == '-f':
|
||||
self.opts['force'] = '1'
|
||||
elif a == '-n':
|
||||
self.opts['dry-run'] = '1'
|
||||
elif a == '-q':
|
||||
self.opts['quiet'] = '1'
|
||||
elif a == '-?':
|
||||
self._help()
|
||||
else:
|
||||
raise error.general('invalid argument (try --help): %s' % (a))
|
||||
else:
|
||||
self.opts['params'].append(a)
|
||||
i += 1
|
||||
|
||||
def _post_process(self, _defaults):
|
||||
if self.no_smp():
|
||||
_defaults['_smp_mflags'] = ('none', 'none', _defaults['nil'][2])
|
||||
if _defaults['_host'][2] == _defaults['nil'][2]:
|
||||
raise error.general('host not set')
|
||||
return _defaults
|
||||
|
||||
def expand(self, s, _defaults):
|
||||
"""Simple basic expander of config file macros."""
|
||||
mf = re.compile(r'%{[^}]+}')
|
||||
expanded = True
|
||||
while expanded:
|
||||
expanded = False
|
||||
for m in mf.findall(s):
|
||||
name = m[2:-1]
|
||||
if name in _defaults:
|
||||
s = s.replace(m, _defaults[name][2])
|
||||
expanded = True
|
||||
else:
|
||||
raise error.general('cannot process default macro: ' + m)
|
||||
return s
|
||||
|
||||
def command(self):
|
||||
return path.join(self.command_path, self.command_name)
|
||||
|
||||
def force(self):
|
||||
return self.opts['force'] != '0'
|
||||
|
||||
def dry_run(self):
|
||||
return self.opts['dry-run'] != '0'
|
||||
|
||||
def set_dry_run(self):
|
||||
self.opts['dry-run'] = '1'
|
||||
|
||||
def quiet(self):
|
||||
return self.opts['quiet'] != '0'
|
||||
|
||||
def trace(self):
|
||||
return self.opts['trace'] != '0'
|
||||
|
||||
def warn_all(self):
|
||||
return self.opts['warn-all'] != '0'
|
||||
|
||||
def no_clean(self):
|
||||
return self.opts['no-clean'] != '0'
|
||||
|
||||
def no_smp(self):
|
||||
return self.opts['no-smp'] != '0'
|
||||
|
||||
def rebuild(self):
|
||||
return self.opts['rebuild'] != '0'
|
||||
|
||||
def params(self):
|
||||
return self.opts['params']
|
||||
|
||||
def get_arg(self, arg):
|
||||
if not arg in self.optargs:
|
||||
raise error.internal('bad arg: %s' % (arg))
|
||||
for a in self.args:
|
||||
if a.startswith(arg):
|
||||
return a
|
||||
return None
|
||||
|
||||
def get_config_files(self, config):
|
||||
#
|
||||
# Convert to shell paths and return shell paths.
|
||||
#
|
||||
# @fixme should this use a passed in set of defaults and not
|
||||
# not the initial set of values ?
|
||||
#
|
||||
config = path.shell(config)
|
||||
if '*' in config or '?' in config:
|
||||
print config
|
||||
configdir = path.dirname(config)
|
||||
configbase = path.basename(config)
|
||||
if len(configbase) == 0:
|
||||
configbase = '*'
|
||||
if not configbase.endswith('.cfg'):
|
||||
configbase = configbase + '.cfg'
|
||||
if len(configdir) == 0:
|
||||
configdir = self.expand(defaults['_configdir'][2], defaults)
|
||||
configs = []
|
||||
for cp in configdir.split(':'):
|
||||
hostconfigdir = path.host(cp)
|
||||
for f in glob.glob(os.path.join(hostconfigdir, configbase)):
|
||||
configs += path.shell(f)
|
||||
else:
|
||||
configs = [config]
|
||||
return configs
|
||||
|
||||
def config_files(self):
|
||||
configs = []
|
||||
for config in self.opts['params']:
|
||||
configs.extend(self.get_config_files(config))
|
||||
return configs
|
||||
|
||||
def logfiles(self):
|
||||
if 'log' in self.opts:
|
||||
return self.opts['log'].split(',')
|
||||
return ['stdout']
|
||||
|
||||
def urls(self):
|
||||
if 'url' in self.opts:
|
||||
return self.opts['url'].split(',')
|
||||
return None
|
||||
|
||||
def prefixbase(self):
|
||||
if 'prefixbase' in self.opts:
|
||||
return self.opts['prefixbase']
|
||||
return None
|
||||
|
||||
def load(args, optargs = None):
|
||||
"""
|
||||
Copy the defaults, get the host specific values and merge them overriding
|
||||
any matching defaults, then create an options object to handle the command
|
||||
line merging in any command line overrides. Finally post process the
|
||||
command line.
|
||||
"""
|
||||
d = defaults
|
||||
overrides = None
|
||||
if os.name == 'nt':
|
||||
import windows
|
||||
overrides = windows.load()
|
||||
else:
|
||||
uname = os.uname()
|
||||
try:
|
||||
if uname[0] == 'Darwin':
|
||||
import darwin
|
||||
overrides = darwin.load()
|
||||
elif uname[0] == 'FreeBSD':
|
||||
import freebsd
|
||||
overrides = freebsd.load()
|
||||
elif uname[0] == 'Linux':
|
||||
import linux
|
||||
overrides = linux.load()
|
||||
except:
|
||||
pass
|
||||
if overrides is None:
|
||||
raise error.general('no hosts defaults found; please add')
|
||||
for k in overrides:
|
||||
d[k] = overrides[k]
|
||||
o = command_line(args, optargs)
|
||||
for k in o.defaults:
|
||||
d[k] = o.defaults[k]
|
||||
d = o._post_process(d)
|
||||
return o, d
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
try:
|
||||
_opts, _defaults = load(args = sys.argv)
|
||||
print _opts
|
||||
pprint.pprint(_defaults)
|
||||
except error.general, gerr:
|
||||
print gerr
|
||||
sys.exit(1)
|
||||
except error.internal, ierr:
|
||||
print ierr
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
54
sb/error.py
Normal file
@ -0,0 +1,54 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
#
|
||||
# Various errors we can raise.
|
||||
#
|
||||
|
||||
class error(Exception):
|
||||
"""Base class for Builder exceptions."""
|
||||
def set_output(self, msg):
|
||||
self.msg = msg
|
||||
def __str__(self):
|
||||
return self.msg
|
||||
|
||||
class general(error):
|
||||
"""Raise for a general error."""
|
||||
def __init__(self, what):
|
||||
self.set_output('error: ' + what)
|
||||
|
||||
class internal(error):
|
||||
"""Raise for an internal error."""
|
||||
def __init__(self, what):
|
||||
self.set_output('internal error: ' + what)
|
||||
|
||||
class exit(error):
|
||||
"""Raise for to exit."""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
raise general('a general error')
|
||||
except general, gerr:
|
||||
print 'caught:', gerr
|
||||
try:
|
||||
raise internal('an internal error')
|
||||
except internal, ierr:
|
||||
print 'caught:', ierr
|
363
sb/execute.py
Executable file
@ -0,0 +1,363 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
#
|
||||
# Execute commands or scripts.
|
||||
#
|
||||
# Note, the subprocess module is only in Python 2.4 or higher.
|
||||
#
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
import threading
|
||||
|
||||
import error
|
||||
import log
|
||||
|
||||
# Redefine the PIPE from subprocess
|
||||
PIPE = subprocess.PIPE
|
||||
|
||||
# Regular expression to find quotes.
|
||||
qstr = re.compile('[rR]?\'([^\\n\'\\\\]|\\\\.)*\'|[rR]?"([^\\n"\\\\]|\\\\.)*"')
|
||||
|
||||
def check_type(command):
|
||||
"""Checks the type of command we have. The types are spawn and
|
||||
shell."""
|
||||
if command in ['spawn', 'shell']:
|
||||
return True
|
||||
return False
|
||||
|
||||
def arg_list(args):
|
||||
"""Turn a string of arguments into a list suitable for
|
||||
spawning a command. If the args are already a list return
|
||||
it."""
|
||||
if type(args) is list:
|
||||
return args
|
||||
argstr = args
|
||||
args = []
|
||||
while len(argstr):
|
||||
qs = qstr.search(argstr)
|
||||
if not qs:
|
||||
args.extend(argstr.split())
|
||||
argstr= ''
|
||||
else:
|
||||
# We have a quoted string. Get the string before
|
||||
# the quoted string and splt on white space then
|
||||
# add the quoted string as an option then remove
|
||||
# the first + quoted string and try again
|
||||
front = argstr[:qs.start()]
|
||||
args.extend(front.split())
|
||||
args.append(argstr[qs.start() + 1:qs.end() - 1])
|
||||
argstr = argstr[qs.end():]
|
||||
return args
|
||||
|
||||
def arg_subst(command, substs):
|
||||
"""Substitute the %[0-9] in the command with the subst values."""
|
||||
args = arg_list(command)
|
||||
if substs:
|
||||
for a in range(0, len(args)):
|
||||
for r in range(0, len(substs)):
|
||||
args[a] = re.compile(('%%%d' % (r))).sub(substs[r], args[a])
|
||||
return args
|
||||
|
||||
def arg_subst_str(command, subst):
|
||||
cmd = arg_subst(command, subst)
|
||||
def add(x, y): return x + ' ' + str(y)
|
||||
return reduce(add, cmd, '')
|
||||
|
||||
class execute:
|
||||
"""Execute commands or scripts. The 'output' is a funtion
|
||||
that handles the output from the process."""
|
||||
def __init__(self, output = None, error_prefix = '', verbose = False):
|
||||
self.output = output
|
||||
self.error_prefix = error_prefix
|
||||
self.verbose = verbose
|
||||
self.shell_exe = None
|
||||
self.shell_commands = False
|
||||
self.path = None
|
||||
self.environment = None
|
||||
|
||||
def capture(self, proc, timeout = None):
|
||||
"""Create 2 threads to read stdout and stderr and send to the
|
||||
output handler. Based on the 'communicate' code in the subprocess
|
||||
module."""
|
||||
def _readthread(fh, out, prefix = ''):
|
||||
"""Read from a file handle and write to the output handler
|
||||
until the file closes."""
|
||||
while True:
|
||||
line = fh.readline()
|
||||
if len(line) == 0:
|
||||
break
|
||||
if out:
|
||||
out(prefix + line)
|
||||
else:
|
||||
log.output(prefix + line)
|
||||
def _timerthread(proc, timer):
|
||||
"""Timer thread calls the timer handler if one
|
||||
is present once a second. The user provides a handler
|
||||
and returns False to kill the process or True continue."""
|
||||
while True:
|
||||
time.sleep(1)
|
||||
if not timer(proc):
|
||||
proc.stdout.close()
|
||||
proc.stderr.close()
|
||||
|
||||
if proc.stdout:
|
||||
stdout_thread = threading.Thread(target = _readthread,
|
||||
args = (proc.stdout,
|
||||
self.output,
|
||||
''))
|
||||
stdout_thread.setDaemon(True)
|
||||
stdout_thread.start()
|
||||
if proc.stderr:
|
||||
stderr_thread = threading.Thread(target = _readthread,
|
||||
args = (proc.stderr,
|
||||
self.output,
|
||||
self.error_prefix))
|
||||
stderr_thread.setDaemon(True)
|
||||
stderr_thread.start()
|
||||
if proc.stdout:
|
||||
stdout_thread.join()
|
||||
if proc.stderr:
|
||||
stderr_thread.join()
|
||||
return proc.wait()
|
||||
|
||||
def open(self, command, capture = True, shell = False,
|
||||
cwd = None, env = None,
|
||||
stdin = None, stdout = None, stderr = None):
|
||||
"""Open a command with arguments. Provide the arguments as a list or
|
||||
a string."""
|
||||
if self.verbose:
|
||||
s = command
|
||||
if type(command) is list:
|
||||
def add(x, y): return x + ' ' + str(y)
|
||||
s = reduce(add, command, '')[1:]
|
||||
what = 'spawn'
|
||||
if shell:
|
||||
what = 'shell'
|
||||
log.output(what + ': ' + s)
|
||||
if shell and self.shell_exe:
|
||||
command = arg_list(command)
|
||||
command[:0] = self.shell_exe
|
||||
if not stdout:
|
||||
stdout = subprocess.PIPE
|
||||
if not stderr:
|
||||
stderr = subprocess.PIPE
|
||||
proc = None
|
||||
if cwd is None:
|
||||
cwd = self.path
|
||||
if env is None:
|
||||
env = self.environment
|
||||
try:
|
||||
# Work around a problem on Windows with commands that
|
||||
# have a '.' and no extension. Windows needs the full
|
||||
# command name.
|
||||
if sys.platform == "win32" and type(command) is list:
|
||||
if command[0].find('.') >= 0:
|
||||
r, e = os.path.splitext(command[0])
|
||||
if e not in ['.exe', '.com', '.bat']:
|
||||
command[0] = command[0] + '.exe'
|
||||
proc = subprocess.Popen(command, shell = shell,
|
||||
cwd = cwd, env = env,
|
||||
stdin = stdin, stdout = stdout,
|
||||
stderr = stderr)
|
||||
if not capture:
|
||||
return (0, proc)
|
||||
exit_code = self.capture(proc)
|
||||
if self.verbose:
|
||||
log.output('exit: ' + str(exit_code))
|
||||
except OSError, ose:
|
||||
exit_code = ose.errno
|
||||
if self.verbose:
|
||||
log.output('exit: ' + str(ose))
|
||||
return (exit_code, proc)
|
||||
|
||||
def spawn(self, command, capture = True, cwd = None, env = None,
|
||||
stdin = None, stdout = None, stderr = None):
|
||||
"""Spawn a command with arguments. Provide the arguments as a list or
|
||||
a string."""
|
||||
return self.open(command, capture, False, cwd, env,
|
||||
stdin, stdout, stderr)
|
||||
|
||||
def shell(self, command, capture = True, cwd = None, env = None,
|
||||
stdin = None, stdout = None, stderr = None):
|
||||
"""Execute a command within a shell context. The command can contain
|
||||
argumments. The shell is specific to the operating system. For example
|
||||
it is cmd.exe on Windows XP."""
|
||||
return self.open(command, capture, True, cwd, env,
|
||||
stdin, stdout, stderr)
|
||||
|
||||
def command(self, command, args = None, capture = True, shell = False,
|
||||
cwd = None, env = None,
|
||||
stdin = None, stdout = None, stderr = None):
|
||||
"""Run the command with the args. The args can be a list
|
||||
or a string."""
|
||||
if args and not type(args) is list:
|
||||
args = arg_list(args)
|
||||
cmd = [command]
|
||||
if args:
|
||||
cmd.extend(args)
|
||||
return self.open(cmd, capture = capture, shell = shell,
|
||||
cwd = cwd, env = env,
|
||||
stdin = stdin, stdout = stdout, stderr = stderr)
|
||||
|
||||
def command_subst(self, command, substs, capture = True, shell = False,
|
||||
cwd = None, env = None,
|
||||
stdin = None, stdout = None, stderr = None):
|
||||
"""Run the command from the config data with the
|
||||
option format string subsituted with the subst variables."""
|
||||
args = arg_subst(command, substs)
|
||||
return self.command(args[0], args[1:], capture = capture,
|
||||
shell = shell or self.shell_commands,
|
||||
cwd = cwd, env = env,
|
||||
stdin = stdin, stdout = stdout, stderr = stderr)
|
||||
|
||||
def set_shell(self, execute):
|
||||
"""Set the shell to execute when issuing a shell command."""
|
||||
args = arg_list(execute)
|
||||
if len(args) == 0 or not os.path.isfile(args[0]):
|
||||
raise error.general('could find shell: ' + execute)
|
||||
self.shell_exe = args
|
||||
|
||||
def command_use_shell(self):
|
||||
"""Force all commands to use a shell. This can be used with set_shell
|
||||
to allow Unix commands be executed on Windows with a Unix shell such
|
||||
as Cygwin or MSYS. This may cause piping to fail."""
|
||||
self.shell_commands = True
|
||||
|
||||
def set_output(self, output):
|
||||
"""Set the output handler. The stdout of the last process in a pipe
|
||||
line is passed to this handler."""
|
||||
old_output = self.output
|
||||
self.output = output
|
||||
return old_output
|
||||
|
||||
def set_path(self, path):
|
||||
"""Set the path changed to before the child process is created."""
|
||||
old_path = self.path
|
||||
self.path = path
|
||||
return old_path
|
||||
|
||||
def set_environ(self, environment):
|
||||
"""Set the environment passed to the child process when created."""
|
||||
old_environment = self.environment
|
||||
self.environment = environment
|
||||
return old_environment
|
||||
|
||||
class capture_execution(execute):
|
||||
"""Capture all output as a string and return it."""
|
||||
|
||||
class _output_snapper:
|
||||
def __init__(self, log = None, dump = False):
|
||||
self.output = ''
|
||||
self.log = log
|
||||
self.dump = dump
|
||||
|
||||
def handler(self, text):
|
||||
if not self.dump:
|
||||
if self.log is not None:
|
||||
self.log.output(text)
|
||||
else:
|
||||
self.output += text
|
||||
|
||||
def get_and_clear(self):
|
||||
text = self.output
|
||||
self.output = ''
|
||||
return text.strip()
|
||||
|
||||
def __init__(self, log = None, dump = False, error_prefix = '', verbose = False):
|
||||
self.snapper = capture_execution._output_snapper(log = log, dump = dump)
|
||||
execute.__init__(self, output = self.snapper.handler,
|
||||
error_prefix = error_prefix,
|
||||
verbose = verbose)
|
||||
|
||||
def open(self, command, capture = True, shell = False, cwd = None, env = None,
|
||||
stdin = None, stdout = None, stderr = None):
|
||||
if not capture:
|
||||
raise error.general('output capture must be true; leave as default')
|
||||
#self.snapper.get_and_clear()
|
||||
exit_code, proc = execute.open(self, command, capture = True, shell = shell,
|
||||
cwd = cwd, env = env,
|
||||
stdin = stdin, stdout = stdout, stderr = stderr)
|
||||
return (exit_code, proc, self.snapper.get_and_clear())
|
||||
|
||||
def set_output(self, output):
|
||||
raise error.general('output capture cannot be overrided')
|
||||
|
||||
if __name__ == "__main__":
|
||||
def run_tests(e, commands, use_shell):
|
||||
for c in commands['shell']:
|
||||
e.shell(c)
|
||||
for c in commands['spawn']:
|
||||
e.spawn(c)
|
||||
for c in commands['cmd']:
|
||||
if type(c) is str:
|
||||
e.command(c, shell = use_shell)
|
||||
else:
|
||||
e.command(c[0], c[1], shell = use_shell)
|
||||
for c in commands['csubsts']:
|
||||
e.command_subst(c[0], c[1], shell = use_shell)
|
||||
ec, proc = e.command(commands['pipe'][0], commands['pipe'][1],
|
||||
capture = False, stdin = subprocess.PIPE)
|
||||
if ec == 0:
|
||||
print 'piping input into ' + commands['pipe'][0] + ': ' + \
|
||||
commands['pipe'][2]
|
||||
proc.stdin.write(commands['pipe'][2])
|
||||
proc.stdin.close()
|
||||
e.capture(proc)
|
||||
del proc
|
||||
|
||||
cmd_shell_test = 'if "%OS%" == "Windows_NT" (echo It is WinNT) else echo Is is not WinNT'
|
||||
sh_shell_test = 'x="me"; if [ $x = "me" ]; then echo "It was me"; else "It was him"; fi'
|
||||
|
||||
commands = {}
|
||||
commands['windows'] = {}
|
||||
commands['unix'] = {}
|
||||
commands['windows']['shell'] = ['cd', 'dir /w', '.\\xyz', cmd_shell_test]
|
||||
commands['windows']['spawn'] = ['hostname', 'hostnameZZ', ['netstat', '/e']]
|
||||
commands['windows']['cmd'] = [('ipconfig'), ('nslookup', 'www.python.org')]
|
||||
commands['windows']['csubsts'] = [('netstat %0', ['-a']),
|
||||
('netstat %0 %1', ['-a', '-n'])]
|
||||
commands['windows']['pipe'] = ('ftp', None, 'help\nquit')
|
||||
commands['unix']['shell'] = ['pwd', 'ls -las', './xyz', sh_shell_test]
|
||||
commands['unix']['spawn'] = ['ls', 'execute.pyc', ['ls', '-i']]
|
||||
commands['unix']['cmd'] = [('date'), ('date', '-R'), ('date', ['-u', '+%d %D']),
|
||||
('date', '-u "+%d %D %S"')]
|
||||
commands['unix']['csubsts'] = [('date %0 "+%d %D %S"', ['-u']),
|
||||
('date %0 %1', ['-u', '+%d %D %S'])]
|
||||
commands['unix']['pipe'] = ('grep', 'hello', 'hello world')
|
||||
|
||||
print arg_list('cmd a1 a2 "a3 is a string" a4')
|
||||
print arg_list('cmd b1 b2 "b3 is a string a4')
|
||||
print arg_subst(['nothing', 'xx-%0-yyy', '%1', '%2-something'],
|
||||
['subst0', 'subst1', 'subst2'])
|
||||
|
||||
e = execute(error_prefix = 'ERR: ', verbose = True)
|
||||
if sys.platform == "win32":
|
||||
run_tests(e, commands['windows'], False)
|
||||
if os.path.exists('c:\\msys\\1.0\\bin\\sh.exe'):
|
||||
e.set_shell('c:\\msys\\1.0\\bin\\sh.exe --login -c')
|
||||
commands['unix']['pipe'] = ('c:\\msys\\1.0\\bin\\grep',
|
||||
'hello', 'hello world')
|
||||
run_tests(e, commands['unix'], True)
|
||||
else:
|
||||
run_tests(e, commands['unix'], False)
|
||||
del e
|
67
sb/freebsd.py
Normal file
@ -0,0 +1,67 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@rtems.org)
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is part of the RTEMS Tools package in 'rtems-tools'.
|
||||
#
|
||||
# RTEMS Tools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# RTEMS Tools is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with RTEMS Tools. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
#
|
||||
# This code is based on what ever doco about spec files I could find and
|
||||
# RTEMS project's spec files.
|
||||
#
|
||||
|
||||
import pprint
|
||||
import os
|
||||
|
||||
import execute
|
||||
|
||||
def load():
|
||||
uname = os.uname()
|
||||
sysctl = '/sbin/sysctl '
|
||||
e = execute.capture_execution()
|
||||
exit_code, proc, output = e.shell(sysctl + 'hw.ncpu')
|
||||
if exit_code == 0:
|
||||
smp_mflags = '-j' + output.split(' ')[1].strip()
|
||||
else:
|
||||
smp_mflags = ''
|
||||
if uname[4] == 'amd64':
|
||||
cpu = 'x86_64'
|
||||
else:
|
||||
cpu = uname[4]
|
||||
version = uname[2]
|
||||
if version.find('-') > 0:
|
||||
version = version.split('-')[0]
|
||||
defines = {
|
||||
'_os': ('none', 'none', 'freebsd'),
|
||||
'_host': ('triplet', 'required', cpu + '-freebsd' + version),
|
||||
'_host_vendor': ('none', 'none', 'pc'),
|
||||
'_host_os': ('none', 'none', 'freebsd'),
|
||||
'_host_cpu': ('none', 'none', cpu),
|
||||
'_host_alias': ('none', 'none', '%{nil}'),
|
||||
'_host_arch': ('none', 'none', cpu),
|
||||
'_usr': ('dir', 'required', '/usr/local'),
|
||||
'_var': ('dir', 'optional', '/usr/local/var'),
|
||||
'optflags': ('none', 'none', '-O2 -I/usr/local/include -L/usr/local/lib'),
|
||||
'_smp_mflags': ('none', 'none', smp_mflags),
|
||||
'__bash': ('exe', 'optional', '/usr/local//bin/bash'),
|
||||
'__xz': ('exe', 'optional', '/usr/bin/xz'),
|
||||
'__make': ('exe', 'required', 'gmake')
|
||||
}
|
||||
return defines
|
||||
|
||||
if __name__ == '__main__':
|
||||
pprint.pprint(load())
|
63
sb/linux.py
Normal file
@ -0,0 +1,63 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
#
|
||||
# This code is based on what ever doco about spec files I could find and
|
||||
# RTEMS project's spec files.
|
||||
#
|
||||
|
||||
import pprint
|
||||
import os
|
||||
|
||||
import execute
|
||||
|
||||
def load():
|
||||
uname = os.uname()
|
||||
smp_mflags = ''
|
||||
processors = '/bin/grep processor /proc/cpuinfo'
|
||||
e = execute.capture_execution()
|
||||
exit_code, proc, output = e.shell(processors)
|
||||
if exit_code == 0:
|
||||
cpus = 0
|
||||
for l in output.split('\n'):
|
||||
count = l.split(':')[1].strip()
|
||||
if count > cpus:
|
||||
cpus = int(count)
|
||||
if cpus > 0:
|
||||
smp_mflags = '-j%d' % (cpus)
|
||||
defines = {
|
||||
'_os': ('none', 'none', 'linux'),
|
||||
'_host': ('triplet', 'required', uname[4] + '-linux-gnu'),
|
||||
'_host_vendor': ('none', 'none', 'gnu'),
|
||||
'_host_os': ('none', 'none', 'linux'),
|
||||
'_host_cpu': ('none', 'none', uname[4]),
|
||||
'_host_alias': ('none', 'none', '%{nil}'),
|
||||
'_host_arch': ('none', 'none', uname[4]),
|
||||
'_usr': ('dir', 'required', '/usr'),
|
||||
'_var': ('dir', 'required', '/usr/var'),
|
||||
'optflags': ('none', 'none', '-O2 -fasynchronous-unwind-tables'),
|
||||
'_smp_mflags': ('none', 'none', smp_mflags),
|
||||
'__bzip2': ('exe', 'required', '/usr/bin/bzip2'),
|
||||
'__gzip': ('exe', 'required', '/bin/gzip'),
|
||||
'__tar': ('exe', 'required', '/bin/tar')
|
||||
}
|
||||
return defines
|
||||
|
||||
if __name__ == '__main__':
|
||||
pprint.pprint(load())
|
111
sb/log.py
Executable file
@ -0,0 +1,111 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@rtems.org)
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is part of the RTEMS Tools package in 'rtems-testing'.
|
||||
#
|
||||
# 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.
|
||||
|
||||
#
|
||||
# Log output to stdout and/or a file.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import error
|
||||
|
||||
#
|
||||
# A global log.
|
||||
#
|
||||
default = None
|
||||
|
||||
def set_default_once(log):
|
||||
if default is None:
|
||||
default = log
|
||||
|
||||
def output(text = os.linesep, log = None):
|
||||
"""Output the text to a log if provided else send it to stdout."""
|
||||
if text is None:
|
||||
text = os.linesep
|
||||
if type(text) is list:
|
||||
_text = ''
|
||||
for l in text:
|
||||
_text += l + os.linesep
|
||||
text = _text
|
||||
if log:
|
||||
log.output(text)
|
||||
elif default is not None:
|
||||
default.output(text)
|
||||
else:
|
||||
for l in text.replace(chr(13), '').splitlines():
|
||||
print l
|
||||
|
||||
def flush(log = None):
|
||||
if log:
|
||||
log.flush()
|
||||
elif default is not None:
|
||||
default.flush()
|
||||
|
||||
class log:
|
||||
"""Log output to stdout or a file."""
|
||||
def __init__(self, streams = None):
|
||||
self.fhs = [None, None]
|
||||
if streams:
|
||||
for s in streams:
|
||||
if s == 'stdout':
|
||||
self.fhs[0] = sys.stdout
|
||||
elif s == 'stderr':
|
||||
self.fhs[1] = sys.stderr
|
||||
else:
|
||||
try:
|
||||
self.fhs.append(file(s, 'w'))
|
||||
except IOError, ioe:
|
||||
raise error.general("creating log file '" + s + \
|
||||
"': " + str(ioe))
|
||||
|
||||
def __del__(self):
|
||||
for f in range(2, len(self.fhs)):
|
||||
self.fhs[f].close()
|
||||
|
||||
def has_stdout(self):
|
||||
return self.fhs[0] is not None
|
||||
|
||||
def has_stderr(self):
|
||||
return self.fhs[1] is not None
|
||||
|
||||
def output(self, text):
|
||||
"""Output the text message to all the logs."""
|
||||
# Reformat the text to have local line types.
|
||||
out = ''
|
||||
for l in text.replace(chr(13), '').splitlines():
|
||||
out += l + os.linesep
|
||||
for f in range(0, len(self.fhs)):
|
||||
if self.fhs[f] is not None:
|
||||
self.fhs[f].write(out)
|
||||
|
||||
def flush(self):
|
||||
"""Flush the output."""
|
||||
for f in range(0, len(self.fhs)):
|
||||
if self.fhs[f] is not None:
|
||||
self.fhs[f].flush()
|
||||
|
||||
if __name__ == "__main__":
|
||||
l = log(['stdout', 'log.txt'])
|
||||
for i in range(0, 10):
|
||||
l.output('hello world: %d\n' % (i))
|
||||
l.output('hello world CRLF\r\n')
|
||||
l.output('hello world NONE')
|
||||
l.flush()
|
||||
del l
|
95
sb/path.py
Normal file
@ -0,0 +1,95 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
#
|
||||
# Manage paths locally. The internally the path is in Unix or shell format and
|
||||
# we convert to the native format when performing operations at the Python
|
||||
# level. This allows macro expansion to work.
|
||||
#
|
||||
|
||||
import os
|
||||
import string
|
||||
|
||||
windows = os.name == 'nt'
|
||||
|
||||
def host(path):
|
||||
if path is not None:
|
||||
while '//' in path:
|
||||
path = path.replace('//', '/')
|
||||
if windows and len(path) > 2:
|
||||
if path[0] == '/' and path[2] == '/' and \
|
||||
(path[1] in string.ascii_lowercase or \
|
||||
path[1] in string.ascii_uppercase):
|
||||
path = ('%s:%s' % (path[1], path[2:])).replace('/', '\\')
|
||||
return path
|
||||
|
||||
def shell(path):
|
||||
if path is not None:
|
||||
if windows and len(path) > 1 and path[1] == ':':
|
||||
path = ('/%s%s' % (path[0], path[2:])).replace('\\', '/')
|
||||
while '//' in path:
|
||||
path = path.replace('//', '/')
|
||||
return path
|
||||
|
||||
def basename(path):
|
||||
return shell(os.path.basename(path))
|
||||
|
||||
def dirname(path):
|
||||
return shell(os.path.dirname(path))
|
||||
|
||||
def join(path, *args):
|
||||
path = shell(path)
|
||||
for arg in args:
|
||||
path += '/' + shell(arg)
|
||||
return shell(path)
|
||||
|
||||
def abspath(path):
|
||||
return shell(os.path.abspath(host(path)))
|
||||
|
||||
def splitext(path):
|
||||
root, ext = os.path.splitext(host(path))
|
||||
return shell(root), ext
|
||||
|
||||
def exists(path):
|
||||
return os.path.exists(host(path))
|
||||
|
||||
def isdir(path):
|
||||
return os.path.isdir(host(path))
|
||||
|
||||
def isfile(path):
|
||||
return os.path.isfile(host(path))
|
||||
|
||||
def isabspath(path):
|
||||
return path[0] == '/'
|
||||
|
||||
if __name__ == '__main__':
|
||||
print host('/a/b/c/d-e-f')
|
||||
print host('//a/b//c/d-e-f')
|
||||
print shell('/w/x/y/z')
|
||||
print basename('/as/sd/df/fg/me.txt')
|
||||
print dirname('/as/sd/df/fg/me.txt')
|
||||
print join('/d', 'g', '/tyty/fgfg')
|
||||
windows = True
|
||||
print host('/a/b/c/d-e-f')
|
||||
print host('//a/b//c/d-e-f')
|
||||
print shell('/w/x/y/z')
|
||||
print shell('w:/x/y/z')
|
||||
print basename('x:/sd/df/fg/me.txt')
|
||||
print dirname('x:/sd/df/fg/me.txt')
|
||||
print join('s:/d/', '/g', '/tyty/fgfg')
|
250
sb/setbuilder.py
Normal file
@ -0,0 +1,250 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
#
|
||||
# This code builds a cross-gcc compiler tool suite given a tool set. A tool
|
||||
# set lists the various tools. These are specific tool configurations.
|
||||
#
|
||||
|
||||
import distutils.dir_util
|
||||
import glob
|
||||
import operator
|
||||
import os
|
||||
|
||||
import build
|
||||
import check
|
||||
import defaults
|
||||
import error
|
||||
import log
|
||||
import path
|
||||
|
||||
#
|
||||
# Version of Source Builder Set Builder.
|
||||
#
|
||||
version = '0.1'
|
||||
|
||||
def _trace(opts, text):
|
||||
if opts.trace():
|
||||
print text
|
||||
|
||||
def _notice(opts, text):
|
||||
if not opts.quiet() and not log.default.has_stdout():
|
||||
print text
|
||||
log.output(text)
|
||||
log.flush()
|
||||
|
||||
class buildset:
|
||||
"""Build a set builds a set of packages."""
|
||||
|
||||
def __init__(self, bset, _defaults, opts):
|
||||
_trace(opts, '_bset:%s: init' % (bset))
|
||||
self.opts = opts
|
||||
self.defaults = _defaults
|
||||
self.bset = bset
|
||||
self.bset_pkg = '%s-%s-set' % (self.opts.expand('%{_target}', _defaults),
|
||||
self.bset)
|
||||
|
||||
def _output(self, text):
|
||||
if not self.opts.quiet():
|
||||
log.output(text)
|
||||
|
||||
def copy(self, src, dst):
|
||||
if os.path.isdir(path.host(src)):
|
||||
topdir = self.opts.expand('%{_topdir}', self.defaults)
|
||||
what = '%s -> %s' % \
|
||||
(path.host(src[len(topdir) + 1:]), path.host(dst[len(topdir) + 1:]))
|
||||
_notice(self.opts, 'installing: %s' % (what))
|
||||
if not self.opts.dry_run():
|
||||
try:
|
||||
files = distutils.dir_util.copy_tree(path.host(src),
|
||||
path.host(dst))
|
||||
for f in files:
|
||||
self._output(f)
|
||||
except IOError, err:
|
||||
raise error.general('installing tree: %s: %s' % (what, str(err)))
|
||||
except distutils.errors.DistutilsFileError, err:
|
||||
raise error.general('installing tree: %s' % (str(err)))
|
||||
|
||||
def first_package(self, _build):
|
||||
tmproot = path.abspath(_build.config.expand('%{_tmproot}'))
|
||||
_build.rmdir(tmproot)
|
||||
_build.mkdir(tmproot)
|
||||
prefix = _build.config.expand('%{_prefix}')
|
||||
if prefix[0] == os.sep:
|
||||
prefix = prefix[1:]
|
||||
tmpprefix = path.join(tmproot, prefix)
|
||||
tmpbindir = path.join(tmpprefix, 'bin')
|
||||
# exporting to the environment
|
||||
os.environ['SB_TMPPREFIX'] = tmpprefix
|
||||
os.environ['SB_TMPBINDIR'] = tmpbindir
|
||||
os.environ['PATH'] = path.host(tmpbindir) + os.pathsep + os.environ['PATH']
|
||||
self._output('path: ' + os.environ['PATH'])
|
||||
# shell format
|
||||
return tmproot
|
||||
|
||||
def every_package(self, _build, tmproot):
|
||||
self.copy(_build.config.abspath('%{buildroot}'), tmproot)
|
||||
|
||||
def last_package(self, _build, tmproot):
|
||||
tar = path.join(_build.config.expand('%{_tardir}'),
|
||||
_build.config.expand('%s.tar.bz2' % (self.bset_pkg)))
|
||||
_notice(self.opts, 'tarball: %s' % path.host(tar))
|
||||
if not self.opts.dry_run():
|
||||
cmd = _build.config.expand("'cd " + tmproot + \
|
||||
" && %{__tar} -cf - . | %{__bzip2} > " + tar + "'")
|
||||
_build.run(cmd, shell_opts = '-c', cwd = tmproot)
|
||||
|
||||
def load(self):
|
||||
|
||||
def _clean(line):
|
||||
line = line[0:-1]
|
||||
b = line.find('#')
|
||||
if b >= 0:
|
||||
line = line[1:b]
|
||||
return line.strip()
|
||||
|
||||
exbset = self.opts.expand(self.bset, self.defaults)
|
||||
|
||||
self.defaults['_bset'] = ('none', 'none', exbset)
|
||||
|
||||
root, ext = path.splitext(exbset)
|
||||
|
||||
if exbset.endswith('.bset'):
|
||||
bset = exbset
|
||||
else:
|
||||
bset = '%s.bset' % (exbset)
|
||||
|
||||
bsetname = bset
|
||||
|
||||
if not path.exists(bsetname):
|
||||
for cp in self.opts.expand('%{_configdir}', self.defaults).split(':'):
|
||||
configdir = path.abspath(cp)
|
||||
bsetname = path.join(configdir, bset)
|
||||
if path.exists(bsetname):
|
||||
break
|
||||
bsetname = None
|
||||
if bsetname is None:
|
||||
raise error.general('no build set file found: %s' % (bset))
|
||||
try:
|
||||
if self.opts.trace():
|
||||
print '_bset:%s: open: %s' % (self.bset, bsetname)
|
||||
bset = open(path.host(bsetname), 'r')
|
||||
except IOError, err:
|
||||
raise error.general('error opening bset file: %s' % (bsetname))
|
||||
|
||||
configs = []
|
||||
|
||||
try:
|
||||
lc = 0
|
||||
for l in bset:
|
||||
lc += 1
|
||||
l = _clean(l)
|
||||
if len(l) == 0:
|
||||
continue
|
||||
if self.opts.trace():
|
||||
print '%03d: %s' % (lc, l)
|
||||
if ':' in l:
|
||||
ls = l.split(':')
|
||||
if ls[0].strip() == 'package':
|
||||
self.bset_pkg = self.opts.expand(ls[1].strip(), self.defaults)
|
||||
self.defaults['package'] = ('none', 'none', self.bset_pkg)
|
||||
elif l[0] == '%':
|
||||
if l.startswith('%define'):
|
||||
ls = l.split()
|
||||
self.defaults[ls[1].strip()] = ('none', 'none', ls[2].strip())
|
||||
else:
|
||||
raise error.general('invalid directive in build set files: %s' % (l))
|
||||
else:
|
||||
configs += [l.strip()]
|
||||
except:
|
||||
bset.close()
|
||||
raise
|
||||
|
||||
bset.close()
|
||||
|
||||
return configs
|
||||
|
||||
def make(self):
|
||||
|
||||
_trace(self.opts, '_bset:%s: make' % (self.bset))
|
||||
_notice(self.opts, 'Build Set: %s' % (self.bset))
|
||||
|
||||
configs = self.load()
|
||||
|
||||
_trace(self.opts, '_bset:%s: configs: %s' % (self.bset, ','.join(configs)))
|
||||
|
||||
current_path = os.environ['PATH']
|
||||
try:
|
||||
builds = []
|
||||
for s in range(0, len(configs)):
|
||||
b = build.build(configs[s], _defaults = self.defaults, opts = self.opts)
|
||||
if s == 0:
|
||||
tmproot = self.first_package(b)
|
||||
b.make()
|
||||
self.every_package(b, tmproot)
|
||||
if s == len(configs) - 1:
|
||||
self.last_package(b, tmproot)
|
||||
builds += [b]
|
||||
if not self.opts.no_clean():
|
||||
for b in builds:
|
||||
_notice(self.opts, 'cleaning: %s' % (b.name()))
|
||||
b.cleanup()
|
||||
for b in builds:
|
||||
del b
|
||||
except:
|
||||
os.environ['PATH'] = current_path
|
||||
raise
|
||||
os.environ['PATH'] = current_path
|
||||
|
||||
def run():
|
||||
import sys
|
||||
try:
|
||||
optargs = { '--list-configs': 'List available configurations',
|
||||
'--list-bsets': 'List available build sets'}
|
||||
opts, _defaults = defaults.load(sys.argv, optargs)
|
||||
log.default = log.log(opts.logfiles())
|
||||
_notice(opts, 'Source Builder - Set Builder, v%s' % (version))
|
||||
if not check.host_setup(opts, _defaults):
|
||||
if not opts.force():
|
||||
raise error.general('host build environment is not set up correctly (use --force to proceed)')
|
||||
_notice(opts, 'warning: forcing build with known host setup problems')
|
||||
if opts.get_arg('--list-configs'):
|
||||
build.list_configs(opts, _defaults)
|
||||
elif opts.get_arg('--list-bsets'):
|
||||
build.list_configs(opts, _defaults, ext = '.bset')
|
||||
else:
|
||||
for bset in opts.params():
|
||||
c = buildset(bset, _defaults = _defaults, opts = opts)
|
||||
c.make()
|
||||
del c
|
||||
except error.general, gerr:
|
||||
print gerr
|
||||
sys.exit(1)
|
||||
except error.internal, ierr:
|
||||
print ierr
|
||||
sys.exit(1)
|
||||
except error.exit, eerr:
|
||||
pass
|
||||
except KeyboardInterrupt:
|
||||
_notice(opts, 'user terminated')
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
91
sb/windows.py
Normal file
@ -0,0 +1,91 @@
|
||||
#
|
||||
# RTEMS Tools Project (http://www.rtems.org/)
|
||||
# Copyright 2010-2012 Chris Johns (chrisj@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.
|
||||
|
||||
#
|
||||
# Windows specific support and overrides.
|
||||
#
|
||||
|
||||
import pprint
|
||||
import os
|
||||
|
||||
import execute
|
||||
|
||||
def load():
|
||||
uname = 'win32'
|
||||
if os.environ.has_key('NUMBER_OF_PROCESSORS'):
|
||||
ncpus = int(os.environ['NUMBER_OF_PROCESSORS'])
|
||||
else:
|
||||
ncpus = 0
|
||||
if ncpus > 1:
|
||||
smp_mflags = '-j' + str(ncpus)
|
||||
else:
|
||||
smp_mflags = ''
|
||||
if os.environ.has_key('HOSTTYPE'):
|
||||
hosttype = os.environ['HOSTTYPE']
|
||||
else:
|
||||
hosttype = 'i686'
|
||||
system = 'mingw32'
|
||||
defines = {
|
||||
'_os': ('none', 'none', 'win32'),
|
||||
'_host': ('triplet', 'required', hosttype + '-pc-' + system),
|
||||
'_host_vendor': ('none', 'none', 'microsoft'),
|
||||
'_host_os': ('none', 'none', 'win32'),
|
||||
'_host_cpu': ('none', 'none', hosttype),
|
||||
'_host_alias': ('none', 'none', '%{nil}'),
|
||||
'_host_arch': ('none', 'none', hosttype),
|
||||
'_usr': ('dir', 'optional', '/opt/local'),
|
||||
'_var': ('dir', 'optional', '/opt/local/var'),
|
||||
'_smp_mflags': ('none', 'none', smp_mflags),
|
||||
'__bash': ('exe', 'required', 'bash'),
|
||||
'__bzip2': ('exe', 'required', 'bzip2'),
|
||||
'__cat': ('exe', 'required', 'cat'),
|
||||
'__cc': ('exe', 'required', 'gcc'),
|
||||
'__chgrp': ('exe', 'required', 'chgrp'),
|
||||
'__chmod': ('exe', 'required', 'chmod'),
|
||||
'__chown': ('exe', 'required', 'chown'),
|
||||
'__cp': ('exe', 'required', 'cp'),
|
||||
'__cxx': ('exe', 'required', 'g++'),
|
||||
'__grep': ('exe', 'required', 'grep'),
|
||||
'__gzip': ('exe', 'required', 'gzip'),
|
||||
'__id': ('exe', 'required', 'id'),
|
||||
'__install': ('exe', 'required', 'install'),
|
||||
'__install_info': ('exe', 'required', 'install-info'),
|
||||
'__ld': ('exe', 'required', 'ld'),
|
||||
'__ldconfig': ('exe', 'none', ''),
|
||||
'__mkdir': ('exe', 'required', 'mkdir'),
|
||||
'__mv': ('exe', 'required', 'mv'),
|
||||
'__nm': ('exe', 'required', 'nm'),
|
||||
'__nm': ('exe', 'required', 'nm'),
|
||||
'__objcopy': ('exe', 'required', 'objcopy'),
|
||||
'__objdump': ('exe', 'required', 'objdump'),
|
||||
'__patch': ('exe', 'required', 'patch'),
|
||||
'__rm': ('exe', 'required', 'rm'),
|
||||
'__sed': ('exe', 'required', 'sed'),
|
||||
'__sh': ('exe', 'required', 'sh'),
|
||||
'__tar': ('exe', 'required', 'bsdtar'),
|
||||
'__unzip': ('exe', 'required', 'unzip'),
|
||||
'__xz': ('exe', 'required', 'xz'),
|
||||
'_buildshell': ('exe', 'required', '%{__sh}'),
|
||||
'___setup_shell': ('exe', 'required', '%{__sh}'),
|
||||
'optflags': ('none', 'none', '-O2 -pipe'),
|
||||
}
|
||||
return defines
|
||||
|
||||
if __name__ == '__main__':
|
||||
pprint.pprint(load())
|