Skip to content
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

I want to compile an application that does not contain any dynamic libraries #176

Closed
cosoc opened this issue Aug 4, 2023 · 5 comments
Closed

Comments

@cosoc
Copy link

cosoc commented Aug 4, 2023

os info: debian11

Linux debian 5.10.0-10-amd64 #1 SMP Debian 5.10.84-1 (2021-12-08) x86_64 GNU/Linux

Cargo.toml

[package]
name = "test"
version = "2.0.0"
description = "test static "
authors = ["test"]
license = "private"
edition = "2021"
rust-version = "1.57"

[dependencies]
rusb = { version = "0.9.2",features = ["vendored"]}

test main function

fn main() {
    for device in rusb::devices().unwrap().iter() {
        let device_desc = device.device_descriptor().unwrap();

        println!("Bus {:03} Device {:03} ID {:04x}:{:04x}",
            device.bus_number(),
            device.address(),
            device_desc.vendor_id(),
            device_desc.product_id());
    }
}

build cmd

 PKG_CONFIG_SYSROOT_DIR=/usr/lib/x86_64-linux-musl  cargo build --target=x86_64-unknown-linux-musl  --release

error

 Compiling libusb1-sys v0.6.4
The following warnings were emitted during compilation:

warning: In file included from libusb/libusb/os/linux_netlink.c:25:
warning: libusb/libusb/os/linux_usbfs.h:24:10: fatal error: linux/magic.h: 没有那个文件或目录
warning:    24 | #include <linux/magic.h>
warning:       |          ^~~~~~~~~~~~~~~
warning: compilation terminated.

error: failed to run custom build command for `libusb1-sys v0.6.4`

Caused by:
  process didn't exit successfully: `/home/hzhzhzh/Development/Test/rusb/target/release/build/libusb1-sys-74a13765ed64a279/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-env-changed=LIBUSB_STATIC
  cargo:vendored=1
  cargo:static=1
  cargo:include=/home/hzhzhzh/Development/Test/rusb/target/x86_64-unknown-linux-musl/release/build/libusb1-sys-7d8a010aa27512a4/out/include
  cargo:rerun-if-env-changed=LIBUDEV_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_ALLOW_CROSS
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=LIBUDEV_STATIC
  cargo:rerun-if-env-changed=LIBUDEV_DYNAMIC
  cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC
  cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=LIBUDEV_STATIC
  cargo:rerun-if-env-changed=LIBUDEV_DYNAMIC
  cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC
  cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC
  cargo:rustc-link-search=native=/usr/lib/x86_64-linux-musl/usr/lib/x86_64-linux-gnu
  cargo:rustc-link-lib=udev
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=LIBUDEV_STATIC
  cargo:rerun-if-env-changed=LIBUDEV_DYNAMIC
  cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC
  cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-musl
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_musl
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
  Including posix!
  TARGET = Some("x86_64-unknown-linux-musl")
  OPT_LEVEL = Some("3")
  HOST = Some("x86_64-unknown-linux-gnu")
  cargo:rerun-if-env-changed=CC_x86_64-unknown-linux-musl
  CC_x86_64-unknown-linux-musl = None
  cargo:rerun-if-env-changed=CC_x86_64_unknown_linux_musl
  CC_x86_64_unknown_linux_musl = None
  cargo:rerun-if-env-changed=TARGET_CC
  TARGET_CC = None
  cargo:rerun-if-env-changed=CC
  CC = None
  RUSTC_LINKER = None
  cargo:rerun-if-env-changed=CROSS_COMPILE
  CROSS_COMPILE = None
  cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
  CRATE_CC_NO_DEFAULTS = None
  DEBUG = Some("false")
  CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
  cargo:rerun-if-env-changed=CFLAGS_x86_64-unknown-linux-musl
  CFLAGS_x86_64-unknown-linux-musl = None
  cargo:rerun-if-env-changed=CFLAGS_x86_64_unknown_linux_musl
  CFLAGS_x86_64_unknown_linux_musl = None
  cargo:rerun-if-env-changed=TARGET_CFLAGS
  TARGET_CFLAGS = None
  cargo:rerun-if-env-changed=CFLAGS
  CFLAGS = None
  running: "musl-gcc" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-m64" "-I" "/home/hzhzhzh/Development/Test/rusb/target/x86_64-unknown-linux-musl/release/build/libusb1-sys-7d8a010aa27512a4/out/include" "-I" "libusb/libusb" "-I" "/usr/lib/x86_64-linux-musl/usr/include" "-Wall" "-Wextra" "-DPRINTF_FORMAT(a, b)=" "-DENABLE_LOGGING=1" "-DOS_LINUX=1" "-DHAVE_ASM_TYPES_H=1" "-D_GNU_SOURCE=1" "-DHAVE_TIMERFD=1" "-DHAVE_EVENTFD=1" "-DHAVE_SYS_TIME_H=1" "-DHAVE_NFDS_T=1" "-DPLATFORM_POSIX=1" "-DHAVE_CLOCK_GETTIME=1" "-DDEFAULT_VISIBILITY=__attribute__((visibility(\"default\")))" "-DUSE_UDEV=1" "-DHAVE_LIBUDEV=1" "-o" "/home/hzhzhzh/Development/Test/rusb/target/x86_64-unknown-linux-musl/release/build/libusb1-sys-7d8a010aa27512a4/out/libusb/libusb/os/linux_netlink.o" "-c" "libusb/libusb/os/linux_netlink.c"
  cargo:warning=In file included from libusb/libusb/os/linux_netlink.c:25:

  cargo:warning=libusb/libusb/os/linux_usbfs.h:24:10: fatal error: linux/magic.h: 没有那个文件或目录

  cargo:warning=   24 | #include <linux/magic.h>

  cargo:warning=      |          ^~~~~~~~~~~~~~~

  cargo:warning=compilation terminated.

  exit status: 1

  --- stderr


  error occurred: Command "musl-gcc" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-m64" "-I" "/home/hzhzhzh/Development/Test/rusb/target/x86_64-unknown-linux-musl/release/build/libusb1-sys-7d8a010aa27512a4/out/include" "-I" "libusb/libusb" "-I" "/usr/lib/x86_64-linux-musl/usr/include" "-Wall" "-Wextra" "-DPRINTF_FORMAT(a, b)=" "-DENABLE_LOGGING=1" "-DOS_LINUX=1" "-DHAVE_ASM_TYPES_H=1" "-D_GNU_SOURCE=1" "-DHAVE_TIMERFD=1" "-DHAVE_EVENTFD=1" "-DHAVE_SYS_TIME_H=1" "-DHAVE_NFDS_T=1" "-DPLATFORM_POSIX=1" "-DHAVE_CLOCK_GETTIME=1" "-DDEFAULT_VISIBILITY=__attribute__((visibility(\"default\")))" "-DUSE_UDEV=1" "-DHAVE_LIBUDEV=1" "-o" "/home/hzhzhzh/Development/Test/rusb/target/x86_64-unknown-linux-musl/release/build/libusb1-sys-7d8a010aa27512a4/out/libusb/libusb/os/linux_netlink.o" "-c" "libusb/libusb/os/linux_netlink.c" with args "musl-gcc" did not execute successfully (status code exit status: 1).

What am I going to do?

I want to compile an application that does not contain any dynamic libraries

My Action Log

  1. If the following results are configured
rusb = { version = "0.9.2"}

Successfully compiled!
But ldd cmd

 linux-vdso.so.1 (0x00007ffe463d8000)
  libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007fd2e1d9c000)
  libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd2e1d82000)
  libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd2e1d60000)
  libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd2e1d5a000)
  libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd2e1b86000)
  /lib64/ld-linux-x86-64.so.2 (0x00007fd2e1e4e000)

My expected outcome is

ldd cmd

statically linked
@a1ien
Copy link
Owner

a1ien commented Aug 5, 2023

This not that easy. You need at least compile libudev statically. And solve some other problem

@a1ien
Copy link
Owner

a1ien commented Aug 5, 2023

For linux/magic.h you need linux-headers

@cosoc
Copy link
Author

cosoc commented Aug 5, 2023

For linux/magic.h you need linux-headers

All necessary dependency packages have been installed

apt install libusb–dev libudev–dev linux-headers-$ (uname -r)

rusb = { version = "0.9.2"}
Can smoothly compile

rusb = { version = "0.9.2",features = ["vendored"]}
Header file not found

@a1ien
Copy link
Owner

a1ien commented Aug 6, 2023

All problems lie in the use of musl. As I said earlier, building under musl is not such an easy task. You need to properly prepare the build environment. And standard packages will not suit you.
You can find similar problem
openssl/openssl#7207
https://www.openwall.com/lists/musl/2017/11/23/1

Another option is to try to find a way to build libusb-1.0 under musl. I tried searching but didn't find any success story.

@a1ien a1ien closed this as completed Apr 27, 2024
@hax0rbana-adam
Copy link

Solved (partially?)

The answer is to create symlinks in /usr/lib/$ARCH-linux-musl/ that point to the files you need from /usr/include/

For example:

sudo ln -s /usr/include/linux /usr/include/x86_64-linux-musl
sudo ln -s /usr/include/asm-generic /usr/include/x86_64-linux-musl/asm
sudo ln -s /usr/include/asm-generic /usr/include/x86_64-linux-musl/asm-generic

After doing this, you will be able to compile using cargo with --target x86_64-unknown-linux-musl

Here's an example from the rayhunter project:

$ cargo build --bin serial --target x86_64-unknown-linux-musl --release
   Compiling libusb1-sys v0.6.4
   Compiling rusb v0.9.3
   Compiling serial v0.1.0 (/home/user/rayhunter/serial)
    Finished `release` profile [optimized] target(s) in 2.00s
$ ldd target/x86_64-unknown-linux-musl/release/serial
	statically linked

A hat tip to both @cosoc and @a1ien for their comments. 🙏 It helped me make progress towards solving a mostly-unrelated issue over here: EFForg/rayhunter#93

Now that the rust code compiles statically, I just have to figure out why the program fails to initialize libusb... Doh! My best guess is that because libusb depends on libudev, we need to compile libudev statically with musl, then manually compile libusb in the same manner, and then we can get cargo to statically link in the resulting libusb file.

Maybe a rust developer will be able to take a look at this and build on my work, just as I built on those earlier in this thread?

How I tracked it down

I'm including this section to help others understand how I figured out how to solve the missing headers issue. No need to read it if you just want to know the conclusion (posted in the section above).

I found it helpful to attempt to compile libusb with musl-gcc outside of rust.

sudo apt-get install musl-tools dh-autoreconf libudev-dev
git clone https://github.com/libusb/libusb.git
cd libusb
./autogen.sh
./configure CC=musl-gcc

This results in an error: configure: error: udev support requested but libudev header not installed

However, the header file is in the location where I would expect it...

$ ls /usr/include/libudev.h
/usr/include/libudev.h

Running ./configure CC=gcc works fine, which reinforces what @a1ien was saying, that this is a problem related to musl-gcc not looking in the correct places for the headers (e.g. preparing the build environment). Looking at the man page for musl-gcc has something interesting in the FILES section:

FILES
       /usr/lib/$ARCH-linux-musl/musl-gcc.specs musl-gcc spec file that defines new/overwritten include paths.

Creating symlinks between where musl-gcc is looking and where the files actually live resolved the problem with the cargo build.

It also resolved the immediate problem with ./configure and the next error (configure: error: udev support requested but libudev not installed) was solved by symlinking the relevant .so file, like so:

$ sudo ln -s /usr/lib/x86_64-linux-gnu/libudev.so /usr/lib/x86_64-linux-musl
$ sudo ln -s /usr/lib/x86_64-linux-gnu/libudev.so.1 /usr/lib/x86_64-linux-musl
$ sudo ln -s /usr/lib/x86_64-linux-gnu/libudev.so.1.7.10 /usr/lib/x86_64-linux-musl

In retrospect, linking to this dynamically linked .so file is probably the mistake that is causing the library to fail to load in the statically compiled rust program.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants