diff options
54 files changed, 1777 insertions, 918 deletions
diff --git a/bare/config/devel/binutils-2.22-1.cfg b/bare/config/devel/binutils-2.22-1.cfg new file mode 100644 index 0000000..33a152a --- /dev/null +++ b/bare/config/devel/binutils-2.22-1.cfg @@ -0,0 +1,19 @@ +# +# Binutils 2.22. +# + +%if %{release} == %{nil} +%define release 1 +%endif + +%include %{_configdir}/checks.cfg +%include %{_configdir}/base.cfg + +%define binutils_version 2.22 +%hash sha512 binutils-2.22.tar.bz2 \ + /+jvJj75kYPozII/6Eh/99D3v5qO/ShTtfRjasoAI4UNE95OrH13pfaUE9ilDm+VuxRWm+U9+GwLzjgDRSWrdA== + +# +# The binutils build instructions. We use 2.xx Release 1. +# +%include %{_configdir}/binutils-2-1.cfg diff --git a/bare/config/devel/binutils-2.24-1.cfg b/bare/config/devel/binutils-2.24-1.cfg index 652c274..52499e3 100644 --- a/bare/config/devel/binutils-2.24-1.cfg +++ b/bare/config/devel/binutils-2.24-1.cfg @@ -8,6 +8,8 @@ %include %{_configdir}/base.cfg %define binutils_version 2.24 +%hash sha512 binutils-2.24.tar.bz2 \ + Xsla1H1JsSxFWKjbDKIQnT7hlV43dgV/MzDEUG+PTRz15QX7+KFrmEA6D83qr5hv4KIr5kViR9vazmPOH3drEg== # # Enable deterministic archives by default. This will be the default diff --git a/bare/config/devel/dtc-1.6.1-1.cfg b/bare/config/devel/dtc-1.6.1-1.cfg new file mode 100644 index 0000000..54aed09 --- /dev/null +++ b/bare/config/devel/dtc-1.6.1-1.cfg @@ -0,0 +1,18 @@ +# +# DTC (Device Tree Compiler) 1.6.1 +# + +%if %{release} == %{nil} +%define release 1 +%endif + +%include %{_configdir}/base.cfg + +%define dtc_version 1.6.1 + +%hash sha256 dtc-%{dtc_version}.tar.gz 38a6257f2c23cb9dfa1781ac4ad122d8358e1a22d33b2da0eb492c190644a376 + +# +# The DTC build instructions. We use 1.x.x Release 1. +# +%include %{_configdir}/dtc-1-1.cfg diff --git a/bare/config/devel/dtc.bset b/bare/config/devel/dtc.bset index 54521f6..56fb61e 100644 --- a/bare/config/devel/dtc.bset +++ b/bare/config/devel/dtc.bset @@ -4,4 +4,4 @@ %define release 1 -devel/dtc-1.4.1-1 +devel/dtc-1.6.1-1 diff --git a/bare/config/devel/gcc-4.6-newlib-1.20-1.cfg b/bare/config/devel/gcc-4.6-newlib-1.20-1.cfg new file mode 100644 index 0000000..e2374aa --- /dev/null +++ b/bare/config/devel/gcc-4.6-newlib-1.20-1.cfg @@ -0,0 +1,39 @@ +# +# 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.1.4 +%define mpc_version 1.0.3 +%define gmp_version 6.1.0 + +%hash sha512 gcc-core-4.6.3.tar.bz2 \ + ucVpu3E/OrCp1PbomMfQGRRUb7vmH021FRU2/+N0SQrm8VTfojgatgcrKJC3YVT769+S8GDoVAT1SZfwFpcvTA== +%hash sha512 gcc-g--4.6.3.tar.gz \ + qVHKvglD9l+ziCNrHuemi3ebq0T4aTQIkzRseYbiVEkA0LZeTyUHxpdlXzaxajB3szQG1Zh8VtMGhYZda9tOGA== +%hash sha512 newlib-1.20.0.tar.gz \ + Kr8dMJgORgxNb/5NFoLjhAPQVgSOAGdTYiVnMeV/5nWdAehby6hCWNIRlBkm4TvzxjL/OCSTGoRMiyWW55VFHw== +%hash sha512 mpfr-3.1.4.tar.bz2 \ + UQZgZv8sEu0hmGBez2iEawyWtUitr6W4Dgx4bQ30iEEaXolzNY/OcZLcl3rU5oQUzxRQDjw5dG3mJGXrFFu4GQ== +%hash sha512 mpc-1.0.3.tar.gz \ + ACi3bfEwcgwfrX3pN6DQQSJIBs5e92WJ8Zx7SdlWBxpoPi8g0VTBkqIx5pdWsZ5III8oibDBOVDOt7PPrwWaQw== +%hash sha512 gmp-6.1.0.tar.bz2 \ + PIKuq5wVltTaivrC7sOOQp6E8yEeGlcs+P0rVGSTxEwDm5IqETPqqki9fz4R2+eVo4TiHtlcvj7MWNesAiRhFw== + +# +# Project custom message +# +%define gcc_version_message GCC %{release}-RSB(%{_sbgit_id}),gcc-%{gcc_version}/newlib-%{newlib_version} + +# +# The gcc/newlib build instructions. We use 4.6 Release 1. +# +%include %{_configdir}/gcc-4.6-1.cfg diff --git a/bare/config/devel/gcc-4.9.1-newlib-2.1.0-1.cfg b/bare/config/devel/gcc-4.9.1-newlib-2.1.0-1.cfg index 495641e..e712725 100644 --- a/bare/config/devel/gcc-4.9.1-newlib-2.1.0-1.cfg +++ b/bare/config/devel/gcc-4.9.1-newlib-2.1.0-1.cfg @@ -8,9 +8,9 @@ %define gcc_version 4.9.1 %define newlib_version 2.1.0 -%define mpfr_version 3.0.1 -%define mpc_version 0.8.2 -%define gmp_version 5.0.5 +%define mpfr_version 3.1.4 +%define mpc_version 1.0.3 +%define gmp_version 6.1.0 %define with_threads 0 %define with_plugin 0 @@ -19,6 +19,17 @@ %define with_iconv 1 %endif +%hash sha512 gcc-4.9.1.tar.bz2 \ + hZgQakt8A7tNbin6G/qe5rY5DR8byobBzNJ67YMK4dEm2qUMQEEBbL+nYJDdZsUfHOBpWLjM1sO+UerodRJVkw== +%hash sha512 newlib-2.1.0.tar.gz \ + Z3CGT5MHq7JAGk5I8oaEXTpK/DCyrJh9pLlkpUhcw4I7MtBqCr9hUo6TxK2KOgqjzB7NOwM4UOayvebZu8mlRw== +%hash sha512 mpfr-3.1.4.tar.bz2 \ + UQZgZv8sEu0hmGBez2iEawyWtUitr6W4Dgx4bQ30iEEaXolzNY/OcZLcl3rU5oQUzxRQDjw5dG3mJGXrFFu4GQ== +%hash sha512 mpc-1.0.3.tar.gz \ + ACi3bfEwcgwfrX3pN6DQQSJIBs5e92WJ8Zx7SdlWBxpoPi8g0VTBkqIx5pdWsZ5III8oibDBOVDOt7PPrwWaQw== +%hash sha512 gmp-6.1.0.tar.bz2 \ + PIKuq5wVltTaivrC7sOOQp6E8yEeGlcs+P0rVGSTxEwDm5IqETPqqki9fz4R2+eVo4TiHtlcvj7MWNesAiRhFw== + # # The gcc/newlib build instructions. We use 4.9 Release 1. # diff --git a/bare/config/devel/gdb-7.7-1.cfg b/bare/config/devel/gdb-7.7-1.cfg index 1afce5a..3d0cdec 100644 --- a/bare/config/devel/gdb-7.7-1.cfg +++ b/bare/config/devel/gdb-7.7-1.cfg @@ -7,6 +7,9 @@ %define gdb_version 7.7 +%hash sha512 gdb-7.7.tar.gz \ + eNYj6X8jJUakcohURCIReUO4YtGZwR4E2E/GF210w27hqGLVJ07qKZbm6d6gnWtp5/DGxkrMS3oHuXSt0eiBPw== + # # The gdb build instructions. We use 7.xx Release 1. # diff --git a/bare/config/devel/glib-2.46.2-1.cfg b/bare/config/devel/glib-2.46.2-1.cfg index 1dc8f78..468afdc 100644 --- a/bare/config/devel/glib-2.46.2-1.cfg +++ b/bare/config/devel/glib-2.46.2-1.cfg @@ -12,11 +12,16 @@ %define glib_version_minor 2 %define glib_version %{glib_version_major}.%{glib_version_minor} -%hash sha256 glib-%{glib_version}.tar.xz 5031722e37036719c1a09163cc6cf7c326e4c4f1f1e074b433c156862bd733db +%hash sha256 glib-%{glib_version}.tar.xz \ + 5031722e37036719c1a09163cc6cf7c326e4c4f1f1e074b433c156862bd733db %patch add glib https://gaisler.se/qemu/glib-2.46.2-werror.patch -%hash sha256 glib-2.46.2-werror.patch 389c00993f2890edaff6774d0dcfc7fcc99e92795ba913443fb9ec522f44a443 +%hash sha256 glib-2.46.2-werror.patch \ + 389c00993f2890edaff6774d0dcfc7fcc99e92795ba913443fb9ec522f44a443 +%patch add glib https://gist.githubusercontent.com/roncapat/34eb82ece80ac26fd290a50dc7e85219/raw/247750ad17c31b26ef31af909fbcac05e57f71bd/glibc_2.46-2.1_rtems_5_rsb.patch +%hash sha512 glibc-2.46-2.1-rtems-5-rsb.patch \ + 6fS0eaLKU/wsMGzwD/cGNycCVQebR9Jquj9pQQtUU+ZTLHuT7Toe1U1ApTXPY69DFngBNXZPsRnE5yUmmzzi/w== # # The GLib build instructions. We use 2.x.x Release 1. diff --git a/bare/config/devel/glib-2.48.2-1.cfg b/bare/config/devel/glib-2.48.2-1.cfg index 76927e9..397a2c9 100644 --- a/bare/config/devel/glib-2.48.2-1.cfg +++ b/bare/config/devel/glib-2.48.2-1.cfg @@ -20,7 +20,7 @@ %patch add glib https://gitlab.gnome.org/GNOME/glib/commit/566e1d61a500267c7849ad0b2552feec9c9a29a6.patch %hash sha512 566e1d61a500267c7849ad0b2552feec9c9a29a6.patch \ - Mz3YZfEOLgNA6eSUzg8y1yiGk0S5YFbYmWRcGyrcRHhmu8mUzuneWmsj6OYXG09zAvBLApxrEGqvaI0iJNhAMg== + azOlfLYsNkeNyJSot1NCGoj15HYgyHLA4gDqiNMnWwImEPxB7K2tvkLWrwOf7QT4hdTG1qBAnhkPQXKhn9OG5Q== # # The GLib build instructions. We use 2.x.x Release 1. diff --git a/bare/config/devel/or1ksim-1.1.0.cfg b/bare/config/devel/or1ksim-1.1.0.cfg index 5e6b592..994897b 100644 --- a/bare/config/devel/or1ksim-1.1.0.cfg +++ b/bare/config/devel/or1ksim-1.1.0.cfg @@ -9,7 +9,8 @@ %include %{_configdir}/base.cfg %define or1ksim_version 1.1.0 -%hash md5 or1k-master.zip 7c9aec3fef6648a380ca5e91b2e3e87f +%hash sha512 or1k-master.zip \ + qi2pPthxvefp9OpwsAz3ul9lakJHkpwIgGlj4fcDa+Lshjsush2ekYm1SKsPJ38YaldSuJdH2buhCmPkXTeWHQ== # # The or1ksim build instructions. We use 1.x.x Release 1. diff --git a/bare/config/devel/qemu-5.2.0-1.cfg b/bare/config/devel/qemu-5.2.0-1.cfg new file mode 100644 index 0000000..1c1cfeb --- /dev/null +++ b/bare/config/devel/qemu-5.2.0-1.cfg @@ -0,0 +1,42 @@ +# +# Qemu from git +# + +%if %{release} == %{nil} + %define release 1 +%endif + +%include %{_configdir}/base.cfg + +%include %{_configdir}/bare-config.cfg + +# +# Stable version. Qemu is fast moving. +# +%define qemu_version 5.2.0-rc1 + +# +# Use released sources. +# +%source set qemu https://download.qemu.org/qemu-%{qemu_version}.tar.xz +%hash sha512 qemu-%{qemu_version}.tar.xz \ + U0XJ6IEe/iwbq5LsuEbyZ9xu8qZ6wDo5VHNE3IEKEwJ+9zUscgnVKOyBEI28Hl6cqW2m9zBsaCrY94X1lvpN3g== + +# +# Patches from Qemu's patchworks site. +# +%patch add qemu pw://patchwork.ozlabs.org/patch/406903/raw/Provide-the-missing-LIBUSB_LOG_LEVEL_-for-older-libusb-or-FreeBSD.-Providing-just-the-needed-value-as-a-defined..patch +%hash sha256 Provide-the-missing-LIBUSB_LOG_LEVEL_-for-older-libusb-or-FreeBSD.-Providing-just-the-needed-value-as-a-defined..patch \ + 40399fcedb44b2c1bfa1a95af482f7f335f42d713967ed2f34980a7a940c3740 + +# +# Patches to build qemu sparc with Leon3 support +# +%patch add qemu https://gaisler.se/qemu/qemu-5.2.0-leon3.patch +%hash sha512 qemu-5.2.0-leon3.patch \ + cQju/ja5SAM+gsXEkzSteeR+7PjG9g2w+yUb4kg1eZoOSm2MmZDjA/auINVdRax8wgtIEWnzq5/hdY7/THnowg== + +# +# The Qemu build instructions. We use 5.x.x Release 1. +# +%include %{_configdir}/qemu-5-1.cfg diff --git a/bare/config/devel/qemu-couverture.bset b/bare/config/devel/qemu-couverture.bset index fd5547c..60bec8e 100644 --- a/bare/config/devel/qemu-couverture.bset +++ b/bare/config/devel/qemu-couverture.bset @@ -22,5 +22,5 @@ devel/gettext-0.18.3.1-1 devel/libffi-3.0.13-1 devel/pixman-0.32.4-1 devel/glib-2.48.2-1 -devel/dtc-1.6.0-1 +devel/dtc-1.6.1-1 devel/qemu-couverture-git-1 diff --git a/bare/config/devel/qemu.bset b/bare/config/devel/qemu.bset index a8b1ebf..3a9b0d5 100644 --- a/bare/config/devel/qemu.bset +++ b/bare/config/devel/qemu.bset @@ -21,4 +21,4 @@ devel/gettext-0.18.3.1-1 devel/libffi-3.0.13-1 devel/pixman-0.40.0-1 devel/glib-2.48.2-1 -devel/qemu-git-1 +devel/qemu-5.2.0-1 diff --git a/bare/config/devel/qemu4-git-1.cfg b/bare/config/devel/qemu4-git-1.cfg index ff241bb..ef51c38 100644 --- a/bare/config/devel/qemu4-git-1.cfg +++ b/bare/config/devel/qemu4-git-1.cfg @@ -36,6 +36,9 @@ %hash sha256 qemu-4.1.0-leon3.patch \ d62ff3418903f1c5eb7f6d727af0400caeb250e23cc120111930601c9ecce02a +%patch add qemu https://gist.githubusercontent.com/roncapat/34eb82ece80ac26fd290a50dc7e85219/raw/9445c0a954e92d3323596c51b1958c7be38b1cb4/qemu_4.10_rtems_5_rsb.patch +%hash sha512 qemu-4.10-rtems-5-rsb.patch \ + Ednm3ItS1N1hNWz3tQ7DSSY6IPRvUqha0aS7AgOfCgZrQ1Yzy9bmyr/O8gn3BhbejBOpeaS7iK52R4sbIJqHdw== # # The Qemu build instructions. We use 4.x.x Release 1. # diff --git a/bare/config/devel/spike-1.1.0.cfg b/bare/config/devel/spike-1.1.0.cfg index 644b754..73cf3c2 100644 --- a/bare/config/devel/spike-1.1.0.cfg +++ b/bare/config/devel/spike-1.1.0.cfg @@ -8,9 +8,9 @@ %include %{_configdir}/base.cfg -%define spike_version 66b44bfbedda562a32e4a2cd0716afbf731b69cd +%define spike_version 530af85d83781a3dae31a4ace84a573ec255fefa -%hash sha512 spike-%{spike_version}.tar.gz a98fc9e564edb3bb471f04063484a5d056befb8b2258b96de2d238cf27d1d5544c2782c91c7731b8f0aa03012eb3d39de33e4f30927349e38c7e131e8241b92f +%hash sha512 spike-%{spike_version}.tar.gz D+9XugRwrZJ8undjx3x3CILr4VSdeaNsTTUZYeENFPZy6MG7TiQAY5umaUr/oOr6vWCq7YjFhqwjPI+fcieqYw== # # The spike build instructions. We use 1.x.x Release 1. diff --git a/bare/config/gnu-tools-4.6.bset b/bare/config/gnu-tools-4.6.bset index fa3ced8..6317d10 100644 --- a/bare/config/gnu-tools-4.6.bset +++ b/bare/config/gnu-tools-4.6.bset @@ -19,7 +19,7 @@ package: gnu-tool-%{_target}-%{_host}-%{release} # # Tool configuration. # -binutils-2.22-1 -gcc-4.6-newlib-1.20-1 -expat-2.1.0-1 -gdb-7.5-1 +devel/binutils-2.22-1 +devel/gcc-4.6-newlib-1.20-1 +devel/expat-2.1.0-1 +devel/gdb-7.7-1 diff --git a/bare/config/gnu-tools-4.8.2.bset b/bare/config/gnu-tools-4.8.2.bset deleted file mode 100644 index 9dd4b8a..0000000 --- a/bare/config/gnu-tools-4.8.2.bset +++ /dev/null @@ -1,25 +0,0 @@ -# -# GNU Tools Set -# - -%define release 1 - -package: gnu-tools-%{_target}-%{_host}-%{release} - -# -# Project custom message -# -%define gcc_version_message SB-%{release},gcc-%{gcc_version}/newlib-%{newlib_version} - -# -# Enable G++ -# -%define enable_cxx 1 - -# -# Tool configuration. -# -devel/expat-2.1.0-1 -devel/binutils-2.23.2-1 -devel/gcc-4.8.2-newlib-cvs-1 -devel/gdb-7.6.1-1 diff --git a/rtems/config/5/rtems-aarch64.bset b/rtems/config/5/rtems-aarch64.bset deleted file mode 100644 index f38aff3..0000000 --- a/rtems/config/5/rtems-aarch64.bset +++ /dev/null @@ -1,4 +0,0 @@ -%define release 1 -%define rtems_arch aarch64 -%define with_libgomp -%include 5/rtems-default.bset diff --git a/rtems/config/5/rtems-all.bset b/rtems/config/5/rtems-all.bset index 00ccfae..81076e4 100644 --- a/rtems/config/5/rtems-all.bset +++ b/rtems/config/5/rtems-all.bset @@ -1,11 +1,9 @@ -5/rtems-aarch64 5/rtems-arm 5/rtems-bfin 5/rtems-epiphany 5/rtems-i386 5/rtems-lm32 5/rtems-m68k -5/rtems-microblaze 5/rtems-mips 5/rtems-moxie 5/rtems-nios2 diff --git a/rtems/config/5/rtems-microblaze.bset b/rtems/config/5/rtems-microblaze.bset deleted file mode 100644 index e5c23af..0000000 --- a/rtems/config/5/rtems-microblaze.bset +++ /dev/null @@ -1,3 +0,0 @@ -%define release 1 -%define rtems_arch microblaze -%include 5/rtems-default.bset diff --git a/rtems/config/5/rtems-moxie.bset b/rtems/config/5/rtems-moxie.bset index 5051b85..85ced02 100644 --- a/rtems/config/5/rtems-moxie.bset +++ b/rtems/config/5/rtems-moxie.bset @@ -8,5 +8,5 @@ %define with_libgomp # Moxie needs dtc to build gdb, then pick up the rest of the set -devel/dtc-1.4.1-1 +devel/dtc-1.6.1-1 %include 5/rtems-default.bset diff --git a/rtems/config/5/rtems-tier-4.bset b/rtems/config/5/rtems-tier-4.bset index 2820fda..042f2a0 100644 --- a/rtems/config/5/rtems-tier-4.bset +++ b/rtems/config/5/rtems-tier-4.bset @@ -5,6 +5,5 @@ # anyone working on adding a BSP. # 5/rtems-epiphany -5/rtems-microblaze -5/rtems-riscv32 +5/rtems-riscv 5/rtems-x86_64 diff --git a/rtems/config/graphics/libjpeg-9a-1.cfg b/rtems/config/graphics/libjpeg-9a-1.cfg index fef32d6..aa48749 100644 --- a/rtems/config/graphics/libjpeg-9a-1.cfg +++ b/rtems/config/graphics/libjpeg-9a-1.cfg @@ -13,7 +13,8 @@ # %define libjpeg_version 9a -%hash sha512 jpegsrc.v%{libjpeg_version}.tar.gz 9b21cc115e22c68bea46db462263c5c7a0d10beb192a919ecccbd801a25982b518ce44d8c301dd582ecaba1850e0e0f20e322be82b0e24ae917b9949b4f10d3b +%hash sha512 jpegsrc.v%{libjpeg_version}.tar.gz \ + iu2Aee2pRisVF0faGrRM5QfqfBZAxATPfrWrVWxYpHdCyj+sZwgM/6dOWUC8dc87Qej8X+j6UXYh15NiGktHrg== # # libjpeg Build configuration diff --git a/rtems/config/graphics/nxlib-0.47-dev-1.cfg b/rtems/config/graphics/nxlib-0.47-dev-1.cfg index deed54e..4296bce 100644 --- a/rtems/config/graphics/nxlib-0.47-dev-1.cfg +++ b/rtems/config/graphics/nxlib-0.47-dev-1.cfg @@ -11,7 +11,10 @@ # # nxlib Version # -%define nxlib_version 0.47-dev +%define nxlib_version 71d911d + +%hash sha512 nxlib-%{nxlib_version}.zip \ + kxPHNeP6HVFLU2zzTErXHtqIxNlU34uxFWQSHDMAG7rEC1c8q87Ua1AdU4m8Eg+YHaodtZG/TAHp2LMAXqlqbA== # # nxlib Build configuration diff --git a/rtems/config/net-mgmt/net-snmp-5.7.2.1-1.cfg b/rtems/config/net-mgmt/net-snmp-5.7.2.1-1.cfg deleted file mode 100644 index e4fe63e..0000000 --- a/rtems/config/net-mgmt/net-snmp-5.7.2.1-1.cfg +++ /dev/null @@ -1,32 +0,0 @@ -# -# NetSNMP 5.7.2.1 -# - -%if %{release} == %{nil} - %define release 1 -%endif - -%include %{_configdir}/rtems-bsp.cfg - -# -# NetSNMP Version -# -%define net_snmp_version 5.7.2.1 - -%hash sha512 net-snmp-%{net_snmp_version}.tar.gz 6c4dadd145cab9572e2559ad99d6794469685086771c6d757d3667da1a061ab86746d53c28d48381c59a90d92b1812b813f3176cff156c41929177fb585299d0 - -# -# We need some special flags to build this version. -# -%define net_snmp_cflags -DNETSNMP_CAN_USE_SYSCTL=1 -DARP_SCAN_FOUR_ARGUMENTS=1 -DINP_IPV6=0 - -# -# Patch for RTEMS support. -# -%patch add net-snmp %{rtems_git_tools}/net-snmp/rtems-net-snmp-5.7.2.1-20190704.patch -#%hash sha512 rtems-net-snmp-5.7.2.1-20140623.patch 4eb987d88c6414f2e07d725c2ebb3e88a40191c7befce879cae9ef67143dc25aa88942cfc525d36cd3683476d1cc0f5882d4a730d3bb9c53be2c7a079874d7dd - -# -# NetSNMP Build configuration -# -%include %{_configdir}/net-snmp-5-1.cfg diff --git a/rtems/config/net-mgmt/net-snmp-5.9.3.cfg b/rtems/config/net-mgmt/net-snmp-5.9.3.cfg new file mode 100644 index 0000000..9339d34 --- /dev/null +++ b/rtems/config/net-mgmt/net-snmp-5.9.3.cfg @@ -0,0 +1,48 @@ +# +# NetSNMP 5.9.3 +# + +%if %{release} == %{nil} + %define release 1 +%endif + +%include %{_configdir}/rtems-bsp.cfg + +# +# NetSNMP Version +# +%define net_snmp_version 5.9.3 + +%hash sha512 net-snmp-%{net_snmp_version}.tar.gz \ + pHbfSWcCmi6wPSew4lAXB4XQqMFD1JuQDulYw8vfrM1BW3CvQPb77Zy4gZ1SLDWmBzpDEJHZCMzHwBj6CqoqvA== + +# +# We need some special flags to build this version. +# +%define net_snmp_cflags \ + -DNETSNMP_CAN_USE_SYSCTL=1 -DARP_SCAN_FOUR_ARGUMENTS=1 \ + -D__FreeBSD_version=1200026 -Dfreebsd4=1 + +# +# Exclude the following modules +# +%define net_snmp_with_out_modules \ + ucd-snmp \ + ucd-snmp/vmstat \ + ucd-snmp/memory \ + hardware/memory \ + hardware/memory/memory_freebsd \ + hardware/cpu \ + hardware/cpu/cpu_sysctl + +# +# Patch for RTEMS support. +# +%patch add net-snmp https://devel.rtems.org/raw-attachment/ticket/4758/rtems-net-snmp-5.9.3-20221113.patch +%hash sha512 rtems-net-snmp-5.9.3-20221113.patch \ + M+BTE1cdl6/yIYDz0iR0MGp4SJti0OzrNmdZ1zsnl4uMHsgAPc3i/S/SzXKmKipEjlBQMOJuwcP+x7wmG8BXBg== + +# +# NetSNMP Build configuration +# +%include %{_configdir}/net-snmp-5-1.cfg diff --git a/rtems/config/net-mgmt/net-snmp.bset b/rtems/config/net-mgmt/net-snmp.bset index 667acaa..c564190 100644 --- a/rtems/config/net-mgmt/net-snmp.bset +++ b/rtems/config/net-mgmt/net-snmp.bset @@ -7,7 +7,7 @@ # # RTEMS Version # -%define rtems_version 4.11 +%define rtems_version 5 # # The RTEMS URL paths. @@ -17,4 +17,4 @@ # # Build NetSNMP. # -net-mgmt/net-snmp-5.7.2.1-1 +net-mgmt/net-snmp-5.9.3 diff --git a/rtems/config/rtems-bsp.cfg b/rtems/config/rtems-bsp.cfg index 801cd5c..af9ad3d 100644 --- a/rtems/config/rtems-bsp.cfg +++ b/rtems/config/rtems-bsp.cfg @@ -40,6 +40,44 @@ %{pkgconfig filter-flags yes} # +# We need a BSP from the user. +# +%ifn %{defined with_rtems_bsp} + %if %{rtems_bsp_error} + %error No RTEMS BSP specified: --with-rtems-bsp=bsp + %endif + %define with_rtems_bsp sparc/erc32 +%endif +%define rtems_bsp %{with_rtems_bsp} + +# +# If the BSP(s) have a '/' it is the arch/bsp notation. +# +%define is_arch_bsp %(echo %{rtems_bsp} | sed -e 's/.*\/.*/yes/g') +%if %{is_arch_bsp} == yes + %define rtems_ab_bsps \ + %(x=''; \ + for b in %{rtems_bsp}; do x="$x "$(echo $b | sed -e 's/.*\///g'); done; \ + echo $x) + %define rtems_ab_archs \ + %(x=''; \ + for b in %{rtems_bsp}; do x="$x "$(echo $b | sed -e 's/\/.*//g'); done; \ + echo $x | tr ' ' '\n' | sort | uniq) + %define rtems_arch_count %(echo %{rtems_ab_archs} | tr ' ' '\n' | wc -l) + %if %{rtems_arch_count} != 1 + %error Invalid BSP architecture count + %endif + %define rtems_bsp %{rtems_ab_bsps} + %define rtems_target %{rtems_ab_archs}-rtems%{rtems_version} + %define rtems_host %{rtems_target} +%endif + +%define rtems_bsp_count %(echo %{rtems_bsp} | tr ' ' '\n' | wc -l) +%if %{rtems_bsp_count} != 1 + %error Building packages with more than one BSP is not supported +%endif + +# # We need a host from the user to specifiy the RTEMS architecture and major # version. It can be defined in rtems_host. # @@ -53,17 +91,6 @@ %endif # -# We need a BSP from the user. -# -%ifn %{defined with_rtems_bsp} - %if %{rtems_bsp_error} - %error No RTEMS BSP specified: --with-rtems-bsp=bsp - %endif - %define with_rtems_bsp sparc/erc32 -%endif -%define rtems_bsp %{with_rtems_bsp} - -# # If no tools or RTEMS provided use the prefix. If staging use the staging # root. # @@ -215,14 +242,14 @@ # # Note: default BSP flags include the standard RTEMS libraries. # -%define rtems-dep-check %(%{_sbdir}/sb/rtems-build-dep -c %{with_tools}/bin/%{rtems_bsp_cc} +%define rtems-dep-check %{_sbdir}/sb/rtems-build-dep -c %{with_tools}/bin/%{rtems_bsp_cc} -%define rtems-libbsd %{rtems-dep-check} -L %{rtems_bsp_libpath} -l libbsd.a) +%define rtems-libbsd %(%{rtems-dep-check} -L %{rtems_bsp_libpath} -l libbsd.a) %if %{rtems-libbsd} == found %define rtems_bsp_libs %{rtems_bsp_libs} -lbsd -lm -lz %endif -%define rtems-defaultconfig %{rtems-dep-check} -L %{rtems_bsp_libpath} -l librtemsdefaultconfig.a) +%define rtems-defaultconfig %(%{rtems-dep-check} -L %{rtems_bsp_libpath} -l librtemsdefaultconfig.a) %if %{rtems-defaultconfig} == found %define rtems_bsp_libs %{rtems_bsp_libs} -lrtemsdefaultconfig %endif diff --git a/rtems/config/tools/rtems-gdb-9.1-1.cfg b/rtems/config/tools/rtems-gdb-9.1-1.cfg index 1d14a20..73648c5 100644 --- a/rtems/config/tools/rtems-gdb-9.1-1.cfg +++ b/rtems/config/tools/rtems-gdb-9.1-1.cfg @@ -12,4 +12,11 @@ %patch add gdb https://devel.rtems.org/raw-attachment/ticket/4366/gdb-9-1-linker-error-fix.diff %hash sha512 gdb-9-1-linker-error-fix.diff QAtNCgJsDdfKno+IqHwqRGz1SR3YdTm34ERox2fqpgaGHI6H4GqNfmkJcJaIvSgzNxif24vqWO+bF/Djqa6wNg== +%if %{_build_os} == win32 + %if %{_windows_os} == cygwin + %patch add gdb https://devel.rtems.org/raw-attachment/ticket/4523/gdb-9-1-thread-local.diff + %hash sha512 gdb-9-1-thread-local.diff ln3rFWltmLCzXvRTz4ts/UoeX7MA49oBtkZWWuslpLEIpm7C/lxDG3/xT0GgJ2eQbENknttittCG31UKhUeljg== + %endif +%endif + %include %{_configdir}/gdb-common-1.cfg diff --git a/rtems/config/tools/rtems-kernel-5.cfg b/rtems/config/tools/rtems-kernel-5.cfg index 5033432..6e5b604 100644 --- a/rtems/config/tools/rtems-kernel-5.cfg +++ b/rtems/config/tools/rtems-kernel-5.cfg @@ -2,9 +2,9 @@ # RTEMS 5 # -%define rtems_kernel_version 61ccb9c05dcd695114541960aa6bfc1315f30514 +%define rtems_kernel_version 05461aa47519c51d3ac5e73337ebeaf395b17589 %hash sha512 rtems-kernel-%{rtems_kernel_version}.tar.bz2 \ - tWJXDeYfDV6UkOSLWp55msQQzd3nvfId0jCbfFWUDQqfeZ7BsuQmP/bP1roUPn5us6wA45SEq2dDx+lYHAYztw== + 4ToHrm8/Ig6DjCSMGNvqXVso7KasDx11TNczJ5wnPjkDjjH49PSVbnZJazuQBPeCOgSuQcMSpnxrS+aBV3aiWg== # # The RTEMS build instructions. diff --git a/rtems/config/tools/rtems-kernel-common.cfg b/rtems/config/tools/rtems-kernel-common.cfg index 3a17a28..ea2e0ac 100644 --- a/rtems/config/tools/rtems-kernel-common.cfg +++ b/rtems/config/tools/rtems-kernel-common.cfg @@ -20,6 +20,43 @@ %endif # +# The BSP. +# +%if !%{defined with_rtems_bsp} && %{rtems_kernel_error} + %error No RTEMS BSP specified: --with-rtems-bsp=bsp +%endif +%define rtems_bsp %{with_rtems_bsp} + +# +# If the BSP(s) have a '/' it is the arch/bsp notation. +# +%define is_arch_bsp %(echo %{rtems_bsp} | sed -e 's/.*\/.*/yes/g') +%if %{is_arch_bsp} == yes + %define rtems_ab_bsps \ + %(x=''; \ + for b in %{rtems_bsp}; do x="$x "$(echo $b | sed -e 's/.*\///g'); done; \ + echo $x) + %define rtems_ab_archs \ + %(x=''; \ + for b in %{rtems_bsp}; do x="$x "$(echo $b | sed -e 's/\/.*//g'); done; \ + echo $x | tr ' ' '\n' | sort | uniq) + %define rtems_arch_count %(echo %{rtems_ab_archs} | tr ' ' '\n' | wc -l) + %if %{rtems_arch_count} != 1 + %error Invalid BSP architecture count + %endif + %define rtems_bsp %{rtems_ab_bsps} + %define rtems_target %{rtems_ab_archs}-rtems%{rtems_version} + %define rtems_host %{rtems_target} +%endif + +%define rtems_bsp_count %(echo %{rtems_bsp} | tr ' ' '\n' | wc -l) +%if %{rtems_bsp_count} == 1 + %define rtems_bsp_pkgname %{rtems_bsp} +%else + %define rtems_bsp_pkgname bsps +%endif + +# # The target. It could be set in rtems_target. # %if %{defined rtems_target} @@ -30,14 +67,6 @@ %endif # -# The BSP. -# -%if !%{defined with_rtems_bsp} && %{rtems_kernel_error} - %error No RTEMS BSP specified: --with-rtems-bsp=bsp -%endif -%define rtems_bsp %{with_rtems_bsp} - -# # If no tools are provided use the prefix. # %ifn %{defined with_tools} @@ -52,12 +81,12 @@ # # Define the package. # -package: rtems-%{rtems_version}-%{_target}-%{rtems_bsp}-%{_host}-%{release} +package: rtems-%{rtems_version}-%{_target}-%{rtems_bsp_pkgname}-%{_host}-%{release} # # Package details. # -Name: %{_target}-kernel-%{rtems_bsp}-%{release} +Name: %{_target}-kernel-%{rtems_bsp_pkgname}-%{release} Summary: RTEMS v%{rtems_kernel_version} for target %{_target} BSP %{rtems_bsp} Version: %{rtems_kernel_version} Release: %{release} diff --git a/rtems/config/tools/rtems-libbsd-5.cfg b/rtems/config/tools/rtems-libbsd-5.cfg index 47ac6a1..5b4840f 100644 --- a/rtems/config/tools/rtems-libbsd-5.cfg +++ b/rtems/config/tools/rtems-libbsd-5.cfg @@ -2,9 +2,9 @@ # RTEMS 5 LibBSD # -%define rtems_libbsd_version 80640fc8438237282c66063f72b6a3f8129d0e2f +%define rtems_libbsd_version 29f9822bace17fe6189a0048b7591a5188cdc329 %hash sha512 rtems-libbsd-%{rtems_libbsd_version}.tar.bz2 \ - d0gkjPFJn0fcB6bm9GLvu2lLhIIm8UV4xFlWGsuUs0O2amhvgZr25bhUasd2v/vmNr1r8aGAz4BaGnhc1mKu7Q== + BzxMjSjgv9JAfDSSJGTY1L7KaNAbJViNSYH95yIvu8uXfWNihO58I23S/nTE0XCh/pB+NvEKb9r6+grRY6kNow== %define rtems_waf_version ad08908c452c6a9bbb3bf7bbbcc9fc03fe46cc7f %hash sha512 rtems-waf-%{rtems_waf_version}.tar.bz2 \ EyuEit0DsAR1gK9Ki1sjl416PFgFe7dcggH3H/hmdAPmMjEIIdX7TVOTDgOIK1Pt0DW6lZ9NcW7O87GZFyy8hg== diff --git a/rtems/config/tools/rtems-tools-5-1.cfg b/rtems/config/tools/rtems-tools-5-1.cfg index 5fb3346..c7d9b36 100644 --- a/rtems/config/tools/rtems-tools-5-1.cfg +++ b/rtems/config/tools/rtems-tools-5-1.cfg @@ -10,14 +10,14 @@ %define rtems_tools_source rtems-tools-%{rtems_tools_version} %define rtems_tools_ext xz %else - %define rtems_tools_version 0a5d2057749066e7d184836e92c7ce5334fccc90 + %define rtems_tools_version 04d6aa3ada572c1fd7352e3a95775824679c0aa0 %define rtems_tools_ext bz2 %endif %define rtems_tools_source rtems-tools-%{rtems_tools_version} %source set rtems-tools https://git.rtems.org/rtems-tools/snapshot/%{rtems_tools_source}.tar.%{rtems_tools_ext} %hash sha512 rtems-tools-%{rtems_tools_version}.tar.bz2 \ - QsjquFu8FJOKDKpa6jXRuJ3HE8/h9YGAenvddcTCAGmHB57VGd54jFXUaxhwRbohlS1rrrL610ulbhf2IzOxYw== + 7GFaovivW18aqni5qjyfJqk4CxnsF3tpA10AMCy1VMIMcc69LZX/tjuU+SX/apIdeTED992T5zX8zAI8YIGdqQ== # # Optionally enable/disable building the RTEMS Tools via the command line. diff --git a/source-builder/config/freetype-1.cfg b/source-builder/config/freetype-1.cfg index 95892dd..03ed603 100644 --- a/source-builder/config/freetype-1.cfg +++ b/source-builder/config/freetype-1.cfg @@ -17,7 +17,11 @@ URL: http://www.freetype.org/ # # freetype Source # -%source set freetype http://download.savannah.gnu.org/releases/freetype/freetype-%{freetype_version}.tar.gz +# Use release 5.1 as the 5 branch version is no longer available on savannah.gnu.org +# +%source set freetype \ + https://ftp.rtems.org/pub/rtems/releases/5/5.1/sources/freetype-%{freetype_version}.tar.gz + # # Prepare the source code. # diff --git a/source-builder/config/gcc-4.6-1.cfg b/source-builder/config/gcc-4.6-1.cfg new file mode 100644 index 0000000..cecfdb5 --- /dev/null +++ b/source-builder/config/gcc-4.6-1.cfg @@ -0,0 +1,28 @@ +# +# 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. +# + +# +# Source +# +# +# GCC core and G++ +# +%source set gcc https://ftp.gnu.org/gnu/gcc/gcc-%{gcc_version}/gcc-core-%{gcc_version}.tar.bz2 + +%if %{enable_cxx} + %source add gcc https://ftp.gnu.org/gnu/gcc/gcc-%{gcc_version}/gcc-g++-%{gcc_version}.tar.gz +%endif + +# +# Newlib +# +%source set newlib https://sourceware.org/pub/newlib/newlib-%{newlib_version}.tar.gz + +# +# GCC Common build script. +# +%include %{_configdir}/gcc-common-1.cfg diff --git a/source-builder/config/gcc-4.9-1.cfg b/source-builder/config/gcc-4.9-1.cfg index e28b560..1cad2f8 100644 --- a/source-builder/config/gcc-4.9-1.cfg +++ b/source-builder/config/gcc-4.9-1.cfg @@ -18,21 +18,18 @@ # %source set newlib https://sourceware.org/pub/newlib/newlib-%{newlib_version}.tar.gz -# -# Packages GCC requires -# -%source set mpfr http://www.mpfr.org/mpfr-%{mpfr_version}/mpfr-%{mpfr_version}.tar.bz2 -%source set mpc http://www.multiprecision.org/mpc/download/mpc-%{mpc_version}.tar.gz -%source set gmp https://ftp.gnu.org/gnu/gmp/gmp-%{gmp_version}.tar.bz2 - %patch add gcc --rsb-file=Make-lang.in-b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch -p1 https://gcc.gnu.org/git/?p=gcc.git;a=blobdiff_plain;f=gcc/cp/Make-lang.in;h=b09fb02bb4c0d16fc2c842bec4069c033897b5f2;hp=e98beb1e33e4bcc4943361c559ae71b7eb345346;hb=1e5f1089dec3af328fd03125d6778f666d0bd4e4;hpb=88375bb2ba8b9004a9924cdae894d7ff32972652 -%hash sha512 Make-lang.in-b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch a47511de21fda0c0c314577ee295b8f2bc9f555084ceca88de12c931ebfe47e5fec349682085a7a1e8637e8e159b8f79188a56d42e54fda2ba5161d5bd3f56ac +%hash sha512 Make-lang.in-b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch \ + h0s+47lNCLhSKUjMuK6qILRHFeNpgsm/MulBzfqv934aPdryogCODhEdPiT5pUV02nMIzvg/kx7wus+8O6zTKQ== %patch add gcc --rsb-file=cfns.gperf.b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch -p1 https://gcc.gnu.org/git/?p=gcc.git;a=blobdiff_plain;f=gcc/cp/cfns.gperf;h=b09fb02bb4c0d16fc2c842bec4069c033897b5f2;hp=e98beb1e33e4bcc4943361c559ae71b7eb345346;hb=1e5f1089dec3af328fd03125d6778f666d0bd4e4;hpb=88375bb2ba8b9004a9924cdae894d7ff32972652 -%hash sha512 cfns.gperf.b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch fdb49abb4f04ba627d6be7b0e0dd9bfdf3eb4b28c045627048bf1c56cabdf2c618cf084991bb847ac60c1eabf582a30ca1e0f4bfd943b9f34efd7e96879d251b +%hash sha512 cfns.gperf.b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch \ + nzj3FPeCC/NcOvuIzyd4EGoJFu3iqn1LUa8ya+P2hstwVLxiHGyvZKHaS1Cb0v7JlRCfhe6eftTZFmEzEqxCqw== %patch add gcc --rsb-file=cfns.h-b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch -p1 https://gcc.gnu.org/git/?p=gcc.git;a=blobdiff_plain;f=gcc/cp/cfns.h;h=b09fb02bb4c0d16fc2c842bec4069c033897b5f2;hp=e98beb1e33e4bcc4943361c559ae71b7eb345346;hb=1e5f1089dec3af328fd03125d6778f666d0bd4e4;hpb=88375bb2ba8b9004a9924cdae894d7ff32972652 -%hash sha512 cfns.h-b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch ec0bd28a8266b136b99db4285c9a088c11fd7ba647dade5fb161308c00cb4189fa665e25ce6b139a7aa9740e97e617fd4e15ca506416dd9316e9fb7202f5c520 +%hash sha512 cfns.h-b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch \ + Wl/1Njp/BOUEwxIVBZtElBLT2rSlBO545FuagJHbL/ajxCllSmtM6611QpWke16fzN/SDgyvkgsJxzfk76WaLw== %patch add gcc --rsb-file=except.c-b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch -p1 https://gcc.gnu.org/git/?p=gcc.git;a=blobdiff_plain;f=gcc/cp/except.c;h=b09fb02bb4c0d16fc2c842bec4069c033897b5f2;hp=e98beb1e33e4bcc4943361c559ae71b7eb345346;hb=1e5f1089dec3af328fd03125d6778f666d0bd4e4;hpb=88375bb2ba8b9004a9924cdae894d7ff32972652 -%hash sha512 except.c-b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch ad05ceea98d7ec95fb2312b0f31aa6260f67119d7c796a1b8c1816fbcd2738edb626705594699bec22a2f770892589f6fc296e184d329bcb967ee2587fbfc5ba +%hash sha512 except.c-b09fb02bb4c0d16fc2c842bec4069c033897b5f2.patch \ + CyuFSBNswd7W8LVDjeOev7HSrQ19dqNEKiuDwNRn0pf02tAxuerxwONQP2fX5QkqwCNxiPnSwB6yzhu4RVSX/A== # # GCC Common build script. diff --git a/source-builder/config/gcc-common-1.cfg b/source-builder/config/gcc-common-1.cfg index 4e13efc..933202a 100644 --- a/source-builder/config/gcc-common-1.cfg +++ b/source-builder/config/gcc-common-1.cfg @@ -34,7 +34,7 @@ URL: http://gcc.gnu.org/ # Default LTO to off. # %ifn %{defined with_lto} - %define with_lto 0 + %define enable_lto 1 %endif # @@ -47,14 +47,36 @@ URL: http://gcc.gnu.org/ %endif # +# Packages GCC URLs, can be defined for older packages +# +%if %{!defined cloog_url} + %define cloog_url https://gcc.gnu.org/pub/gcc/infrastructure +%endif +%if %{!defined isl_url} + %define isl_url https://gcc.gnu.org/pub/gcc/infrastructure +%endif +%if %{!defined mpc_url} + %define mpc_url https://gcc.gnu.org/pub/gcc/infrastructure +%endif +%if %{!defined gmp_url} + %define gmp_url https://gcc.gnu.org/pub/gcc/infrastructure +%endif +%if %{!defined mpfr_url} + %define mpfr_url https://gcc.gnu.org/pub/gcc/infrastructure +%endif + +# # Packages GCC requires # %if %{defined cloog_version} -%source set cloog https://gcc.gnu.org/pub/gcc/infrastructure/cloog-%{cloog_version}.tar.gz +%source set cloog %{_url}/cloog-%{cloog_version}.tar.gz %endif %if %{defined isl_version} -%source set isl https://gcc.gnu.org/pub/gcc/infrastructure/isl-%{isl_version}.tar.bz2 +%source set isl %{isl_url}/isl-%{isl_version}.tar.bz2 %endif +%source set mpc %{mpc_url}/mpc-%{mpc_version}.tar.gz +%source set gmp %{gmp_url}/gmp-%{gmp_version}.tar.bz2 +%source set mpfr %{mpfr_url}/mpfr-%{mpfr_version}.tar.bz2 # # Prepare the source code. @@ -90,7 +112,7 @@ URL: http://gcc.gnu.org/ %source setup cloog -q -D -n cloog-%{cloog_version} %patch setup cloog -p1 cd ${build_top} - # Build MPFR one-tree style + # Build CLooG one-tree style %{__rmfile} ${source_dir_gcc}/cloog %{__ln_s} $PWD/${source_dir_cloog} ${source_dir_gcc}/cloog %endif @@ -101,7 +123,7 @@ URL: http://gcc.gnu.org/ %source setup isl -q -D -n isl-%{isl_version} %patch setup isl -p1 cd ${build_top} - # Build MPFR one-tree style + # Build ISL one-tree style %{__rmfile} ${source_dir_gcc}/isl %{__ln_s} $PWD/${source_dir_isl} ${source_dir_gcc}/isl %endif @@ -143,6 +165,10 @@ URL: http://gcc.gnu.org/ %build build_top=$(pwd) + %if %{defined _internal_gsed_path} + export PATH=%{_internal_gsed_path}/bin:$PATH + %endif + %{build_directory} mkdir -p ${build_dir} @@ -162,11 +188,8 @@ URL: http://gcc.gnu.org/ %if %{enable_fortran} languages="$languages,fortran" %endif -%if %{enable_java} - languages="$languages,java" -%endif -%if %{enable_objc} - languages="$languages,objc" +%if %{enable_lto} + languages="$languages,lto" %endif %{host_build_flags} @@ -188,10 +211,11 @@ URL: http://gcc.gnu.org/ --with-newlib \ --disable-nls --without-included-gettext \ --disable-win32-registry \ + --disable-werror \ --enable-version-specific-runtime-libs \ - %{?with_lto:--enable-lto}%{!?with_lto:--disable-lto} \ --enable-newlib-io-c99-formats \ %{?disable_MAKEINFO:MAKEINFO=missing} \ + %{?enable_newlib_tls:--enable-newlib-reent-thread-local} \ %{?with_iconv:--enable-newlib-iconv} \ %{?with_iconv:--enable-newlib-iconv-encodings=%{_newlib_iconv_encodings}} \ %{?with_threads:--enable-threads}%{!?with_threads:--disable-threads} \ diff --git a/source-builder/config/gdb-common-1.cfg b/source-builder/config/gdb-common-1.cfg index 397d44d..b9dd47f 100644 --- a/source-builder/config/gdb-common-1.cfg +++ b/source-builder/config/gdb-common-1.cfg @@ -173,7 +173,7 @@ URL: http://www.gnu.org/software/gdb/ # # Source # -%source set gdb http://ftp.gnu.org/gnu/gdb/gdb-%{gdb_version}.tar.%{gdb_src_ext} +%source set gdb https://ftp.gnu.org/gnu/gdb/gdb-%{gdb_version}.tar.%{gdb_src_ext} # # Disable Python on Cxc builds for now. diff --git a/source-builder/config/net-snmp-5-1.cfg b/source-builder/config/net-snmp-5-1.cfg index c82e310..3adfc06 100644 --- a/source-builder/config/net-snmp-5-1.cfg +++ b/source-builder/config/net-snmp-5-1.cfg @@ -20,6 +20,23 @@ URL: http://www.net-snmp.org/ %source set net-snmp http://downloads.sourceforge.net/project/net-snmp/net-snmp/%{net_snmp_version}/net-snmp-%{net_snmp_version}.tar.gz # +# NetSMP needs the have the spec stuff handled differently +# +%define bsp_specs -qrtems -B%{_libdir} --specs bsp_specs +%define host_cc %{rtems_bsp_cc} %{bsp_specs} +%define _host_cc gcc %{bsp_specs} +%define host_cxx %{rtems_bsp_cxx} %{bsp_specs} +%define _host_cxx gcc %{bsp_specs} +%define host_cflags %(echo %{rtems_bsp_cflags} | \ + sed -e 's/\-qrtems//' \ + -e 's/\-\-specs bsp_specs//' \ + -e 's/\-B[^ ]*//g') +%define host_cxxflags %(echo %{rtems_bsp_ccflags} | \ + sed -e 's/\-qrtems//' \ + -e 's/\-\-specs bsp_specs//' \ + -e 's/\-B[^ ]*//g') + +# # Prepare the source code. # %prep @@ -41,26 +58,24 @@ URL: http://www.net-snmp.org/ %{host_build_flags} - CFLAGS="${CFLAGS} %{net_snmp_cflags}" + CPPFLAGS="%{net_snmp_cflags} %{rtems_bsp_includes}" LIBS="-lbsd -lm -lz -lrtemsdefaultconfig" \ ../${source_dir_net_snmp}/configure \ --host=%{_host} \ + --target=%{_host} \ --prefix=%{_prefix} \ - --bindir=%{_bindir} \ - --exec_prefix=%{_exec_prefix} \ - --includedir=%{_includedir} \ - --libdir=%{_libdir} \ - --libexecdir=%{_libexecdir} \ - --mandir=%{_mandir} \ - --infodir=%{_infodir} \ - --datadir=%{_datadir} \ + %{?net_snmp_with_out_modules: --with-out-mib-modules="%{net_snmp_with_out_modules}"} \ + --enable-internal-md5 \ --disable-embedded-perl \ + --disable-perl-cc-checks \ --disable-shared \ --without-openssl \ --without-rsaref \ --disable-ipv6 \ - --with-defaults + --with-defaults \ + --without-rpm \ + --without-pcre # # NetSNMP fails to build when make runs parallel jobs diff --git a/source-builder/config/nxlib-1.cfg b/source-builder/config/nxlib-1.cfg index d177aa4..29e7320 100644 --- a/source-builder/config/nxlib-1.cfg +++ b/source-builder/config/nxlib-1.cfg @@ -17,7 +17,8 @@ URL: http://www.microwindows.org/ # # nxlib Source # -%source set nxlib git://github.com/alex-sever-h/nxlib.git +%source set nxlib --rsb-file=nxlib-%{nxlib_version}.zip \ + https://github.com/alex-sever-h/nxlib/archive/%{nxlib_version}.zip # # Prepare the source code. diff --git a/source-builder/config/qemu-5-1.cfg b/source-builder/config/qemu-5-1.cfg new file mode 100644 index 0000000..7ca58b8 --- /dev/null +++ b/source-builder/config/qemu-5-1.cfg @@ -0,0 +1,9 @@ +# +# QEMU 5 Version 1. +# +# This configuration file configure's, make's and install's QEMU. +# + +%define qemu_disables --disable-nettle + +%include %{_configdir}/qemu-common-2.cfg diff --git a/source-builder/config/qemu-common-2.cfg b/source-builder/config/qemu-common-2.cfg new file mode 100644 index 0000000..1dbaf05 --- /dev/null +++ b/source-builder/config/qemu-common-2.cfg @@ -0,0 +1,145 @@ +# +# QEMU Common Version 1. +# +# This configuration file configure's, make's and install's QEMU. +# + +%if %{release} == %{nil} +%define release 1 +%endif + +# +# Select Snapshot Macro Maps +# +%select qemu-snapshot + +# +# The description. +# +Name: qemu-%{qemu_version}-%{_host}-%{release} +Summary: Qemu is a simulator of various processors. +Version: %{qemu_version} +Release: %{release} +URL: http://www.qemu.org/ + +# +# Source +# +%source set qemu http://wiki.qemu-project.org/download/qemu-%{qemu_version}.tar.bz2 + + +# +# QEMU Disable component list. +# +# We are not interested in the VM use case for qemu and most of that +# functionality carries host platform baggage which complicates building on a +# range of host platforms. +# +# You can specialise before including this config file. +# +# +%define qemu_std_disables --disable-werror +%define qemu_std_disables %{qemu_std_disables} --disable-tools +%define qemu_std_disables %{qemu_std_disables} --disable-pie +%define qemu_std_disables %{qemu_std_disables} --disable-vnc +%define qemu_std_disables %{qemu_std_disables} --disable-sdl +%define qemu_std_disables %{qemu_std_disables} --disable-gtk +%define qemu_std_disables %{qemu_std_disables} --disable-opengl +%define qemu_std_disables %{qemu_std_disables} --disable-netmap +%ifn %{defined qemu_disables} + %define qemu_disables %{nil} +%endif +%define qemu_disables %{qemu_std_disables} %{qemu_disables} + +# +# QEMU Targets to build. +# +%if %{!defined qemu_archs} && %{!defined with_qemu_archs} + %define qemu_target_list %{nil} +%else + %if %{defined with_qemu_archs} + %define qemu_target_list --target-list=%{with_qemu_archs} + %else + %define qemu_target_list --target-list=%{qemu_archs} + %endif +%endif + +# +# Clear the path to SB, meson does not like the python pkg-config +# +%define _extra_path %{nil} + +# +# Prepare the source code. +# +%prep + build_top=$(pwd) + + source_dir_qemu="qemu-%{qemu_version}" + %source setup qemu -q -n qemu-%{qemu_version} + %patch setup qemu -p1 + + cd ${build_top} + +%build + build_top=$(pwd) + + %{build_directory} + + mkdir -p ${build_dir} + cd ${build_dir} + + %if %{pkgconfig check vdeplug} + VDE_CONFIG="--enable-vde" + VDE_CFLAGS="%{pkgconfig cflags vdeplug}" + VDE_LDFLAGS="%{pkgconfig ldflags vdeplug} %{pkgconfig libs vdeplug}" + %endif + + %{host_build_flags} + + if test "%{_build}" != "%{_host}" ; then + CROSS_PREFIX_OPTION="--cross-prefix=%{_host}-" + fi + + SYSROOT=$SB_TMPPREFIX + + STAGED_GLIB="-I${SB_TMPPREFIX}/include/glib-2.0 -I${SB_TMPPREFIX}/lib/glib-2.0/include" + STAGED_PIXMAN=" -I${SB_TMPPREFIX}/include/pixman-1" + STAGED_INCLUDES="${STAGED_GLIB} ${STAGED_PIXMAN}" + + CC="${CC} ${STAGED_INCLUDES}" + CXX="${CXX} ${STAGED_INCLUDES}" + + # + # Hack warning: MSYS2 does not seem to convert the path to + # a shell path from Windows so we keep them + # separate and handle it in the pkgconfig tool. + # + PKG_CONFIG_DEFAULT_PATH=${PKG_CONFIG_PATH} \ + PKG_CONFIG_PATH=$SYSROOT/lib/pkgconfig \ + PKG_CONFIG_BUILD_TOP_DIR=$SB_TMPROOT \ + %{_ld_library_path}=$SYSROOT/lib \ + LDFLAGS="-Wl,-rpath -Wl,/$SB_PREFIX_CLEAN/lib -L$SYSROOT/lib ${VDE_LDFLAGS}" \ + CFLAGS="${CFLAGS} ${VDE_CFLAGS}" \ + ../${source_dir_qemu}/configure \ + --prefix=%{_prefix} \ + ${CROSS_PREFIX_OPTION} \ + --make=%{__make} \ + %{qemu_target_list} \ + ${VDE_CONFIG} \ + %{qemu_disables} + + %{_ld_library_path}=$SYSROOT/lib \ + %{__make} %{?_smp_mflags} all + + cd ${build_top} + +%install + build_top=$(pwd) + + %{__rmdir} $SB_BUILD_ROOT + + cd ${build_dir} + %{_ld_library_path}=$SYSROOT/lib \ + %{__make} DESTDIR=$SB_BUILD_ROOT install + cd ${build_top} diff --git a/source-builder/config/swig-4-1.cfg b/source-builder/config/swig-4-1.cfg index 6c10114..82c2cd6 100644 --- a/source-builder/config/swig-4-1.cfg +++ b/source-builder/config/swig-4-1.cfg @@ -16,8 +16,10 @@ URL: http://www.swig.org/ # # Source # -%source set swig --rsb-file=swig-rel-%{swig_version}.tar.gz https://github.com/swig/swig/archive/rel-%{swig_version}.tar.gz -%source set pcre https://ftp.pcre.org/pub/pcre/pcre-%{pcre_version}.tar.bz2 +%source set swig --rsb-file=swig-rel-%{swig_version}.tar.gz \ + https://github.com/swig/swig/archive/rel-%{swig_version}.tar.gz +%source set pcre --rsb-file=pcre-%{pcre_version}.tar.bz2 \ + https://sourceforge.net/projects/pcre/files/pcre/%{pcre_version}/pcre-%{pcre_version}.tar.bz2/download # # See if a special swig prefix is provided diff --git a/source-builder/defaults.mc b/source-builder/defaults.mc index 8ed7003..4658277 100644 --- a/source-builder/defaults.mc +++ b/source-builder/defaults.mc @@ -98,7 +98,7 @@ _host_cc: none, none, 'gcc' _host_cxx: none, none, 'g++' _arch: none, none, '%{_host_arch}' _topdir: dir, required, '%{_cwd}' -_configdir: dir, optional, '%{_topdir}/config:%{_sbdir}/config:%{_sbtop}/bare/config' +_configdir: dir, optional, '%{_topdir}/config:%{_sbdir}/config:%{_sbtop}/bare/config:%{_sbtop}/rtems/config' _tardir: dir, optional, '%{_topdir}/tar' _sourcedir: dir, optional, '%{_topdir}/sources' _patchdir: dir, optional, '%{_topdir}/patches:%{_sbdir}/patches' diff --git a/source-builder/sb/build.py b/source-builder/sb/build.py index ceb179a..c1b76a3 100644 --- a/source-builder/sb/build.py +++ b/source-builder/sb/build.py @@ -48,8 +48,7 @@ except KeyboardInterrupt: print('abort: user terminated') sys.exit(1) except: - print('error: unknown application load error') - sys.exit(1) + raise def humanize_number(num, suffix): for unit in ['','K','M','G','T','P','E','Z']: @@ -635,6 +634,10 @@ class build: return 0 return package.get_size('installed') + def includes(self): + if self.config: + return self.config.includes() + def get_configs(opts): def _scan(_path, ext): @@ -648,10 +651,17 @@ def get_configs(opts): return configs configs = { 'paths': [], 'files': [] } - for cp in opts.defaults.expand('%{_configdir}').split(':'): + paths = opts.defaults.expand('%{_configdir}').split(':') + root = path.host(os.path.commonprefix(paths)) + configs['root'] = root + configs['localpaths'] = [lp[len(root):] for lp in paths] + for cp in paths: hcp = path.host(path.abspath(cp)) configs['paths'] += [hcp] - configs['files'] += _scan(hcp, ['.cfg', '.bset']) + hpconfigs = sorted(set(_scan(hcp, ['.cfg', '.bset']))) + hcplocal = hcp[len(root):] + configs[hcplocal] = [path.join(hcplocal, c) for c in hpconfigs] + configs['files'] += hpconfigs configs['files'] = sorted(set(configs['files'])) return configs diff --git a/source-builder/sb/config.py b/source-builder/sb/config.py index a40147d..24590eb 100644 --- a/source-builder/sb/config.py +++ b/source-builder/sb/config.py @@ -45,8 +45,7 @@ except KeyboardInterrupt: print('user terminated', file = sys.stderr) sys.exit(1) except: - print('error: unknown application load error', file = sys.stderr) - sys.exit(1) + raise def _check_bool(value): istrue = None @@ -69,6 +68,13 @@ def _check_nil(value): istrue = False return istrue +def _check_number(value): + try: + float(value) + return True + except ValueError: + return False + class package: def __init__(self, name, arch, config): @@ -252,7 +258,7 @@ class file: re.compile('%select'), re.compile('%disable') ] - def __init__(self, name, opts, macros = None): + def __init__(self, name, opts, macros = None, load = True): log.trace('config: %s: initialising' % (name)) self.opts = opts self.init_name = name @@ -261,7 +267,8 @@ class file: self.sf = re.compile(r'%\([^\)]+\)') self.set_macros(macros) self._reset(name) - self.load(name) + if load: + self.load(name) def __str__(self): @@ -283,6 +290,7 @@ class file: return s def _reset(self, name): + self.parent = 'root' self.name = name self.load_depth = 0 self.configpath = [] @@ -430,7 +438,8 @@ class file: if len(shell_macro) > 3: e = execute.capture_execution() if options.host_windows: - shell_cmd = ''.join([c if c != '"' else '\\' + c for c in shell_macro[2:-1]]) + shell_cmd = \ + ''.join([c if c != '"' else '\\' + c for c in shell_macro[2:-1]]) cmd = '%s -c "%s"' % (self.macros.expand('%{__sh}'), shell_cmd) else: cmd = shell_macro[2:-1] @@ -458,7 +467,8 @@ class file: if braces > 0: braces -= 1 else: - shell_cmd = '%(' + self._shell(line[pos + 2:p], nesting + 1) + ')' + shell_cmd = '%(' + \ + self._shell(line[pos + 2:p], nesting + 1) + ')' line = line[:pos] + _exec(shell_cmd) + line[p + 1:] updating = True break @@ -472,9 +482,10 @@ class file: ('with_download' in self.macros and self.macros['with_download'] == '1'): return '0' ok = False - log.trace('pkgconfig: check: crossc=%d pkg_crossc=%d prefix=%s' % ( self._cross_compile(), - self.pkgconfig_crosscompile, - self.pkgconfig_prefix)) + log.trace('pkgconfig: check: crossc=%d pkg_crossc=%d prefix=%s' + % ( self._cross_compile(), + self.pkgconfig_crosscompile, + self.pkgconfig_prefix)) log.trace('pkgconfig: check: test=%s' % (test)) if type(test) == str: test = test.split() @@ -496,6 +507,7 @@ class file: except pkgconfig.error as pe: self._error('pkgconfig: check: %s' % (pe)) except: + raise raise error.internal('pkgconfig failure') if ok: return '1' @@ -520,6 +532,7 @@ class file: except pkgconfig.error as pe: self._error('pkgconfig: %s: %s' % (flags, pe)) except: + raise raise error.internal('pkgconfig failure') if pkg_flags is None: pkg_flags = '' @@ -594,7 +607,8 @@ class file: elif m.startswith('%{expand'): colon = m.find(':') if colon < 8: - log.warning(self._name_line_msg('malformed expand macro, no colon found')) + log.warning(self._name_line_msg('malformed expand macro, ' \ + 'no colon found')) else: e = self._expand(m[colon + 1:-1].strip()) s = s.replace(m, self._label(e)) @@ -772,7 +786,16 @@ class file: mn = '%{nil}' if mn: if mn.lower() in self.macros: - s = s.replace(m, self.macros[mn.lower()]) + em = self.macros[mn.lower()] + if self.macros.get_type(mn) == 'dir' and ':' in em: + ss = [] + for sp in s.split(): + if m in sp: + sp = ':'.join([sp.replace(mn, ps) for ps in em.split(':')]) + ss += [sp] + s = ' '.join(ss) + else: + s = s.replace(m, self.macros[mn.lower()]) expanded = True elif show_warning: self._error("macro '%s' not found" % (mn)) @@ -861,7 +884,8 @@ class file: dir, info, data = self._process_directive(r, dir, info, data) else: if in_dir != dir: - self._error('directives cannot change scope across if statements') + self._error('directives cannot change' \ + ' scope across if statements') return data if r[1] == '%else': @@ -904,34 +928,42 @@ class file: elif cls[0] == '&&': join_op = 'and' cls = cls[1:] - log.trace('config: %s: %3d: _if[%i]: joining: %s' % (self.name, self.lc, - self.if_depth, - join_op)) + log.trace('config: %s: %3d: _if[%i]: joining: %s' % \ + (self.name, self.lc, + self.if_depth, + join_op)) + # If OR and the previous check was true short circuit the evaluation + if join_op == 'or' and cistrue: + log.trace('config: %s: %3d: _if[%i]: OR true, short circuit eval' % \ + (self.name, self.lc, + self.if_depth)) + break ori = 0 andi = 0 i = len(cls) if '||' in cls: ori = cls.index('||') - log.trace('config: %s: %3d: _if[%i}: OR found at %i' % (self.name, self.lc, - self.if_depth, - ori)) + log.trace('config: %s: %3d: _if[%i}: OR found at %i' % \ + (self.name, self.lc, + self.if_depth, + ori)) if '&&' in cls: andi = cls.index('&&') - log.trace('config: %s: %3d: _if[%i]: AND found at %i' % (self.name, self.lc, - self.if_depth, - andi)) + log.trace('config: %s: %3d: _if[%i]: AND found at %i' % \ + (self.name, self.lc, + self.if_depth, + andi)) if ori > 0 or andi > 0: if ori == 0: i = andi elif andi == 0: i = ori - elif ori < andi: - i = andi else: - i = andi - log.trace('config: %s: %3d: _if[%i]: next OP found at %i' % (self.name, self.lc, - self.if_depth, - i)) + i = min(ori, andi) + log.trace('config: %s: %3d: _if[%i]: next OP found at %i' % \ + (self.name, self.lc, + self.if_depth, + i)) ls = cls[:i] if len(ls) == 0: self._error('invalid if expression: ' + reduce(add, sls, '')) @@ -985,37 +1017,27 @@ class file: ifls = (' '.join(ifls[:op_pos]), op, ' '.join(ifls[op_pos + 1:])) break if len(ifls) != 3: - self._error('malformed if: ' + reduce(add, ls, '')) - 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 + self._error('malformed if: ' + reduce(add, ls, '')) + lhs = ifls[0] + operator = ifls[1] + rhs = ifls[2] + if _check_number(lhs) and _check_number(rhs): + log.trace('config: %s: %3d: _if: numeric value check' % \ + (self.name, self.lc)) + lhs = float(lhs) + rhs = float(rhs) + if operator == '==': + istrue = lhs == rhs + elif operator == '!=' or operator == '=!': + istrue = lhs != rhs + elif operator == '>': + istrue = lhs > rhs + elif operator == '>=' or operator == '=>': + istrue = lhs >= rhs + elif operator == '<=' or operator == '=<': + istrue = lhs <= rhs + elif operator == '<': + istrue = lhs < rhs else: self._error('invalid %if operator: ' + reduce(add, ls, '')) @@ -1226,7 +1248,8 @@ class file: log.trace('config: %s: %3d: _parse: directive: %s' % \ (self.name, self.lc, ls[0].strip())) return ('directive', ls[0].strip(), ls[1:]) - log.warning(self._name_line_msg("unknown directive: '" + ls[0] + "'")) + log.warning(self._name_line_msg("unknown directive: '" + \ + ls[0] + "'")) return ('data', [lo]) else: return ('data', [lo]) @@ -1247,7 +1270,8 @@ class file: _package = results[2][0] else: if results[2][0].strip() != '-n': - log.warning(self._name_line_msg("unknown directive option: '%s'" % (' '.join(results[2])))) + log.warning(self._name_line_msg("unknown directive option: '%s'" % \ + (' '.join(results[2])))) _package = results[2][1].strip() self._set_package(_package) if directive and directive != results[1]: @@ -1257,7 +1281,8 @@ class file: return (directive, info, data) def _process_data(self, results, directive, info, data): - log.trace('config: %s: %3d: _process_data: result=#%r# directive=#%s# info=#%r# data=#%r#' % \ + log.trace('config: %s: %3d: _process_data: result=#%r# ' \ + 'directive=#%s# info=#%r# data=#%r#' % \ (self.name, self.lc, results, directive, info, data)) new_data = [] for l in results[1]: @@ -1284,10 +1309,12 @@ class file: if info is not None: self._info_append(info, info_data) else: - log.warning(self._name_line_msg("invalid format: '%s'" % (info_data[:-1]))) + log.warning(self._name_line_msg("invalid format: '%s'" % \ + (info_data[:-1]))) else: l = self._expand(l) - log.trace('config: %s: %3d: _data: %s %s' % (self.name, self.lc, l, new_data)) + log.trace('config: %s: %3d: _data: %s %s' % \ + (self.name, self.lc, l, new_data)) new_data.append(l) return (directive, info, data + new_data) @@ -1303,7 +1330,8 @@ class file: self.package = _package def _directive_extend(self, dir, data): - log.trace('config: %s: %3d: _directive_extend: %s: %r' % (self.name, self.lc, dir, data)) + log.trace('config: %s: %3d: _directive_extend: %s: %r' % \ + (self.name, self.lc, dir, data)) self._packages[self.package].directive_extend(dir, data) def _info_append(self, info, data): @@ -1327,8 +1355,15 @@ class file: right = right[:-1] return end + def search_path(confignames): + for configname in confignames.split(':'): + if not configname.endswith('.cfg'): + configname = '%s.cfg' % (configname) + if path.exists(configname): + return configname + return None + if self.load_depth == 0: - self._reset(name) self._packages[self.package] = package(self.package, self.define('%{_arch}'), self) @@ -1336,11 +1371,12 @@ class file: self.load_depth += 1 save_name = self.name + save_parent = self.parent save_lc = self.lc # # Locate the config file. Expand any macros then add the - # extension. Check if the file exists, therefore directly + # extension. Check if the file exists then it is 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. @@ -1348,32 +1384,13 @@ class file: exname = self.expand(name) - # - # Macro could add an extension. - # - if exname.endswith('.cfg'): - configname = exname - else: - configname = '%s.cfg' % (exname) - name = '%s.cfg' % (name) - - if ':' in configname: - cfgname = path.basename(configname) - else: - cfgname = common_end(configname, name) + configname = search_path(exname) + if configname is None: + configname = search_path(self.expand(path.join('%{_configdir}', exname))) + if configname is None: + raise error.general('no config file found: %s' % (','.join(exname.split(':')))) - 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)) + name = path.basename(configname) try: log.trace('config: %s: _open: %s' % (self.name, path.host(configname))) @@ -1382,7 +1399,9 @@ class file: raise error.general('error opening config file: %s' % (path.host(configname))) self.configpath += [configname] - self._includes += [configname] + + self._includes += [configname + ':' + self.parent] + self.parent = configname self.name = self._relative_path(configname) self.lc = 0 @@ -1413,13 +1432,12 @@ class file: except: config.close() raise - - config.close() - - self.name = save_name - self.lc = save_lc - - self.load_depth -= 1 + finally: + config.close() + self.name = save_name + self.parent = save_parent + self.lc = save_lc + self.load_depth -= 1 def defined(self, name): return name in self.macros @@ -1456,7 +1474,7 @@ class file: 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 + '"') + '" not found in package "' + _package + '"') return self._packages[_package].directives[name] def abspath(self, rpath): diff --git a/source-builder/sb/download.py b/source-builder/sb/download.py index 3aaa701..9ee5ca3 100644 --- a/source-builder/sb/download.py +++ b/source-builder/sb/download.py @@ -132,9 +132,7 @@ def _hash_check(file_, absfile, macros, remove = True): if hasher is not None: del hasher else: - if version.released(): - raise error.general('%s: no hash found in released RSB' % (file_)) - log.warning('%s: no hash found' % (file_)) + raise error.general('%s: no hash found in released RSB' % (file_)) return not failed def _local_path(source, pathkey, config): diff --git a/source-builder/sb/execute.py b/source-builder/sb/execute.py index 06f9b7d..e3809ec 100755 --- a/source-builder/sb/execute.py +++ b/source-builder/sb/execute.py @@ -27,6 +27,7 @@ from __future__ import print_function import functools +import codecs import io import os import re @@ -181,6 +182,10 @@ class execute(object): if trace_threads: print('execute:_readthread: start') + if sys.stdout.encoding is not None: + decoder = codecs.getincrementaldecoder(sys.stdout.encoding)() + else: + decoder = None count = 0 line = '' try: @@ -200,8 +205,8 @@ class execute(object): _output_line(line + '\n', exe, prefix, out, count) break # str and bytes are the same type in Python2 - if type(data) is not str and type(data) is bytes: - data = data.decode(sys.stdout.encoding) + if decoder is not None and type(data) is not str and type(data) is bytes: + data = decoder.decode(data) last_ch = data[-1] sd = (line + data).split('\n') if last_ch != '\n': diff --git a/source-builder/sb/getsources.py b/source-builder/sb/getsources.py index 523a3a5..733598b 100644 --- a/source-builder/sb/getsources.py +++ b/source-builder/sb/getsources.py @@ -32,562 +32,15 @@ import sys try: import build - import check import error - import git import log - import macros - import path - import sources + import simhost import version except KeyboardInterrupt: print('abort: user terminated', file = sys.stderr) sys.exit(1) except: - print('error: unknown application load error', file = sys.stderr) - sys.exit(1) - -# -# Define host profiles so it can simulated on another host. -# -host_profiles = { - 'darwin': { '_os': ('none', 'none', 'darwin'), - '_host': ('triplet', 'required', 'x86_64-apple-darwin18.5.0'), - '_host_vendor': ('none', 'none', 'apple'), - '_host_os': ('none', 'none', 'darwin'), - '_host_os_version': ('none', 'none', '18.5.0'), - '_host_cpu': ('none', 'none', 'x86_64'), - '_host_alias': ('none', 'none', '%{nil}'), - '_host_arch': ('none', 'none', 'x86_64'), - '_usr': ('dir', 'optional', '/usr/local'), - '_var': ('dir', 'optional', '/usr/local/var') }, - 'freebsd': { '_os': ('none', 'none', 'freebsd'), - '_host': ('triplet', 'required', 'x86_64-freebsd12.0-RELEASE-p3'), - '_host_vendor': ('none', 'none', 'pc'), - '_host_os': ('none', 'none', 'freebsd'), - '_host_os_version': ('none', 'none', '12.0-RELEASE-p3'), - '_host_cpu': ('none', 'none', 'x86_64'), - '_host_alias': ('none', 'none', '%{nil}'), - '_host_arch': ('none', 'none', 'x86_64'), - '_usr': ('dir', 'optional', '/usr/local'), - '_var': ('dir', 'optional', '/usr/local/var') }, - 'linux': { '_os': ('none', 'none', 'linux'), - '_host': ('triplet', 'required', 'x86_64-linux-gnu'), - '_host_vendor': ('none', 'none', 'gnu'), - '_host_os': ('none', 'none', 'linux'), - '_host_os_version': ('none', 'none', '4.18.0-16'), - '_host_cpu': ('none', 'none', 'x86_64'), - '_host_alias': ('none', 'none', '%{nil}'), - '_host_arch': ('none', 'none', 'x86_64'), - '_usr': ('dir', 'optional', '/usr/local'), - '_var': ('dir', 'optional', '/usr/local/var') }, - 'netbsd': { '_os': ('none', 'none', 'netbsd'), - '_host': ('triplet', 'required', 'x86_64-netbsd8.0'), - '_host_vendor': ('none', 'none', 'pc'), - '_host_os': ('none', 'none', 'netbsd'), - '_host_os_version': ('none', 'none', '8.0'), - '_host_cpu': ('none', 'none', 'x86_64'), - '_host_alias': ('none', 'none', '%{nil}'), - '_host_arch': ('none', 'none', 'x86_64'), - '_usr': ('dir', 'optional', '/usr/local'), - '_var': ('dir', 'optional', '/usr/local/var') }, - 'solaris': { '_os': ('none', 'none', 'solaris'), - '_host': ('triplet', 'required', 'x86_64-pc-solaris2'), - '_host_vendor': ('none', 'none', 'pc'), - '_host_os': ('none', 'none', 'solaris'), - '_host_os_version': ('none', 'none', '2'), - '_host_cpu': ('none', 'none', 'x86_64'), - '_host_alias': ('none', 'none', '%{nil}'), - '_host_arch': ('none', 'none', 'x86_64'), - '_usr': ('dir', 'optional', '/usr/local'), - '_var': ('dir', 'optional', '/usr/local/var') }, - 'win32': { '_os': ('none', 'none', 'win32'), - '_windows_os': ('none', 'none', 'mingw32'), - '_host': ('triplet', 'required', 'x86_64-w64-mingw32'), - '_host_vendor': ('none', 'none', 'pc'), - '_host_os': ('none', 'none', 'win32'), - '_host_os_version': ('none', 'none', '10'), - '_host_cpu': ('none', 'none', 'x86_64'), - '_host_alias': ('none', 'none', '%{nil}'), - '_host_arch': ('none', 'none', 'x86_64'), - '_usr': ('dir', 'optional', '/usr/local'), - '_var': ('dir', 'optional', '/usr/local/var') }, - 'cygwin': { '_os': ('none', 'none', 'win32'), - '_windows_os': ('none', 'none', 'cygwin'), - '_host': ('triplet', 'required', 'x86_64-w64-cygwin'), - '_host_vendor': ('none', 'none', 'microsoft'), - '_host_os': ('none', 'none', 'win32'), - '_host_os_version': ('none', 'none', '10'), - '_host_cpu': ('none', 'none', 'x86_64'), - '_host_alias': ('none', 'none', '%{nil}'), - '_host_arch': ('none', 'none', 'x86_64'), - '_usr': ('dir', 'optional', '/usr/local'), - '_var': ('dir', 'optional', '/usr/local/var') }, -} - -class log_capture(object): - def __init__(self): - self.log = [] - log.capture = self.capture - - def __str__(self): - return os.linesep.join(self.log) - - def capture(self, text): - self.log += [l for l in text.replace(chr(13), '').splitlines()] - - def get(self): - return self.log - - def clear(self): - self.log = [] - -# -# A skinny options command line class to get the configs to load. -# -class options(object): - def __init__(self, argv, argopts, defaults): - command_path = path.dirname(path.abspath(argv[1])) - if len(command_path) == 0: - command_path = '.' - self.command_path = command_path - self.command_name = path.basename(argv[0]) - extras = ['--dry-run', - '--with-download', - '--quiet', - '--without-log', - '--without-error-report', - '--without-release-url'] - self.argv = argv - self.args = argv[1:] + extras - self.defaults = macros.macros(name = defaults, - sbdir = command_path) - self.load_overrides() - self.opts = { 'params' : extras } - self.sb_git() - self.rtems_bsp() - if argopts.download_dir is not None: - self.defaults['_sourcedir'] = ('dir', - 'optional', - path.abspath(argopts.download_dir)) - self.defaults['_patchdir'] = ('dir', - 'optional', - path.abspath(argopts.download_dir)) - - def load_overrides(self): - overrides = None - if os.name == 'nt': - try: - import windows - overrides = windows.load() - host_windows = True - host_posix = False - except: - raise error.general('failed to load Windows host support') - elif os.name == 'posix': - uname = os.uname() - try: - if uname[0].startswith('MINGW64_NT'): - import windows - overrides = windows.load() - host_windows = True - elif uname[0].startswith('CYGWIN_NT'): - import windows - overrides = windows.load() - elif uname[0] == 'Darwin': - import darwin - overrides = darwin.load() - elif uname[0] == 'FreeBSD': - import freebsd - overrides = freebsd.load() - elif uname[0] == 'NetBSD': - import netbsd - overrides = netbsd.load() - elif uname[0] == 'Linux': - import linux - overrides = linux.load() - elif uname[0] == 'SunOS': - import solaris - overrides = solaris.load() - except error.general as ge: - raise error.general('failed to load %s host support: %s' % (uname[0], ge)) - except: - raise error.general('failed to load %s host support' % (uname[0])) - else: - raise error.general('unsupported host type; please add') - if overrides is None: - raise error.general('no hosts defaults found; please add') - for k in overrides: - self.defaults[k] = overrides[k] - - def parse_args(self, arg, error = True, extra = True): - for a in range(0, len(self.args)): - if self.args[a].startswith(arg): - lhs = None - rhs = None - if '=' in self.args[a]: - eqs = self.args[a].split('=') - lhs = eqs[0] - if len(eqs) > 2: - rhs = '='.join(eqs[1:]) - else: - rhs = eqs[1] - elif extra: - lhs = self.args[a] - a += 1 - if a < len(self.args): - rhs = self.args[a] - return [lhs, rhs] - a += 1 - return None - - def rtems_bsp(self): - self.defaults['rtems_version'] = str(version.version()) - self.defaults['_target'] = 'arch-rtems' - self.defaults['rtems_host'] = 'rtems-arch' - self.defaults['with_rtems_bsp'] = 'rtems-bsp' - - def sb_git(self): - repo = git.repo(self.defaults.expand('%{_sbdir}'), self) - repo_mail = None - if repo.valid(): - repo_valid = '1' - repo_head = repo.head() - repo_clean = not repo.dirty() - repo_remotes = '%{nil}' - remotes = repo.remotes() - if 'origin' in remotes: - repo_remotes = '%s/origin' % (remotes['origin']['url']) - repo_id = repo_head - if not repo_clean: - repo_id += '-modified' - repo_mail = repo.email() - else: - repo_valid = '0' - repo_head = '%{nil}' - repo_clean = '%{nil}' - repo_remotes = '%{nil}' - repo_id = 'no-repo' - self.defaults['_sbgit_valid'] = repo_valid - self.defaults['_sbgit_head'] = repo_head - self.defaults['_sbgit_clean'] = str(repo_clean) - self.defaults['_sbgit_remotes'] = str(repo_remotes) - self.defaults['_sbgit_id'] = repo_id - if repo_mail is not None: - self.defaults['_sbgit_mail'] = repo_mail - - def get_arg(self, arg): - if self.optargs is None or arg not in self.optargs: - return None - return self.parse_args(arg) - - def with_arg(self, label, default = 'not-found'): - # the default if there is no option for without. - result = default - for pre in ['with', 'without']: - arg_str = '--%s-%s' % (pre, label) - arg_label = '%s_%s' % (pre, label) - arg = self.parse_args(arg_str, error = False, extra = False) - if arg is not None: - if arg[1] is None: - result = 'yes' - else: - result = arg[1] - break - return [arg_label, result] - - def dry_run(self): - return True - - def keep_going(self): - return False - - def quiet(self): - return True - - def no_clean(self): - return True - - def always_clean(self): - return False - - def no_install(self): - return True - - def download_disabled(self): - return False - - def disable_install(self): - return True - - def urls(self): - return None - - def info(self): - s = ' Command Line: %s%s' % (' '.join(self.argv), os.linesep) - s += ' Python: %s' % (sys.version.replace('\n', '')) - return s - -class buildset: - """Build a set builds a set of packages.""" - - def __init__(self, bset, _configs, opts, macros = None): - log.trace('_bset: %s: init' % (bset)) - self.configs = _configs - self.opts = opts - if macros is None: - self.macros = copy.copy(opts.defaults) - else: - self.macros = copy.copy(macros) - self.macros.define('_rsb_getting_source') - log.trace('_bset: %s: macro defaults' % (bset)) - log.trace(str(self.macros)) - self.bset = bset - _target = self.macros.expand('%{_target}') - if len(_target): - pkg_prefix = _target - else: - pkg_prefix = self.macros.expand('%{_host}') - self.bset_pkg = '%s-%s-set' % (pkg_prefix, self.bset) - self.build_failure = None - - def build_package(self, _config, _build): - if not _build.disabled(): - _build.make() - - def parse(self, bset): - - # - # Ouch, this is a copy of the setbuilder.py code. - # - - def _clean(line): - line = line[0:-1] - b = line.find('#') - if b >= 0: - line = line[1:b] - return line.strip() - - bsetname = bset - - if not path.exists(bsetname): - for cp in self.macros.expand('%{_configdir}').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: - log.trace('_bset: %s: open: %s' % (self.bset, bsetname)) - bset = open(path.host(bsetname), 'r') - except IOError as 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 - log.trace('_bset: %s: %03d: %s' % (self.bset, lc, l)) - ls = l.split() - if ls[0][-1] == ':' and ls[0][:-1] == 'package': - self.bset_pkg = ls[1].strip() - self.macros['package'] = self.bset_pkg - elif ls[0][0] == '%': - def err(msg): - raise error.general('%s:%d: %s' % (self.bset, lc, msg)) - if ls[0] == '%define': - if len(ls) > 2: - self.macros.define(ls[1].strip(), - ' '.join([f.strip() for f in ls[2:]])) - else: - self.macros.define(ls[1].strip()) - elif ls[0] == '%undefine': - if len(ls) > 2: - raise error.general('%s:%d: %undefine requires just the name' % \ - (self.bset, lc)) - self.macros.undefine(ls[1].strip()) - elif ls[0] == '%include': - configs += self.parse(ls[1].strip()) - elif ls[0] in ['%patch', '%source']: - sources.process(ls[0][1:], ls[1:], self.macros, err) - elif ls[0] == '%hash': - sources.hash(ls[1:], self.macros, err) - else: - l = l.strip() - c = build.find_config(l, self.configs) - if c is None: - raise error.general('%s:%d: cannot find file: %s' % (self.bset, lc, l)) - configs += [c] - except: - bset.close() - raise - - bset.close() - - return configs - - def load(self): - # - # If the build set file ends with .cfg the user has passed to the - # buildset builder a configuration so we just return it. - # - if self.bset.endswith('.cfg'): - configs = [self.bset] - else: - exbset = self.macros.expand(self.bset) - self.macros['_bset'] = exbset - self.macros['_bset_tmp'] = build.short_name(exbset) - root, ext = path.splitext(exbset) - if exbset.endswith('.bset'): - bset = exbset - else: - bset = '%s.bset' % (exbset) - configs = self.parse(bset) - return configs - - def set_host_details(self, host, opts, macros): - if host not in host_profiles: - raise error.general('invalid host: ' + host) - for m in host_profiles[host]: - opts.defaults[m] = host_profiles[host][m] - macros[m] = host_profiles[host][m] - macros_to_copy = [('%{_build}', '%{_host}'), - ('%{_build_alias}', '%{_host_alias}'), - ('%{_build_arch}', '%{_host_arch}'), - ('%{_build_cpu}', '%{_host_cpu}'), - ('%{_build_os}', '%{_host_os}'), - ('%{_build_vendor}', '%{_host_vendor}')] - for m in macros_to_copy: - opts.defaults[m[0]] = opts.defaults[m[1]] - macros[m[0]] = macros[m[1]] - # - # Look for a valid cc and cxx. - # - for cc in ['/usr/bin/cc', '/usr/bin/clang', '/usr/bin/gcc']: - if check.check_exe(cc, cc): - opts.defaults['__cc'] = cc - macros['__cc'] = cc - break - if not macros.defined('__cc'): - raise error.general('no valid cc found') - for cxx in ['/usr/bin/c++', '/usr/bin/clang++', '/usr/bin/g++']: - if check.check_exe(cxx, cxx): - opts.defaults['__cxx'] = cxx - macros['__cxx'] = cxx - if not macros.defined('__cxx'): - raise error.general('no valid c++ found') - - def build(self, host, nesting_count = 0): - - build_error = False - - nesting_count += 1 - - log.trace('_bset: %s for %s: make' % (self.bset, host)) - log.notice('Build Set: %s for %s' % (self.bset, host)) - - mail_subject = '%s on %s' % (self.bset, - self.macros.expand('%{_host}')) - - current_path = os.environ['PATH'] - - start = datetime.datetime.now() - - have_errors = False - - try: - configs = self.load() - - log.trace('_bset: %s: configs: %s' % (self.bset, ','.join(configs))) - - sizes_valid = False - builds = [] - for s in range(0, len(configs)): - b = None - try: - # - # Each section of the build set gets a separate set of - # macros so we do not contaminate one configuration with - # another. - # - opts = copy.copy(self.opts) - macros = copy.copy(self.macros) - self.set_host_details(host, opts, macros) - if configs[s].endswith('.bset'): - log.trace('_bset: == %2d %s' % (nesting_count + 1, '=' * 75)) - bs = buildset(configs[s], self.configs, opts, macros) - bs.build(host, nesting_count) - del bs - elif configs[s].endswith('.cfg'): - log.trace('_bset: -- %2d %s' % (nesting_count + 1, '-' * 75)) - try: - b = build.build(configs[s], - False, - opts, - macros) - except: - build_error = True - raise - self.build_package(configs[s], b) - builds += [b] - # - # Dump post build macros. - # - log.trace('_bset: macros post-build') - log.trace(str(macros)) - else: - raise error.general('invalid config type: %s' % (configs[s])) - except error.general as gerr: - have_errors = True - if b is not None: - if self.build_failure is None: - self.build_failure = b.name() - raise - # - # Clear out the builds ... - # - for b in builds: - del b - except error.general as gerr: - if not build_error: - log.stderr(str(gerr)) - raise - except KeyboardInterrupt: - raise - except: - self.build_failure = 'RSB general failure' - raise - finally: - end = datetime.datetime.now() - os.environ['PATH'] = current_path - build_time = str(end - start) - log.notice('Build Set: Time %s' % (build_time)) - -def list_bset_files(opts, configs): - ext = '.bset' - for p in configs['paths']: - print('Examining: %s' % (os.path.relpath(p))) - for c in configs['files']: - if c.endswith(ext): - print(' %s' % (c[:c.rfind('.')])) - -def load_log(logfile): - log.default = log.log(streams = [logfile]) - -def log_default(): - return 'rsb-log-getsource-%s.txt' % (datetime.datetime.now().strftime('%Y%m%d-%H%M%S')) - -def load_options(argv, argopts, defaults = '%{_sbdir}/defaults.mc'): - opts = options(argv, argopts, defaults) - opts.defaults['rtems_version'] = str(argopts.rtems_version) - return opts + raise def run(args = sys.argv): ec = 0 @@ -600,14 +53,16 @@ def run(args = sys.argv): description = 'RTEMS Get Sources downloads all the source a build set ' description += 'references for all hosts.' - argsp = argparse.ArgumentParser(prog = 'rtems-get-sources', + argsp = argparse.ArgumentParser(prog = 'sb-get-sources', description = description) argsp.add_argument('--rtems-version', help = 'Set the RTEMS version.', type = str, default = version.version()) argsp.add_argument('--list-hosts', help = 'List the hosts.', action = 'store_true') - argsp.add_argument('--list-bsets', help = 'List the hosts.', + argsp.add_argument('--list-bsets', help = 'List the buildsets.', + action = 'store_true') + argsp.add_argument('--list-root-bsets', help = 'List the toplevel or root buildsets.', action = 'store_true') argsp.add_argument('--download-dir', help = 'Download directory.', type = str) @@ -617,22 +72,34 @@ def run(args = sys.argv): action = 'store_true') argsp.add_argument('--log', help = 'Log file.', type = str, - default = log_default()) + default = simhost.log_default('getsource')) + argsp.add_argument('--stop-on-error', help = 'Stop on error.', + action = 'store_true') argsp.add_argument('--trace', help = 'Enable trace logging for debugging.', action = 'store_true') + argsp.add_argument('--used', help = 'Save the used buildset and config files.', + type = str, default = None) + argsp.add_argument('--unused', help = 'Save the unused buildset and config files.', + type = str, default = None) argsp.add_argument('bsets', nargs='*', help = 'Build sets.') argopts = argsp.parse_args(args[2:]) - load_log(argopts.log) + simhost.load_log(argopts.log) log.notice('RTEMS Source Builder - Get Sources, %s' % (version.string())) log.tracing = argopts.trace - opts = load_options(args, argopts) + opts = simhost.load_options(args[1:], argopts, extras = ['--with-download']) configs = build.get_configs(opts) - if argopts.list_bsets: - list_bset_files(opts, configs) + stop_on_error = argopts.stop_on_error + + if argopts.list_hosts: + simhost.list_hosts() + elif argopts.list_bsets: + simhost.list_bset_files(opts, configs) + elif argopts.list_root_bsets: + simhost.list_root_bset_files(opts, configs) else: if argopts.clean: if argopts.download_dir is None: @@ -641,14 +108,35 @@ def run(args = sys.argv): log.notice('Cleaning source directory: %s' % (argopts.download_dir)) path.removeall(argopts.download_dir) if len(argopts.bsets) == 0: - raise error.general('no build sets provided on the command line') - for bset in argopts.bsets: - get_sources_error = True - b = buildset(bset, configs, opts) - get_sources_error = False - for host in host_profiles: - b.build(host) + bsets = simhost.get_root_bset_files(opts, configs) + else: + bsets = argopts.bsets + deps = copy.copy(simhost.strip_common_prefix(bsets)) + for bset in bsets: + b = None + try: + for host in simhost.profiles: + get_sources_error = True + b = simhost.buildset(bset, configs, opts) + get_sources_error = False + b.build(host) + deps += b.deps() + del b + except error.general as gerr: + if stop_on_error: + raise + log.stderr(str(gerr)) + log.stderr('Build FAILED') b = None + deps = sorted(list(set(deps))) + if argopts.used: + with open(argopts.used, 'w') as o: + o.write(os.linesep.join(deps)) + if argopts.unused: + cfgs_bsets = \ + [cb for cb in simhost.get_config_bset_files(opts, configs) if not cb in deps] + with open(argopts.unused, 'w') as o: + o.write(os.linesep.join(cfgs_bsets)) except error.general as gerr: if get_sources_error: log.stderr(str(gerr)) diff --git a/source-builder/sb/mailer.py b/source-builder/sb/mailer.py index 42b4fa6..1d3cbb5 100644 --- a/source-builder/sb/mailer.py +++ b/source-builder/sb/mailer.py @@ -1,21 +1,33 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2013 Chris Johns (chrisj@rtems.org) +# Copyright 2013-2016 Chris Johns (chrisj@rtems.org) +# Copyright (C) 2021 On-Line Applications Research Corporation (OAR) # 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. +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. # -# 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 emailing results or reports. @@ -28,18 +40,72 @@ import smtplib import socket import error +import execute import options import path +_options = { + '--mail' : 'Send email report or results.', + '--use-gitconfig': 'Use mail configuration from git config.', + '--mail-to' : 'Email address to send the email to.', + '--mail-from' : 'Email address the report is from.', + '--smtp-host' : 'SMTP host to send via.', + '--smtp-port' : 'SMTP port to send via.', + '--smtp-user' : 'User for SMTP authentication.', + '--smtp-password': 'Password for SMTP authentication.' +} + def append_options(opts): - opts['--mail'] = 'Send email report or results.' - opts['--smtp-host'] = 'SMTP host to send via.' - opts['--mail-to'] = 'Email address to send the email too.' - opts['--mail-from'] = 'Email address the report is from.' + for o in _options: + opts[o] = _options[o] + +def add_arguments(argsp): + argsp.add_argument('--mail', help = _options['--mail'], action = 'store_true') + argsp.add_argument('--use-gitconfig', help = _options['--use-gitconfig'], action = 'store_true') + no_add = ['--mail', '--use-gitconfig'] + for o in [opt for opt in list(_options) if opt not in no_add]: + argsp.add_argument(o, help = _options[o], type = str) class mail: def __init__(self, opts): self.opts = opts + self.gitconfig_lines = None + if opts.find_arg('--use-gitconfig') is not None: + # Read the output of `git config --list` instead of reading the + # .gitconfig file directly because Python 2 ConfigParser does not + # accept tabs at the beginning of lines. + e = execute.capture_execution() + exit_code, proc, output = e.open('git config --list', shell=True) + if exit_code == 0: + self.gitconfig_lines = output.split(os.linesep) + + def _args_are_macros(self): + return isinstance(self.opts, options.command_line) + + def _get_arg(self, arg): + if self._args_are_macros(): + value = self.opts.find_arg(arg) + if value is not None: + value = self.opts.find_arg(arg)[1] + else: + if arg.startswith('--'): + arg = arg[2:] + arg = arg.replace('-', '_') + if arg in vars(self.opts): + value = vars(self.opts)[arg] + else: + value = None + return value + + def _get_from_gitconfig(self, variable_name): + if self.gitconfig_lines is None: + return None + + for line in self.gitconfig_lines: + if line.startswith(variable_name): + ls = line.split('=') + if len(ls) >= 2: + return ls[1] def from_address(self): @@ -52,9 +118,15 @@ class mail: l = l[:l.index('\n')] return l.strip() - addr = self.opts.get_arg('--mail-from') + addr = self._get_arg('--mail-from') if addr is not None: - return addr[1] + return addr + addr = self._get_from_gitconfig('user.email') + if addr is not None: + name = self._get_from_gitconfig('user.name') + if name is not None: + addr = '%s <%s>' % (name, addr) + return addr mailrc = None if 'MAILRC' in os.environ: mailrc = os.environ['MAILRC'] @@ -63,9 +135,8 @@ class mail: if mailrc is not None and path.exists(mailrc): # set from="Joe Blow <joe@blow.org>" try: - mrc = open(mailrc, 'r') - lines = mrc.readlines() - mrc.close() + with open(mailrc, 'r') as mrc: + lines = mrc.readlines() except IOError as err: raise error.general('error reading: %s' % (mailrc)) for l in lines: @@ -76,40 +147,99 @@ class mail: addr = fa[fa.index('=') + 1:].replace('"', ' ').strip() if addr is not None: return addr - addr = self.opts.defaults.get_value('%{_sbgit_mail}') + if self._args_are_macros(): + addr = self.opts.defaults.get_value('%{_sbgit_mail}') + else: + raise error.general('no valid from address for mail') return addr def smtp_host(self): - host = self.opts.get_arg('--smtp-host') + host = self._get_arg('--smtp-host') if host is not None: - return host[1] - host = self.opts.defaults.get_value('%{_mail_smtp_host}') + return host + host = self._get_from_gitconfig('sendemail.smtpserver') + if host is not None: + return host + if self._args_are_macros(): + host = self.opts.defaults.get_value('%{_mail_smtp_host}') if host is not None: return host return 'localhost' + def smtp_port(self): + port = self._get_arg('--smtp-port') + if port is not None: + return port + port = self._get_from_gitconfig('sendemail.smtpserverport') + if port is not None: + return port + if self._args_are_macros(): + port = self.opts.defaults.get_value('%{_mail_smtp_port}') + return port + + def smtp_user(self): + user = self._get_arg('--smtp-user') + if user is not None: + return user + user = self._get_from_gitconfig('sendemail.smtpuser') + return user + + def smtp_password(self): + password = self._get_arg('--smtp-password') + if password is not None: + return password + password = self._get_from_gitconfig('sendemail.smtppass') + return password + def send(self, to_addr, subject, body): from_addr = self.from_address() msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % \ (from_addr, to_addr, subject) + body - if type(to_addr) is str: - to_addr = to_addr.split(',') - if type(to_addr) is not list: - raise error.general('invalid to_addr type') + port = self.smtp_port() + try: - s = smtplib.SMTP(self.smtp_host()) - s.sendmail(from_addr, to_addr, msg) + s = smtplib.SMTP(self.smtp_host(), port, timeout=10) + + password = self.smtp_password() + # If a password is provided, assume that authentication is required. + if password is not None: + user = self.smtp_user() + if user is None: + user = from_addr + s.starttls() + s.login(user, password) + + s.sendmail(from_addr, [to_addr], msg) except smtplib.SMTPException as se: raise error.general('sending mail: %s' % (str(se))) except socket.error as se: raise error.general('sending mail: %s' % (str(se))) + def send_file_as_body(self, to_addr, subject, name, intro = None): + try: + with open(name, 'r') as f: + body = f.readlines() + except IOError as err: + raise error.general('error reading mail body: %s' % (name)) + if intro is not None: + body = intro + body + self.send(to_addr, from_addr, body) + if __name__ == '__main__': import sys + import macros optargs = {} + rtdir = 'source-builder' + defaults = '%s/defaults.mc' % (rtdir) append_options(optargs) - opts = options.load(sys.argv, optargs = optargs, defaults = 'defaults.mc') + opts = options.command_line(base_path = '.', + argv = sys.argv, + optargs = optargs, + defaults = macros.macros(name = defaults, rtdir = rtdir), + command_path = '.') + options.load(opts) m = mail(opts) print('From: %s' % (m.from_address())) print('SMTP Host: %s' % (m.smtp_host())) - m.send(m.from_address(), 'Test mailer.py', 'This is a test') + if '--mail' in sys.argv: + m.send(m.from_address(), 'Test mailer.py', 'This is a test') diff --git a/source-builder/sb/options.py b/source-builder/sb/options.py index fe4182d..c2f7bb2 100644 --- a/source-builder/sb/options.py +++ b/source-builder/sb/options.py @@ -518,6 +518,15 @@ class command_line: return None return self.parse_args(arg) + def find_arg(self, arg): + if self.optargs is None or arg not in self.optargs: + raise error.internal('bad arg: %s' % (arg)) + for a in self.args: + sa = a.split('=') + if sa[0].startswith(arg): + return sa + return None + def with_arg(self, label, default = 'not-found'): # the default if there is no option for without. result = default @@ -583,7 +592,22 @@ class command_line: self.opts['no-install'] = '1' def info(self): - s = ' Command Line: %s%s' % (' '.join(self.argv), os.linesep) + # Filter potentially sensitive mail options out. + filtered_args = [ + arg for arg in self.argv + if all( + smtp_opt not in arg + for smtp_opt in [ + '--smtp-host', + '--mail-to', + '--mail-from', + '--smtp-user', + '--smtp-password', + '--smtp-port' + ] + ) + ] + s = ' Command Line: %s%s' % (' '.join(filtered_args), os.linesep) s += ' Python: %s' % (sys.version.replace('\n', '')) return s diff --git a/source-builder/sb/setbuilder.py b/source-builder/sb/setbuilder.py index a6efd75..41f5589 100644 --- a/source-builder/sb/setbuilder.py +++ b/source-builder/sb/setbuilder.py @@ -30,11 +30,14 @@ import glob import operator import os import sys +import tarfile + import textwrap try: import build import check + import config import error import log import mailer @@ -48,8 +51,7 @@ except KeyboardInterrupt: print('abort: user terminated', file = sys.stderr) sys.exit(1) except: - print('error: unknown application load error', file = sys.stderr) - sys.exit(1) + raise def macro_expand(macros, _str): cstr = None @@ -224,6 +226,9 @@ class buildset: def installing(self): return self.install_mode() == 'installing' + def installable(self): + return not self.opts.no_install() and self.installing() + def staging(self): return not self.installing() @@ -260,21 +265,31 @@ class buildset: self.root_copy(_build.config.expand('%{buildroot}'), _build.config.expand('%{_tmproot}')) - def bset_tar(self, _build): - tardir = _build.config.expand('%{_tardir}') - if (self.opts.get_arg('--bset-tar-file') or self.opts.canadian_cross()) \ - and not _build.macros.get('%{_disable_packaging}'): + def bset_tar(self, stagingroot): + if self.opts.get_arg('--bset-tar-file') or self.opts.canadian_cross(): + # Use a config to expand the macros because it supports all + # expansions, ie %{_cwd} + cfg = config.file(self.bset, self.opts, self.macros, load=False) + prefix = cfg.expand('%{_prefix}') + tardir = cfg.expand('%{_tardir}') path.mkdir(tardir) - tar = path.join(tardir, - _build.config.expand('%s.tar.bz2' % \ - (_build.main_package().name()))) - log.notice('tarball: %s' % (os.path.relpath(path.host(tar)))) + tarname = path.join(tardir, + path.basename('%s.tar.bz2' % (self.bset))) + log.notice('tarfile: %s' % (os.path.relpath(path.host(tarname)))) if not self.opts.dry_run(): - tmproot = _build.config.expand('%{_tmproot}') - cmd = _build.config.expand('"cd ' + tmproot + \ - ' && %{__tar} -cf - . | %{__bzip2} > ' + \ - tar + '"') - _build.run(cmd, shell_opts = '-c', cwd = tmproot) + tar = None + try: + tar = tarfile.open(tarname, 'w:bz2') + for filedir in sorted(path.listdir(stagingroot)): + src = path.join(stagingroot, filedir) + dst = path.join(prefix, filedir) + log.trace('tar: %s -> %s' % (src, dst)) + tar.add(src, dst) + except OSError as oe: + raise error.general('tarfile: %s: %s' % (self.bset, oe)) + finally: + if tar is not None: + tar.close() def parse(self, bset): @@ -285,6 +300,14 @@ class buildset: line = line[1:b] return line.strip() + def _clean_and_pack(line, last_line): + leading_ws = ' ' if len(line) > 0 and line[0].isspace() else '' + line = _clean(line) + if len(last_line) > 0: + line = last_line + leading_ws + line + return line + + bset = macro_expand(self.macros, bset) bsetname = bset if not path.exists(bsetname): @@ -306,25 +329,37 @@ class buildset: try: lc = 0 + ll = '' for l in bset: lc += 1 - l = _clean(l) + l = _clean_and_pack(l, ll) if len(l) == 0: continue + if l[-1] == '\\': + ll = l[0:-1] + continue + ll = '' log.trace('_bset: : %s: %03d: %s' % (self.bset, lc, l)) ls = l.split() if ls[0][-1] == ':' and ls[0][:-1] == 'package': self.bset_pkg = ls[1].strip() self.macros['package'] = self.bset_pkg - elif ls[0][0] == '%': + elif ls[0][0] == '%' and (len(ls[0]) > 1 and ls[0][1] != '{'): def err(msg): raise error.general('%s:%d: %s' % (self.bset, lc, msg)) - if ls[0] == '%define': + if ls[0] == '%define' or ls[0] == '%defineifnot' : + name = ls[1].strip() + value = None if len(ls) > 2: - self.macros.define(ls[1].strip(), - ' '.join([f.strip() for f in ls[2:]])) - else: - self.macros.define(ls[1].strip()) + value = ' '.join([f.strip() for f in ls[2:]]) + if ls[0] == '%defineifnot': + if self.macros.defined(name): + name = None + if name is not None: + if value is not None: + self.macros.define(name, value) + else: + self.macros.define(name) elif ls[0] == '%undefine': if len(ls) > 2: raise error.general('%s:%d: %undefine requires ' \ @@ -337,7 +372,7 @@ class buildset: elif ls[0] == '%hash': sources.hash(ls[1:], self.macros, err) else: - l = l.strip() + l = macro_expand(self.macros, l.strip()) c = build.find_config(l, self.configs) if c is None: raise error.general('%s:%d: cannot find file: %s' % (self.bset, @@ -398,19 +433,11 @@ class buildset: interrupted = False # - # If this is the outter most buildset it's files are installed. Nested - # build sets staged their installed file. The staged files are install - # when the outtter most build finishes. + # If installing switch to staging. Not sure if this is still + # needed. # - if nesting_count != 1: - if self.installing(): - self.macros['install_mode'] = 'staging' - - # - # Only the outter build set can have staging to install. Get the staging - # root via the config because it could require a valid config. - # - have_staging = False + if nesting_count > 1 and self.installing(): + self.macros['install_mode'] = 'staging' try: configs = self.load() @@ -418,7 +445,7 @@ class buildset: log.trace('_bset: %2d: %s: configs: %s' % (nesting_count, self.bset, ', '.join(configs))) - if nesting_count == 1 and len(configs) > 1: + if nesting_count == 1: # # Prepend staging areas, bin directory to the # path. Lets the later package depend on the earlier @@ -450,8 +477,6 @@ class buildset: '=' * (74 - len(configs[s])))) bs = buildset(configs[s], self.configs, opts, macros) bs.build(deps, nesting_count, mail) - if self.installing(): - have_staging = True del bs elif configs[s].endswith('.cfg'): if mail: @@ -481,8 +506,6 @@ class buildset: copy.copy(self.macros), format = 'xml', mail = mail) - if s == len(configs) - 1 and not have_errors: - self.bset_tar(b) else: deps += b.config.includes() builds += [b] @@ -515,23 +538,22 @@ class buildset: # # Installing or staging ... # - log.trace('_bset: %2d: %s: deps:%r no-install:%r' % \ + log.trace('_bset: %2d: mode: %s: deps:%r no-install:%r' % \ (nesting_count, self.install_mode(), deps is None, self.opts.no_install())) - log.trace('_bset: %2d: %s: builds: %s' % \ + log.trace('_bset: %2d: mode: %s: builds: %s' % \ (nesting_count, self.install_mode(), ', '.join([b.name() for b in builds]))) - if deps is None and not self.opts.no_install() and not have_errors: + if deps is None and not have_errors: for b in builds: - log.trace('_bset: : %s: %r' % (self.install_mode(), - b.installable())) + log.trace('_bset: : %s: installable=%r build-installable=%r' % \ + (self.install_mode(), self.installable(), b.installable())) if b.installable(): prefix = b.config.expand('%{_prefix}') buildroot = path.join(b.config.expand('%{buildroot}'), prefix) - if self.staging(): - prefix = b.config.expand('%{stagingroot}') - self.install(self.install_mode(), b.name(), buildroot, prefix) - + self.install('staging', b.name(), buildroot, b.config.expand('%{stagingroot}')) + if self.installable(): + self.install('installing', b.name(), buildroot, prefix) # # Sizes ... # @@ -585,16 +607,20 @@ class buildset: del b # - # If builds have been staged install into the finaly prefix. + # If builds have been staged install into the final prefix. # - if have_staging and not self.opts.no_install() and not have_errors: + if self.installing() and not have_errors: stagingroot = macro_expand(self.macros, '%{stagingroot}') have_stagingroot = path.exists(stagingroot) - log.trace('_bset: %2d: install staging, present: %s' % \ - (nesting_count, have_stagingroot)) + do_install = not self.opts.no_install() + if do_install: + log.trace('_bset: %2d: install staging, present: %s' % \ + (nesting_count, have_stagingroot)) if have_stagingroot: prefix = macro_expand(self.macros, '%{_prefix}') - self.install(self.install_mode(), self.bset, stagingroot, prefix) + if do_install: + self.install(self.install_mode(), self.bset, stagingroot, prefix) + self.bset_tar(stagingroot) staging_size = path.get_size(stagingroot) if not self.opts.no_clean() or self.opts.always_clean(): log.notice('clean staging: %s' % (self.bset)) @@ -674,6 +700,16 @@ def list_bset_cfg_files(opts, configs): return True return False +def list_host(opts): + if opts.get_arg('--list-host'): + print('Host operating system information:') + print('Operating system: %s' % macro_expand(opts.defaults, '%{_os}')) + print('Number of processors: %s' % macro_expand(opts.defaults, '%{_ncpus}')) + print('Build architecture: %s' % macro_expand(opts.defaults, '%{_host_arch}')) + print('Host triplet: %s' % macro_expand(opts.defaults, '%{_host}')) + return True + return False + def run(): import sys ec = 0 @@ -684,6 +720,7 @@ def run(): '--list-bsets': 'List available build sets', '--list-configs': 'List available configuration files.', '--list-deps': 'List the dependent files.', + '--list-host': 'List host information and the host triplet.', '--bset-tar-file': 'Create a build set tar file', '--pkg-tar-files': 'Create package tar files', '--no-report': 'Do not create a package report.', @@ -696,6 +733,8 @@ def run(): 'log' : '', 'reports': [], 'failure': None } + # Request this now to generate any errors. + smtp_host = mail['mail'].smtp_host() to_addr = opts.get_arg('--mail-to') if to_addr is not None: mail['to'] = to_addr[1] @@ -719,7 +758,8 @@ def run(): deps = [] else: deps = None - if not list_bset_cfg_files(opts, configs): + + if not list_bset_cfg_files(opts, configs) and not list_host(opts): prefix = macro_expand(opts.defaults, '%{_prefix}') if opts.canadian_cross(): opts.disable_install() diff --git a/source-builder/sb/simhost.py b/source-builder/sb/simhost.py new file mode 100644 index 0000000..9196151 --- /dev/null +++ b/source-builder/sb/simhost.py @@ -0,0 +1,720 @@ +# +# RTEMS Tools Project (http://www.rtems.org/) +# Copyright 2010-2020 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 compiler tool suite given a tool set. A tool +# set lists the various tools. These are specific tool configurations. +# + +from __future__ import print_function + +import copy +import datetime +import os + +try: + import build + import check + import error + import git + import log + import macros + import path + import shell + import sources + import version +except KeyboardInterrupt: + print('abort: user terminated', file = sys.stderr) + sys.exit(1) +except: + raise + +# +# Define host profiles so it can simulated on another host. +# +profiles = { + 'darwin': { '_os': ('none', 'none', 'darwin'), + '_host': ('triplet', 'required', 'x86_64-apple-darwin18.5.0'), + '_host_vendor': ('none', 'none', 'apple'), + '_host_os': ('none', 'none', 'darwin'), + '_host_os_version': ('none', 'none', '18.5.0'), + '_host_cpu': ('none', 'none', 'x86_64'), + '_host_alias': ('none', 'none', '%{nil}'), + '_host_arch': ('none', 'none', 'x86_64'), + '_usr': ('dir', 'optional', '/usr/local'), + '_var': ('dir', 'optional', '/usr/local/var') }, + 'freebsd': { '_os': ('none', 'none', 'freebsd'), + '_host': ('triplet', 'required', 'x86_64-freebsd12.0-RELEASE-p3'), + '_host_vendor': ('none', 'none', 'pc'), + '_host_os': ('none', 'none', 'freebsd'), + '_host_os_version': ('none', 'none', '12.0-RELEASE-p3'), + '_host_cpu': ('none', 'none', 'x86_64'), + '_host_alias': ('none', 'none', '%{nil}'), + '_host_arch': ('none', 'none', 'x86_64'), + '_usr': ('dir', 'optional', '/usr/local'), + '_var': ('dir', 'optional', '/usr/local/var') }, + 'linux': { '_os': ('none', 'none', 'linux'), + '_host': ('triplet', 'required', 'x86_64-linux-gnu'), + '_host_vendor': ('none', 'none', 'gnu'), + '_host_os': ('none', 'none', 'linux'), + '_host_os_version': ('none', 'none', '4.18.0-16'), + '_host_cpu': ('none', 'none', 'x86_64'), + '_host_alias': ('none', 'none', '%{nil}'), + '_host_arch': ('none', 'none', 'x86_64'), + '_usr': ('dir', 'optional', '/usr/local'), + '_var': ('dir', 'optional', '/usr/local/var') }, + 'netbsd': { '_os': ('none', 'none', 'netbsd'), + '_host': ('triplet', 'required', 'x86_64-netbsd8.0'), + '_host_vendor': ('none', 'none', 'pc'), + '_host_os': ('none', 'none', 'netbsd'), + '_host_os_version': ('none', 'none', '8.0'), + '_host_cpu': ('none', 'none', 'x86_64'), + '_host_alias': ('none', 'none', '%{nil}'), + '_host_arch': ('none', 'none', 'x86_64'), + '_usr': ('dir', 'optional', '/usr/local'), + '_var': ('dir', 'optional', '/usr/local/var') }, + 'solaris': { '_os': ('none', 'none', 'solaris'), + '_host': ('triplet', 'required', 'x86_64-pc-solaris2'), + '_host_vendor': ('none', 'none', 'pc'), + '_host_os': ('none', 'none', 'solaris'), + '_host_os_version': ('none', 'none', '2'), + '_host_cpu': ('none', 'none', 'x86_64'), + '_host_alias': ('none', 'none', '%{nil}'), + '_host_arch': ('none', 'none', 'x86_64'), + '_usr': ('dir', 'optional', '/usr/local'), + '_var': ('dir', 'optional', '/usr/local/var') }, + 'win32': { '_os': ('none', 'none', 'win32'), + '_windows_os': ('none', 'none', 'mingw32'), + '_host': ('triplet', 'required', 'x86_64-w64-mingw32'), + '_host_vendor': ('none', 'none', 'pc'), + '_host_os': ('none', 'none', 'win32'), + '_host_os_version': ('none', 'none', '10'), + '_host_cpu': ('none', 'none', 'x86_64'), + '_host_alias': ('none', 'none', '%{nil}'), + '_host_arch': ('none', 'none', 'x86_64'), + '_usr': ('dir', 'optional', '/usr/local'), + '_var': ('dir', 'optional', '/usr/local/var') }, + 'cygwin': { '_os': ('none', 'none', 'win32'), + '_windows_os': ('none', 'none', 'cygwin'), + '_host': ('triplet', 'required', 'x86_64-w64-cygwin'), + '_host_vendor': ('none', 'none', 'microsoft'), + '_host_os': ('none', 'none', 'win32'), + '_host_os_version': ('none', 'none', '10'), + '_host_cpu': ('none', 'none', 'x86_64'), + '_host_alias': ('none', 'none', '%{nil}'), + '_host_arch': ('none', 'none', 'x86_64'), + '_usr': ('dir', 'optional', '/usr/local'), + '_var': ('dir', 'optional', '/usr/local/var') }, +} + +class log_capture(object): + def __init__(self): + self.log = [] + log.capture = self.capture + + def __str__(self): + return os.linesep.join(self.log) + + def capture(self, text): + self.log += [l for l in text.replace(chr(13), '').splitlines()] + + def get(self): + return self.log + + def clear(self): + self.log = [] + +def find_bset_config(bset_config, macros): + '''Find the build set or config file using the macro config defined path.''' + name = bset_config + if not path.exists(name): + for cp in macros.expand('%{_configdir}').split(':'): + configdir = path.abspath(cp) + name = path.join(configdir, bset_config) + if path.exists(name): + break + name = None + if name is None: + raise error.general('no build set file found: %s' % (bset_config)) + return name + +def macro_expand(macros, _str): + cstr = None + while cstr != _str: + cstr = _str + _str = macros.expand(_str) + _str = shell.expand(macros, _str) + return _str + +def strip_common_prefix(files): + commonprefix = os.path.commonprefix(files) + return sorted(list(set([f[len(commonprefix):] for f in files]))) + +# +# A skinny options command line class to get the configs to load. +# +class options(object): + def __init__(self, argv, argopts, defaults, extras): + command_path = path.dirname(path.abspath(argv[0])) + if len(command_path) == 0: + command_path = '.' + self.command_path = command_path + self.command_name = path.basename(argv[0]) + extras += ['--dry-run', + '--quiet', + '--without-log', + '--without-error-report', + '--without-release-url'] + self.argv = argv + self.args = argv[1:] + extras + self.defaults = macros.macros(name = defaults, + sbdir = command_path) + self.load_overrides() + self.opts = { 'params' : extras } + self.sb_git() + self.rtems_bsp() + if 'download_dir' in argopts and argopts.download_dir is not None: + self.defaults['_sourcedir'] = ('dir', + 'optional', + path.abspath(argopts.download_dir)) + self.defaults['_patchdir'] = ('dir', + 'optional', + path.abspath(argopts.download_dir)) + + def load_overrides(self): + overrides = None + if os.name == 'nt': + try: + from . import windows + overrides = windows.load() + host_windows = True + host_posix = False + except: + raise error.general('failed to load Windows host support') + elif os.name == 'posix': + uname = os.uname() + try: + if uname[0].startswith('MINGW64_NT'): + import windows + overrides = windows.load() + host_windows = True + elif uname[0].startswith('CYGWIN_NT'): + import windows + overrides = windows.load() + elif uname[0] == 'Darwin': + import darwin + overrides = darwin.load() + elif uname[0] == 'FreeBSD': + import freebsd + overrides = freebsd.load() + elif uname[0] == 'NetBSD': + import netbsd + overrides = netbsd.load() + elif uname[0] == 'Linux': + import linux + overrides = linux.load() + elif uname[0] == 'SunOS': + import solaris + overrides = solaris.load() + except error.general as ge: + raise error.general('failed to load %s host support: %s' % (uname[0], ge)) + except: + raise error.general('failed to load %s host support' % (uname[0])) + else: + raise error.general('unsupported host type; please add') + if overrides is None: + raise error.general('no hosts defaults found; please add') + for k in overrides: + self.defaults[k] = overrides[k] + + def parse_args(self, arg, error = True, extra = True): + for a in range(0, len(self.args)): + if self.args[a].startswith(arg): + lhs = None + rhs = None + if '=' in self.args[a]: + eqs = self.args[a].split('=') + lhs = eqs[0] + if len(eqs) > 2: + rhs = '='.join(eqs[1:]) + else: + rhs = eqs[1] + elif extra: + lhs = self.args[a] + a += 1 + if a < len(self.args): + rhs = self.args[a] + return [lhs, rhs] + a += 1 + return None + + def rtems_bsp(self, arch='arch'): + self.defaults['rtems_version'] = str(version.version()) + self.defaults['_target'] = arch + '-rtems' + self.defaults['rtems_host'] = 'rtems-' + arch + self.defaults['with_rtems_bsp'] = 'rtems-bsp' + + def sb_git(self): + repo = git.repo(self.defaults.expand('%{_sbdir}'), self) + repo_mail = None + if repo.valid(): + repo_valid = '1' + repo_head = repo.head() + repo_clean = not repo.dirty() + repo_remotes = '%{nil}' + remotes = repo.remotes() + if 'origin' in remotes: + repo_remotes = '%s/origin' % (remotes['origin']['url']) + repo_id = repo_head + if not repo_clean: + repo_id += '-modified' + repo_mail = repo.email() + else: + repo_valid = '0' + repo_head = '%{nil}' + repo_clean = '%{nil}' + repo_remotes = '%{nil}' + repo_id = 'no-repo' + self.defaults['_sbgit_valid'] = repo_valid + self.defaults['_sbgit_head'] = repo_head + self.defaults['_sbgit_clean'] = str(repo_clean) + self.defaults['_sbgit_remotes'] = str(repo_remotes) + self.defaults['_sbgit_id'] = repo_id + if repo_mail is not None: + self.defaults['_sbgit_mail'] = repo_mail + + def get_arg(self, arg): + if self.optargs is None or arg not in self.optargs: + return None + return self.parse_args(arg) + + def with_arg(self, label, default = 'not-found'): + # the default if there is no option for without. + result = default + for pre in ['with', 'without']: + arg_str = '--%s-%s' % (pre, label) + arg_label = '%s_%s' % (pre, label) + arg = self.parse_args(arg_str, error = False, extra = False) + if arg is not None: + if arg[1] is None: + result = 'yes' + else: + result = arg[1] + break + return [arg_label, result] + + def dry_run(self): + return True + + def keep_going(self): + return False + + def quiet(self): + return True + + def no_clean(self): + return True + + def always_clean(self): + return False + + def no_install(self): + return True + + def download_disabled(self): + return False + + def disable_install(self): + return True + + def urls(self): + return None + + def info(self): + s = ' Command Line: %s%s' % (' '.join(self.argv), os.linesep) + s += ' Python: %s' % (sys.version.replace('\n', '')) + return s + +class buildset: + """Build a set builds a set of packages.""" + + def __init__(self, bset, _configs, opts, macros = None): + log.trace('_bset: %s: init' % (bset)) + self.parent = 'root' + self._includes = [] + self._errors = [] + self.configs = _configs + self.opts = opts + if macros is None: + self.macros = copy.copy(opts.defaults) + else: + self.macros = copy.copy(macros) + self.macros.define('_rsb_getting_source') + log.trace('_bset: %s: macro defaults' % (bset)) + log.trace(str(self.macros)) + self.bset = bset + _target = self.macros.expand('%{_target}') + if len(_target): + pkg_prefix = _target + else: + pkg_prefix = self.macros.expand('%{_host}') + self.bset_pkg = '%s-%s-set' % (pkg_prefix, self.bset) + self.build_failure = None + + def _add_includes(self, includes, parent = None): + if parent is None: + parent = self.parent + if not isinstance(includes, list): + includes = [includes] + self._includes += [i + ':' + parent for i in includes] + + def _rebase_includes(self, includes, parent): + if not isinstance(includes, list): + includes = [includes] + rebased = [] + for i in includes: + if i.split(':', 2)[1] == 'root': + rebased += [i.split(':', 2)[0] + ':' + parent] + else: + rebased += [i] + return rebased + + def root(self): + for i in self._includes: + si = i.split(':') + if len(si) == 2: + if si[1] == 'root': + return si[0] + return None + + def includes(self): + return [i for i in self._includes if not i.endswith(':root')] + + def deps(self): + return strip_common_prefix([i.split(':')[0] for i in self.includes()]) + + def errors(self): + return sorted(list(set(self._errors))) + + def build_package(self, _config, _build): + if not _build.disabled(): + _build.make() + + def parse(self, bset, expand=True): + + # + # Ouch, this is a copy of the setbuilder.py code. + # + + def _clean(line): + line = line[0:-1] + b = line.find('#') + if b >= 0: + line = line[1:b] + return line.strip() + + bsetname = find_bset_config(bset, self.macros) + + try: + log.trace('_bset: %s: open: %s %s' % (self.bset, bsetname, expand)) + bsetf = open(path.host(bsetname), 'r') + except IOError as err: + raise error.general('error opening bset file: %s' % (bsetname)) + + self._add_includes(bsetname) + parent = self.parent + self.parent = bsetname + + configs = [] + + try: + lc = 0 + for l in bsetf: + lc += 1 + l = _clean(l) + if len(l) == 0: + continue + log.trace('_bset: %s: %03d: %s' % (self.bset, lc, l)) + ls = l.split() + if ls[0][-1] == ':' and ls[0][:-1] == 'package': + self.bset_pkg = ls[1].strip() + self.macros['package'] = self.bset_pkg + elif ls[0][0] == '%' and (len(ls[0]) > 1 and ls[0][1] != '{'): + def err(msg): + raise error.general('%s:%d: %s' % (self.bset, lc, msg)) + if ls[0] == '%define' or ls[0] == '%defineifnot' : + name = ls[1].strip() + value = None + if len(ls) > 2: + value = ' '.join([f.strip() for f in ls[2:]]) + if ls[0] == '%defineifnot': + if self.macros.defined(name): + name = None + if name is not None: + if value is not None: + self.macros.define(name, value) + else: + self.macros.define(name) + elif ls[0] == '%undefine': + if len(ls) > 2: + raise error.general('%s:%d: %undefine requires ' \ + 'just the name' % (self.bset, lc)) + self.macros.undefine(ls[1].strip()) + elif ls[0] == '%include': + configs += self.parse(ls[1].strip()) + elif ls[0] in ['%patch', '%source']: + sources.process(ls[0][1:], ls[1:], self.macros, err) + elif ls[0] == '%hash': + sources.hash(ls[1:], self.macros, err) + else: + try: + l = macro_expand(self.macros, l.strip()) + except: + if expand: + raise + l = None + if l is not None: + c = build.find_config(l, self.configs) + if c is None: + raise error.general('%s:%d: cannot find file: %s' + % (self.bset, lc, l)) + configs += [c + ':' + self.parent] + finally: + bsetf.close() + self.parent = parent + + return configs + + def load(self): + # + # If the build set file ends with .cfg the user has passed to the + # buildset builder a configuration so we just return it. + # + if self.bset.endswith('.cfg'): + self._add_includes(self.bset) + configs = [self.bset] + else: + exbset = self.macros.expand(self.bset) + self.macros['_bset'] = exbset + self.macros['_bset_tmp'] = build.short_name(exbset) + root, ext = path.splitext(exbset) + if exbset.endswith('.bset'): + bset = exbset + else: + bset = '%s.bset' % (exbset) + configs = self.parse(bset) + return configs + + def set_host_details(self, host, opts, macros): + if host not in profiles: + raise error.general('invalid host: ' + host) + for m in profiles[host]: + opts.defaults[m] = profiles[host][m] + macros[m] = profiles[host][m] + macros_to_copy = [('%{_build}', '%{_host}'), + ('%{_build_alias}', '%{_host_alias}'), + ('%{_build_arch}', '%{_host_arch}'), + ('%{_build_cpu}', '%{_host_cpu}'), + ('%{_build_os}', '%{_host_os}'), + ('%{_build_vendor}', '%{_host_vendor}')] + for m in macros_to_copy: + opts.defaults[m[0]] = opts.defaults[m[1]] + macros[m[0]] = macros[m[1]] + # + # Look for a valid cc and cxx. + # + for cc in ['/usr/bin/cc', '/usr/bin/clang', '/usr/bin/gcc']: + if check.check_exe(cc, cc): + opts.defaults['__cc'] = cc + macros['__cc'] = cc + break + if not macros.defined('__cc'): + raise error.general('no valid cc found') + for cxx in ['/usr/bin/c++', '/usr/bin/clang++', '/usr/bin/g++']: + if check.check_exe(cxx, cxx): + opts.defaults['__cxx'] = cxx + macros['__cxx'] = cxx + if not macros.defined('__cxx'): + raise error.general('no valid c++ found') + + def build(self, host, nesting_count = 0): + + build_error = False + + nesting_count += 1 + + log.trace('_bset: %2d: %s for %s: make' % (nesting_count, self.bset, host)) + log.notice('Build Set: %s for %s' % (self.bset, host)) + + mail_subject = '%s on %s' % (self.bset, + self.macros.expand('%{_host}')) + + current_path = os.environ['PATH'] + + start = datetime.datetime.now() + + have_errors = False + + try: + configs = self.load() + + log.trace('_bset: %2d: %s: configs: %s' % (nesting_count, self.bset, ','.join(configs))) + + sizes_valid = False + builds = [] + for s in range(0, len(configs)): + bs = None + b = None + try: + # + # Each section of the build set gets a separate set of + # macros so we do not contaminate one configuration with + # another. + # + opts = copy.copy(self.opts) + macros = copy.copy(self.macros) + self.set_host_details(host, opts, macros) + config, parent = configs[s].split(':', 2) + if config.endswith('.bset'): + log.trace('_bset: %2d: %s' % (nesting_count + 1, '=' * 75)) + bs = buildset(config, self.configs, opts, macros) + bs.build(host, nesting_count) + self._includes += \ + self._rebase_includes(bs.includes(), parent) + del bs + elif config.endswith('.cfg'): + log.trace('_bset: %2d: %s' % (nesting_count + 1, '-' * 75)) + try: + b = build.build(config, + False, + opts, + macros) + self._includes += \ + self._rebase_includes(b.includes(), parent) + except: + build_error = True + raise + self.build_package(config, b) + builds += [b] + # + # Dump post build macros. + # + log.trace('_bset: %2d: macros post-build' % (nesting_count)) + log.trace(str(macros)) + else: + raise error.general('invalid config type: %s' % (config)) + except error.general as gerr: + have_errors = True + if b is not None: + if self.build_failure is None: + self.build_failure = b.name() + self._includes += b.includes() + self._errors += \ + [find_bset_config(config, opts.defaults) + ':' + parent] + self._includes + raise + # + # Clear out the builds ... + # + for b in builds: + del b + self._includes += \ + [find_bset_config(c.split(':')[0], self.macros) + ':' + self.bset for c in configs] + except error.general as gerr: + if not build_error: + log.stderr(str(gerr)) + raise + except KeyboardInterrupt: + raise + except: + self.build_failure = 'RSB general failure' + raise + finally: + end = datetime.datetime.now() + os.environ['PATH'] = current_path + build_time = str(end - start) + log.notice('Build Set: Time %s' % (build_time)) + +def list_hosts(): + hosts = sorted(profiles.keys()) + max_os_len = max(len(h) for h in hosts) + max_host_len = max(len(profiles[h]['_host'][2]) for h in hosts) + for h in hosts: + log.notice('%*s: %-*s %s' % (max_os_len, h, max_host_len, + profiles[h]['_host'][2], + profiles[h]['_host'][2])) + +def get_files(configs, ext, localpath): + files = [] + if localpath: + for cp in configs['localpaths']: + files += [c for c in configs[cp] if c.endswith(ext)] + else: + files = [c for c in configs['files'] if c.endswith(ext)] + return files + +def get_config_files(configs, localpath = False): + return get_files(configs, '.cfg', localpath) + +def get_bset_files(configs, localpath = False): + return get_files(configs, '.bset', localpath) + +def get_config_bset_files(opts, configs): + cbs = get_config_files(configs) + get_bset_files(configs) + return strip_common_prefix([find_bset_config(cb, opts.defaults) for cb in cbs]) + +def get_root_bset_files(opts, configs, localpath = False): + bsets = get_bset_files(configs, localpath) + incs = {} + for bs in bsets: + bset = buildset(bs, configs, opts) + cfgs = [find_bset_config(c.split(':')[0], bset.macros) for c in bset.parse(bs, False)] + incs[bset.root()] = bset.includes() + cfgs + roots = sorted(incs.keys()) + for inc in incs: + for i in incs[inc]: + si = i.split(':') + if len(si) > 0 and si[0] in roots: + roots.remove(si[0]) + return roots + +def get_root(configs): + return configs['root'] + +def list_root_bset_files(opts, configs): + for p in configs['paths']: + log.notice('Examining: %s' % (os.path.relpath(p))) + for r in strip_common_prefix(get_root_bset_files(opts, configs)): + log.notice(' %s' % (r)) + +def list_bset_files(opts, configs): + for p in configs['paths']: + log.notice('Examining: %s' % (os.path.relpath(p))) + for b in get_bset_files(configs): + log.notice(' %s' % (b[:b.rfind('.')])) + +def load_log(logfile): + log.default = log.log(streams = [logfile]) + +def log_default(name): + return 'rsb-log-%s-%s.txt' % (name, datetime.datetime.now().strftime('%Y%m%d-%H%M%S')) + +def load_options(argv, argopts, defaults = '%{_sbdir}/defaults.mc', extras = []): + opts = options(argv, argopts, defaults, extras) + opts.defaults['rtems_version'] = str(argopts.rtems_version) + return opts diff --git a/source-builder/sb/version.py b/source-builder/sb/version.py index 296f717..007f3b6 100644 --- a/source-builder/sb/version.py +++ b/source-builder/sb/version.py @@ -89,9 +89,15 @@ _version_str = '%s.%s' % (_version, _revision) _released = False _git = False _is_loaded = False +_top_dir = None def _top(): - top = path.dirname(sys.argv[0]) + if _top_dir is None: + top = path.dirname(sys.argv[0]) + if top.endswith('source-builder/sb'): + top = path.dirname(path.dirname(top)) + else: + top = _top_dir if len(top) == 0: top = '.' return top @@ -183,6 +189,10 @@ def _load_git_version(): _is_loaded = True return _git +def set_top(top): + global _top_dir + _top_dir = top + def load_release_settings(section, error = False): vc, v = _load_released_version_config() items = [] |