vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.69k stars 2.15k forks source link

Default compiler cc not detected during compilation #22240

Open lcheylus opened 3 days ago

lcheylus commented 3 days ago

Describe the bug

When using cc as compiler, it's not detected during compilation using Conditional compilation/Compile time code.

$ cc -v
OpenBSD clang version 16.0.6
Target: amd64-unknown-openbsd7.6
Thread model: posix
InstalledDir: /usr/bin

$ /v -cc cc run ~/tmp/get_compiler.v
different compiler

Reproduction Steps

Expected Behavior

cc compiler detected for tcc, clang and gcc

$ cc -v
OpenBSD clang version 16.0.6
Target: amd64-unknown-openbsd7.6
Thread model: posix
InstalledDir: /usr/bin

$ ./v -cc cc run get_compiler.v
clang

Current Behavior

On OpenBSD/amd64:

$ ./v run ~/tmp/get_compiler.v
tcc
(tcc = default compiler)

$ clang -v
OpenBSD clang version 16.0.6
(...)
$ ./v -cc clang run ~/tmp/get_compiler.v
clang

$ egcc -v
(...)
gcc version 11.2.0 (GCC)
$ ./v -cc egcc run ~/tmp/get_compiler.v
gcc

On Linux Debian/amd64, if I copy thirdparty/tcc/tcc.exe as /tmp/cc, compiler /tmp/cc not detected

$ cp thirdparty/tcc/tcc.exe /tmp/cc
$ ./v -cc /tmp/cc run ~/tmp/get_compiler.v
Compilation with unknown C compiler `cc`
different compiler

Possible Solution

Modify code in vlib/v/builder/cc.v to detect compiler in every case, especially for cc.

Additional Information/Context

No response

V version

V 0.4.7 5f495e2

Environment details (OS name and version, etc.)

V full version: V 0.4.7 acf6b34.5f495e2 OS: openbsd, 7.6, GENERIC.MP#312 Processor: 2 cpus, 64bit, little endian

getwd: /home/fox/dev/vlang.git vexe: /home/fox/dev/vlang.git/v vexe mtime: 2024-09-17 07:14:24

vroot: OK, value: /home/fox/dev/vlang.git VMODULES: OK, value: /home/fox/.vmodules VTMP: OK, value: /tmp/v_1000

Git version: git version 2.46.0 Git vroot status: weekly.2024.37-11-g5f495e23 .git/config present: true

CC version: OpenBSD clang version 16.0.6 thirdparty/tcc status: thirdparty-openbsd-amd64 8205cc59

[!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.

lcheylus commented 3 days ago

I propose to modify some code in vlib/v/builder/cc.v, function setup_ccompiler_options line 187 and beyond (https://github.com/vlang/v/blob/master/vlib/v/builder/cc.v#L187): create a specific function to detect compiler for every case and set ccoptions.cc variable.

Do you agree?

spytheman commented 3 days ago

The problem, is that if we do not know the name of the compiler, we do not know the available options. tcc, clang, and gcc do happen to all support a --version flag, but we can not be sure if that is the case for any cc (although it is likely, since cc is usually a symlink to one of those, and most unix compilers do support a version flag).

lcheylus commented 3 days ago

After some debug on OpenBSD/amd64 with clang as cc, my issue is not in compiler detection (code in vlib/v/builder/cc.v).

It seems that the root cause is in C generation => the generated main__main C function is wrong for my get_compiler.v code (see above).

Transpile C code with compiler = cc (Clang 16 on OpenBSD)

$ ll $(which cc)
-r-xr-xr-x  6 root  bin  101256712 Sep  7 08:09 /usr/bin/cc

$ cc --version
OpenBSD clang version 16.0.6
Target: amd64-unknown-openbsd7.6
Thread model: posix
InstalledDir: /usr/bin

$ ./v -cc cc -cg -showcc -keepc -o /tmp/get_compiler ~/tmp/get_compiler.v
> C compiler cmd: 'cc' '@/tmp/v_1000/get_compiler.tmp.c.rsp'
> C compiler response file "/tmp/v_1000/get_compiler.tmp.c.rsp":
  -g -O0 "/home/fox/.vmodules/cache/9c/9c240fe0481bca0aea2fd3ad9c3d3956.module.builtin.o" -o "/tmp/get_compiler" -D GC_BUILTIN_ATOMIC=1 -D GC_THREADS=1 -I "/home/fox/dev/vlang.git/thirdparty/libgc/include" "/tmp/v_1000/get_compiler.tmp.c" -std=c99 -D_DEFAULT_SOURCE -rdynamic -lpthread

$ /tmp/get_compiler
different compiler => **NOK**

Error in C generation => function main__main (/tmp/v_1000/get_compiler.tmp.c). Case for if defined(__clang__) is void !

void main__main(void) {
        #if defined(__TINYC__)
        {
        }
        #elif defined(__clang__)
        {
        }
        #elif defined(__V_GCC__)
        {
                println(_SLIT("gcc"));
                _v_exit(0);
                VUNREACHABLE();
        }
        #endif
        println(_SLIT("different compiler"));
}
lcheylus commented 2 days ago

Same issue with Clang v16 on Linux/amd64

$ cc --version
Debian clang version 16.0.6 (27+b1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

$ ./v -cc cc -cg -showcc -keepc -o /tmp/get_compiler ~/tmp/get_compiler.v
> C compiler cmd: 'cc' '@/tmp/v_1000/get_compiler.tmp.c.rsp'
> C compiler response file "/tmp/v_1000/get_compiler.tmp.c.rsp":
  -fwrapv -g -O0 -o "/tmp/get_compiler" -D GC_BUILTIN_ATOMIC=1 -D GC_THREADS=1 -I "/home/fox/dev/vlang.git/thirdparty/libgc/include" "/tmp/v_1000/get_compiler.tmp.c" -std=gnu99 -D_DEFAULT_SOURCE -rdynamic "/home/fox/dev/vlang.git/thirdparty/tcc/lib/libgc.a" -ldl -lpthread

$ /tmp/get_compiler
different compiler => **NOK**

Conclusion: C code generated with clang is wrong (case for if defined(__clang__) is void).