mirror of
https://github.com/uutils/coreutils.git
synced 2026-05-06 07:26:38 -04:00
311 lines
10 KiB
Makefile
311 lines
10 KiB
Makefile
# spell-checker:ignore (misc) testsuite runtest findstring (targets) busytest toybox distclean pkgs nextest ; (vars/env) BINDIR BUILDDIR CARGOFLAGS CFLAGS DESTDIR DOCSDIR INSTALLDIR INSTALLEES MULTICALL DATAROOTDIR TESTDIR manpages
|
|
|
|
# Config options
|
|
ifneq (,$(filter install, $(MAKECMDGOALS)))
|
|
PROFILE?=release
|
|
endif
|
|
PROFILE ?= debug
|
|
MULTICALL ?= n
|
|
COMPLETIONS ?= y
|
|
MANPAGES ?= y
|
|
LOCALES ?= y
|
|
INSTALL ?= install
|
|
|
|
# Needed for the foreach loops to split each loop into a separate command
|
|
define newline
|
|
|
|
|
|
endef
|
|
|
|
PROFILE_CMD := --profile=${PROFILE}
|
|
ifeq ($(PROFILE),debug)
|
|
PROFILE_CMD =
|
|
endif
|
|
|
|
# Binaries
|
|
CARGO ?= cargo
|
|
CARGOFLAGS ?=
|
|
|
|
#prefix prepended to all binaries and library dir
|
|
PROG_PREFIX ?=
|
|
|
|
# Install directories
|
|
PREFIX ?= /usr/local
|
|
DESTDIR ?=
|
|
BINDIR ?= $(PREFIX)/bin
|
|
DATAROOTDIR ?= $(PREFIX)/share
|
|
LIBSTDBUF_DIR ?= $(PREFIX)/libexec/$(PROG_PREFIX)coreutils
|
|
# Export variable so that it is used during the build
|
|
export LIBSTDBUF_DIR
|
|
|
|
INSTALLDIR_BIN=$(DESTDIR)$(BINDIR)
|
|
|
|
# This won't support any directory with spaces in its name, but you can just
|
|
# make a symlink without spaces that points to the directory.
|
|
BASEDIR ?= $(shell pwd)
|
|
ifdef CARGO_TARGET_DIR
|
|
BUILDDIR := $(CARGO_TARGET_DIR)/${PROFILE}
|
|
BUILDDIR_UUDOC := $(CARGO_TARGET_DIR)/${PROFILE}
|
|
else
|
|
BUILDDIR := $(BASEDIR)/target/$(CARGO_BUILD_TARGET)/${PROFILE}
|
|
# uudoc should not be cross build
|
|
BUILDDIR_UUDOC := $(BASEDIR)/target/$(PROFILE)
|
|
endif
|
|
PKG_BUILDDIR := $(BUILDDIR)/deps
|
|
DOCSDIR := $(BASEDIR)/docs
|
|
|
|
BUSYBOX_ROOT := $(BASEDIR)/tmp
|
|
BUSYBOX_VER := 1.36.1
|
|
BUSYBOX_SRC := $(BUSYBOX_ROOT)/busybox-$(BUSYBOX_VER)
|
|
|
|
TOYBOX_ROOT := $(BASEDIR)/tmp
|
|
TOYBOX_VER := 0.8.12
|
|
TOYBOX_SRC := $(TOYBOX_ROOT)/toybox-$(TOYBOX_VER)
|
|
|
|
# Detect the target system
|
|
# See https://doc.rust-lang.org/beta/rustc/platform-support.html
|
|
# todo: support building wasm
|
|
OS := $(or $(CARGO_BUILD_TARGET),$(shell rustc --print host-tuple))
|
|
|
|
# hardlinks are better default since
|
|
# - Windows(cygwin) does not allow symlink by default
|
|
# - std::env:current_exe resolves symlink
|
|
LN ?= ln -f
|
|
|
|
SELINUX_PROGS := \
|
|
chcon \
|
|
runcon
|
|
|
|
$(info Detected OS = $(OS))
|
|
|
|
ifeq (,$(findstring windows,$(OS)))
|
|
FEATURE_EXTRACT_UTILS := feat_os_unix
|
|
else
|
|
FEATURE_EXTRACT_UTILS := feat_Tier1
|
|
endif
|
|
PROGS := $(shell cargo tree --depth 1 --features $(FEATURE_EXTRACT_UTILS) --format "{p}" --prefix none | sed -E -n 's/^uu_([^ ]+).*/\1/p')
|
|
|
|
ifeq ($(SELINUX_ENABLED),1)
|
|
PROGS += $(SELINUX_PROGS)
|
|
endif
|
|
|
|
UTILS ?= $(filter-out $(SKIP_UTILS),$(PROGS))
|
|
|
|
ifneq ($(findstring stdbuf,$(UTILS)),)
|
|
# Use external libstdbuf per default. It is more robust than embedding libstdbuf.
|
|
CARGOFLAGS += --features feat_external_libstdbuf
|
|
endif
|
|
|
|
# Programs with usable tests
|
|
|
|
TESTS := \
|
|
$(sort $(filter $(UTILS),$(PROGS) $(SELINUX_PROGS)))
|
|
|
|
TEST_NO_FAIL_FAST :=
|
|
TEST_SPEC_FEATURE :=
|
|
ifneq ($(SPEC),)
|
|
TEST_NO_FAIL_FAST :=--no-fail-fast
|
|
TEST_SPEC_FEATURE := test_unimplemented
|
|
else ifeq ($(SELINUX_ENABLED),1)
|
|
TEST_NO_FAIL_FAST :=
|
|
TEST_SPEC_FEATURE := selinux
|
|
BUILD_SPEC_FEATURE := selinux
|
|
endif
|
|
|
|
define TEST_BUSYBOX
|
|
test_busybox_$(1):
|
|
-(cd $(BUSYBOX_SRC)/testsuite && bindir=$(BUILDDIR) ./runtest $(RUNTEST_ARGS) $(1))
|
|
endef
|
|
|
|
# Output names
|
|
EXES := \
|
|
$(sort $(UTILS))
|
|
|
|
INSTALLEES := ${EXES}
|
|
ifeq (${MULTICALL}, y)
|
|
INSTALLEES := ${INSTALLEES} coreutils
|
|
endif
|
|
|
|
all: build
|
|
|
|
build-pkgs:
|
|
ifneq (${MULTICALL}, y)
|
|
ifdef BUILD_SPEC_FEATURE
|
|
${CARGO} build ${CARGOFLAGS} --features "$(BUILD_SPEC_FEATURE)" ${PROFILE_CMD} $(foreach pkg,$(EXES),-p uu_$(pkg))
|
|
else
|
|
${CARGO} build ${CARGOFLAGS} ${PROFILE_CMD} $(foreach pkg,$(EXES),-p uu_$(pkg))
|
|
endif
|
|
endif
|
|
|
|
build-coreutils:
|
|
${CARGO} build ${CARGOFLAGS} --features "${EXES} $(BUILD_SPEC_FEATURE)" ${PROFILE_CMD} --no-default-features
|
|
|
|
ifeq (${MULTICALL}, y)
|
|
build: build-coreutils locales
|
|
else
|
|
build: build-pkgs locales
|
|
endif
|
|
|
|
$(foreach test,$(UTILS),$(eval $(call TEST_BUSYBOX,$(test))))
|
|
|
|
test:
|
|
${CARGO} test ${CARGOFLAGS} --features "$(TESTS) $(TEST_SPEC_FEATURE)" $(PROFILE_CMD) --no-default-features $(TEST_NO_FAIL_FAST)
|
|
|
|
nextest:
|
|
${CARGO} nextest run ${CARGOFLAGS} --features "$(TESTS) $(TEST_SPEC_FEATURE)" $(PROFILE_CMD) --no-default-features $(TEST_NO_FAIL_FAST)
|
|
|
|
test_toybox:
|
|
-(cd $(TOYBOX_SRC)/ && CFLAGS="-pipe -O0 -s" make tests)
|
|
|
|
toybox-src:
|
|
if [ ! -e "$(TOYBOX_SRC)" ] ; then \
|
|
mkdir -p "$(TOYBOX_ROOT)" ; \
|
|
curl -Ls "https://github.com/landley/toybox/archive/refs/tags/$(TOYBOX_VER).tar.gz" -o "$(TOYBOX_ROOT)/$(TOYBOX_VER).tar.gz" ; \
|
|
tar -C "$(TOYBOX_ROOT)" -xf "$(TOYBOX_ROOT)/$(TOYBOX_VER).tar.gz" ; \
|
|
sed -i -e "s|TESTDIR=\".*\"|TESTDIR=\"$(BUILDDIR)\"|g" $(TOYBOX_SRC)/scripts/test.sh; \
|
|
sed -i -e "s/ || exit 1//g" $(TOYBOX_SRC)/scripts/test.sh; \
|
|
fi ;
|
|
|
|
busybox-src:
|
|
if [ ! -e "$(BUSYBOX_SRC)" ] ; then \
|
|
mkdir -p "$(BUSYBOX_ROOT)" ; \
|
|
curl -Ls "https://github.com/mirror/busybox/archive/refs/tags/$(subst .,_,$(BUSYBOX_VER)).tar.gz" -o "$(BUSYBOX_ROOT)/busybox-$(BUSYBOX_VER).tar.gz" ; \
|
|
tar -C "$(BUSYBOX_ROOT)" -xf "$(BUSYBOX_ROOT)/busybox-$(BUSYBOX_VER).tar.gz" ; \
|
|
fi ;
|
|
|
|
# This is a busybox-specific config file their test suite wants to parse.
|
|
$(BUILDDIR)/.config: $(BASEDIR)/.busybox-config
|
|
$(INSTALL) -m 644 $< $@
|
|
|
|
# Test under the busybox test suite
|
|
$(BUILDDIR)/busybox: busybox-src build-coreutils $(BUILDDIR)/.config
|
|
$(INSTALL) -m 755 "$(BUILDDIR)/coreutils" "$(BUILDDIR)/busybox"
|
|
|
|
prepare-busytest: $(BUILDDIR)/busybox
|
|
# disable inapplicable tests
|
|
-( cd "$(BUSYBOX_SRC)/testsuite" ; if [ -e "busybox.tests" ] ; then mv busybox.tests busybox.tests- ; fi ; )
|
|
|
|
ifeq ($(EXES),)
|
|
busytest:
|
|
else
|
|
busytest: $(BUILDDIR)/busybox $(addprefix test_busybox_,$(filter-out $(SKIP_UTILS),$(EXES)))
|
|
endif
|
|
|
|
clean:
|
|
cargo clean
|
|
cd $(DOCSDIR) && $(MAKE) clean
|
|
|
|
distclean: clean
|
|
$(CARGO) clean $(CARGOFLAGS) && $(CARGO) update $(CARGOFLAGS)
|
|
|
|
ifeq ($(MANPAGES),y)
|
|
# Do not cross-build uudoc
|
|
build-uudoc:
|
|
@unset CARGO_BUILD_TARGET && ${CARGO} build ${CARGOFLAGS} --bin uudoc --features "uudoc ${EXES}" ${PROFILE_CMD} --no-default-features
|
|
|
|
install-manpages: build-uudoc
|
|
mkdir -p $(DESTDIR)$(DATAROOTDIR)/man/man1
|
|
$(foreach prog, $(INSTALLEES), \
|
|
$(BUILDDIR_UUDOC)/uudoc manpage $(prog) > $(DESTDIR)$(DATAROOTDIR)/man/man1/$(PROG_PREFIX)$(prog).1 $(newline) \
|
|
)
|
|
else
|
|
install-manpages:
|
|
endif
|
|
|
|
ifeq ($(COMPLETIONS),y)
|
|
|
|
install-completions: build-uudoc
|
|
mkdir -p $(DESTDIR)$(DATAROOTDIR)/zsh/site-functions
|
|
mkdir -p $(DESTDIR)$(DATAROOTDIR)/bash-completion/completions
|
|
mkdir -p $(DESTDIR)$(DATAROOTDIR)/fish/vendor_completions.d
|
|
$(foreach prog, $(INSTALLEES), \
|
|
$(BUILDDIR_UUDOC)/uudoc completion $(prog) zsh > $(DESTDIR)$(DATAROOTDIR)/zsh/site-functions/_$(PROG_PREFIX)$(prog) $(newline) \
|
|
$(BUILDDIR_UUDOC)/uudoc completion $(prog) bash > $(DESTDIR)$(DATAROOTDIR)/bash-completion/completions/$(PROG_PREFIX)$(prog).bash $(newline) \
|
|
$(BUILDDIR_UUDOC)/uudoc completion $(prog) fish > $(DESTDIR)$(DATAROOTDIR)/fish/vendor_completions.d/$(PROG_PREFIX)$(prog).fish $(newline) \
|
|
)
|
|
else
|
|
install-completions:
|
|
endif
|
|
|
|
ifeq ($(LOCALES),y)
|
|
locales:
|
|
@# Copy uucore common locales
|
|
@if [ -d "$(BASEDIR)/src/uucore/locales" ]; then \
|
|
mkdir -p "$(BUILDDIR)/locales/uucore"; \
|
|
for locale_file in "$(BASEDIR)"/src/uucore/locales/*.ftl; do \
|
|
$(INSTALL) -m 644 "$$locale_file" "$(BUILDDIR)/locales/uucore/"; \
|
|
done; \
|
|
fi; \
|
|
# Copy utility-specific locales
|
|
@for prog in $(INSTALLEES); do \
|
|
if [ -d "$(BASEDIR)/src/uu/$$prog/locales" ]; then \
|
|
mkdir -p "$(BUILDDIR)/locales/$$prog"; \
|
|
for locale_file in "$(BASEDIR)"/src/uu/$$prog/locales/*.ftl; do \
|
|
if [ "$$(basename "$$locale_file")" != "en-US.ftl" ]; then \
|
|
$(INSTALL) -m 644 "$$locale_file" "$(BUILDDIR)/locales/$$prog/"; \
|
|
fi; \
|
|
done; \
|
|
fi; \
|
|
done
|
|
|
|
# Some utils require extra locale files outside of their package:
|
|
# - *sum binaries need the files from checksum_common
|
|
INSTALLEES_WITH_EXTRA_LOCALE = \
|
|
$(INSTALLEES) \
|
|
$(if $(findstring sum, $(INSTALLEES)),checksum_common, )
|
|
install-locales:
|
|
@for prog in $(INSTALLEES_WITH_EXTRA_LOCALE); do \
|
|
if [ -d "$(BASEDIR)/src/uu/$$prog/locales" ]; then \
|
|
mkdir -p "$(DESTDIR)$(DATAROOTDIR)/locales/$$prog"; \
|
|
for locale_file in "$(BASEDIR)"/src/uu/$$prog/locales/*.ftl; do \
|
|
if [ "$$(basename "$$locale_file")" != "en-US.ftl" ]; then \
|
|
$(INSTALL) -m 644 "$$locale_file" "$(DESTDIR)$(DATAROOTDIR)/locales/$$prog/"; \
|
|
fi; \
|
|
done; \
|
|
fi; \
|
|
done
|
|
else
|
|
locales:
|
|
install-locales:
|
|
endif
|
|
|
|
install: build install-manpages install-completions install-locales
|
|
mkdir -p $(INSTALLDIR_BIN)
|
|
ifneq (,$(and $(findstring stdbuf,$(UTILS)),$(findstring feat_external_libstdbuf,$(CARGOFLAGS))))
|
|
mkdir -p $(DESTDIR)$(LIBSTDBUF_DIR)
|
|
ifneq (,$(findstring cygwin,$(OS)))
|
|
$(INSTALL) -m 755 $(BUILDDIR)/deps/stdbuf.dll $(DESTDIR)$(LIBSTDBUF_DIR)/libstdbuf.dll
|
|
else
|
|
$(INSTALL) -m 755 $(BUILDDIR)/deps/libstdbuf.* $(DESTDIR)$(LIBSTDBUF_DIR)/
|
|
endif
|
|
endif
|
|
ifeq (${MULTICALL}, y)
|
|
$(INSTALL) -m 755 $(BUILDDIR)/coreutils $(INSTALLDIR_BIN)/$(PROG_PREFIX)coreutils
|
|
$(foreach prog, $(filter-out coreutils, $(INSTALLEES)), \
|
|
cd $(INSTALLDIR_BIN) && $(LN) $(PROG_PREFIX)coreutils $(PROG_PREFIX)$(prog) $(newline) \
|
|
)
|
|
$(if $(findstring test,$(INSTALLEES)), cd $(INSTALLDIR_BIN) && $(LN) $(PROG_PREFIX)coreutils $(PROG_PREFIX)[)
|
|
else
|
|
$(foreach prog, $(INSTALLEES), \
|
|
$(INSTALL) -m 755 $(BUILDDIR)/$(prog) $(INSTALLDIR_BIN)/$(PROG_PREFIX)$(prog) $(newline) \
|
|
)
|
|
$(if $(findstring test,$(INSTALLEES)), $(INSTALL) -m 755 $(BUILDDIR)/test $(INSTALLDIR_BIN)/$(PROG_PREFIX)[)
|
|
endif
|
|
|
|
uninstall:
|
|
ifeq (,$(findstring windows,$(OS)))
|
|
rm -f $(DESTDIR)$(LIBSTDBUF_DIR)/libstdbuf.*
|
|
-rm -d $(DESTDIR)$(LIBSTDBUF_DIR) 2>/dev/null || true
|
|
endif
|
|
ifeq (${MULTICALL}, y)
|
|
rm -f $(addprefix $(INSTALLDIR_BIN)/,$(PROG_PREFIX)coreutils)
|
|
endif
|
|
rm -f $(addprefix $(INSTALLDIR_BIN)/$(PROG_PREFIX),$(PROGS))
|
|
rm -f $(INSTALLDIR_BIN)/$(PROG_PREFIX)[
|
|
rm -f $(addprefix $(DESTDIR)$(DATAROOTDIR)/zsh/site-functions/_$(PROG_PREFIX),$(PROGS))
|
|
rm -f $(addprefix $(DESTDIR)$(DATAROOTDIR)/bash-completion/completions/$(PROG_PREFIX),$(PROGS).bash)
|
|
rm -f $(addprefix $(DESTDIR)$(DATAROOTDIR)/fish/vendor_completions.d/$(PROG_PREFIX),$(addsuffix .fish,$(PROGS)))
|
|
rm -f $(addprefix $(DESTDIR)$(DATAROOTDIR)/man/man1/$(PROG_PREFIX),$(addsuffix .1,$(PROGS)))
|
|
|
|
.PHONY: all build build-coreutils build-pkgs build-uudoc test distclean clean busytest install uninstall
|