Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

allow building multicall binary as dynamic library #7928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
Loading
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 35 additions & 18 deletions 53 .github/workflows/CICD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name: CICD
# spell-checker:ignore (jargon) SHAs deps dequote softprops subshell toolchain fuzzers dedupe devel profdata
# spell-checker:ignore (people) Peltoche rivy dtolnay Anson dawidd
# spell-checker:ignore (shell/tools) binutils choco clippy dmake dpkg esac fakeroot fdesc fdescfs gmake grcov halium lcov libclang libfuse libssl limactl mkdir nextest nocross pacman popd printf pushd redoxer rsync rustc rustfmt rustup shopt sccache utmpdump xargs
# spell-checker:ignore (misc) aarch alnum armhf bindir busytest coreutils defconfig DESTDIR gecos getenforce gnueabihf issuecomment maint manpages msys multisize noconfirm nullglob onexitbegin onexitend pell runtest Swatinem tempfile testsuite toybox uutils
# spell-checker:ignore (misc) aarch alnum armhf bindir busytest coreutils defconfig DESTDIR dylib gecos getenforce gnueabihf issuecomment maint manpages msys multisize noconfirm nullglob onexitbegin onexitend pell runtest Swatinem tempfile testsuite toybox uutils

env:
PROJECT_NAME: coreutils
Expand Down Expand Up @@ -513,25 +513,25 @@ jobs:
fail-fast: false
matrix:
job:
# - { os , target , cargo-options , default-features, features , use-cross , toolchain, skip-tests, workspace-tests, skip-package, skip-publish }
- { os: ubuntu-latest , target: arm-unknown-linux-gnueabihf , features: feat_os_unix_gnueabihf , use-cross: use-cross , skip-tests: true }
- { os: ubuntu-24.04-arm , target: aarch64-unknown-linux-gnu , features: feat_os_unix_gnueabihf }
- { os: ubuntu-latest , target: aarch64-unknown-linux-musl , features: feat_os_unix , use-cross: use-cross , skip-tests: true }
# - { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , features: feat_selinux , use-cross: use-cross }
- { os: ubuntu-latest , target: i686-unknown-linux-gnu , features: "feat_os_unix,test_risky_names", use-cross: use-cross }
- { os: ubuntu-latest , target: i686-unknown-linux-musl , features: feat_os_unix , use-cross: use-cross }
- { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , features: "feat_os_unix,test_risky_names", use-cross: use-cross }
- { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , features: "feat_os_unix,uudoc" , use-cross: no, workspace-tests: true }
- { os: ubuntu-latest , target: x86_64-unknown-linux-musl , features: feat_os_unix , use-cross: use-cross }
- { os: ubuntu-latest , target: x86_64-unknown-redox , features: feat_os_unix_redox , use-cross: redoxer , skip-tests: true }
- { os: ubuntu-latest , target: wasm32-unknown-unknown , default-features: false, features: uucore/format, skip-tests: true, skip-package: true, skip-publish: true }
- { os: macos-latest , target: aarch64-apple-darwin , features: feat_os_macos, workspace-tests: true } # M1 CPU
- { os: macos-13 , target: x86_64-apple-darwin , features: feat_os_macos, workspace-tests: true }
- { os: windows-latest , target: i686-pc-windows-msvc , features: feat_os_windows }
# - { os , target , cargo-options , default-features , features , dyn , use-cross , toolchain , skip-tests , workspace-tests , skip-package , skip-publish }
- { os: ubuntu-latest , target: arm-unknown-linux-gnueabihf , features: feat_os_unix_gnueabihf , use-cross: use-cross , skip-tests: true }
- { os: ubuntu-24.04-arm , target: aarch64-unknown-linux-gnu , features: feat_os_unix_gnueabihf , dyn: true }
- { os: ubuntu-latest , target: aarch64-unknown-linux-musl , features: feat_os_unix , use-cross: use-cross , skip-tests: true }
# - { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , features: feat_selinux , use-cross: use-cross }
- { os: ubuntu-latest , target: i686-unknown-linux-gnu , features: "feat_os_unix,test_risky_names" , dyn: true , use-cross: use-cross }
- { os: ubuntu-latest , target: i686-unknown-linux-musl , features: feat_os_unix , use-cross: use-cross }
- { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , features: "feat_os_unix,test_risky_names" , dyn: true , use-cross: use-cross }
- { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , features: "feat_os_unix,uudoc" , use-cross: no, workspace-tests: true }
- { os: ubuntu-latest , target: x86_64-unknown-linux-musl , features: feat_os_unix , use-cross: use-cross }
- { os: ubuntu-latest , target: x86_64-unknown-redox , features: feat_os_unix_redox , dyn: true , use-cross: redoxer , skip-tests: true }
- { os: ubuntu-latest , target: wasm32-unknown-unknown , default-features: false, features: uucore/format, skip-tests: true, skip-package: true, skip-publish: true }
- { os: macos-latest , target: aarch64-apple-darwin , features: feat_os_macos , dyn: true , workspace-tests: true } # M1 CPU
- { os: macos-13 , target: x86_64-apple-darwin , features: feat_os_macos , dyn: true , workspace-tests: true }
- { os: windows-latest , target: i686-pc-windows-msvc , features: feat_os_windows }
# TODO: Re-enable after rust-onig release: https://github.com/rust-onig/rust-onig/issues/193
# - { os: windows-latest , target: x86_64-pc-windows-gnu , features: feat_os_windows }
- { os: windows-latest , target: x86_64-pc-windows-msvc , features: feat_os_windows }
- { os: windows-latest , target: aarch64-pc-windows-msvc , features: feat_os_windows, use-cross: use-cross , skip-tests: true }
- { os: windows-latest , target: x86_64-pc-windows-msvc , features: feat_os_windows }
- { os: windows-latest , target: aarch64-pc-windows-msvc , features: feat_os_windows , use-cross: use-cross , skip-tests: true }
steps:
- uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -765,6 +765,23 @@ jobs:
## Build
${{ steps.vars.outputs.CARGO_CMD }} ${{ steps.vars.outputs.CARGO_CMD_OPTIONS }} build --release \
--target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} ${{ steps.vars.outputs.CARGO_DEFAULT_FEATURES_OPTION }}
- name: Build dynamic library
if: matrix.job.dyn == true
shell: bash
run: |
## Build dynamic library
${{ steps.vars.outputs.CARGO_CMD }} ${{ steps.vars.outputs.CARGO_CMD_OPTIONS }} rustc --release --target-dir ./target/${{ matrix.job.target }}/dynamic --crate-type=dylib --lib \
--target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }},dynamic ${{ steps.vars.outputs.CARGO_DEFAULT_FEATURES_OPTION }}
## Build the multicall shim
${{ steps.vars.outputs.CARGO_CMD }} ${{ steps.vars.outputs.CARGO_CMD_OPTIONS }} build --release --target-dir ./target/${{ matrix.job.target }}/dynamic \
--target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }},dynamic ${{ steps.vars.outputs.CARGO_DEFAULT_FEATURES_OPTION }}
- name: Check dynamic library
if: matrix.job.dyn == true && matrix.job.skip-tests != true
shell: bash
run: |
export LD_LIBRARY_PATH="./target/${{ matrix.job.target }}/dynamic/:$LD_LIBRARY_PATH"
${{ steps.vars.outputs.CARGO_CMD }} ${{ steps.vars.outputs.CARGO_CMD_OPTIONS }} run --release --target-dir ./target/${{ matrix.job.target }}/dynamic \
--target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }},dynamic ${{ steps.vars.outputs.CARGO_DEFAULT_FEATURES_OPTION }}
- name: Test
if: matrix.job.skip-tests != true
shell: bash
Expand Down
1 change: 1 addition & 0 deletions 1 Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion 10 Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# coreutils (uutils)
# * see the repository LICENSE, README, and CONTRIBUTING files for more information

# spell-checker:ignore (libs) bigdecimal datetime serde bincode gethostid kqueue libselinux mangen memmap procfs uuhelp startswith constness expl
# spell-checker:ignore (libs) bigdecimal datetime serde bincode gethostid kqueue libselinux libloading mangen memmap procfs uuhelp startswith constness expl

[package]
name = "coreutils"
Expand Down Expand Up @@ -36,6 +36,8 @@ expensive_tests = []
test_risky_names = []
# * only build `uudoc` when `--feature uudoc` is activated
uudoc = ["zip", "dep:uuhelp_parser"]
# * only build `coreutils` with dynamic loading when `--feature dynamic` is activated
dynamic = ["libloading"]
## features
# "feat_acl" == enable support for ACLs (access control lists; by using`--features feat_acl`)
# NOTE:
Expand Down Expand Up @@ -304,6 +306,7 @@ iana-time-zone = "0.1.57"
indicatif = "0.17.8"
itertools = "0.14.0"
libc = "0.2.172"
libloading = "0.8.6"
linux-raw-sys = "0.9"
lscolors = { version = "0.20.0", default-features = false, features = [
"gnu_legacy",
Expand Down Expand Up @@ -377,6 +380,7 @@ phf = { workspace = true }
selinux = { workspace = true, optional = true }
textwrap = { workspace = true }
zip = { workspace = true, optional = true }
libloading = { workspace = true, optional = true }

uuhelp_parser = { optional = true, version = ">=0.0.19", path = "src/uuhelp_parser" }

Expand Down Expand Up @@ -542,6 +546,10 @@ phf_codegen = { workspace = true }
name = "coreutils"
path = "src/bin/coreutils.rs"

[lib]
name = "coreutils"
path = "src/lib/coreutils.rs"

[[bin]]
name = "uudoc"
path = "src/bin/uudoc.rs"
Expand Down
35 changes: 31 additions & 4 deletions 35 GNUmakefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# spell-checker:ignore (misc) testsuite runtest findstring (targets) busytest toybox distclean pkgs nextest ; (vars/env) BINDIR BUILDDIR CARGOFLAGS DESTDIR DOCSDIR INSTALLDIR INSTALLEES MULTICALL DATAROOTDIR TESTDIR manpages
# spell-checker:ignore (misc) testsuite runtest findstring libcoreutils dylib (targets) busytest toybox distclean pkgs nextest ; (vars/env) BINDIR BUILDDIR CARGOFLAGS DESTDIR DOCSDIR INSTALLDIR INSTALLEES MULTICALL DATAROOTDIR TESTDIR manpages

# Config options
PROFILE ?= debug
DYNAMIC ?= n
MULTICALL ?= n
COMPLETIONS ?= y
MANPAGES ?= y
Expand Down Expand Up @@ -31,9 +32,11 @@ CARGOFLAGS ?=
PREFIX ?= /usr/local
DESTDIR ?=
BINDIR ?= $(PREFIX)/bin
LIBDIR ?= $(PREFIX)/lib
DATAROOTDIR ?= $(PREFIX)/share

INSTALLDIR_BIN=$(DESTDIR)$(BINDIR)
INSTALLDIR_LIB=$(DESTDIR)$(LIBDIR)

#prefix to apply to coreutils binary and all tool binaries
PROG_PREFIX ?=
Expand Down Expand Up @@ -271,6 +274,17 @@ TEST_SPEC_FEATURE := selinux
BUILD_SPEC_FEATURE := selinux
endif

ifeq (${DYNAMIC}, y)
BUILD_SPEC_FEATURE += dynamic
ifeq ($(OS),Windows_NT)
LIBNAME := libcoreutils.dll
else ifeq ($(shell uname -s),Darwin)
LIBNAME := libcoreutils.dylib
else
LIBNAME := libcoreutils.so
endif
endif

define TEST_BUSYBOX
test_busybox_$(1):
-(cd $(BUSYBOX_SRC)/testsuite && bindir=$(BUILDDIR) ./runtest $(RUNTEST_ARGS) $(1))
Expand Down Expand Up @@ -299,10 +313,15 @@ else
endif
endif

build-lib:
ifeq (${DYNAMIC}, y)
${CARGO} rustc ${CARGOFLAGS} --features "${EXES} $(BUILD_SPEC_FEATURE)" ${PROFILE_CMD} --crate-type dylib --lib
endif

build-coreutils:
${CARGO} build ${CARGOFLAGS} --features "${EXES} $(BUILD_SPEC_FEATURE)" ${PROFILE_CMD} --no-default-features

build: build-coreutils build-pkgs
build: build-coreutils build-pkgs build-lib

$(foreach test,$(filter-out $(SKIP_UTILS),$(PROGS)),$(eval $(call TEST_BUSYBOX,$(test))))

Expand Down Expand Up @@ -341,7 +360,7 @@ $(BUILDDIR)/busybox: busybox-src build-coreutils $(BUILDDIR)/.config
chmod +x $@

prepare-busytest: $(BUILDDIR)/busybox
# disable inapplicable tests
# disable inapplicable tests
-( cd "$(BUSYBOX_SRC)/testsuite" ; if [ -e "busybox.tests" ] ; then mv busybox.tests busybox.tests- ; fi ; )

ifeq ($(EXES),)
Expand Down Expand Up @@ -395,7 +414,12 @@ else
install-completions:
endif

install: build install-manpages install-completions
install-lib:
ifeq (${DYNAMIC}, y)
$(INSTALL) $(BUILDDIR)/$(LIBNAME) $(INSTALLDIR_LIB)/
endif

install: build install-manpages install-completions install-lib
mkdir -p $(INSTALLDIR_BIN)
ifeq (${MULTICALL}, y)
$(INSTALL) $(BUILDDIR)/coreutils $(INSTALLDIR_BIN)/$(PROG_PREFIX)coreutils
Expand All @@ -413,6 +437,9 @@ endif
uninstall:
ifeq (${MULTICALL}, y)
rm -f $(addprefix $(INSTALLDIR_BIN)/,$(PROG_PREFIX)coreutils)
endif
ifeq (${DYNAMIC}, y)
rm -f $(INSTALLDIR_BIN)/$(LIBNAME)
endif
rm -f $(addprefix $(INSTALLDIR_BIN)/$(PROG_PREFIX),$(PROGS))
rm -f $(INSTALLDIR_BIN)/$(PROG_PREFIX)[
Expand Down
39 changes: 37 additions & 2 deletions 39 README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!-- markdownlint-disable MD033 MD041 MD002 -->
<!-- markdownlint-disable commands-show-output no-duplicate-heading -->
<!-- spell-checker:ignore markdownlint ; (options) DESTDIR UTILNAME manpages reimplementation oranda -->
<!-- spell-checker:ignore markdownlint ; (options) DESTDIR UTILNAME dylib manpages reimplementation oranda -->
<div class="oranda-hide">
<div align="center">

Expand Down Expand Up @@ -129,6 +129,22 @@ the `--package` [aka `-p`] option). For example:
cargo build -p uu_base32 -p uu_cat -p uu_echo -p uu_rm
```

The multicall code can also be built as a dynamic library, and the multicall
binary turned into a minimal shim to load it:

```shell
cargo rustc --release --features dynamic,unix --lib --crate-type dylib
cargo build --release --features dynamic
```

Note that the shim multicall binary will not function unless the library is
accessible in one of the dynamic loader's search paths—either a default library
search path, or a modified environment. For example, on Linux:

```shell
LD_LIBRARY_PATH=$(pwd)/target/release/ ./target/release/coreutils
```

### GNU Make

Building using `make` is a simple process as well.
Expand Down Expand Up @@ -212,13 +228,26 @@ To install the multicall binary:
make MULTICALL=y install
```

Set install parent directory (default value is /usr/local):
Set install parent directory (default value is `/usr/local`):

```shell
# DESTDIR is also supported
make PREFIX=/my/path install
```

The dynamically liked multicall library and binary can be installed instead.
Note, however, that while the standard local `/usr/local/bin` path for binaries
is typically in the default `PATH` environment variable, the standard local
`/usr/local/lib` path for libraries is typically *not* in the default library
search paths. If you do not address this in a persistent manner, then do a
default dynamic install, your system will likely to fail to fully boot. With
that in mind, to install the dynamically linked library and shim multicall
binary:

```shell
make MULTICALL=y DYNAMIC=y install
```

Installing with `make` installs shell completions for all installed utilities
for `bash`, `fish` and `zsh`. Completions for `elvish` and `powershell` can also
be generated; See `Manually install shell completions`.
Expand Down Expand Up @@ -295,6 +324,12 @@ To uninstall the multicall binary:
make MULTICALL=y uninstall
```

Similarly, for the dynamically linked library and binary:

```shell
make MULTICALL=y DYNAMIC=y uninstall
```

To uninstall from a custom parent directory:

```shell
Expand Down
8 changes: 5 additions & 3 deletions 8 build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// spell-checker:ignore (vars) krate
// spell-checker:ignore (vars) krate libloading

use std::env;
use std::fs::File;
Expand Down Expand Up @@ -32,11 +32,13 @@ pub fn main() {
// Allow this as we have a bunch of info in the comments
#[allow(clippy::match_same_arms)]
match krate.as_ref() {
"default" | "macos" | "unix" | "windows" | "selinux" | "zip" => continue, // common/standard feature names
"default" | "macos" | "unix" | "windows" | "selinux" | "zip" | "libloading" => {
continue;
} // common/standard feature names
"nightly" | "test_unimplemented" | "expensive_tests" | "test_risky_names" => {
continue;
} // crate-local custom features
"uudoc" => continue, // is not a utility
"uudoc" | "dynamic" => continue, // is not a utility
"test" => continue, // over-ridden with 'uu_test' to avoid collision with rust core crate 'test'
s if s.starts_with(FEATURE_PREFIX) => continue, // crate feature sets
_ => {} // util feature name
Expand Down
Loading
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.