标签: musl

在cmake项目中使用替代libc

我有一个使用CMake构建的C / C ++项目。在尝试编译静态二进制文件时,我GLIBC在计算机和目标计算机上遇到了不同版本的问题。在关于SO的另一个问题中,对类似问题的公认答案是使用libc的替代实现,例如musluClibc。(请参阅此处

我找不到有关如何指向cmake使用此类替代libc的任何信息。FindMusl.cmake文件既没有寄出,也无法在互联网上找到。简单使用CC=/usr/bin/musl-gcc是行不通的。

如何将我的cmake项目与此类替代libc实现静态链接,使其独立于GLIBC?

c++ cmake libc uclibc musl

6
推荐指数
1
解决办法
2272
查看次数

如何使用本机依赖项编译Rust项目的静态musl二进制文件?

我有一个依赖于Hyper和Diesel的项目,因此,在本机库OpenSSL和libpq上.该项目建立在每晚Rust上,因为它使用编译器插件.

我目前的尝试是建立在Docker容器上.我有MUSL libc和库make'd并安装了前缀/usr/local/musl.我cargo使用以下命令运行:(不确定某些选项是否冗余,我不太熟悉编译器链,甚至不确定它们是否最终到链接器,但我必须尝试,对.)

LDFLAGS="-static -L/usr/local/musl/lib" \
LD_LIBRARY_PATH=/usr/local/musl/lib:$LD_LIBRARY_PATH \
CFLAGS="-I/usr/local/musl/include" \
PKG_CONFIG_PATH=/usr/local/musl/lib/pkgconfig \
cargo build --release --target=x86_64-unknown-linux-musl
Run Code Online (Sandbox Code Playgroud)

当我ldd得到的文件,它揭示了这个:

$ ldd server
linux-vdso.so.1 (0x00007fffb878e000)
libpq.so.5 => /usr/local/musl/lib/libpq.so.5 (0x00007f4d730e7000)
libssl.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007f4d72e82000)
libcrypto.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007f4d72a85000)
libc.so => /usr/local/musl/lib/libc.so (0x00007f4d727f6000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4d725f2000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4d72246000)
/lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x000055e2124a2000)
Run Code Online (Sandbox Code Playgroud)

有所有动态链接的东西,有些甚至与"x86_64-linux-gnu"链!什么地方出了错?

我可以毫无问题地制作静态链接,简单的纯Rust项目.ldd说它们是静态链接的,它们运行没有问题,不像我遇到问题的可执行文件.

当我使用--verbose与货物,我得到了下面rustc的命令,即实际编制的可执行文件:http://pastebin.com/ywv0zNBK(哎呀,这人有一个自定义的outdir-Z print-link-args,由我添加)添加print-link-args标志,我得到了下面的链接器命令:http://pastebin.com/Aw43qd7h

我如何得到 …

static-linking rust rust-cargo musl

6
推荐指数
2
解决办法
2770
查看次数

Alpine Linux 上的符号版本控制

musl C 库只有符号版本控制的近似实现。这可能导致具有不同符号版本的符号绑定在一起,这在完整实现中不会发生。因此,希望使用 musl 构建的项目最好完全避免符号版本控制。(不支持符号版本控制本身对于工具链来说不一定是一个糟糕的选择;这完全取决于目标受众。)

但是,Alpine Linux 工具链编译 binutils 时具有完整的符号版本支持:GAS 支持该.symver指令,链接编辑器处理版本脚本并分配符号版本(就像在 GNU/Linux 上一样)。一个简单的编译器/汇编器或链接检查显示符号版本支持。因此,Alpine Linux 在发行版中包含的一些共享对象实际上使用了符号版本控制,尽管 musl 动态加载器会忽略这些数据。(数据只会使二进制文件膨胀。)

在某些情况下,软件无法运行(在构建正常之后),因为它以 musl 动态链接器不支持的方式使用兼容性符号(没有默认版本的符号)。这是一个不起作用的小例子:

cat > symver.c <<EOF
void
compat_function (void)
{
}
__asm__ (".symver compat_function,compat_function@SYMVER");

void
call_compat_function (void)
{
  return compat_function ();
}
EOF

echo "SYMVER { };" > symver.map

cat > main.c <<EOF
extern void call_compat_function (void);

int
main (void)
{
  call_compat_function ();
}
EOF

gcc -fpic -shared -o symver.so -Wl,--version-script=symver.map symver.c
gcc -Wl,--rpath=. -o main …
Run Code Online (Sandbox Code Playgroud)

binutils musl alpine-linux

6
推荐指数
0
解决办法
211
查看次数

如何实际检测 musl libc?

musl 团队声称不需要检测 musl libc 的方法,因为他们只实现标准功能并且没有需要检测的怪癖。

直到今天,这种说法很可能是正确的,但它不再是正确的。正常功能检测不起作用,因为该功能存在但已损坏,我宁愿不对其进行探测,因为我不想在编译时要求 root 并禁止交叉编译。该错误已通过最小化示例代码报告,维护人员根本不想修复它,也不会接受我的补丁。

我不会惩罚所有其他 libc,因为 musl 有一个损坏的功能。

从逻辑上讲我想做

#if MUSL || APPLE
    pid = fork();
#else
    pid = vfork();
#endif
Run Code Online (Sandbox Code Playgroud)

我已经有了,#if APPLE因为 Mac OSX 有一个不值得信赖的vfork().

说我vfork()不好是没有意义的。自 2008 年以来,情况发生了变化vfork(),无论涉及的复杂性如何,只要有可能,这都是更好的选择。一些来源:https : //gist.github.com/nicowilliams/a8a07b0fc75df05f684c23c18d7db234

c portability musl

6
推荐指数
2
解决办法
2518
查看次数

为 linux-musl-arm 编译 dotnet core 应用程序

我尝试使用以下命令在ARM Cortex A7上为OpenWRT编译一个简单的.NET Core hello world 应用程序:linux-musl-arm

dotnet publish --configuration Release --runtime linux-musl-arm --self-contained
Run Code Online (Sandbox Code Playgroud)

但是当我尝试执行它时出现以下错误:

root@Routeur:~/RutxApp# ./RutxApp
Error relocating ./RutxApp: _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED2Ev: symbol not found
Error relocating ./RutxApp: _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_createERjj: symbol not found
Error relocating ./RutxApp: _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_assignERKS4_: symbol not found
Error relocating ./RutxApp: _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_replaceEjjPKcj: symbol not found
Error relocating ./RutxApp: _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEjjPKcj: symbol not found
Error relocating ./RutxApp: _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_appendEPKcj: symbol not found
Error relocating ./RutxApp: _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEPKcjj: symbol not found
Error relocating ./RutxApp: _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEcj: symbol not found
Error relocating …
Run Code Online (Sandbox Code Playgroud)

c# arm openwrt musl .net-core

6
推荐指数
1
解决办法
1770
查看次数

如何将 Nix 包中的 libc 覆盖为 musl?

我使用 Nix 作为 Rust 程序的依赖管理器。我有以下 default.nix (简化,但有效):

rec {
  pkgs = import <nixpkgs> {};

  hello = pkgs.stdenv.mkDerivation rec {
    name = "rust-hello";

    buildInputs = [
      pkgs.rustc
    ];

    src = ./source;

    buildPhase = "rustc main.rs -o rust-hello";
    installPhase = ''
      mkdir -p $out/bin
      install -s rust-hello $out/bin
    '';
  };
}
Run Code Online (Sandbox Code Playgroud)

我试图将所有依赖项(包括 Rust 编译器)的 libc 覆盖为 pkg.musl,但我没有这样做。如何才能实现这一目标?

rust musl nix

5
推荐指数
1
解决办法
2514
查看次数

GCC 正在生成填充零的二进制文件

我试图弄清楚为什么 GCC 生成的二进制文件如此之大。

考虑这个空程序:

int main() {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在我使用GCC 9.2.1 20190827 (Red Hat 9.2.1-1)glibc 2.29构建它,没有任何附加参数:

gcc -o test test.c

生成的二进制文件为 21984 字节 (~22 KB)。查看使用 生成的文件xxd,在多个地方有大量的空字节:

00000370: 006c 6962 632e 736f 2e36 005f 5f6c 6962  .libc.so.6.__lib
00000380: 635f 7374 6172 745f 6d61 696e 0047 4c49  c_start_main.GLI
00000390: 4243 5f32 2e32 2e35 005f 5f67 6d6f 6e5f  BC_2.2.5.__gmon_
000003a0: 7374 6172 745f 5f00 0000 0200 0000 0000  start__.........
000003b0: 0100 0100 0100 0000 1000 0000 …
Run Code Online (Sandbox Code Playgroud)

c gcc glibc uclibc musl

5
推荐指数
2
解决办法
263
查看次数

加载核心文件时,gdb 不会加载共享库符号,甚至不会加载 libc.so (musl)

我正在尝试调试在具有 MIPS cpu 的板上远程运行的程序,使用 musl 作为其 libc。如果我在板上启动 gdbserver,设置 sysroot viaset sysroot /path/to/sysroot并从 gdb 进行实时连接,我会得到有意义的堆栈跟踪(由于 musl 缺乏 MIPS 上的 CFI 指令,而我必须添加它们,因此需要花费数小时的时间,但这是一个单独的问题),我可以看到 gdb 从libc.sosysroot 加载符号。

另一方面,如果我让该程序崩溃并生成核心转储(我曾经kill -6 <pid>强制使用一个核心转储进行测试),gdb 将从二进制文件中加载符号,但不会加载其任何共享库,甚至不会加载libc.so. 虽然其他共享库很好但不是必需的,如果没有来自 libc.so 的调试信息,gdb 无法解析堆栈跟踪,并且它们看起来都像垃圾。

成功的实时 gdb 会话

$ mipsel-poky-linux-gdb -iex "set sysroot /path/to/sysroot" /path/to/testprog
GNU gdb (GDB) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute …
Run Code Online (Sandbox Code Playgroud)

linux debugging gdb mips musl

5
推荐指数
1
解决办法
4050
查看次数

Issues with time() when running a C musl application in docker container on arm

My application is unable to handle time operations like time(2) when it runs in alpine docker container on an arm device.

What I have: I am building a native c application which is statically linked to musl with toolchain from musl.cc (arm-linux-musleabihf-gcc). I am using latest alpine container (without image tag).

How it behaves:

  • Running binary directly on arm device works as expected
  • Running in alpine container on x64 device works as expected
  • Running in alpine container on arm device …

c arm docker musl alpine-linux

5
推荐指数
1
解决办法
627
查看次数

决定用 Java 构建 Linux 的 GNU 或 MUSL

我有一个 Java 桌面应用程序,应该可以在 GNU Linux 发行版(Debian 和 Ubuntu)和 MUSL Linux 发行版(Alpine)中运行。我的应用程序也使用本机库,并且两种类型的 Linux 发行版的本机库构建都不同。

我会将两者与我的申请放在不同的文件夹中。因此,在运行时,Java 程序需要根据 Linux(GNU 或 MUSL)选择正确的本地库发行版。

我没有找到任何机制来了解 Java 程序中运行的是哪个 Linux 发行版 JVM。

我正在考虑从 Linux 的 /etc/ 文件夹中读取操作系统文件的一种方法。但我认为这不是一个好的解决方案(因为某些自定义构建可能会更改此细节),有人可以为这个问题建议一些更好的解决方案吗?或者如何做到这一点?

java native glibc jna musl

5
推荐指数
1
解决办法
4087
查看次数

标签 统计

musl ×10

c ×3

alpine-linux ×2

arm ×2

glibc ×2

rust ×2

uclibc ×2

.net-core ×1

binutils ×1

c# ×1

c++ ×1

cmake ×1

debugging ×1

docker ×1

gcc ×1

gdb ×1

java ×1

jna ×1

libc ×1

linux ×1

mips ×1

native ×1

nix ×1

openwrt ×1

portability ×1

rust-cargo ×1

static-linking ×1