v
v copied to clipboard
Unclear how to compile a static binary
Describe the bug
The V website claims that "You get a single statically linked binary". However, by default the compiler produces a dynamic binary, and there seems to be no way to produce a working static binary.
Reproduction Steps
Compile any code with V. Result is a dynamically linked binary.
Expected Behavior
Expected V to produce a statically linked binary.
Current Behavior
Compiling without any additional flags produces a dynamic binary:
$ cat hello.v
fn main() {
println("hello world")
}
$ v hello.v
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, not stripped
Compiling with musl-gcc as suggested in https://github.com/vlang/v/discussions/19792#discussioncomment-7510933 does not work because pthreads fail to link:
$ v -cc musl-gcc -cg hello.v
/usr/bin/ld: /home/justinas/vlang-box/compiler/thirdparty/tcc/lib/libgc.a(gc.o): in function `open_proc_fd':
gc.c:(.text+0x13a7): undefined reference to `__snprintf_chk'
/usr/bin/ld: gc.c:(.text+0x13ba): undefined reference to `__open_2'
/usr/bin/ld: /home/justinas/vlang-box/compiler/thirdparty/tcc/lib/libgc.a(gc.o): in function `GC_fault_handler':
gc.c:(.text+0x14aa): undefined reference to `__longjmp_chk'
/usr/bin/ld: /home/justinas/vlang-box/compiler/thirdparty/tcc/lib/libgc.a(gc.o): in function `GC_with_callee_saves_pushed':
gc.c:(.text+0x2f2c): undefined reference to `getcontext'
/usr/bin/ld: /home/justinas/vlang-box/compiler/thirdparty/tcc/lib/libgc.a(gc.o): in function `GC_printf':
gc.c:(.text+0x420a): undefined reference to `__vsnprintf_chk'
/usr/bin/ld: /home/justinas/vlang-box/compiler/thirdparty/tcc/lib/libgc.a(gc.o): in function `GC_log_printf':
gc.c:(.text+0x4867): undefined reference to `__vsnprintf_chk'
/usr/bin/ld: /home/justinas/vlang-box/compiler/thirdparty/tcc/lib/libgc.a(gc.o): in function `GC_err_printf':
gc.c:(.text+0x79f4): undefined reference to `__vsnprintf_chk'
/usr/bin/ld: /home/justinas/vlang-box/compiler/thirdparty/tcc/lib/libgc.a(gc.o): in function `GC_print_callers':
gc.c:(.text+0x7c54): undefined reference to `__snprintf_chk'
/usr/bin/ld: gc.c:(.text+0x7cef): undefined reference to `__snprintf_chk'
/usr/bin/ld: gc.c:(.text+0x7d36): undefined reference to `__memcpy_chk'
/usr/bin/ld: gc.c:(.text+0x7e64): undefined reference to `__snprintf_chk'
/usr/bin/ld: /home/justinas/vlang-box/compiler/thirdparty/tcc/lib/libgc.a(gc.o): in function `GC_print_all_errors.part.0':
gc.c:(.text+0x826e): undefined reference to `__memcpy_chk'
/usr/bin/ld: gc.c:(.text+0x828a): undefined reference to `__memset_chk'
/usr/bin/ld: /home/justinas/vlang-box/compiler/thirdparty/tcc/lib/libgc.a(gc.o): in function `GC_init':
gc.c:(.text+0xf53e): undefined reference to `gnu_get_libc_version'
/usr/bin/ld: /home/justinas/vlang-box/compiler/thirdparty/tcc/lib/libgc.a(pthread_start.o): in function `GC_pthread_start_inner':
pthread_start.c:(.text+0x82): undefined reference to `__pthread_register_cancel'
/usr/bin/ld: pthread_start.c:(.text+0xa9): undefined reference to `__pthread_unregister_cancel'
collect2: error: ld returned 1 exit status
builder error:
==================
C error found. It should never happen, when compiling pure V code.
This is a V compiler bug, please report it using `v bug file.v`,
or goto https://github.com/vlang/v/issues/new/choose .
You can also use #help on Discord: https://discord.gg/vlang .
Compiling with -freestanding
as suggested by a Stack Overflow answer does produce a static binary, but it also makes V not link the C standard library at all (statically or dynamically). Since basic functionality of V depends on libc, this means that even basic code does not work out of the box in this mode:
$ cat array.v
fn main() {
mut foo := [1, 2, 3]
foo.sort()
println(foo)
}
$ v -freestanding array.v
$ file array
array: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=19986c1fa887f421581deb1982106b06a5a33ee6, not stripped
$ ./array
V panicsort does not work with -freestanding
Possible Solution
V should either:
- Output static binaries by default, since that is the claim on the front page.
- Provide a dedicated, well documented flag that would link the resulting binary statically instead of dynamically, e.g.
v -static
. V shouldn't lose basic functionality when the code is compiled this way.
Additional Information/Context
No response
V version
V 0.4.6 4a7c70c
Environment details (OS name and version, etc.)
$ v doctor
V full version: V 0.4.6 4a7c70c
OS: linux, Linux version 6.6.33 (nixbld@localhost) (gcc (GCC) 13.2.0, GNU ld (GNU Binutils) 2.41) #1-NixOS SMP PREEMPT_DYNAMIC Wed Jun 12 09:13:03 UTC 2024 (chroot)
Processor: 16 cpus, 64bit, little endian, AMD Ryzen 7 PRO 4750U with Radeon Graphics
getwd: /home/justinas/vlang-testcases
vexe: /home/justinas/vlang-box/compiler/v
vexe mtime: 2024-06-28 20:18:31
vroot: OK, value: /home/justinas/vlang-box/compiler
VMODULES: OK, value: /home/justinas/.vmodules
VTMP: OK, value: /tmp/v_1000
Git version: git version 2.43.0
Git vroot status: weekly.2024.26-14-g4a7c70c9 (3 commit(s) behind V master)
.git/config present: true
CC version: cc (Ubuntu 13.2.0-23ubuntu4) 13.2.0
thirdparty/tcc status: thirdparty-linux-amd64 40e5cbb5
[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.