* [ptxdist] [PATCH 0/6] New BSP from template
@ 2026-10-13 11:16 Ladislav Michl
2026-10-13 11:16 ` [ptxdist] [PATCH 1/6] scripts: add ptxdist_bootstrap.sh with out-of-tree build support Ladislav Michl
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Ladislav Michl @ 2026-10-13 11:16 UTC (permalink / raw)
To: ptxdist; +Cc: rob
Running freshly deployed PTXdist currently gives you:
ladis@lenoch:/tmp/test_bsp$ ~/src/ptxdist/bin/ptxdist menuconfig
ptxdist: error: PTXdist in /home/ladis/src/ptxdist is not built.
Simply put:
"Why on _earth_ would you need to install source code before you're
allowed to configure and compile it? The only thing it actually
built when I did the first "make" was the kconfig binaries. The
kernel (where kconfig comes from) does not require you to make and
install kconfig before using menuconfig. Neither do long-term users
of it like busybox or uClibc..." -- Rob Landley
(https://sourceware.org/legacy-ml/crossgcc/2009-04/msg00038.html)
I'd suggest read whole Design discussion archived at:
https://sourceware.org/legacy-ml/crossgcc/2009-04/msg00015.html
before reading the rest or even looking at the patchset.
I had this in mind for a quite long time and was carrying patches
to achieve that, but still was not quite happy with them until last
rainy weekend (figuring out where I read above rant was a pretty hard
task itself...)
Back then I was making excuses PTXdist still being in development,
which was, with respect to PTXdist age at that time, a bit silly, so
now the following patchset brings you this:
ladis@lenoch:/tmp/test_bsp$ ~/src/ptxdist/bin/ptxdist menuconfig
ptxdist: preparing host tools in '/home/ladis/.cache/ptxdist/git' ...
ptxdist: there is no PTXdist project in '/tmp/test_bsp'
ptxdist: create a new one? [y/N] y
ptxdist: project name.................: test_bsp
ptxdist: select option by number:
ptxdist: [1] ALPHA
ptxdist: [2] AVR32
ptxdist: [3] AVR
ptxdist: [4] ARM
ptxdist: [5] ARM64
ptxdist: [6] BLACKFIN
ptxdist: [7] X86
ptxdist: [8] MINGW
ptxdist: [9] PPC
ptxdist: [10] M68K
ptxdist: [11] SPARC
ptxdist: [12] MICROBLAZE
ptxdist: [13] MIPS
ptxdist: [14] CRIS
ptxdist: [15] PARISC
ptxdist: [16] SH
ptxdist: [17] RISCV
ptxdist: [18] LOONGARCH
ptxdist: architecture.................: 13
ptxdist: platform name................: mips
ptxdist: creating project 'test_bsp'
ptxdist: creating platform 'mips' (mips)
[here menuconfig is presented]
ptxdist: done. There is no toolchain yet, select one with
ptxdist: 'ptxdist toolchain <path>'. 'ptxdist platformconfig' refines
ptxdist: the platform, 'ptxdist newpackage <type>' adds own packages.
*** End of the configuration.
*** Execute 'ptxdist go' to build the project or try 'ptxdist help'.
And that's it. Previous configure && make && make install still works
the same as before in case you are installing system-wide or into
a docker image.
The following patchset it trying to address all Rob's remarks about
PTXdist, except those the time invalidated: flex and bison are now
required even by kernel, so we still do the same.
Comments and suggestions welcome, as always.
Ladislav Michl (6):
scripts: add ptxdist_bootstrap.sh with out-of-tree build support
ptxdist: introduce PTXDIST_HOSTTOOLS_DIR
ptxdist: prepare host tools on demand
ptxdist: don't depend on bash being /bin/bash
configure: use ptxdist_bootstrap.sh to check the host
ptxdist: let new project raise from template
.gitignore | 1 +
Makefile.in | 65 ++---
README | 16 +-
bin/ptxdist | 259 ++++++++++++++++++--
bin/ptxdist-auto-version | 4 +-
configure.ac | 314 +++---------------------
doc/ref_parameter.rst | 4 +
rules/host-qemu.make | 2 +-
rules/other/Toplevel.make | 6 +-
rules/templates/project/gitignore | 9 +
rules/templates/project/platformconfig | 10 +
rules/templates/project/ptxconfig | 6 +
scripts/lib/ptxd_lib_kconfig.sh | 6 +-
scripts/lib/ptxd_make_nested.sh | 2 +-
scripts/lib/ptxd_make_report.sh | 2 +-
scripts/ptxdist_bootstrap.sh | 315 +++++++++++++++++++++++++
16 files changed, 661 insertions(+), 360 deletions(-)
create mode 100644 rules/templates/project/gitignore
create mode 100644 rules/templates/project/platformconfig
create mode 100644 rules/templates/project/ptxconfig
create mode 100755 scripts/ptxdist_bootstrap.sh
--
2.47.3
^ permalink raw reply [flat|nested] 7+ messages in thread* [ptxdist] [PATCH 1/6] scripts: add ptxdist_bootstrap.sh with out-of-tree build support 2026-10-13 11:16 [ptxdist] [PATCH 0/6] New BSP from template Ladislav Michl @ 2026-10-13 11:16 ` Ladislav Michl 2026-10-13 11:17 ` [ptxdist] [PATCH 2/6] ptxdist: introduce PTXDIST_HOSTTOOLS_DIR Ladislav Michl ` (4 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Ladislav Michl @ 2026-10-13 11:16 UTC (permalink / raw) To: ptxdist From: Ladislav Michl <ladis@triops.cz> The bootstrap script makes ready everything PTXdist needs from the host: - links to the GNU tools in <builddir>/bin - kconfig in <builddir>/scripts/kconfig All the missing prerequisites are reported at once. Add support for out-of-tree builds to the Makefile; all generated files ends in the build directory, 'install' and 'dist' targets are only supported in-tree. Signed-off-by: Ladislav Michl <ladis@triops.cz> --- .gitignore | 1 + Makefile.in | 65 +++------- configure.ac | 2 +- scripts/ptxdist_bootstrap.sh | 230 +++++++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+), 48 deletions(-) create mode 100755 scripts/ptxdist_bootstrap.sh diff --git a/.gitignore b/.gitignore index 1e2cd1c31..79657ecab 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ man/ptxdist.1.gz /env/ /scripts/report/__pycache__/ +/build.log diff --git a/Makefile.in b/Makefile.in index da8cb9d7c..5eb7b407b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,9 +1,10 @@ -version := $(shell . ./scripts/ptxdist_version.sh && echo $${PTXDIST_VERSION_FULL}) +version := $(shell PTXDIST_TOPDIR=@abs_srcdir@ && . @abs_srcdir@/scripts/ptxdist_version.sh && echo $${PTXDIST_VERSION_FULL}) project := ptxdist-$(version) prefix := @prefix@ exec_prefix := @exec_prefix@ abs_srcdir := @abs_srcdir@ +abs_builddir := @abs_builddir@ libdir := @libdir@ bindir := @bindir@ instdir := $(libdir)/$(project) @@ -13,49 +14,13 @@ RST2MAN := @RST2MAN@ export SHELL -all: kconfig environment - @touch .done - -kconfig: - @echo "building conf and mconf ..." - $(MAKE) -C "$(abs_srcdir)/scripts/kconfig" +all: + @echo "preparing PTXdist host tools ..." + @CC="@CC@" CFLAGS="@CFLAGS@" CPPFLAGS="@CPPFLAGS@" LDFLAGS="@LDFLAGS@" \ + LEX="@LEX@" YACC="@YACC@" \ + "@BASH@" "$(abs_srcdir)/scripts/ptxdist_bootstrap.sh" "$(abs_builddir)" @echo "done." -environment: - @echo -n "preparing PTXdist environment ..." - @ln -sf @AWK@ "$(abs_srcdir)/bin/awk" - @ln -sf @GNU_chmod@ "$(abs_srcdir)/bin/chmod" - @ln -sf @GNU_chown@ "$(abs_srcdir)/bin/chown" - @ln -sf @GNU_mv@ "$(abs_srcdir)/bin/mv" - @ln -sf @GNU_cp@ "$(abs_srcdir)/bin/cp" - @ln -sf @GNU_rm@ "$(abs_srcdir)/bin/rm" - @ln -sf @GNU_ln@ "$(abs_srcdir)/bin/ln" - @ln -sf @GNU_rmdir@ "$(abs_srcdir)/bin/rmdir" - @ln -sf @GNU_md5sum@ "$(abs_srcdir)/bin/md5sum" - @ln -sf @GNU_mkdir@ "$(abs_srcdir)/bin/mkdir" - @ln -sf @GNU_mktemp@ "$(abs_srcdir)/bin/mktemp" - @ln -sf @GNU_install@ "$(abs_srcdir)/bin/install" - @ln -sf @GNU_stat@ "$(abs_srcdir)/bin/stat" - @ln -sf @GNU_mknod@ "$(abs_srcdir)/bin/mknod" - @ln -sf @GNU_tty@ "$(abs_srcdir)/bin/tty" - @ln -sf @GNU_tar@ "$(abs_srcdir)/bin/tar" - @ln -sf @GNU_find@ "$(abs_srcdir)/bin/find" - @ln -sf @PTXDIST_FILE@ "$(abs_srcdir)/bin/file" - @ln -sf @GNU_cat@ "$(abs_srcdir)/bin/cat" - @ln -sf @GNU_dirname@ "$(abs_srcdir)/bin/dirname" - @ln -sf @GNU_readlink@ "$(abs_srcdir)/bin/readlink" - @ln -sf @GNU_realpath@ "$(abs_srcdir)/bin/realpath" - @ln -sf @GNU_sort@ "$(abs_srcdir)/bin/sort" - @ln -sf @SED@ "$(abs_srcdir)/bin/sed" - @ln -sf @GNU_xargs@ "$(abs_srcdir)/bin/xargs" - @ln -sf @BASH@ "$(abs_srcdir)/bin/bash" - @ln -sf @SYSCTL@ "$(abs_srcdir)/bin/sysctl" - @ln -sf @MAKE@ "$(abs_srcdir)/bin/make" - @if [ @SPHINX@ != "sphinx-build" ]; then \ - ln -sf @SPHINX@ "$(abs_srcdir)/bin/sphinx-build"; \ - fi - @echo " done" - man: man/ptxdist.1.gz man/ptxdist.1: doc/ptxdist.man doc/ref_parameter.rst @mkdir -pv man @@ -66,16 +31,22 @@ man/ptxdist.1.gz: man/ptxdist.1 gzip -f $< clean: - @rm -f .done - @find "$(abs_srcdir)/bin" -type l -print0 | xargs -0 rm -f - @$(MAKE) -C "$(abs_srcdir)/scripts/kconfig" clean + @rm -f "$(abs_builddir)/.done" + @find "$(abs_builddir)/bin" -type l -print0 | xargs -0 rm -f + @$(MAKE) -C "$(abs_builddir)/scripts/kconfig" \ + -f "$(abs_srcdir)/scripts/kconfig/Makefile" clean + +intree-check: + @if [ "$(abs_srcdir)" != "$(abs_builddir)" ]; then \ + echo "install and dist are only supported for in-tree builds!" ; exit 1 ; \ + fi -dirty-check: +dirty-check: intree-check @case "$(version)" in \ *-dirty) echo "refusing to install or package a dirty git tree!" ; exit 1 ;; \ esac -install: all dirty-check +install: intree-check all dirty-check @echo "installing PTXdist to $(DESTDIR)$(prefix)..." @rm -fr "$(DESTDIR)$(instdir)" @mkdir -p "$(DESTDIR)$(instdir)" diff --git a/configure.ac b/configure.ac index c368e46b1..2590ebbed 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ dnl dnl Check if the user has extracted the patches archive dnl AC_MSG_CHECKING(for ptxdist patches) -if test -d `dirname $0`/patches +if test -d "$srcdir/patches" then AC_MSG_RESULT(yes) else diff --git a/scripts/ptxdist_bootstrap.sh b/scripts/ptxdist_bootstrap.sh new file mode 100755 index 000000000..b9f4c7a5c --- /dev/null +++ b/scripts/ptxdist_bootstrap.sh @@ -0,0 +1,230 @@ +#!/bin/sh +# +# Prepare the host tools PTXdist needs: +# - links to sane (GNU) tools found on the host in <builddir>/bin +# - kconfig (conf, mconf and, if possible, nconf) in <builddir>/scripts/kconfig +# +# All missing prerequisites are reported at once. Only tools that PTXdist +# itself needs are checked, everything required by some packages only is +# left to the package build. +# +# usage: ptxdist_bootstrap.sh <builddir> +# +# CC, CFLAGS, CPPFLAGS, LDFLAGS, LEX, YACC and PKG_CONFIG from the +# environment are used if set. +# + +PTXDIST_LOG_PROMPT="ptxdist: " + +# +# Everything up to the bash version check must be plain POSIX sh: the +# script may be started by any shell and re-executes itself with bash. +# +if [ -z "${BASH_VERSION}" ]; then + bash="$(command -v bash)" || { + echo "${PTXDIST_LOG_PROMPT}error: bash >= 4.2 is required, please install it" >&2 + exit 1 + } + exec "${bash}" "${0}" "${@}" +fi + +case "${BASH_VERSION}" in +[0-3].*|4.[01].*) + echo "${PTXDIST_LOG_PROMPT}error: bash >= 4.2 is required, found ${BASH_VERSION} as '${BASH}'" >&2 + exit 1 + ;; +esac + +# e.g. when started as 'sh' with /bin/sh -> bash +set +o posix + +topdir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" || exit +builddir="${1}" +if [ -z "${builddir}" ]; then + echo "usage: ${0} <builddir>" >&2 + exit 1 +fi + +declare -A links +declare -a missing + +# +# $1: version found, $2: version required +# +version_ge() { + local -a have want + local i + + IFS=. read -r -a have <<< "${1}" + IFS=. read -r -a want <<< "${2}" + for (( i = 0; i < ${#want[@]}; i++ )); do + if [ "${have[i]:-0}" -gt "${want[i]}" ]; then + return 0 + elif [ "${have[i]:-0}" -lt "${want[i]}" ]; then + return 1 + fi + done +} + +# +# find a GNU tool and register a link for it +# +# $1: link name +# $2: expected '--version' output, e.g. 'GNU coreutils' +# $3: minimum version, may be empty +# $4: package that provides it (to print the hint) +# $5...: names to look for in PATH +# +find_gnu() { + local link="${1}" id="${2}" min="${3}" pkg="${4}" + local name path version + shift 4 + + for name in "${@}"; do + path="$(type -P "${name}")" || continue + version="$("${path}" --version 2>/dev/null | head -n 1)" + [[ "${version}" =~ ${id} ]] || continue + if [ -n "${min}" ]; then + [[ "${version}" =~ ([0-9]+(\.[0-9]+)+) ]] && + version_ge "${BASH_REMATCH[1]}" "${min}" || continue + fi + links[${link}]="${path}" + return + done + missing+=( "${id}${min:+ >= ${min}} as '${link}' (package: ${pkg})" ) +} + +for tool in cat chmod chown cp dirname install ln md5sum mkdir mknod \ + mktemp mv readlink realpath rm rmdir sort stat tty; do + find_gnu "${tool}" "GNU coreutils" "" coreutils "g${tool}" "${tool}" +done +find_gnu tar "GNU tar" "" tar gtar tar +find_gnu find "GNU findutils" 4 findutils gfind find +find_gnu xargs "GNU findutils" 4 findutils gxargs xargs +find_gnu sed "GNU sed" 4 sed gsed sed +find_gnu awk "GNU Awk" "" gawk gawk awk +find_gnu make "GNU Make" 3.81 make gmake gnumake make + +links[bash]="${BASH}" + +if path="$(type -P file)"; then + links[file]="${path}" +else + missing+=( "'file' (package: file)" ) +fi + +# optional +links[sysctl]="$(type -P sysctl || type -P false)" +if path="$(type -P sphinx-build)"; then + links[sphinx-build]="${path}" +fi + +# +# kconfig +# +if [ -z "${CC}" ]; then + CC="$(type -P gcc || type -P cc)" || CC=cc +fi +if ! type -P "${CC%% *}" > /dev/null; then + missing+=( "C compiler '${CC}' (package: gcc)" ) +fi +: ${LEX:=flex} ${YACC:=bison} ${PKG_CONFIG:=pkg-config} +if ! type -P "${LEX%% *}" > /dev/null; then + missing+=( "'${LEX}' (package: flex)" ) +fi +if ! type -P "${YACC%% *}" > /dev/null; then + missing+=( "'${YACC}' (package: bison)" ) +fi + +# +# $1: test program; possibly followed by compiler and linker flags +# +try_link() { + local prog="${1}" + shift + echo "${prog}" | + ${CC} ${CFLAGS} ${CPPFLAGS} -x c - -o /dev/null ${LDFLAGS} "${@}" > /dev/null 2>&1 +} + +# +# $1: pkg-config modules (space separated, all required) +# $2: fallback libs +# $3: test program +# out: libs_cflags, libs_libs +# +find_libs() { + local modules="${1}" fallback="${2}" prog="${3}" + + if ${PKG_CONFIG} --exists ${modules} 2>/dev/null; then + libs_cflags="$(${PKG_CONFIG} --cflags ${modules})" + libs_libs="$(${PKG_CONFIG} --libs ${modules})" + else + libs_cflags="" + libs_libs="${fallback}" + fi + try_link "${prog}" ${libs_cflags} ${libs_libs} +} + +ncurses_prog='#include <ncurses.h> +int main(void) { initscr(); endwin(); return 0; }' +nconf_prog='#include <ncurses.h> +#include <menu.h> +#include <panel.h> +int main(void) { initscr(); new_panel(stdscr); free_menu(NULL); return 0; }' + +if type -P "${CC%% *}" > /dev/null; then + if find_libs "ncursesw" "-lncursesw" "${ncurses_prog}" || + find_libs "ncurses" "-lncurses" "${ncurses_prog}"; then + mconf_cflags="${libs_cflags}" + mconf_libs="${libs_libs}" + else + missing+=( "ncurses development files (package: libncurses-dev or ncurses-devel)" ) + fi + # nconf is optional + if find_libs "ncursesw menuw panelw" "-lmenuw -lpanelw -lncursesw" "${nconf_prog}" || + find_libs "ncurses menu panel" "-lmenu -lpanel -lncurses" "${nconf_prog}"; then + nconf=nconf + nconf_libs="${libs_libs}" + fi +fi + +if [ ${#missing[@]} -gt 0 ]; then + { + echo + echo "${PTXDIST_LOG_PROMPT}error: missing host tools, please install:" + echo + printf " - %s\n" "${missing[@]}" + echo + } >&2 + exit 1 +fi + +# +# all prerequisites are there, set up the build directory +# +mkdir -p "${builddir}/bin" "${builddir}/scripts/kconfig" && +for link in "${!links[@]}"; do + ln -sfn "${links[${link}]}" "${builddir}/bin/${link}" || exit +done + +if ! "${links[make]}" -C "${builddir}/scripts/kconfig" \ + -f "${topdir}/scripts/kconfig/Makefile" \ + CC="${CC}" \ + ${CFLAGS:+CFLAGS="${CFLAGS}"} \ + ${CPPFLAGS:+CPPFLAGS="${CPPFLAGS}"} \ + ${LDFLAGS:+LDFLAGS="${LDFLAGS}"} \ + LEX="${LEX}" \ + YACC="${YACC}" \ + MCONF_CFLAGS="${mconf_cflags}" \ + MCONF_LIBS="${mconf_libs}" \ + NCONF_LIBS="${nconf_libs}" \ + NCONF="${nconf}" \ + > "${builddir}/build.log" 2>&1; then + tail -n 20 "${builddir}/build.log" >&2 + echo >&2 + echo "${PTXDIST_LOG_PROMPT}error: building kconfig failed, see '${builddir}/build.log'" >&2 + echo >&2 + exit 1 +fi + +echo "${topdir}" > "${builddir}/.done" -- 2.47.3 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [ptxdist] [PATCH 2/6] ptxdist: introduce PTXDIST_HOSTTOOLS_DIR 2026-10-13 11:16 [ptxdist] [PATCH 0/6] New BSP from template Ladislav Michl 2026-10-13 11:16 ` [ptxdist] [PATCH 1/6] scripts: add ptxdist_bootstrap.sh with out-of-tree build support Ladislav Michl @ 2026-10-13 11:17 ` Ladislav Michl 2026-10-13 11:17 ` [ptxdist] [PATCH 3/6] ptxdist: prepare host tools on demand Ladislav Michl ` (3 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Ladislav Michl @ 2026-10-13 11:17 UTC (permalink / raw) To: ptxdist From: Ladislav Michl <ladis@triops.cz> Store the links to the host tools and kconfig in a separate variable for now the same as PTXDIST_TOPDIR. Signed-off-by: Ladislav Michl <ladis@triops.cz> --- bin/ptxdist | 7 +++++-- rules/host-qemu.make | 2 +- rules/other/Toplevel.make | 6 +++--- scripts/lib/ptxd_lib_kconfig.sh | 6 +++--- scripts/lib/ptxd_make_nested.sh | 2 +- scripts/lib/ptxd_make_report.sh | 2 +- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/bin/ptxdist b/bin/ptxdist index 2557cb9a2..94c41412f 100755 --- a/bin/ptxdist +++ b/bin/ptxdist @@ -2118,6 +2118,7 @@ _realpath() # # out: PTXDIST # PTXDIST_TOPDIR +# PTXDIST_HOSTTOOLS_DIR # PTXDIST_WORKSPACE # PTXDIST_PTXCONFIG_DEFAULT # PTXDIST_PLATFORMCONFIG_DEFAULT @@ -2142,6 +2143,7 @@ setup_topdir() { PTXDIST="${ptxdist}" PTXDIST_TOPDIR="${topdir}" + PTXDIST_HOSTTOOLS_DIR="${topdir}" PTXDIST_WORKSPACE="$(pwd)" eval PTXDIST_PTXCONFIG_DEFAULT="${PTXDIST_PTXCONFIG_DEFAULT}" @@ -2149,8 +2151,8 @@ setup_topdir() { eval PTXDIST_COLLECTIONCONFIG_DEFAULT="${PTXDIST_COLLECTIONCONFIG_DEFAULT}" eval PTXDIST_TOOLCHAIN_DEFAULT="${PTXDIST_TOOLCHAIN_DEFAULT}" - # ${PTXDIST_TOPDIR}/bin contains links to sane tools found by configure - export PATH="${PTXDIST_TOPDIR}/bin:${PATH}" + # ${PTXDIST_HOSTTOOLS_DIR}/bin contains links to sane tools found by configure + export PATH="${PTXDIST_HOSTTOOLS_DIR}/bin:${PATH}" } @@ -2727,6 +2729,7 @@ setup_export() { \ PTXDIST \ PTXDIST_TOPDIR \ + PTXDIST_HOSTTOOLS_DIR \ PTXDIST_SRCDIR \ PTXDIST_TEMPDIR \ PTXDIST_LIB_DIR \ diff --git a/rules/host-qemu.make b/rules/host-qemu.make index eef2dc133..77cd8dcea 100644 --- a/rules/host-qemu.make +++ b/rules/host-qemu.make @@ -249,7 +249,7 @@ ifdef PTXCONF_HOST_QEMU_USR -e 's|RTLDLIST=.*|RTLDLIST="$(PTXDIST_SYSROOT_TOOLCHAIN)$(QEMU_CROSS_DL)"|' \ -e 's|eval $$add_env|eval $(PTXDIST_SYSROOT_CROSS)/usr/bin/qemu-cross -E "$${add_env// /,}"|' \ -e 's|verify_out=`|verify_out=`$(PTXDIST_SYSROOT_CROSS)/usr/bin/qemu-cross |' \ - -e 's|#! */.*$$|#!$(shell readlink $(PTXDIST_TOPDIR)/bin/bash)|' \ + -e 's|#! */.*$$|#!$(shell readlink $(PTXDIST_HOSTTOOLS_DIR)/bin/bash)|' \ $(PTXDIST_SYSROOT_TOOLCHAIN)/usr/bin/ldd > $(PTXDIST_SYSROOT_CROSS)/usr/bin/qemu/ldd @chmod +x $(PTXDIST_SYSROOT_CROSS)/usr/bin/qemu/ldd endif diff --git a/rules/other/Toplevel.make b/rules/other/Toplevel.make index 44a030825..5dec61bb3 100644 --- a/rules/other/Toplevel.make +++ b/rules/other/Toplevel.make @@ -8,7 +8,7 @@ ifneq ($(findstring n,$(filter-out --%,$(MAKEFLAGS))),) MAKE=true SHELL=true define ptx/force-shell -$(eval SHELL=$(realpath $(PTXDIST_TOPDIR)/bin/bash))$(shell $(1))$(eval SHELL=true) +$(eval SHELL=$(realpath $(PTXDIST_HOSTTOOLS_DIR)/bin/bash))$(shell $(1))$(eval SHELL=true) endef define ptx/force-sh $(eval SHELL=/bin/sh)$(shell $(1))$(eval SHELL=true) @@ -17,12 +17,12 @@ define ptx/sh endef else # make sure bash is used to execute commands from makefiles -SHELL=$(realpath $(PTXDIST_TOPDIR)/bin/bash) +SHELL=$(realpath $(PTXDIST_HOSTTOOLS_DIR)/bin/bash) define ptx/force-shell $(shell $(1)) endef define ptx/force-sh -$(eval SHELL=/bin/sh)$(shell $(1))$(eval SHELL=$(realpath $(PTXDIST_TOPDIR)/bin/bash)) +$(eval SHELL=/bin/sh)$(shell $(1))$(eval SHELL=$(realpath $(PTXDIST_HOSTTOOLS_DIR)/bin/bash)) endef define ptx/sh $(call ptx/force-sh,$(1)) diff --git a/scripts/lib/ptxd_lib_kconfig.sh b/scripts/lib/ptxd_lib_kconfig.sh index 0cec1edac..625a32c8a 100644 --- a/scripts/lib/ptxd_lib_kconfig.sh +++ b/scripts/lib/ptxd_lib_kconfig.sh @@ -781,9 +781,9 @@ ptxd_kconfig() { ;; esac - local conf="${PTXDIST_TOPDIR}/scripts/kconfig/conf" - local mconf="${PTXDIST_TOPDIR}/scripts/kconfig/mconf" - local nconf="${PTXDIST_TOPDIR}/scripts/kconfig/nconf" + local conf="${PTXDIST_HOSTTOOLS_DIR}/scripts/kconfig/conf" + local mconf="${PTXDIST_HOSTTOOLS_DIR}/scripts/kconfig/mconf" + local nconf="${PTXDIST_HOSTTOOLS_DIR}/scripts/kconfig/nconf" export \ KCONFIG_NOTIMESTAMP="1" \ diff --git a/scripts/lib/ptxd_make_nested.sh b/scripts/lib/ptxd_make_nested.sh index 54535377f..35087034c 100644 --- a/scripts/lib/ptxd_make_nested.sh +++ b/scripts/lib/ptxd_make_nested.sh @@ -47,7 +47,7 @@ ptxd_make_nested_ptxdist() { args=( "cd" "${pkg_workspace}" "&&" "${PTXDIST_TOPDIR}/bin/ptxdist" ) PTXDIST_TOOLCHAIN="$(readlink "${PTXDIST_PLATFORMDIR}/selected_toolchain")" - PATH=$(sed -e 's;[^:]*/sysroot-\(host\|cross\)/[^:]*:;;g' -e "s;${PTXDIST_TOPDIR}/bin:;;" -e "s;${PTXDIST_TOOLCHAIN}:;;" <<< "${PATH}") + PATH=$(sed -e 's;[^:]*/sysroot-\(host\|cross\)/[^:]*:;;g' -e "s;${PTXDIST_HOSTTOOLS_DIR}/bin:;;" -e "s;${PTXDIST_TOOLCHAIN}:;;" <<< "${PATH}") if [ "${PTXDIST_WORKSPACE}" != "${pkg_workspace}" ]; then unset PTXDIST_PLATFORMDIR diff --git a/scripts/lib/ptxd_make_report.sh b/scripts/lib/ptxd_make_report.sh index 7eea60900..7f8ad07ad 100644 --- a/scripts/lib/ptxd_make_report.sh +++ b/scripts/lib/ptxd_make_report.sh @@ -24,7 +24,7 @@ ptxd_make_bsp_report_header() { do_path() { local orig_IFS="${IFS}" # only the paths added by PTXdist - local path="${2%:${PTXDIST_TOPDIR}/bin:*}:${PTXDIST_TOPDIR}/bin" + local path="${2%:${PTXDIST_HOSTTOOLS_DIR}/bin:*}:${PTXDIST_HOSTTOOLS_DIR}/bin" echo "${indent}${1}" awk "BEGIN { RS=\":\" } { if (\$1) print \"${indent}- '\" \$1 \"'\" }" <<<"${path}" } -- 2.47.3 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [ptxdist] [PATCH 3/6] ptxdist: prepare host tools on demand 2026-10-13 11:16 [ptxdist] [PATCH 0/6] New BSP from template Ladislav Michl 2026-10-13 11:16 ` [ptxdist] [PATCH 1/6] scripts: add ptxdist_bootstrap.sh with out-of-tree build support Ladislav Michl 2026-10-13 11:17 ` [ptxdist] [PATCH 2/6] ptxdist: introduce PTXDIST_HOSTTOOLS_DIR Ladislav Michl @ 2026-10-13 11:17 ` Ladislav Michl 2026-10-13 11:18 ` [ptxdist] [PATCH 4/6] ptxdist: don't depend on bash being /bin/bash Ladislav Michl ` (2 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Ladislav Michl @ 2026-10-13 11:17 UTC (permalink / raw) To: ptxdist From: Ladislav Michl <ladis@triops.cz> Run ptxdist_bootstrap.sh on first use if PTXdist is neither installed nor configured in-tree. The PTXdist tree itself is never written to. Concurrent PTXdist runs are serialized using lock file, host tools are prepared again if they were built for another PTXdist tree or a linked host tool vanished. Signed-off-by: Ladislav Michl <ladis@triops.cz> --- README | 13 ++++++-- bin/ptxdist | 86 +++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 84 insertions(+), 15 deletions(-) diff --git a/README b/README index debf098d8..5774e046a 100644 --- a/README +++ b/README @@ -20,9 +20,16 @@ to install it. When you start using PTXdist, make sure your $PATH environment variable points to <installpath>/bin, because that's where the PTXdist frontend program is being installed to. -For developers who want to work with git versions of PTXdist it is only -necessary to run "./autogen.sh && ./configure && make" and set the PATH -variable to the bin/ directory inside the PTXdist tree. +Installing is optional. PTXdist can be used directly from an unpacked +tarball or a git checkout, without any configure or build step: + + cd <your BSP> + /path/to/ptxdist/bin/ptxdist menuconfig + +On first use, PTXdist checks the host for everything it needs, reports +all missing tools at once, and builds kconfig in .ptxdist/<version>/ +(.ptxdist/git/ for git checkouts) inside the BSP. The PTXdist tree +itself is never written to. Idea ---- diff --git a/bin/ptxdist b/bin/ptxdist index 94c41412f..7b20026bb 100755 --- a/bin/ptxdist +++ b/bin/ptxdist @@ -2131,19 +2131,8 @@ setup_topdir() { ptxdist="$(_realpath "${0}")" && topdir="$(cd "$(dirname "${ptxdist}")"/.. && pwd)" || return - # - # sanity check: is PTXdist already configured? - # - if [ ! -e "${topdir}/.done" ]; then - echo - echo "${PTXDIST_LOG_PROMPT}error: PTXdist in ${topdir} is not built." - echo - exit 1 - fi - PTXDIST="${ptxdist}" PTXDIST_TOPDIR="${topdir}" - PTXDIST_HOSTTOOLS_DIR="${topdir}" PTXDIST_WORKSPACE="$(pwd)" eval PTXDIST_PTXCONFIG_DEFAULT="${PTXDIST_PTXCONFIG_DEFAULT}" @@ -2151,11 +2140,84 @@ setup_topdir() { eval PTXDIST_COLLECTIONCONFIG_DEFAULT="${PTXDIST_COLLECTIONCONFIG_DEFAULT}" eval PTXDIST_TOOLCHAIN_DEFAULT="${PTXDIST_TOOLCHAIN_DEFAULT}" - # ${PTXDIST_HOSTTOOLS_DIR}/bin contains links to sane tools found by configure + setup_hosttools || return + + # ${PTXDIST_HOSTTOOLS_DIR}/bin contains links to sane tools found on the host export PATH="${PTXDIST_HOSTTOOLS_DIR}/bin:${PATH}" } +# +# check that the host tools in ${1} are complete and built for this +# PTXdist, that no linked host tool vanished meanwhile and that the +# sources did not change since, e.g. after 'git pull' +# +_check_hosttools() { + local link + + [ "$(cat "${1}/.done" 2>/dev/null)" = "${PTXDIST_TOPDIR}" ] || return + for link in "${1}/bin/"*; do + [ -e "${link}" ] || return + done + [ -z "$(find "${PTXDIST_TOPDIR}/scripts/kconfig" \ + "${PTXDIST_TOPDIR}/scripts/ptxdist_bootstrap.sh" \ + -newer "${1}/.done" -print -quit)" ] +} + +# +# prepare the host tools (kconfig and links to sane tools) out-of-tree +# unless PTXdist is installed or configured in-tree. +# +# in: PTXDIST_TOPDIR +# PTXDIST_WORKSPACE +# out: PTXDIST_HOSTTOOLS_DIR +# +setup_hosttools() { + local hosttools version lock + + if [ -e "${PTXDIST_TOPDIR}/.done" ]; then + # installed or configured in-tree + PTXDIST_HOSTTOOLS_DIR="${PTXDIST_TOPDIR}" + return + fi + + source "${PTXDIST_TOPDIR}/scripts/ptxdist_version.sh" || return + + # like ptxdistrc: one for all git versions, they change with each commit + version="${PTXDIST_VERSION_FULL}" + if [ -n "${PTXDIST_VERSION_SCM}" ]; then + version=git + fi + + if [ -e "${PTXDIST_WORKSPACE}/selected_ptxconfig" -o \ + -e "${PTXDIST_WORKSPACE}/configs/ptxconfig" ]; then + hosttools="${PTXDIST_WORKSPACE}/.ptxdist/${version}" + else + # not in a BSP, e.g. 'ptxdist setup' + hosttools="${XDG_CACHE_HOME:-${HOME}/.cache}/ptxdist/${version}" + fi + PTXDIST_HOSTTOOLS_DIR="${hosttools}" + + if _check_hosttools "${hosttools}"; then + return + fi + + mkdir -p "$(dirname "${hosttools}")" && + exec {lock}>"${hosttools}.lock" && + flock "${lock}" || return + + # a concurrent PTXdist may have finished first + if ! _check_hosttools "${hosttools}"; then + echo "${PTXDIST_LOG_PROMPT}preparing host tools in '${hosttools}' ..." >&2 + rm -rf "${hosttools}" && + mkdir "${hosttools}" || return + "${BASH}" "${PTXDIST_TOPDIR}/scripts/ptxdist_bootstrap.sh" "${hosttools}" || exit 1 + fi + + exec {lock}>&- +} + + ensure_ptxrc() { local ptxrc tmpptxrc local rc_default="${PTXDIST_TOPDIR}/config/setup/ptxdistrc.default" -- 2.47.3 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [ptxdist] [PATCH 4/6] ptxdist: don't depend on bash being /bin/bash 2026-10-13 11:16 [ptxdist] [PATCH 0/6] New BSP from template Ladislav Michl ` (2 preceding siblings ...) 2026-10-13 11:17 ` [ptxdist] [PATCH 3/6] ptxdist: prepare host tools on demand Ladislav Michl @ 2026-10-13 11:18 ` Ladislav Michl 2026-10-13 11:18 ` [ptxdist] [PATCH 5/6] configure: use ptxdist_bootstrap.sh to check the host Ladislav Michl 2026-10-13 11:18 ` [ptxdist] [PATCH 6/6] ptxdist: let new project raise from template Ladislav Michl 5 siblings, 0 replies; 7+ messages in thread From: Ladislav Michl @ 2026-10-13 11:18 UTC (permalink / raw) To: ptxdist From: Ladislav Michl <ladis@triops.cz> Provide a helpful message instead of 'bad interpreter' and check bash version. Signed-off-by: Ladislav Michl <ladis@triops.cz> --- bin/ptxdist | 24 +++++++++++++++++++++++- bin/ptxdist-auto-version | 4 ++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/bin/ptxdist b/bin/ptxdist index 7b20026bb..3c86aa225 100755 --- a/bin/ptxdist +++ b/bin/ptxdist @@ -1,4 +1,26 @@ -#!/bin/bash +#!/bin/sh + +# +# Everything up to the bash version check must be plain POSIX sh: PTXdist +# may be started by any shell and re-executes itself with bash. +# +if [ -z "${BASH_VERSION}" ]; then + bash="$(command -v bash)" || { + echo "ptxdist: error: bash >= 4.2 is required, please install it" >&2 + exit 1 + } + exec "${bash}" "${0}" "${@}" +fi + +case "${BASH_VERSION}" in +[0-3].*|4.[01].*) + echo "ptxdist: error: bash >= 4.2 is required, found ${BASH_VERSION} as '${BASH}'" >&2 + exit 1 + ;; +esac + +# e.g. when started as 'sh' with /bin/sh -> bash +set +o posix LANG=C LC_ALL=POSIX diff --git a/bin/ptxdist-auto-version b/bin/ptxdist-auto-version index 2f6414ae0..92c50fc3d 100755 --- a/bin/ptxdist-auto-version +++ b/bin/ptxdist-auto-version @@ -1,7 +1,7 @@ -#!/bin/bash +#!/bin/sh # -# bash implementation of realpath / readlink -f +# shell implementation of realpath / readlink -f # arg1 - filename realpath() { -- 2.47.3 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [ptxdist] [PATCH 5/6] configure: use ptxdist_bootstrap.sh to check the host 2026-10-13 11:16 [ptxdist] [PATCH 0/6] New BSP from template Ladislav Michl ` (3 preceding siblings ...) 2026-10-13 11:18 ` [ptxdist] [PATCH 4/6] ptxdist: don't depend on bash being /bin/bash Ladislav Michl @ 2026-10-13 11:18 ` Ladislav Michl 2026-10-13 11:18 ` [ptxdist] [PATCH 6/6] ptxdist: let new project raise from template Ladislav Michl 5 siblings, 0 replies; 7+ messages in thread From: Ladislav Michl @ 2026-10-13 11:18 UTC (permalink / raw) To: ptxdist From: Ladislav Michl <ladis@triops.cz> Drop checks for things nothing uses: C++ compiler, headers, types and functions (kconfig has no config.h), the #! test, the bison++ test, and AC_CANONICAL_*. Move the remaining runtime checks to the bootstrap, so both ways check the same things. While there try to unify things a bit; every host tool used ends linked, so that all host tools PTXdist depends on are in one place, show up in the BSP report and trigger a rebuild of the host tools when any of them vanishes. patch keeps its special handling: GNU patch >= 2.1 is preferred (gpatch, then patch). Anything else is used with a warning, as before; Sun's patch is known to be buggy and patch 2.0 cannot create directories. CC, CFLAGS, CPPFLAGS, LDFLAGS, LEX, YACC, PATCH and PKG_CONFIG can still be passed to configure and end up in the bootstrap when running make. Signed-off-by: Ladislav Michl <ladis@triops.cz> --- Makefile.in | 2 +- configure.ac | 312 ++++------------------------------- scripts/ptxdist_bootstrap.sh | 111 +++++++++++-- 3 files changed, 130 insertions(+), 295 deletions(-) diff --git a/Makefile.in b/Makefile.in index 5eb7b407b..f16a3744f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,7 +17,7 @@ export SHELL all: @echo "preparing PTXdist host tools ..." @CC="@CC@" CFLAGS="@CFLAGS@" CPPFLAGS="@CPPFLAGS@" LDFLAGS="@LDFLAGS@" \ - LEX="@LEX@" YACC="@YACC@" \ + LEX="@LEX@" YACC="@YACC@" PATCH="@PATCH@" PKG_CONFIG="@PKG_CONFIG@" \ "@BASH@" "$(abs_srcdir)/scripts/ptxdist_bootstrap.sh" "$(abs_builddir)" @echo "done." diff --git a/configure.ac b/configure.ac index 2590ebbed..17edbd769 100644 --- a/configure.ac +++ b/configure.ac @@ -8,8 +8,6 @@ AC_INIT([ptxdist], [m4_esyscmd([scripts/kernel/setlocalversion .tarball-version])], [ptxdist@pengutronix.de]) AC_CONFIG_AUX_DIR(scripts/autoconf) -AC_CANONICAL_BUILD -AC_CANONICAL_HOST dnl dnl Check if the user has extracted the patches archive @@ -24,62 +22,8 @@ else fi dnl -dnl Check for C and C++ compilers +dnl Check for Bourne-Again Shell, needed to run anything else dnl -AC_PROG_CC -AC_PROG_CXX - -dnl -dnl Check for pkg-config -dnl -PKG_PROG_PKG_CONFIG -AS_IF([test -z "$PKG_CONFIG"], AC_MSG_ERROR([pkg-config not found.])) - -AC_CHECK_HEADERS([fcntl.h inttypes.h libintl.h limits.h locale.h malloc.h stddef.h stdlib.h string.h sys/time.h unistd.h]) - -AC_CHECK_HEADER([regex.h], [], AC_MSG_ERROR([Cannot find regex.h.])) - -PKG_CHECK_MODULES([MCONF], [ncursesw],, [ - PKG_CHECK_MODULES([MCONF], [ncurses],, [ - AC_MSG_ERROR([Cannot find ncurses library.]) - ]) -]) -CFLAGS="${CFLAGS} ${MCONF_CFLAGS}" - -dnl -dnl Checks for typedefs, structures, and compiler characteristics. -dnl -AC_CHECK_HEADER_STDBOOL -AC_C_INLINE -AC_TYPE_INT16_T -AC_TYPE_INT32_T -AC_TYPE_INT8_T -AC_TYPE_OFF_T -AC_TYPE_SIZE_T -AC_TYPE_SSIZE_T -AC_TYPE_UINT16_T -AC_TYPE_UINT32_T -AC_TYPE_UINT8_T - -dnl -dnl Checks for library functions. -dnl -AC_FUNC_ALLOCA -AC_FUNC_MALLOC -AC_FUNC_REALLOC -AC_CHECK_FUNCS([bzero gettimeofday memmove memset mkdir regcomp setlocale strcasecmp strchr strcspn strdup strncasecmp strpbrk strrchr strspn strtol strtoull uname]) - - -AC_SYS_INTERPRETER -if test "$interpval" != yes ; then - AC_MSG_WARN([no - -bash scripts may not be invoked correctly due to problems with your -systems implementation of #! being either broken or non-existant. -]) -fi - -dnl Check for Bourne-Again Shell unset BASH # bash sets this itself! AC_ARG_WITH(bash, AS_HELP_STRING([--with-bash],[name of the bash executable to use]), [ @@ -93,230 +37,42 @@ if test -z "$BASH" ; then AC_MSG_ERROR([Please specify the location of bash with the option '--with-bash']) fi -# It would be nice not to have to use backticks, but too many retarded sh -# implementations still don't support $( ) -# BEWARE: There is a distinct possibility that we are currently running under -# bash in this configure script (/bin/sh being a symlink to /bin/bash). Even -# though the result /could/ be available to us directly as $BASH_VERSION we -# don't want to use, or trust it, incase the user is specifying a different -# bash executable. -if `$BASH -c '[[ "$BASH_VERSION" \< "4.2" ]]'` ; then - AC_MSG_ERROR([ -$PACKAGE_NAME requires at least version 4.2 of bash, you can download a current -version of bash from ftp.gnu.org -]) -fi - - -dnl Check for sed >= 4.0 -AC_PATH_PROGS(SED, gsed sed,, $PATH) -if test -z "$SED"; then - AC_MSG_ERROR([sed could not be found, please install]) -fi - -AC_MSG_CHECKING([sed version]) -SED_VERSION=`$SED --version 2>/dev/null | $SED -ne "1 s/.*GNU.*\s\([[0-9\+\.]]\+\).*/\1/p"` -case "$SED_VERSION" in -3.*) AC_MSG_ERROR([we need at least GNU sed 4.x but found $SED_VERSION]) ;; -4.*) ;; -*) AC_MSG_ERROR([we need at least GNU sed 4.x]) ;; -esac -AC_MSG_RESULT([$SED_VERSION]) - -dnl check for gnu tools -dnl $1: tool to search for -dnl $2: package where the tool is (e.g. 'coreutils') -AC_DEFUN([GNU_TOOL], - [AC_CACHE_CHECK([for GNU $1], [ac_cv_path_gnu_$1], - [AC_PATH_PROGS_FEATURE_CHECK([gnu_$1], [g$1 $1.gnu $1-gnu $1], - [[out=`$ac_path_gnu_$1 --version 2>/dev/null | $SED -ne "s/.*\(GNU\) $2.*/\1/p"` - test "x$out" = xGNU && ac_cv_path_gnu_$1=$ac_path_gnu_$1 ac_path_gnu_$1_found=:]], - [AC_MSG_ERROR([could not find GNU $1])])]) - AC_SUBST([GNU_$1], [$ac_cv_path_gnu_$1])]) - -GNU_TOOL(cat, coreutils) -GNU_TOOL(chmod, coreutils) -GNU_TOOL(chown, coreutils) -GNU_TOOL(cp, coreutils) -GNU_TOOL(dirname, coreutils) -GNU_TOOL(install, coreutils) -GNU_TOOL(ln, coreutils) -GNU_TOOL(md5sum, coreutils) -GNU_TOOL(mkdir, coreutils) -GNU_TOOL(mknod, coreutils) -GNU_TOOL(mktemp, coreutils) -GNU_TOOL(mv, coreutils) -GNU_TOOL(readlink, coreutils) -GNU_TOOL(realpath, coreutils) -GNU_TOOL(rm, coreutils) -GNU_TOOL(rmdir, coreutils) -GNU_TOOL(sha256sum, coreutils) -GNU_TOOL(sort, coreutils) -GNU_TOOL(stat, coreutils) -GNU_TOOL(touch, coreutils) -GNU_TOOL(tty, coreutils) -GNU_TOOL(tar, tar) -GNU_TOOL(find, findutils) -GNU_TOOL(xargs, findutils) - -dnl Check for awk -AC_PROG_AWK -AC_PATH_PROGS(AWK, ${AWK},) -AC_MSG_CHECKING([awk version]) -AWK_VERSION=`$AWK --version 2>/dev/null | $SED -ne "s/GNU [[Aa]]wk \([[0-9\.]]*\)/\1/p"` -case "$AWK_VERSION" in -"") AC_MSG_ERROR([we need GNU awk]) ;; -*) ;; -esac -AC_MSG_RESULT([$AWK_VERSION]) - -# fall back to 'false' for systems which do not provide a 'sysctl' tool -AC_PATH_PROGS(SYSCTL, sysctl false,, $PATH) - -dnl Check for lex -AC_PROG_LEX(noyywrap) -AC_PATH_PROGS(LEX, ${LEX},, $PATH) -if test -z "${LEX}"; then - AC_MSG_ERROR([(f)lex could not be found, please install]) -fi - -dnl Check for yacc -AC_PROG_YACC -AC_PATH_PROGS(YACC, ${YACC},, $PATH) -if test -z "${YACC}"; then - AC_MSG_ERROR([yacc/bison could not be found, please install]) -fi - - -AC_MSG_CHECKING([whether yacc is bison++]) -if $YACC --version 2>/dev/null | grep bison++ -q; then - AC_MSG_ERROR([your $YACC turns out to be bison++, please install plain bison]) -else - AC_MSG_RESULT([no, this is good]) -fi - -AC_MSG_CHECKING([yacc/bison version]) -YACC_VERSION=`$YACC --version 2>/dev/null | $SED -ne "s/.*GNU Bison.* \([[0-9.]]*\).*/\1/p"` -case "${YACC_VERSION}" in - 1.*) - AC_MSG_ERROR([$YACC_VERSION, your bison version is too old, install 2.3 or sth. like that]) ;; - "") - AC_MSG_WARN([no GNU bison found, continuing anyway....]) ;; - *) - AC_MSG_RESULT([$YACC_VERSION]) ;; -esac - -dnl Check for bunzip2 -AC_PATH_PROGS(BUNZIP2, bunzip2,, $PATH) -if test -z "$BUNZIP2"; then - AC_MSG_ERROR([bunzip2 could not be found, please install]) -fi - -dnl Check for gunzip -AC_PATH_PROGS(GUNZIP, gunzip,, $PATH) -if test -z "$GUNZIP"; then - AC_MSG_ERROR([gunzip could not be found, please install]) -fi - -dnl Check for unzip -AC_PATH_PROGS(UNZIP, unzip,, $PATH) -if test -z "$UNZIP"; then - AC_MSG_ERROR([unzip could not be found, please install]) -fi - -dnl Check for xz -AC_PATH_PROGS(XZ, xz,, $PATH) -if test -z "$XZ"; then - AC_MSG_ERROR([xz could not be found, please install]) -fi - -dnl Check for wget -AC_PATH_PROGS(WGET, wget,, $PATH) -if test -z "$WGET"; then - AC_MSG_ERROR([wget could not be found, please install]) -fi - -AC_MSG_CHECKING([find version]) -FIND_VERSION=`$GNU_find --version 2>/dev/null | $SED -ne "s/.*\s\+\([[0-9]]\+\.[[0-9]]\+\.[[0-9]]\+\).*$/\1/p"` -case "$FIND_VERSION" in -4.*) ;; -*) AC_MSG_ERROR([we need at least GNU find 4.x]) ;; -esac -AC_MSG_RESULT([$FIND_VERSION]) - -dnl Check for make -AC_PATH_PROGS(MAKE, gmake gnumake make,, $PATH) -if test -z "$MAKE"; then - AC_MSG_ERROR([make could not be found, please install]) -fi -MAKE_VERSION=`$MAKE --version 2>/dev/null | $SED -ne "s/^GNU Make \([[0-9]]\+\.[[0-9.]]\+\).*$/\1/p"` -MAJOR_MAKE_VERSION="${MAKE_VERSION%%.*}" -MINOR_MAKE_VERSION="${MAKE_VERSION#*.}" -MINOR_MAKE_VERSION="${MINOR_MAKE_VERSION%%.*}" -if test -z "${MAJOR_MAKE_VERSION}" -o -z "${MINOR_MAKE_VERSION}" ; then - AC_MSG_ERROR([could not parse make version. GNU make >= 3.81 required]) -fi -if test $MAJOR_MAKE_VERSION -eq 3 -a $MINOR_MAKE_VERSION -lt 81 -o $MAJOR_MAKE_VERSION -lt 3 ; then - AC_MSG_ERROR([GNU make >= 3.81 required ($MAKE_VERSION found)]) -fi - -dnl Check for file -AC_PATH_PROGS(FILE, file,, $PATH) -if test -z "$FILE"; then - AC_MSG_ERROR([file could not be found, please install]) -fi -AC_SUBST([PTXDIST_FILE], [$FILE]) - -AC_PATH_PROG(SPHINX, sphinx-build,, $PATH) -if test -z "$SPHINX"; then - AC_MSG_NOTICE([sphinx not found, required to build the documentation]) - SPHINX=sphinx-build +dnl +dnl Everything else is checked by the bootstrap script, which reports all +dnl missing tools at once. It is run again by 'make' to set things up. +dnl +AC_ARG_VAR([CC], [C compiler command for kconfig]) +AC_ARG_VAR([CFLAGS], [C compiler flags for kconfig]) +AC_ARG_VAR([CPPFLAGS], [C preprocessor flags for kconfig]) +AC_ARG_VAR([LDFLAGS], [linker flags for kconfig]) +AC_ARG_VAR([LEX], [lexer generator, default: flex]) +AC_ARG_VAR([YACC], [parser generator, default: bison]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config]) +AC_ARG_VAR([PATCH], [patch executable to use, default: GNU patch from PATH]) +AC_ARG_WITH(patch, AS_HELP_STRING([--with-patch],[name of the patch executable to use, same as PATCH=]), + [PATCH="$withval"]) + +AC_MSG_CHECKING([host tools]) +if CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS" \ + LEX="$LEX" YACC="$YACC" PATCH="$PATCH" PKG_CONFIG="$PKG_CONFIG" \ + "$BASH" "$srcdir/scripts/ptxdist_bootstrap.sh" --check >&AS_MESSAGE_LOG_FD 2>config.bootstrap +then + AC_MSG_RESULT([ok]) + # warnings + cat config.bootstrap >&2 + cat config.bootstrap >&AS_MESSAGE_LOG_FD + rm -f config.bootstrap else - AC_MSG_NOTICE([sphinx found, run 'ptxdist docs-html' to get documentation]) + AC_MSG_RESULT([failed]) + cat config.bootstrap >&2 + cat config.bootstrap >&AS_MESSAGE_LOG_FD + rm -f config.bootstrap + AC_MSG_ERROR([host check failed]) fi -AC_SUBST(SPHINX) AC_PATH_PROGS(RST2MAN, rst2man,, $PATH) AC_SUBST(RST2MAN) -dnl Check for patch -AC_ARG_WITH(patch, AS_HELP_STRING([--with-patch],[name of the patch executable to use]), - [ - PATCH="$withval" - AC_SUBST(PATCH) - AC_MSG_NOTICE([Using patch executable $PATCH]) - ],[ - AC_PATH_PROG(PATCH, patch) - ]) -if test -z "$PATCH"; then - AC_MSG_ERROR([Please specify the location of the patch executable with the option '--with-patch']) -fi - -# Sun's patch is a mess, issue a warning. But we are going to continue with -# the build because you might just be lucky. -AC_MSG_CHECKING([whether $PATCH will work]) -if $PATCH -v 2>&1 | grep -q "Sun" >/dev/null 2>&1; then - AC_MSG_RESULT(no) - AC_MSG_WARN([ -Sorry, you have a Sun version of patch which is notoriously buggy. $PACKAGE_NAME -may function correctly, or minor errors may occur due to Sun's patch tool. -Please consider upgrading to GNU patch, if you already have GNU patch then you -can supply its path with the '--with-patch=' option. -]) -elif $PATCH --version 2>&1 | grep -q "patch 2.0" >/dev/null 2>&1; then - AC_MSG_RESULT(no) - AC_MSG_WARN([ -Sorry, the version of patch you are using can cause severe problems when a patch -creates a directory. $PACKAGE_NAME may well function correctly with this version -of patch or small problems could creep in. -Please consider upgrading your patch to a more recent version, if you already -have a more recent version of patch then you can supply its path with the -'--with-patch=' option. -]) -else - AC_MSG_RESULT(yes) -fi - dnl check if bash completion is desired (adapted from 'source-highlight' by Lorenzo Bettini) dnl don't use sysconfdir! as bash_completion does not check multiple directories, we use the system default @@ -347,12 +103,6 @@ dnl Print results AC_MSG_RESULT([$PACKAGE_NAME version $PACKAGE_VERSION configured.]) AC_MSG_RESULT([Using '$prefix' for installation prefix.]) -# we don't need to see this just for the backup-files command -# but we may as well spec it for the future -#AC_MSG_RESULT([Using '$CC' for C compiler.]) -#AC_MSG_RESULT([Building with '$CFLAGS' for C compiler flags.]) -#AC_MSG_RESULT([Building with '$LIBS' for linker flags.]) - AC_MSG_RESULT([]) AC_MSG_RESULT([Report bugs to $PACKAGE_BUGREPORT]) AC_MSG_RESULT([]) diff --git a/scripts/ptxdist_bootstrap.sh b/scripts/ptxdist_bootstrap.sh index b9f4c7a5c..081bace1a 100755 --- a/scripts/ptxdist_bootstrap.sh +++ b/scripts/ptxdist_bootstrap.sh @@ -9,9 +9,12 @@ # left to the package build. # # usage: ptxdist_bootstrap.sh <builddir> +# ptxdist_bootstrap.sh --check # -# CC, CFLAGS, CPPFLAGS, LDFLAGS, LEX, YACC and PKG_CONFIG from the -# environment are used if set. +# With --check, only the prerequisites are checked and nothing is built. +# +# CC, CFLAGS, CPPFLAGS, LDFLAGS, LEX, YACC, PATCH and PKG_CONFIG from +# the environment are used if set and not empty. # PTXDIST_LOG_PROMPT="ptxdist: " @@ -39,14 +42,26 @@ esac set +o posix topdir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" || exit -builddir="${1}" -if [ -z "${builddir}" ]; then - echo "usage: ${0} <builddir>" >&2 +case "${1}" in +"") + echo "usage: ${0} <builddir>|--check" >&2 exit 1 -fi + ;; +--check) + check_only=true + ;; +*) + builddir="${1}" + ;; +esac + +# empty means unset, e.g. when passed from configure +for var in CC CFLAGS CPPFLAGS LDFLAGS LEX YACC PATCH PKG_CONFIG; do + [ -n "${!var}" ] || unset "${var}" +done declare -A links -declare -a missing +declare -a missing warnings # # $1: version found, $2: version required @@ -95,7 +110,7 @@ find_gnu() { } for tool in cat chmod chown cp dirname install ln md5sum mkdir mknod \ - mktemp mv readlink realpath rm rmdir sort stat tty; do + mktemp mv readlink realpath rm rmdir sha256sum sort stat touch tty; do find_gnu "${tool}" "GNU coreutils" "" coreutils "g${tool}" "${tool}" done find_gnu tar "GNU tar" "" tar gtar tar @@ -107,11 +122,69 @@ find_gnu make "GNU Make" 3.81 make gmake gnumake make links[bash]="${BASH}" -if path="$(type -P file)"; then - links[file]="${path}" -else - missing+=( "'file' (package: file)" ) -fi +# +# find a tool, any implementation will do, and register a link for it +# +# $1: tool, $2: package that provides it +# +find_tool() { + local path + + if path="$(type -P "${1}")"; then + links[${1}]="${path}" + else + missing+=( "'${1}' (package: ${2})" ) + fi +} + +find_tool file file +find_tool bzip2 bzip2 +find_tool gzip gzip +find_tool xz xz +find_tool unzip unzip +find_tool wget wget + +# +# patch: any implementation works in principle, but some are known to +# be broken, e.g. Sun's patch or patch 2.0, which cannot create +# directories. Prefer GNU patch and warn about anything else. +# +find_patch() { + local -a names=( gpatch patch ) + local name path version + + if [ -n "${PATCH}" ]; then + names=( "${PATCH}" ) + fi + + for name in "${names[@]}"; do + path="$(type -P "${name}")" || continue + version="$("${path}" --version 2>/dev/null | head -n 1)" + if [[ "${version}" =~ ^(GNU )?patch\ ([0-9]+(\.[0-9]+)+) ]] && + version_ge "${BASH_REMATCH[2]}" 2.1; then + links[patch]="${path}" + return + fi + done + + # no GNU patch, take what is there + for name in "${names[@]}"; do + path="$(type -P "${name}")" && break + done + if [ -z "${path}" ]; then + missing+=( "'${names[-1]}' (package: patch)" ) + return + fi + links[patch]="${path}" + if "${path}" -v 2>&1 | grep -q Sun; then + warnings+=( "'${path}' is Sun's patch, which is notoriously buggy." ) + else + warnings+=( "'${path}' is not GNU patch >= 2.1, it may not work correctly." ) + fi + warnings+=( "Please consider installing GNU patch (package: patch) or set PATCH." ) +} + +find_patch # optional links[sysctl]="$(type -P sysctl || type -P false)" @@ -188,6 +261,14 @@ if type -P "${CC%% *}" > /dev/null; then fi fi +if [ ${#warnings[@]} -gt 0 ]; then + { + echo + printf "${PTXDIST_LOG_PROMPT}warning: %s\n" "${warnings[@]}" + echo + } >&2 +fi + if [ ${#missing[@]} -gt 0 ]; then { echo @@ -199,6 +280,10 @@ if [ ${#missing[@]} -gt 0 ]; then exit 1 fi +if [ -n "${check_only}" ]; then + exit 0 +fi + # # all prerequisites are there, set up the build directory # -- 2.47.3 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [ptxdist] [PATCH 6/6] ptxdist: let new project raise from template 2026-10-13 11:16 [ptxdist] [PATCH 0/6] New BSP from template Ladislav Michl ` (4 preceding siblings ...) 2026-10-13 11:18 ` [ptxdist] [PATCH 5/6] configure: use ptxdist_bootstrap.sh to check the host Ladislav Michl @ 2026-10-13 11:18 ` Ladislav Michl 5 siblings, 0 replies; 7+ messages in thread From: Ladislav Michl @ 2026-10-13 11:18 UTC (permalink / raw) To: ptxdist From: Ladislav Michl <ladis@triops.cz> Let PTXdist offer to create the project from template when BSP directory it is running from appears unconfigured. Nothing is written before all questions are answered, so declining or Ctrl-C leaves the directory untouched. Without a terminal or for configs given with --ptxconfig/--platformconfig, the error is shown as before. The toolchain check is disabled in the new platformconfig, as there is no toolchain yet. The host tools prepared in ~/.cache before the project existed are copied into it, so they are not built twice. Signed-off-by: Ladislav Michl <ladis@triops.cz> --- README | 3 + bin/ptxdist | 146 ++++++++++++++++++++++++- doc/ref_parameter.rst | 4 + rules/templates/project/gitignore | 9 ++ rules/templates/project/platformconfig | 10 ++ rules/templates/project/ptxconfig | 6 + 6 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 rules/templates/project/gitignore create mode 100644 rules/templates/project/platformconfig create mode 100644 rules/templates/project/ptxconfig diff --git a/README b/README index 5774e046a..5ac1c6468 100644 --- a/README +++ b/README @@ -31,6 +31,9 @@ all missing tools at once, and builds kconfig in .ptxdist/<version>/ (.ptxdist/git/ for git checkouts) inside the BSP. The PTXdist tree itself is never written to. +In case the BSP directory appears uninitialized, PTXdist offers to +create the project from template. + Idea ---- diff --git a/bin/ptxdist b/bin/ptxdist index 3c86aa225..65bc70ce8 100755 --- a/bin/ptxdist +++ b/bin/ptxdist @@ -264,11 +264,18 @@ check_version() { +_init_hint() { + if [ -z "${ptxd_init_asked}" -a ! -t 0 ]; then + echo " or run ptxdist in a terminal to create a new ${1}" + fi +} + _get_config_ptx() { - if [ ! -e "${PTXDIST_PTXCONFIG}" ]; then + if [ ! -e "${PTXDIST_PTXCONFIG}" ] && ! do_init ptx; then ptxd_dialog_msgbox \ "error: '${PTXDIST_PTXCONFIG#${PTXDIST_WORKSPACE}/}' file is missing\n" \ - " try 'ptxdist select <ptxconfig>'\n" + " try 'ptxdist select <ptxconfig>'\n" \ + "$(_init_hint project)\n" return 1 fi @@ -321,10 +328,11 @@ _check_config_platform() { # ptxd_get_ptxconf PTXCONF_NO_PLATFORM >/dev/null && return || true - if [ ! -e "${PTXDIST_PLATFORMCONFIG}" ]; then + if [ ! -e "${PTXDIST_PLATFORMCONFIG}" ] && ! do_init platform; then ptxd_dialog_msgbox \ "error: '${PTXDIST_PLATFORMCONFIG#${PTXDIST_WORKSPACE}/}' is missing\n" \ - " try 'ptxdist platform <platformconfig>'" + " try 'ptxdist platform <platformconfig>'\n" \ + "$(_init_hint platform)" return 1 fi @@ -1507,6 +1515,136 @@ do_select() } +# +# create what is missing for a new project on demand: +# the ptxconfig and, if not selected either, the platformconfig, +# or just the platformconfig; returns 1 if nothing was created. +# +# $1: what is missing: 'ptx' or 'platform' +# +do_init() +{ + local part="${1}" + local project platform arch answer + local -a archs + local templates="${PTXDIST_TOPDIR}/rules/templates/project" + local ptxconfig="configs/ptxconfig" + local platformconfig + + # only interactive and only for the default locations + if [ ! -t 0 -o ! -t 1 -o -n "${PTX_MENU}" ]; then + return 1 + fi + if [ "${part}" = ptx -a "${PTX_ptxconfig_SET}" = true ]; then + return 1 + fi + if [ "${PTX_platformconfig_SET}" = true ]; then + [ "${part}" = platform ] && return 1 + elif [ ! -e "${PTXDIST_PLATFORMCONFIG}" ]; then + platformconfig=new + fi + + if [ "${part}" = ptx -a -e "${ptxconfig}" ]; then + return 1 + fi + + ptxd_init_asked=true + echo + if [ "${part}" = ptx ]; then + echo "${PTXDIST_LOG_PROMPT}there is no PTXdist project in '${PTXDIST_WORKSPACE}'" + read -e -p "${PTXDIST_LOG_PROMPT}create a new one? [y/N] " answer || return 1 + else + echo "${PTXDIST_LOG_PROMPT}no platform is selected" + read -e -p "${PTXDIST_LOG_PROMPT}create a new one? [y/N] " answer || return 1 + fi + case "${answer}" in + y|Y|yes) ;; + *) return 1 ;; + esac + echo + + if [ "${part}" = ptx ]; then + project="$(basename "${PTXDIST_WORKSPACE}")" + ptxd_template_read "project name" project "${project}" || return 1 + if [ -z "${project}" ]; then + ptxd_bailout "the project name must not be empty" + fi + fi + if [ -n "${platformconfig}" ]; then + # the architectures from the main choice in architecture.in + archs=( $(awk '/^choice/ { c++ } c == 1 && /^\tconfig ARCH_/ { print $2 } /^endchoice/ && c == 1 { exit }' \ + "${PTXDIST_TOPDIR}/platforms/architecture.in") ) && + ptxd_template_read_options "architecture" arch "${archs[@]#ARCH_}" || return 1 + platform="${arch,,}" + while :; do + ptxd_template_read "platform name" platform "${platform}" || return 1 + platformconfig="configs/platform-${platform}/platformconfig" + if [ -z "${platform}" ]; then + echo "${PTXDIST_LOG_PROMPT}the platform name must not be empty" + elif [ -e "${platformconfig}" ]; then + echo "${PTXDIST_LOG_PROMPT}'${platformconfig}' already exists" + else + break + fi + done + fi + + # create everything after all questions answered + echo + if [ -n "${project}" ]; then + echo "${PTXDIST_LOG_PROMPT}creating project '${project}'" + mkdir -p configs rules projectroot && + if [ ! -e .gitignore ]; then + ptxd_replace_magic "${templates}/gitignore" > .gitignore + fi && + PROJECT="${project}" \ + ptxd_replace_magic "${templates}/ptxconfig" > "${ptxconfig}" && + ln -sf "${ptxconfig}" "${PTXDIST_PTXCONFIG_DEFAULT}" || return + PTXDIST_PTXCONFIG="${PTXDIST_PTXCONFIG_DEFAULT}" + fi + if [ -n "${platform}" ]; then + echo "${PTXDIST_LOG_PROMPT}creating platform '${platform}' (${arch,,})" + mkdir -p "$(dirname "${platformconfig}")" && + PLATFORM="${platform}" ARCH="ARCH_${arch}" \ + ptxd_replace_magic "${templates}/platformconfig" > "${platformconfig}" && + ln -sf "${platformconfig}" "${PTXDIST_PLATFORMCONFIG_DEFAULT}" || return + PTXDIST_PLATFORMCONFIG="${PTXDIST_PLATFORMCONFIG_DEFAULT}" + fi + + # this is a project now, keep the host tools with it + case "${PTXDIST_HOSTTOOLS_DIR}" in + "${PTXDIST_TOPDIR}"|"${PTXDIST_WORKSPACE}/.ptxdist/"*) + ;; + *) + if [ ! -e ".ptxdist/${PTXDIST_HOSTTOOLS_DIR##*/}" ]; then + mkdir -p .ptxdist && + cp -a "${PTXDIST_HOSTTOOLS_DIR}" ".ptxdist/" || return + fi + ;; + esac + + unset PTXDIST_PLATFORMDIR + setup_platform && + setup_path && + setup_export || return + + # fill in the defaults for everything else + if [ -n "${project}" ]; then + KCONFIG_ALLCONFIG="${PTXDIST_WORKSPACE}/${ptxconfig}" \ + do_config alldefconfig ptx > /dev/null || return + fi + if [ -n "${platform}" ]; then + KCONFIG_ALLCONFIG="${PTXDIST_WORKSPACE}/${platformconfig}" \ + do_config alldefconfig platform > /dev/null || return + fi + + echo + echo "${PTXDIST_LOG_PROMPT}done. There is no toolchain yet, select one with" + echo "${PTXDIST_LOG_PROMPT}'ptxdist toolchain <path>'. 'ptxdist platformconfig' refines" + echo "${PTXDIST_LOG_PROMPT}the platform, 'ptxdist newpackage <type>' adds own packages." + echo +} + # # guess and find the toolchain diff --git a/doc/ref_parameter.rst b/doc/ref_parameter.rst index e167f28fe..52d470304 100644 --- a/doc/ref_parameter.rst +++ b/doc/ref_parameter.rst @@ -28,6 +28,8 @@ Setup and Project Actions the same project. The default location for the configuration file is ``configs/ptxconfig``. PTXdist will use this if no other configuration is selected. + If there is no configuration at all and PTXdist runs in a terminal, it + offers to create a new project instead, see ``rules/templates/project/``. ``platform <config>`` this action will select a platform @@ -38,6 +40,8 @@ Setup and Project Actions The default location for the configuration file is ``configs/*/platformconfig``. PTXdist will use that if the pattern matches exactly one file and no other configuration is selected. + If no platform is selected and PTXdist runs in a terminal, it offers to + create a new one instead. ``toolchain [<path>]`` this action will select the toolchain to use. If no path is specified diff --git a/rules/templates/project/gitignore b/rules/templates/project/gitignore new file mode 100644 index 000000000..20ede9441 --- /dev/null +++ b/rules/templates/project/gitignore @@ -0,0 +1,9 @@ +/.ptxdist/ +/configs/*.old +/configs/platform-*/*.old +/platform-* +/selected_collectionconfig +/selected_platformconfig +/selected_ptxconfig +/selected_toolchain* +/src diff --git a/rules/templates/project/platformconfig b/rules/templates/project/platformconfig new file mode 100644 index 000000000..165143199 --- /dev/null +++ b/rules/templates/project/platformconfig @@ -0,0 +1,10 @@ +# +# template for a new project, everything not set here gets its default +# +PTXCONF__platformconfig_MAGIC__=y +PTXCONF_PLATFORMCONFIG_VERSION="@PTXDIST_VERSION_FULL@" +PTXCONF_PLATFORM="@PLATFORM@" +PTXCONF_@ARCH@=y +# no toolchain yet, select one with 'ptxdist toolchain <path>' +PTXCONF_CROSSCHAIN_VENDOR="" +PTXCONF_CROSSCHAIN_CHECK="" diff --git a/rules/templates/project/ptxconfig b/rules/templates/project/ptxconfig new file mode 100644 index 000000000..2b4b71024 --- /dev/null +++ b/rules/templates/project/ptxconfig @@ -0,0 +1,6 @@ +# +# template for a new project, everything not set here gets its default +# +PTXCONF__ptxconfig_MAGIC__=y +PTXCONF_CONFIGFILE_VERSION="@PTXDIST_VERSION_FULL@" +PTXCONF_PROJECT="@PROJECT@" -- 2.47.3 ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-13 11:19 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-10-13 11:16 [ptxdist] [PATCH 0/6] New BSP from template Ladislav Michl 2026-10-13 11:16 ` [ptxdist] [PATCH 1/6] scripts: add ptxdist_bootstrap.sh with out-of-tree build support Ladislav Michl 2026-10-13 11:17 ` [ptxdist] [PATCH 2/6] ptxdist: introduce PTXDIST_HOSTTOOLS_DIR Ladislav Michl 2026-10-13 11:17 ` [ptxdist] [PATCH 3/6] ptxdist: prepare host tools on demand Ladislav Michl 2026-10-13 11:18 ` [ptxdist] [PATCH 4/6] ptxdist: don't depend on bash being /bin/bash Ladislav Michl 2026-10-13 11:18 ` [ptxdist] [PATCH 5/6] configure: use ptxdist_bootstrap.sh to check the host Ladislav Michl 2026-10-13 11:18 ` [ptxdist] [PATCH 6/6] ptxdist: let new project raise from template Ladislav Michl
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox