From mboxrd@z Thu Jan 1 00:00:00 1970 Delivery-date: Tue, 13 Oct 2026 13:17:00 +0200 Received: from metis.whiteo.stw.pengutronix.de ([2a0a:edc0:2:b01:1d::104]) by lore.white.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1xGaVA-00D8qF-1H for lore@lore.pengutronix.de; Tue, 13 Oct 2026 13:17:00 +0200 Received: from [127.0.0.1] (helo=metis.whiteo.stw.pengutronix.de) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1xGaV9-0007OI-8z; Tue, 13 Oct 2026 13:16:59 +0200 Received: from mx1.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::107]) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1xGaV4-0007O9-Rd for ptxdist@pengutronix.de; Tue, 13 Oct 2026 13:16:54 +0200 Received: from h3.cmg1.smtp.forpsi.com (h3.cmg1.smtp.forpsi.com [185.129.138.162]) by mx1.white.stw.pengutronix.de (Postfix) with ESMTPS id 14086200758 for ; Tue, 13 Oct 2026 13:16:54 +0200 (CEST) ARC-Seal: i=1; s=20260414; d=pengutronix.de; t=1791890214; a=rsa-sha256; cv=none; b=Cq4ZrWjqbaaGZnCYwJCGLUfWHotxG/N4Rij/Qn3FtOtMmX0NXFziez3OCcuE56Wygmbuvk bWxhfQrswngMO25s9TJQdlLwKcALVt5AETePTAFv18LWBDUkjaYBPZB0ZZW8pNZ8R6yoOq StLL9CnMLkBcB7hzCMqjP6Y5PLnAiSLdEvRMbSL2Tnd4nMu7ns9Cma1nCB9IXlG5Ark/BP aU9riYtmQ7KDT/vQ3YX0n01UAJFvEcTiBTU6RrZPXK8K2ZczyLdMeARKOh6pOZzKnW9vel 6XizJX5lkNJLPGyQ9d+F/qyJfKhMyeqOg7qdQ8pE0pfV3Qc67CbYsCTXhnzYfw== ARC-Authentication-Results: i=1; mx1.white.stw.pengutronix.de; dkim=pass header.d=triops.cz header.s=f2019 header.b=Aziruol8; spf=none (mx1.white.stw.pengutronix.de: domain of oss-lists@triops.cz has no SPF policy when checking 185.129.138.162) smtp.mailfrom=oss-lists@triops.cz; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=pengutronix.de; s=20260414; t=1791890214; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references:dkim-signature; bh=ZlF/4obYu0K9DziyLuhj1lXRZ5LogDf7KMDNqEs12/A=; b=R7StBW0p1MPsCsZIIBWYVsRUdgkpw2nU4GO7ep0MfJWnZkoBNV6omlO/zqOB5m/Hd3+4n3 Gr8YyemL+ZFSTzKWzZxCi/fxAmCV1Bo9vAhf5SyiltZ3Iu3PS8ysC3tuzvDNcKZpkW860b 1sQ6ZKwTfBedz5ZfBK5MP7BbFxBo/Bp4chiNg/sVm72ZVKyVU2GT3nAO5XpDWD7inasRNY RWahbhrWum+dZ4npZbtfezOu/p3xe+jG1KkU4Q5H3tU/67DNSMWYzXFzhmo+jZaneFZVvn 8Evj/9rdgSDHxvUfhNHDYcFPk/F7FVJvclD2SP5KHQsSqD/83WtFXY0Qy8gIuA== Received: from lenoch ([91.218.190.200]) by cmgsmtp with ESMTPSA id GaV2xAq7gDJUVGaV3x0cRK; Tue, 13 Oct 2026 13:16:54 +0200 Date: Tue, 13 Oct 2026 13:16:52 +0200 From: Ladislav Michl To: ptxdist@pengutronix.de Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-CMAE-Envelope: MS4xfIucnDtWp51GPMFnBJbOaMhznDAd2j7dn8eEwENtQq6VXLXlpQDwAEYSqUWBrKl1/xRLCOXY9WkCZqHkkeYDYtEWTR/9XHc6NkuA9NseLz24G5DBAXSe ZCfFIscCdgKtMb79qR5eX93Ct3jQHB+qlDq8U2eP3K3KZZd2nHgZDApWxxZjHT5VYE2uu4czVQnFDQ== X-Spamd-Result: default: False [-2.60 / 15.00]; BAYES_HAM(-3.00)[100.00%]; MID_RHS_NOT_FQDN(0.50)[]; R_DKIM_ALLOW(-0.20)[triops.cz:s=f2019]; ONCE_RECEIVED(0.20)[]; MIME_GOOD(-0.10)[text/plain]; TO_MATCH_ENVRCPT_ALL(0.00)[]; R_SPF_NA(0.00)[no SPF record]; DMARC_NA(0.00)[triops.cz]; RCVD_TLS_ALL(0.00)[]; ARC_NA(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; DKIM_TRACE(0.00)[triops.cz:+]; MISSING_XM_UA(0.00)[]; RCVD_COUNT_ONE(0.00)[1]; FROM_EQ_ENVFROM(0.00)[]; FROM_HAS_DN(0.00)[]; MIME_TRACE(0.00)[0:+]; TO_DN_NONE(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; NEURAL_HAM(-0.00)[-1.000]; ASN(0.00)[asn:24806, ipnet:185.129.136.0/22, country:CZ]; ARC_SIGNED(0.00)[pengutronix.de:s=20260414:i=1] X-Rspamd-Action: no action X-Rspamd-Server: mx1 X-Rspamd-Queue-Id: 14086200758 X-Stat-Signature: ia88igaonop8tpd4hcea8x9twksyotm6 Subject: [ptxdist] [PATCH 1/6] scripts: add ptxdist_bootstrap.sh with out-of-tree build support X-BeenThere: ptxdist@pengutronix.de X-Mailman-Version: 2.1.29 Precedence: list List-Id: PTXdist Development Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: ptxdist@pengutronix.de Sender: "ptxdist" X-SA-Exim-Connect-IP: 127.0.0.1 X-SA-Exim-Mail-From: ptxdist-bounces@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false From: Ladislav Michl The bootstrap script makes ready everything PTXdist needs from the host: - links to the GNU tools in /bin - kconfig in /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 --- .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 /bin +# - kconfig (conf, mconf and, if possible, nconf) in /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 +# +# 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} " >&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 +int main(void) { initscr(); endwin(); return 0; }' +nconf_prog='#include +#include +#include +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