【发布时间】:2020-11-15 00:21:21
【问题描述】:
今天我的 NixOS 发行版遇到了一个非常有趣的问题。我只是想创建一个静态编译的 OCaml 程序,但做不到。然后我尝试使用 ANSI C 规范玩具“hello world!”来做到这一点。应用:
$> cat mytest.c
#include <stdio.h>
int
main ()
{
puts ("hello world!") ;
}
我的发行版:
$> uname -a
Linux cat 4.19.36 #1-NixOS SMP Sat Apr 20 07:16:05 UTC 2019 x86_64 GNU/Linux
编译器:
$> gcc -v
Using built-in specs.
COLLECT_GCC=/nix/store/myq0x6mjbdzxr9fckqn6kgy89kz19nkp-gfortran-7.4.0/bin/gcc
COLLECT_LTO_WRAPPER=/nix/store/myq0x6mjbdzxr9fckqn6kgy89kz19nkp-gfortran-7.4.0/libexec/gcc/x86_64-unknown-linux-gnu/7.4.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with:
Thread model: posix
gcc version 7.4.0 (GCC)
无法产生静态执行:
$> gcc -static mytest.c -o hello
/nix/store/0y7jmqnj48ikjh37n3dl9kqw9hnn68nq-binutils-2.31.1/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
有什么想法吗?
通常由gcc生成“动态链接”程序hello没有问题。
在 Lubuntu 上没有此类问题。有人建议我尝试不同的发行版并测试 exec 在 NixOS 上运行。我做到了——在 Lubuntu 上用gcc 生成了一个 exec,并在 NixOS 上启动了它。因此我认为问题不在于gcc,而在于 NixOS。
NixOS 如何处理这个问题(即生成静态编译的 exec 文件)?
当然,我也对ocamlopt 编译器而不是gcc 的结果感兴趣,但我认为这个问题对于所有编译器都很常见(顺便说一下,我也尝试过 Haskell ghc结果相同)。
brgs
更新:来自另一个线程的讨论:
1 @Ston17 You may have the .so but not the .a – norok2
2
3 yes - i have .so what the difference? can the presence of .a improve the situation? – Ston17
4
5 Yes. You typically need .a library to have the static linking work correctly – norok2
$> find /nix/store/ -name *libc.a.*
$>
可能是这个原因吗?
UPDATE2:关于 ocamlopt:
源文件
$> cat mytest.ml
print_string "hello world!" ;;
print_newline () ;;
你可以看到没有对任何东西的特殊调用。让我们尝试做静态执行:
$> ocamlopt -ccopt -static mytest.ml -o ocaml_test
/nix/store/0y7jmqnj48ikjh37n3dl9kqw9hnn68nq-binutils-2.31.1/bin/ld: cannot find -lm
/nix/store/0y7jmqnj48ikjh37n3dl9kqw9hnn68nq-binutils-2.31.1/bin/ld: cannot find -ldl
/nix/store/0y7jmqnj48ikjh37n3dl9kqw9hnn68nq-binutils-2.31.1/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
所以 ld 只是无法链接到 libc 的静态版本。我在孔系统中找不到 libc.a
有什么建议吗?
【问题讨论】:
-
你可以在 nix-shell 中尝试:
$ nix-shell -p glibc.static。适用于 GCC,但我不了解 Ocaml。 -
tnx - 这对我帮助很大