gpt4 book ai didi

gcc - 如何在 NixOS 上生成静态可执行文件?

转载 作者:行者123 更新时间:2023-12-04 15:26:57 62 4
gpt4 key购买 nike

今天,我在使用 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)
无法产生静态 exec :
$> 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
有任何想法吗?
通常是“动态链接”程序 hellogcc 生成没有问题。
Lubuntu 上没有这样的问题。有人建议我尝试不同的发行版并测试 exec 在 NixOS 上运行。我做到了 - 用 gcc 生成了一个 exec在 Lubuntu 上并在 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.*
$>
这可能是原因吗?
更新2:关于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
有什么建议吗?

最佳答案

这里https://vaibhavsagar.com/blog/2018/01/03/static-haskell-nix/解释了如何在 NixOS 静态版本的 sys 库中获取

nix-shell 配置文件:

let
pkgs = import <nixpkgs> {} ;
in pkgs.buildFHSUserEnv {
name = "fhs" ;
targetPkgs = pkgs: with pkgs; [
pkgs.glibc.static
pkgs.zlib.static
pkgs.libffi
pkgs.libtool
pkgs.musl
pkgs.ghc
pkgs.gcc
pkgs.ocaml
] ;
}

之后在 nix-shell 中启动 chroot FHS 并将所需的 sys libs 复制到您的文件夹中并关闭 chroot FHS

然后静态编译你的文件

适合 gcc:
$> gcc -static -L/home/.local/lib/ mytest.c -o ansiC_test
$> ldd ansiC_test
not a dynamic executable

不太好,但可能与 ocaml 一起工作:
ocamlopt -ccopt -static -cclib -L/home/.local/lib mytest.ml -o ocaml_test

ocamlopt -ccopt -static -cclib -L/home/nomad/.local/lib mytest.ml -o ocaml_test
/nix/store/0y7jmqnj48ikjh37n3dl9kqw9hnn68nq-binutils-2.31.1/bin/ld: /nix/store/j1v6kkxq081q4m4fw7gazaf6rb3vy87p-ocaml-4.06.1/lib/ocaml/libasmrun.a(unix.o): in function `caml_dlopen':
/build/ocaml-4.06.1/asmrun/unix.c:273: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

$> ldd ocaml_test
not a dynamic executable

不过不要与 ghc 一起工作:
ghc -static -optl-static -L/home/.local/lib/ mytest.hs -o haskell_test
[1 of 1] Compiling Main ( mytest.hs, mytest.o )
Linking haskell_test ...
/nix/store/0y7jmqnj48ikjh37n3dl9kqw9hnn68nq-binutils-2.31.1/bin/ld: /nix/store/wfgrz42bpcl1r635dasfk7r236hm83az-ghc-8.6.4/lib/ghc-8.6.4/rts/libHSrts.a(Linker.o): in function `internal_dlopen':
Linker.c:(.text.internal_dlopen+0x7): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/nix/store/0y7jmqnj48ikjh37n3dl9kqw9hnn68nq-binutils-2.31.1/bin/ld: cannot find -lffi
collect2: error: ld returned 1 exit status
`cc' failed in phase `Linker'. (Exit code: 1)
make: *** [makefile:5: haskell] Error 1

好的。 ocaml 作品:
lubuntu@lubuntu:~/Documents$ ./ocaml_hello_nix 
hello world!

lubuntu@lubuntu:~/Documents$ readelf -l ocaml_hello_nix

Elf file type is EXEC (Executable file)
Entry point 0x4017a0
There are 9 program headers, starting at offset 64

Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000005d8 0x00000000000005d8 R 0x1000
LOAD 0x0000000000001000 0x0000000000401000 0x0000000000401000
0x0000000000107275 0x0000000000107275 R E 0x1000
LOAD 0x0000000000109000 0x0000000000509000 0x0000000000509000
0x00000000000db191 0x00000000000db191 R 0x1000
LOAD 0x00000000001e5140 0x00000000005e6140 0x00000000005e6140
0x0000000000008a18 0x000000000001dfe0 RW 0x1000
NOTE 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x0000000000000020 0x0000000000000020 R 0x4
NOTE 0x0000000000000258 0x0000000000400258 0x0000000000400258
0x0000000000000020 0x0000000000000020 R 0x8
TLS 0x00000000001e5140 0x00000000005e6140 0x00000000005e6140
0x0000000000000020 0x0000000000000060 R 0x8
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000

0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x00000000001e5140 0x00000000005e6140 0x00000000005e6140
0x0000000000002ec0 0x0000000000002ec0 R 0x1

Section to Segment mapping:
Segment Sections...
00 .note.ABI-tag .note.gnu.property .rela.plt
01 .init .plt .text __libc_freeres_fn __libc_thread_freeres_fn .fini
02 .rodata .eh_frame .gcc_except_table
03 .tdata .init_array .fini_array .data.rel.ro .got .got.plt .data __libc_subfreeres __libc_IO_vtables __libc_atexit __libc_thread_subfreeres .bss __libc_freeres_ptrs
04 .note.ABI-tag
05 .note.gnu.property
06 .tdata .tbss
07
08 .tdata .init_array .fini_array .data.rel.ro .got

haskell 工作。原因是二进制 NixOS 数据包是在没有 FFI 支持的情况下构建的。我从源代码安装了 ghc,一切都变得很好:
lubuntu@lubuntu:~/Documents$ ./haskell_hello_nix 
hello world!

lubuntu@lubuntu:~/Documents$ readelf -l haskell_hello_nix

Elf file type is EXEC (Executable file)
Entry point 0x405d40
There are 6 program headers, starting at offset 64

Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x0000000000188ba4 0x0000000000188ba4 R E 0x1000
LOAD 0x0000000000188ec0 0x0000000000589ec0 0x0000000000589ec0
0x00000000000104c0 0x000000000001ac98 RW 0x1000
NOTE 0x0000000000000190 0x0000000000400190 0x0000000000400190
0x0000000000000020 0x0000000000000020 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
TLS 0x0000000000188ec0 0x0000000000589ec0 0x0000000000589ec0
0x0000000000000070 0x00000000000000b8 R 0x8
GNU_RELRO 0x0000000000188ec0 0x0000000000589ec0 0x0000000000589ec0
0x0000000000003140 0x0000000000003140 RW 0x20

Section to Segment mapping:
Segment Sections...
00 .note.ABI-tag .rela.plt .init .plt .text __libc_thread_freeres_fn .fini .rodata .gcc_except_table .eh_frame
01 .tdata .data.rel.ro.local .fini_array .init_array .data.rel.ro .preinit_array .got .got.plt .data .tm_clone_table __libc_IO_vtables __libc_atexit __libc_thread_subfreeres .bss __libc_freeres_ptrs
02 .note.ABI-tag
03
04 .tdata .tbss
05 .tdata .data.rel.ro.local .fini_array .init_array .data.rel.ro .preinit_array .got

好的。 tnx 所有关心的人。你省了我的a$$

关于gcc - 如何在 NixOS 上生成静态可执行文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62065592/

62 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com