lnstools

Linux namespace tools
git clone https://ccx.te2000.cz/git/lnstools
Log | Files | Refs | README

commit 0253d2bcae9a5fe32fe14ae79a8b0f18ce5fe066
parent 1a15532cb8e3fd3f7a0977851df41887c8aacf82
Author: Jan Pobrislo <ccx@te2000.cz>
Date:   Fri, 21 Nov 2025 03:18:21 +0000

WIP configure script

Diffstat:
MMakefile | 10++++++++--
Mconfigure | 330+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Ascripts/args_to_sh.awk | 25+++++++++++++++++++++++++
Msimplelink.mk | 8+++++---
4 files changed, 344 insertions(+), 29 deletions(-)

diff --git a/Makefile b/Makefile @@ -8,11 +8,11 @@ script_executables: ${script_executables} c_executables:=lns-lockdown lns-envuidgid lns-applyuidgid lns-pidns include simplelink.mk -conf/cc conf/ld.shared conf/ld.static conf/script_gen: +conf/cc conf/ld.shared conf/ld.static conf/script_gen conf/config.mk: @printf '%s\n' "Please run configure script first!"; exit 1 build/%: src/%.in conf/script_gen scripts/abspaths2.awk - conf/script_gen awk -f ./scripts/abspaths2.awk 'src/$*.in' >'$@.new' + sh conf/script_gen awk -f ./scripts/abspaths2.awk 'src/$*.in' >'$@.new' mv -v '$@.new' '$@' clean: @@ -21,3 +21,9 @@ clean: distclean: rm -rf conf build .PHONY: clean + +-include conf/config.mk + +install: $(install_bin_files) + install -d $(DESTDIR)$(INSTALL_BINDIR) + install -t $(DESTDIR)$(INSTALL_BINDIR) $(install_bin_files) diff --git a/configure b/configure @@ -3,6 +3,191 @@ cd "$(dirname "$0")" || exit $? sh=$(which sh) || exit $? export sh +usage () { +cat <<EOF +Usage: $0 [OPTION]... [TARGET] + +Defaults for the options are specified in brackets. + +System types: + --target=TARGET configure to run on target TARGET [detected] + --host=TARGET same as --target + +Installation directories: + --prefix=PREFIX main installation prefix [/] + --exec-prefix=EPREFIX installation prefix for executable files [PREFIX] + +Fine tuning of the installation directories: + --dynlibdir=DIR shared library files [PREFIX/lib] + --bindir=BINDIR user executables [EPREFIX/bin] + --libexecdir=DIR package-scoped executables [EPREFIX/libexec] + --libdir=DIR static library files [PREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --sysconfdir=DIR global configuration files [PREFIX/etc] + --pkgconfdir=DIR pkg-config .pc files [PREFIX/lib/pkgconfig] + + If no --prefix option is given, by default libdir (but not dynlibdir) will be + /usr/lib, and includedir will be /usr/include. + +Dependencies: + --with-sysdeps=DIR use sysdeps in DIR [PREFIX/lib/skalibs/sysdeps] + --with-include=DIR add DIR to the list of searched directories for headers + --with-lib=DIR add DIR to the list of searched directories for static libraries + --with-dynlib=DIR add DIR to the list of searched directories for shared libraries + --with-pkgconfig[=PROG] use pkg-config to look for dependencies + + If no --prefix option is given, by default sysdeps will be fetched from + /usr/lib/skalibs/sysdeps. + +Optional features: + --enable-shared build shared libraries [disabled] + --disable-static do not build static libraries [enabled] + --disable-allstatic do not prefer linking against static libraries [enabled] + --enable-static-libc make entirely static binaries [disabled] + --disable-all-pic do not build executables or static libs as PIC [enabled] + --enable-pkgconfig Build and install .pc files for pkg-config [disabled] + --enable-slashpackage[=ROOT] assume /package installation at ROOT [disabled] + --enable-absolute-paths hardcode absolute BINDIR/foobar paths in binaries [disabled] + --enable-nsss use the nsss library for user information [disabled] + --disable-execline don't use the execline library [enabled] + +EOF +exit 0 +} + +stripdir() { + eval 'while true; do case $'$1' in (*/) '$1'=${'$1'%/};; (*) break;; esac; done' +} + +got_arg() { + case $1 in + (prefix) arg_prefix=$2; stripdir arg_prefix ;; + (dynlibdir) arg_dynlibdir=$2; stripdir arg_dynlibdir ;; + (libexecdir) arg_libexecdir=$2; stripdir arg_libexecdir ;; + (bindir) arg_bindir=$2; stripdir arg_bindir ;; + (libdir) arg_libdir=$2; stripdir arg_libdir ;; + (includedir) arg_includedir=$2; stripdir arg_includedir ;; + (sysconfdir) arg_sysconfdir=$2; stripdir arg_sysconfdir ;; + (pkgconfdir) arg_pkgconfdir=$2; stripdir arg_pkgconfdir ;; + (*) return 1 ;; + esac +} + +got_enable() { + case $1 in + (shared) + case $2 in + (libc) enable_shared=libc;; + (yes) enable_shared=true;; + (no) enable_shared=false;; + (*) return 2;; + esac + ;; + (static) + case $2 in + (yes) enable_shared=false;; + (no) enable_shared=true;; + (*) return 2;; + esac + ;; + (absolute-paths) + case $2 in + (manual) enable_abspath=manual;; + (yes) enable_abspath=true;; + (no) enable_abspath=false;; + (*) return 2;; + esac + ;; + (*) return 1 ;; + esac +} + +got_prog() { + case $1 in + (awk) prog_awk=$2 ;; + (cd) prog_cd=$2 ;; + (execlineb) prog_execlineb=$2 ;; + (if) prog_if=$2 ;; + (importas) prog_importas=$2 ;; + (ln) prog_ln=$2 ;; + (mkdir) prog_mkdir=$2 ;; + (mknod) prog_mknod=$2 ;; + (mount) prog_mount=$2 ;; + (multisubstitute) prog_multisubstitute=$2 ;; + (runblock) prog_runblock=$2 ;; + (s6-mount) prog_s6_mount=$2 ;; + (sh) prog_sh=$2 ;; + (shift) prog_shift=$2 ;; + (*) return 1 ;; + esac +} + +parse_args() { + for arg ; do + case "$arg" in + (--help) usage ;; + (--enable-*=*) + arg1=${arg%%=*} + arg1=${arg1#--enable-} + arg2=${arg#*=} + got_enable "$arg1" "$arg2" && continue + ;; + (--enable-*) + got_enable "${arg#--enable-}" yes && continue + ;; + (--disable-*=yes) + arg1=${arg#--disable-} + got_enable "${arg%=*}" no && continue + ;; + (--disable-*=no) + arg1=${arg#--disable-} + got_enable "${arg%=*}" yes && continue + ;; + (--disable-*=*) # error + ;; + (--disable-*) + arg1=${arg#--disable-} + got_enable "${arg%=*}" no && continue + ;; + (--path-to-*=*) + arg1=${arg%%=*} + arg1=${arg1#--path-to-} + arg2=${arg#*=} + got_prog "$arg1" "$arg2" && continue + ;; + (--*=*) + arg1=${arg%%=*} + arg1=${arg1#--} + arg2=${arg#*=} + got_arg "$arg1" "$arg2" && continue + ;; +# --exec-prefix=*) exec_prefix=${arg#*=} ;; +# --with-sysdeps=*) sysdeps=${arg#*=} manualsysdeps=true ;; +# --with-include=*) var=${arg#*=} ; stripdir var ; addincpath="$addincpath -I$var" ; depincpath="${depincpath}${depincpath:+ }-I$var" ;; +# --with-lib=*) var=${arg#*=} ; stripdir var ; addlibspath="$addlibspath -L$var" ; deplibpath="${deplibpath}${deplibpath:+ }-L$var" ; vpaths="$vpaths $var" ;; +# --with-dynlib=*) var=${arg#*=} ; stripdir var ; addlibdpath="$addlibdpath -L$var" ; vpathd="$vpathd $var" ;; +# --with-pkgconfig=*) pkgconf=${arg#*=} ;; +# --with-pkgconfig) pkgconf=${PKG_CONFIG:-pkg-config} ;; +# --without-pkgconfig) pkgconf= ;; +# --enable-all-pic|--enable-all-pic=yes) allpic=true ;; +# --disable-all-pic|--enable-all-pic=no) allpic=false ;; + esac + printf >&2 'configure: fatal: unrecognized option: %s\n' "$arg" + exit 2 + done +} + +parse_args "$@" + +prefix=${arg_prefix-/usr/local} +dynlibdir=${arg_dynlibdir-${prefix}/lib} +libexecdir=${arg_libexecdir-${prefix}/libexec} +bindir=${arg_bindir-${prefix}/bin} +libdir=${arg_libdir-${prefix}/lib} +includedir=${arg_includedir-${prefix}/include} +sysconfdir=${arg_sysconfdir-${prefix}/etc} +pkgconfdir=${arg_pkgconfdir-${prefix}/lib/pkgconfig} + # CC # CFLAGS : ${CFLAGS=-D_GNU_SOURCE -Werror -pipe -std=c11 -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections -g} @@ -17,38 +202,135 @@ export LDLIBS # LIBRARY_PATH # LOADLIBES +case $enable_abspath in + (false) + : ${prog_awk=awk} + : ${prog_cd=cd} + : ${prog_execlineb=execlineb} + : ${prog_if=if} + : ${prog_importas=importas} + : ${prog_ln=ln} + # : ${prog_lns_mounts_to_env=lns-mounts-to-env} + : ${prog_mkdir=mkdir} + : ${prog_mknod=mknod} + : ${prog_mount=mount} + : ${prog_multisubstitute=multisubstitute} + : ${prog_runblock=runblock} + : ${prog_s6_mount=s6-mount} + : ${prog_sh=sh} + : ${prog_shift=shift} + ;; + (true) + : ${prog_awk=$(which awk 2>/dev/null )} + : ${prog_cd=$(which cd 2>/dev/null )} + : ${prog_execlineb=$(which execlineb 2>/dev/null )} + : ${prog_if=$(which if 2>/dev/null )} + : ${prog_importas=$(which importas 2>/dev/null )} + : ${prog_ln=$(which ln 2>/dev/null )} + # : ${prog_lns_mounts_to_env=$(which lns-mounts-to-env 2>/dev/null )} + : ${prog_mkdir=$(which mkdir 2>/dev/null )} + : ${prog_mknod=$(which mknod 2>/dev/null )} + : ${prog_mount=$(which mount 2>/dev/null )} + : ${prog_multisubstitute=$(which multisubstitute 2>/dev/null )} + : ${prog_runblock=$(which runblock 2>/dev/null )} + : ${prog_s6_mount=$(which s6-mount 2>/dev/null )} + : ${prog_sh=$(which sh 2>/dev/null )} + : ${prog_shift=$(which shift 2>/dev/null )} + ;; + (manual) ;; + (*) exit 3 ;; +esac + +prog_lns_mounts_to_env=$bindir/lns-mount-to-env + +die_notfound() { + printf >&2 "configure: fatal: absolute paths required and path to '%s' was not found\n" "$1" + exit 1 +} + +test -n "$prog_awk" || die_notfound awk +test -n "$prog_cd" || die_notfound cd +test -n "$prog_execlineb" || die_notfound execlineb +test -n "$prog_if" || die_notfound if +test -n "$prog_importas" || die_notfound importas +test -n "$prog_ln" || die_notfound ln +test -n "$prog_lns_mounts_to_env" || die_notfound lns-mounts-to-env +test -n "$prog_mkdir" || die_notfound mkdir +test -n "$prog_mknod" || die_notfound mknod +test -n "$prog_mount" || die_notfound mount +test -n "$prog_multisubstitute" || die_notfound multisubstitute +test -n "$prog_runblock" || die_notfound runblock +test -n "$prog_s6_mount" || die_notfound s6-mount +test -n "$prog_sh" || die_notfound sh +test -n "$prog_shift" || die_notfound shift + replace_if_different() { - if ! test -e "$1"; then - mv "$1.new" "$1" || exit $? - return 0 - fi - local R - cmp -s "$1" "$1.new" - R=$? - case $R in - (0) - rm "$1.new" || exit $? - ;; - (1) - mv "$1.new" "$1" || exit $? - ;; - (*) - printf >&2 "configure: fatal: failed to compare files %s and %s\n" "$1" "$1.new" - exit $R - ;; - esac + if ! test -e "$1"; then + mv "$1.new" "$1" || exit $? + return 0 + fi + local R + cmp -s "$1" "$1.new" + R=$? + case $R in + (0) + rm "$1.new" || exit $? + ;; + (1) + mv "$1.new" "$1" || exit $? + ;; + (*) + printf >&2 "configure: fatal: failed to compare files %s and %s\n" "$1" "$1.new" + exit $R + ;; + esac } generate() { - local out=$1 - shift || exit $? - "$@" >"$out.new" || exit $? - chmod +x "$out.new" || exit $? - replace_if_different "$out" || exit $? + local out=$1 + shift || exit $? + "$@" >"$out.new" || exit $? + chmod +x "$out.new" || exit $? + replace_if_different "$out" || exit $? +} + +mk_script_gen() { + set -e + awk -f ./scripts/args_to_sh.awk \ + awk="$prog_awk" \ + cd="$prog_cd" \ + execlineb="$prog_execlineb" \ + if="$prog_if" \ + importas="$prog_importas" \ + ln="$prog_ln" \ + lns-mounts-to-env="$prog_lns_mounts_to_env" \ + mkdir="$prog_mkdir" \ + mknod="$prog_mknod" \ + mount="$prog_mount" \ + multisubstitute="$prog_multisubstitute" \ + runblock="$prog_runblock" \ + s6-mount="$prog_s6_mount" \ + sh="$prog_sh" \ + shift="$prog_shift" +} + +mk_config_mk() { + set -e + printf '%s\n' "INSTALL_BINDIR:=$bindir" + case $enable_shared in + (false) + printf '%s\n' 'install_bin_files:=${script_executables} $(static_executables)' + ;; + (*) + printf '%s\n' 'install_bin_files:=${script_executables} $(shared_executables)' + ;; + esac } mkdir -p conf || exit $? +generate conf/config.mk mk_config_mk +generate conf/script_gen mk_script_gen generate conf/cc awk -f ./scripts/gen-cc generate conf/ld.shared awk -f ./scripts/gen-ld generate conf/ld.static env LDFLAGS="$LDFLAGS -static" awk -f ./scripts/gen-ld diff --git a/scripts/args_to_sh.awk b/scripts/args_to_sh.awk @@ -0,0 +1,25 @@ +#!/bin/awk -f +function die(msg) { + print msg >>"/dev/stderr" + exit 1 +} + +function s(re, t, str) { + gsub(re, t, str) + return str +} + +function shquote(text) { + if(text !~ "[^-+,_./:@0-9A-Za-z]") { + return text + } + return "'" s("'", "'\\''", text) "'" +} + +BEGIN { + printf "%s\n%s", "#!/bin/sh", "exec \"$@\"" + for(i=1; i<ARGC; i++) { + printf " %s", shquote(ARGV[i]) + } + ARGC = 1 +} diff --git a/simplelink.mk b/simplelink.mk @@ -4,9 +4,11 @@ BUILD_DIR ?= ${TOP_DIR}/build SCRIPTS_DIR ?= ${TOP_DIR}/scripts CONF_DIR ?= ${TOP_DIR}/conf -shared_executables: $(patsubst %,$(BUILD_DIR)/bin-shared/%,$(c_executables)) -static_executables: $(patsubst %,$(BUILD_DIR)/bin-static/%,$(c_executables)) +shared_executables:=$(patsubst %,$(BUILD_DIR)/bin-shared/%,$(c_executables)) +static_executables:=$(patsubst %,$(BUILD_DIR)/bin-static/%,$(c_executables)) .PHONY: shared_executables static_executables +shared_executables: $(shared_executables) +static_executables: $(static_executables) define simplelink = include $$(BUILD_DIR)/$(1)_main.c.deps.mk @@ -16,7 +18,7 @@ include $$(BUILD_DIR)/$(1)_main.c.deps.mk $$(BUILD_DIR)/bin-static/$(1): $$(LINKDEP_$(subst -,__,$(1))_main__c) $$(CONF_DIR)/ld.static $$(BUILD_DIR)/$(1)_main.c.deps.mk $$(BUILD_DIR)/bin-static/.exists $$(CONF_DIR)/ld.static -o '$$@' $$(LINKDEP_$(subst -,__,$(1))_main__c) endef -$(foreach var,$(executables),$(eval $(call simplelink,$(var)))) +$(foreach var,$(c_executables),$(eval $(call simplelink,$(var)))) ## pattern rules: