是否可以使用ocamlopt ghc和gcc编译器创建可移植的x86-64 Linux可执行文件?

问题描述 投票:1回答:1

在我的NixOS x86-64发行版上,我确定了四个“ hello world!”应用程序使用:

  • ocamlopt编译器
  • ghc编译器
  • gcc编译器
  • 作为编译器

我的makefile:

  ocaml:
    ocamlopt mytest.ml -o ocaml_test

  haskell:
    ghc mytest.hs -o haskell_test

  ansiC:
    gcc mytest.c -o ansiC_test 

  asm:
    as -o asm_test.o mytest.s 
    ld -s -o asm_test asm_test.o

并且所有四个在本机上都可以正常工作

但是我无法在其他x86-64 Linux(准确地说是Lubuntu x86-64)计算机上执行前三个应用程序-我的应用程序无法在目标计算机上找到系统库,因此系统告诉我该文件不存在

但是该文件存在,我可以通过readelf utilite读取它:


为gcc创建的可执行文件:

$> readelf -l ansiC_test 

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

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x0000000000000268 0x0000000000000268  R      0x8
  INTERP         0x00000000000002a8 0x00000000004002a8 0x00000000004002a8
                 0x0000000000000050 0x0000000000000050  R      0x1
      [Requesting program interpreter: /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000004f0 0x00000000000004f0  R      0x1000

$> ldd ansiC_test 
  linux-vdso.so.1 (0x00007ffee735f000)
  libc.so.6 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libc.so.6 (0x00007f8db6ca8000)
  /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2 => /nix/store/xvj2l5llpmcgx99cl37v5xqpazs38195-glibc-multi-2.27/lib/ld-linux-x86-64.so.2 (0x00007f8db6e60000)

为ghc创建的可执行文件:

$> readelf -l haskell_test

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

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x0000000000000268 0x0000000000000268  R      0x8
  INTERP         0x00000000000002a8 0x00000000004002a8 0x00000000004002a8
                 0x0000000000000050 0x0000000000000050  R      0x1
      [Requesting program interpreter: /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000

$> ldd haskell_test 
  linux-vdso.so.1 (0x00007ffe7840a000)
  libm.so.6 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libm.so.6 (0x00007f13eb093000)
  libgmp.so.10 => /nix/store/7mrq5v4nnqfkv1ka7a0kdw9mzvqs5w3c-gmp-6.1.2/lib/libgmp.so.10 (0x00007f13eaffd000)
  librt.so.1 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/librt.so.1 (0x00007f13eaff3000)
  libdl.so.2 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libdl.so.2 (0x00007f13eafee000)
  libffi.so.6 => /nix/store/kbbiky87bsdndh63m7919sxkf3gsh5zq-libffi-3.2.1/lib/libffi.so.6 (0x00007f13eafe1000)
  libpthread.so.0 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libpthread.so.0 (0x00007f13eafbe000)
  libc.so.6 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libc.so.6 (0x00007f13eae08000)
  /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2 => /nix/store/xvj2l5llpmcgx99cl37v5xqpazs38195-glibc-multi-2.27/lib/ld-linux-x86-64.so.2 (0x00007f13eb22b000)

对于ocamlopt创建的可执行文件:

$> readelf -l ocaml_test

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

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x0000000000000268 0x0000000000000268  R      0x8
  INTERP         0x00000000000002a8 0x00000000004002a8 0x00000000004002a8
                 0x0000000000000050 0x0000000000000050  R      0x1
      [Requesting program interpreter: /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x000000000000fb58 0x000000000000fb58  R      0x1000
$> ldd ocaml_test 
  linux-vdso.so.1 (0x00007ffc90657000)
  libm.so.6 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libm.so.6 (0x00007f1b01f0b000)
  libdl.so.2 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libdl.so.2 (0x00007f1b01f06000)
  libc.so.6 => /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libc.so.6 (0x00007f1b01d50000)
  /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/ld-linux-x86-64.so.2 => /nix/store/xvj2l5llpmcgx99cl37v5xqpazs38195-glibc-multi-2.27/lib/ld-linux-x86-64.so.2 (0x00007f1b020a3000)

而且我没有用汇编程序创建的可执行文件这个问题:

$> readelf -l asm_test

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

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x0000000000000140 0x0000000000000140  R      0x1000
  LOAD           0x0000000000001000 0x0000000000401000 0x0000000000401000
                 0x0000000000000022 0x0000000000000022  R E    0x1000
  LOAD           0x0000000000002000 0x0000000000402000 0x0000000000402000
                 0x000000000000000e 0x000000000000000e  RW     0x1000
  NOTE           0x0000000000000120 0x0000000000400120 0x0000000000400120
                 0x0000000000000020 0x0000000000000020  R      0x8

 Section to Segment mapping:
  Segment Sections...
   00     .note.gnu.property
   01     .text
   02     .data
   03     .note.gnu.property


$> ldd asm_test
  not a dynamic executable

如您所见,没有对ld-linux-x86-64.so.2库的引用


我的问题是:是否可以使用gcc,ghc和ocamlopt创建这样的“非动态可执行文件”应用程序文件?一些编译器的选项?也许应用程序文件夹中有一些库?

我无权访问另一台机器-我只能将tar.gz存档提供给最终用户-仅此而已。绝对不希望用户在自己的计算机上安装ghc或ocaml

有什么建议吗?

仅供参考:src文件


haskell:

module Main where

main = putStrLn "hello world!"

ocaml:

print_string "hello world!" ;;
print_newline () ;;

ansi C:

#include <stdio.h>

int
main ()
{
  puts ("hello world!") ;
}

asm:

.code64
.global _start 

.text 

_start:
          movl    $len, %edx
          movl    $msg, %ecx
          movl    $1, %ebx 
          movl    $4, %eax 
          int     $0x80   

          movl    $0, %ebx       
          movl    $1, %eax      
          int     $0x80        

.data     

         msg: .ascii    "hello, world!\n"
         len = . - msg 
haskell ocaml executable portability
1个回答
0
投票

我自己还没有测试过,但是我认为-ccoptfrom ocamlopt)和ocamlopt-static)的组合将达到目的。

gcc
  • 摘自ocamlopt手册
-ccopt option
    Pass the given option to the C compiler and linker. For instance,-ccopt -Ldir causes the C linker to search for C libraries in directory dir. 

© www.soinside.com 2019 - 2024. All rights reserved.