1

on my NixOS x86-64 distro i cerated four "hello world!" applications using:

  • ocamlopt compiler
  • ghc compiler
  • gcc compiler
  • as compiler

my 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

and all four work fine on the native machine

but i cannot execute the first three applications on the other x86-64 Linux (to be precise - Lubuntu x86-64) computer - my applications cannot find system libraries on the target machine, so the system tells me that file does not exist

but the file exists and i can read it by readelf utilite:


for gcc created executable:

$> 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)

for ghc created executable:

$> 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)

for ocamlopt created executable:

$> 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)

and i dont have this problem with asembler created executable:

$> 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

as you can see no referencies to glibc.so.x library


my question is: is it possible to create such "not a dynamic executable" application file with gcc, ghc and ocamlopt? some compiler's options? maybe some libs in the folder of application?

i dont have access to another machine - i can only provide tar.gz arhive to the end user - thats all. and absolutly no hope that the user will install ghc or ocaml on his/her machine

any suggestions?

FYI: src files


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 
Ston17
  • 115
  • 1
  • 7
  • 2
    Are you asking for a way to of creating a statically linked executable in any/all of those compilers? If so, have you checked their manuals? – norok2 May 28 '20 at 11:42
  • to be honest iam intrested only in ocamlopt. and yes - RTFM step has been done already – Ston17 May 28 '20 at 11:43
  • See https://www.systutorials.com/how-to-statically-link-ocaml-programs/ – Yawar May 28 '20 at 16:38

1 Answers1

1

I have not tested it myself, but I assume that the combination of -ccopt (from ocamlopt) and -static (from gcc) will do the trick.

  • from ocamlopt manual
-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. 
  • from gcc manual
-static
    On systems that support dynamic linking, this overrides -pie and prevents linking with the shared libraries. On other systems, this option has no effect.

norok2
  • 25,683
  • 4
  • 73
  • 99
  • $> gcc -static mytest.c /nix/store/0y7jmqnj48ikjh37n3dl9kqw9hnn68nq-binutils-2.31.1/bin/ld: cannot find -lc collect2: error: ld returned 1 exit status – Ston17 May 28 '20 at 12:15
  • i think that i should ask compiler to include all system calls into executable file but i dont know howto . and again - i have read manuals - all three (for gcc, for ocamlopt and for ghc) – Ston17 May 28 '20 at 12:18
  • @Ston17 Is there something broken on your system? If I run `gcc helloworld.c -static -o helloworld` with the file `helloworld.c` having the content you indicated for ANSI C, it works like a charm. – norok2 May 28 '20 at 12:18
  • $> gcc mytest.c -static -o hello /nix/store/0y7jmqnj48ikjh37n3dl9kqw9hnn68nq-binutils-2.31.1/bin/ld: cannot find -lc collect2: error: ld returned 1 exit status | yes - i use NixOS and this OS keeps system files in very unusiall way - maybe that is the reason – Ston17 May 28 '20 at 12:21
  • Can you try it on a virtual machine with a more popular OS (Debian, Ubuntu, Fedora, you name it)? If so, it may be a bug of NixOS. – norok2 May 28 '20 at 12:22
  • yes - you are right. i just tried it on Lubuntu and it produced for me static executable which can be run on my NixOS distro. but i dont interested in gcc and i cannot install OCaml on Lubuntu :( – Ston17 May 28 '20 at 12:32
  • 1
    @Ston17 Quite likely your system is lacking some `lib*.a` version of the libraries. I am not sure how to get this fixed in NixOS, though. – norok2 May 28 '20 at 12:52
  • dont think that lib is absent - i can create dynamically linked program. and yes - i am triing to ask this question to NixOS community . tnx for your cooperation – Ston17 May 28 '20 at 12:54
  • @Ston17 You may have the `.so` but not the `.a` – norok2 May 28 '20 at 12:55
  • yes - i have .so what the difference? can the presence of .a improve the situation? – Ston17 May 28 '20 at 12:56
  • 1
    Yes. You typically need `.a` library to have the static linking work correctly https://stackoverflow.com/questions/6578484/telling-gcc-directly-to-link-a-library-statically – norok2 May 28 '20 at 12:57
  • here https://vaibhavsagar.com/blog/2018/01/03/static-haskell-nix/ is explained how you could obtain in NixOS statical versions of sys libraries – Ston17 May 28 '20 at 20:04