compiler: use thirdparty/tcc/tcc.exe by default, when no explicit -cc is given (#6598)

pull/6213/head
Delyan Angelov 2020-11-29 17:18:49 +02:00 committed by GitHub
parent 0b96cd50e1
commit adeebad2a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 105 additions and 80 deletions

View File

@ -71,7 +71,7 @@ jobs:
runs-on: ubuntu-18.04 runs-on: ubuntu-18.04
timeout-minutes: 30 timeout-minutes: 30
env: env:
VFLAGS: -cc /var/tmp/tcc/bin/tcc -cflags -bt10 VFLAGS: -cc tcc -cflags -bt10
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Install dependencies - name: Install dependencies
@ -83,12 +83,12 @@ jobs:
- name: Build v - name: Build v
run: | run: |
echo $VFLAGS echo $VFLAGS
sudo ln -s $PWD/thirdparty/tcc/tcc.exe /usr/local/bin/tcc ## TODO: remove
make -j4 make -j4
./v -cg -o v cmd/v ./v -cg -o v cmd/v
- name: Test v->c - name: Test v->c
run: | run: |
sudo ln -s /var/tmp/tcc/bin/tcc /usr/local/bin/tcc thirdparty/tcc/tcc.exe -version
tcc -version
./v -cg -o v cmd/v # Make sure vtcc can build itself twice ./v -cg -o v cmd/v # Make sure vtcc can build itself twice
# ./v -silent test-compiler # ./v -silent test-compiler
- name: v self compilation - name: v self compilation
@ -112,7 +112,7 @@ jobs:
image: thevlang/vlang:alpine-build image: thevlang/vlang:alpine-build
env: env:
V_CI_MUSL: 1 V_CI_MUSL: 1
VFLAGS: -cc gcc
volumes: volumes:
- ${{github.workspace}}:/opt/vlang - ${{github.workspace}}:/opt/vlang
steps: steps:
@ -127,11 +127,10 @@ jobs:
v -silent test-fixed v -silent test-fixed
macos: macos:
runs-on: ${{ matrix.os }} runs-on: macOS-latest
timeout-minutes: 30 timeout-minutes: 30
strategy: env:
matrix: VFLAGS: -cc clang
os: [macOS-latest]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-node@v1 - uses: actions/setup-node@v1
@ -146,11 +145,11 @@ jobs:
## brew install sdl2 sdl2_ttf sdl2_mixer sdl2_image ## brew install sdl2 sdl2_ttf sdl2_mixer sdl2_image
export LIBRARY_PATH="$LIBRARY_PATH:/usr/local/opt/openssl/lib/" export LIBRARY_PATH="$LIBRARY_PATH:/usr/local/opt/openssl/lib/"
- name: Build V - name: Build V
run: make -j4 && ./v -cg -o v cmd/v run: make -j4 && ./v -o v cmd/v
- name: Build V using V - name: Build V using V
run: ./v -o v2 cmd/v && ./v2 -o v3 cmd/v run: ./v -o v2 cmd/v && ./v2 -o v3 cmd/v
- name: Test symlink - name: Test symlink
run: sudo ./v symlink run: ./v symlink
# - name: Set up pg database # - name: Set up pg database
# run: | # run: |
# pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start # pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start
@ -163,8 +162,6 @@ jobs:
# run: ./v -silent build-vbinaries # run: ./v -silent build-vbinaries
## - name: Test v->js ## - name: Test v->js
## run: ./v -o hi.js examples/hello_v_js.v && node hi.js ## run: ./v -o hi.js examples/hello_v_js.v && node hi.js
- name: Test symlink
run: ./v symlink && v -o v2 cmd/v
- name: Fixed tests - name: Fixed tests
run: VJOBS=1 ./v -silent test-fixed run: VJOBS=1 ./v -silent test-fixed
- name: Build examples - name: Build examples

View File

@ -2,15 +2,17 @@ CC ?= cc
CFLAGS ?= CFLAGS ?=
LDFLAGS ?= LDFLAGS ?=
TMPDIR ?= /tmp TMPDIR ?= /tmp
VROOT ?= .
VC ?= ./vc VC ?= ./vc
V := ./v V ?= ./v
VCREPO ?= https://github.com/vlang/vc
TCCREPO ?= https://github.com/vlang/tccbin
VCFILE := v.c VCFILE := v.c
TMPTCC := /var/tmp/tcc TMPTCC := $(VROOT)/thirdparty/tcc
VCREPO := https://github.com/vlang/vc TCCBRANCH := thirdparty-unknown-unknown
TCCREPO := https://github.com/vlang/tccbin
GITCLEANPULL := git clean -xf && git pull --quiet GITCLEANPULL := git clean -xf && git pull --quiet
GITFASTCLONE := git clone --depth 1 --quiet GITFASTCLONE := git clone --depth 1 --quiet --single-branch
#### Platform detections and overrides: #### Platform detections and overrides:
_SYS := $(shell uname 2>/dev/null || echo Unknown) _SYS := $(shell uname 2>/dev/null || echo Unknown)
@ -24,10 +26,12 @@ endif
ifeq ($(_SYS),Linux) ifeq ($(_SYS),Linux)
LINUX := 1 LINUX := 1
TCCBRANCH := thirdparty-linux-amd64
endif endif
ifeq ($(_SYS),Darwin) ifeq ($(_SYS),Darwin)
MAC := 1 MAC := 1
TCCBRANCH := thirdparty-macos-amd64
endif endif
ifeq ($(_SYS),FreeBSD) ifeq ($(_SYS),FreeBSD)
@ -37,11 +41,12 @@ endif
ifdef ANDROID_ROOT ifdef ANDROID_ROOT
ANDROID := 1 ANDROID := 1
undefine LINUX undefine LINUX
TCCBRANCH := thirdparty-linux-arm64
endif endif
##### #####
ifdef WIN32 ifdef WIN32
TCCREPO := https://github.com/vlang/tccbin_win TCCBRANCH := thirdparty-windows-amd64
VCFILE := v_win.c VCFILE := v_win.c
endif endif
@ -91,27 +96,25 @@ fresh_vc:
latest_tcc: $(TMPTCC)/.git/config latest_tcc: $(TMPTCC)/.git/config
ifndef ANDROID ifndef ANDROID
ifndef MAC
ifndef local ifndef local
cd $(TMPTCC) && $(GITCLEANPULL) cd $(TMPTCC) && $(GITCLEANPULL)
else else
@echo "Using local tcc" @echo "Using local tcc"
endif endif
endif endif
endif
fresh_tcc: fresh_tcc:
ifndef ANDROID ifndef ANDROID
ifndef MAC ifdef LINUX
rm -rf $(TMPTCC) rm -rf /var/tmp/tcc
$(GITFASTCLONE) $(TCCREPO) $(TMPTCC) git clone https://github.com/vlang/tccbin /var/tmp/tcc
endif endif
rm -rf $(TMPTCC)
$(GITFASTCLONE) --branch $(TCCBRANCH) $(TCCREPO) $(TMPTCC)
endif endif
$(TMPTCC)/.git/config: $(TMPTCC)/.git/config:
ifndef MAC
$(MAKE) fresh_tcc $(MAKE) fresh_tcc
endif
$(VC)/.git/config: $(VC)/.git/config:
$(MAKE) fresh_vc $(MAKE) fresh_vc

View File

@ -122,9 +122,6 @@ fn (mut a App) collect_info() {
a.line('Git vroot status', a.git_info()) a.line('Git vroot status', a.git_info())
a.line('.git/config present', os.is_file('.git/config').str()) a.line('.git/config present', os.is_file('.git/config').str())
// //
if os_kind == 'linux' {
a.report_tcc_version('/var/tmp/tcc')
}
a.report_tcc_version('thirdparty/tcc') a.report_tcc_version('thirdparty/tcc')
} }

View File

@ -14,13 +14,17 @@ set subcmd=
set target=build set target=build
REM TCC variables REM TCC variables
set "tcc_url=https://github.com/vlang/tccbin_win.git" set "tcc_url=https://github.com/vlang/tccbin"
set "tcc_dir=%~dp0thirdparty\tcc" set "tcc_dir=%~dp0thirdparty\tcc"
set "vc_url=https://github.com/vlang/vc.git" set "tcc_branch=thirdparty-windows-amd64"
REM VC settings
set "vc_url=https://github.com/vlang/vc"
set "vc_dir=%~dp0vc" set "vc_dir=%~dp0vc"
REM Let a particular environment specify their own TCC repo REM Let a particular environment specify their own TCC repo
if /I not ["%TCC_GIT%"] == [""] set "tcc_url=%TCC_GIT%" if /I not ["%TCC_GIT%"] == [""] set "tcc_url=%TCC_GIT%"
if /I not ["%TCC_BRANCH%"] == [""] set "tcc_branch=%TCC_BRANCH%"
pushd %~dp0 pushd %~dp0
@ -227,7 +231,7 @@ if %ERRORLEVEL% NEQ 0 (
if not exist %tcc_dir% ( if not exist %tcc_dir% (
echo ^> TCC not found echo ^> TCC not found
echo ^> Downloading TCC from %tcc_url% echo ^> Downloading TCC from %tcc_url%
call :buildcmd "git clone --depth 1 --quiet "!tcc_url!" "%tcc_dir%"" " " call :buildcmd "git clone --depth 1 --quiet --single-branch --branch "!tcc_branch!" "!tcc_url!" "%tcc_dir%"" " "
) )
pushd %tcc_dir% || ( pushd %tcc_dir% || (
echo ^> TCC not found, even after cloning echo ^> TCC not found, even after cloning

View File

@ -217,6 +217,12 @@ fn (mut v Builder) cc() {
return return
} }
} }
//
mut tried_compilation_commands := []string{}
original_pwd := os.getwd()
// TODO remove the start: goto start construct;
// use a labeled for break instead
start:
mut ccompiler := v.pref.ccompiler mut ccompiler := v.pref.ccompiler
$if windows { $if windows {
if ccompiler == 'msvc' { if ccompiler == 'msvc' {
@ -248,35 +254,6 @@ fn (mut v Builder) cc() {
args << '-fobjc-arc' args << '-fobjc-arc'
} }
mut linker_flags := []string{} mut linker_flags := []string{}
// TCC on Linux by default, unless -cc was provided
// TODO if -cc = cc, TCC is still used, default compiler should be
// used instead.
if v.pref.fast {
$if linux {
$if !android {
tcc_3rd := '$vdir/thirdparty/tcc/bin/tcc'
// println('tcc third "$tcc_3rd"')
tcc_path := '/var/tmp/tcc/bin/tcc'
if os.exists(tcc_3rd) && !os.exists(tcc_path) {
// println('moving tcc')
// if there's tcc in thirdparty/, that means this is
// a prebuilt V_linux.zip.
// Until the libtcc1.a bug is fixed, we neeed to move
// it to /var/tmp/
os.system('mv $vdir/thirdparty/tcc /var/tmp/')
}
if v.pref.ccompiler == 'cc' && os.exists(tcc_path) {
// TODO tcc bug, needs an empty libtcc1.a fila
// os.mkdir('/var/tmp/tcc/lib/tcc/') or { panic(err) }
// os.create('/var/tmp/tcc/lib/tcc/libtcc1.a')
v.pref.ccompiler = tcc_path
args << '-m64'
}
}
} $else {
verror('-fast is only supported on Linux right now')
}
}
if !v.pref.is_shared && v.pref.build_mode != .build_module && os.user_os() == 'windows' && if !v.pref.is_shared && v.pref.build_mode != .build_module && os.user_os() == 'windows' &&
!v.pref.out_name.ends_with('.exe') { !v.pref.out_name.ends_with('.exe') {
v.pref.out_name += '.exe' v.pref.out_name += '.exe'
@ -353,9 +330,9 @@ fn (mut v Builder) cc() {
} }
if debug_mode { if debug_mode {
args << debug_options args << debug_options
$if macos { // $if macos {
args << ' -ferror-limit=5000 ' // args << ' -ferror-limit=5000 '
} // }
} }
if v.pref.is_prod { if v.pref.is_prod {
args << optimization_options args << optimization_options
@ -448,8 +425,10 @@ fn (mut v Builder) cc() {
} }
// macOS code can include objective C TODO remove once objective C is replaced with C // macOS code can include objective C TODO remove once objective C is replaced with C
if v.pref.os == .macos || v.pref.os == .ios { if v.pref.os == .macos || v.pref.os == .ios {
if !is_cc_tcc {
args << '-x objective-c' args << '-x objective-c'
} }
}
// The C file we are compiling // The C file we are compiling
args << '"$v.out_name_c"' args << '"$v.out_name_c"'
if v.pref.os == .macos { if v.pref.os == .macos {
@ -535,10 +514,11 @@ fn (mut v Builder) cc() {
v.pref.cleanup_files << v.out_name_c v.pref.cleanup_files << v.out_name_c
v.pref.cleanup_files << response_file v.pref.cleanup_files << response_file
} }
start: //
todo() todo()
// TODO remove os.chdir(vdir)
cmd := '$ccompiler @$response_file' cmd := '$ccompiler @$response_file'
tried_compilation_commands << cmd
v.show_cc(cmd, response_file, response_file_content) v.show_cc(cmd, response_file, response_file_content)
// Run // Run
ticks := time.ticks() ticks := time.ticks()
@ -546,6 +526,7 @@ fn (mut v Builder) cc() {
// C compilation failed. // C compilation failed.
// If we are on Windows, try msvc // If we are on Windows, try msvc
println('C compilation failed.') println('C compilation failed.')
os.chdir(original_pwd)
/* /*
if os.user_os() == 'windows' && v.pref.ccompiler != 'msvc' { if os.user_os() == 'windows' && v.pref.ccompiler != 'msvc' {
println('Trying to build with MSVC') println('Trying to build with MSVC')
@ -561,20 +542,28 @@ fn (mut v Builder) cc() {
if v.pref.show_c_output { if v.pref.show_c_output {
v.show_c_compiler_output(res) v.show_c_compiler_output(res)
} }
if res.exit_code == 127 { os.chdir(original_pwd)
// the command could not be found by the system if res.exit_code != 0 {
$if linux { if ccompiler.contains('tcc.exe') {
// TCC problems on linux? Try GCC. // a TCC problem? Retry with the system cc:
if ccompiler.contains('tcc') { if tried_compilation_commands.len > 1 {
v.pref.ccompiler = 'cc' eprintln('Recompilation loop detected (ccompiler: $ccompiler):')
for recompile_command in tried_compilation_commands {
eprintln(' $recompile_command')
}
exit(101)
}
eprintln('recompilation with tcc failed; retrying with cc ...')
v.pref.ccompiler = pref.default_c_compiler()
goto start goto start
} }
} if res.exit_code == 127 {
verror('C compiler error, while attempting to run: \n' + verror('C compiler error, while attempting to run: \n' +
'-----------------------------------------------------------\n' + '$cmd\n' + '-----------------------------------------------------------\n' + '$cmd\n' +
'-----------------------------------------------------------\n' + 'Probably your C compiler is missing. \n' + '-----------------------------------------------------------\n' + 'Probably your C compiler is missing. \n' +
'Please reinstall it, or make it available in your PATH.\n\n' + missing_compiler_info()) 'Please reinstall it, or make it available in your PATH.\n\n' + missing_compiler_info())
} }
}
if !v.pref.show_c_output { if !v.pref.show_c_output {
v.post_process_c_compiler_output(res) v.post_process_c_compiler_output(res)
} }

View File

@ -124,6 +124,11 @@ typedef int (*qsort_callback_func)(const void*, const void*);
#define _MOV #define _MOV
#endif #endif
#if defined(__TINYC__) && defined(__has_include)
// tcc does not support has_include properly yet, turn it off completely
#undef __has_include
#endif
#ifndef _WIN32 #ifndef _WIN32
#if defined __has_include #if defined __has_include
#if __has_include (<execinfo.h>) #if __has_include (<execinfo.h>)

View File

@ -53,6 +53,8 @@ pub fn (mut p Preferences) fill_with_defaults() {
// No OS specifed? Use current system // No OS specifed? Use current system
p.os = get_host_os() p.os = get_host_os()
} }
//
p.try_to_use_tcc_by_default()
if p.ccompiler == '' { if p.ccompiler == '' {
p.ccompiler = default_c_compiler() p.ccompiler = default_c_compiler()
} }
@ -83,7 +85,33 @@ pub fn (mut p Preferences) fill_with_defaults() {
// eprintln('prefs.cache_manager: $p') // eprintln('prefs.cache_manager: $p')
} }
fn default_c_compiler() string { fn (mut p Preferences) try_to_use_tcc_by_default() {
if p.ccompiler == 'tcc' {
p.ccompiler = default_tcc_compiler()
return
}
if p.ccompiler == '' {
// tcc is known to fail several tests on macos, so do not
// try to use it by default, only when it is explicitly set
$if macos {
return
}
p.ccompiler = default_tcc_compiler()
return
}
}
pub fn default_tcc_compiler() string {
vexe := vexe_path()
vroot := os.dir(vexe)
vtccexe := os.join_path(vroot, 'thirdparty', 'tcc', 'tcc.exe')
if os.exists(vtccexe) {
return vtccexe
}
return ''
}
pub fn default_c_compiler() string {
// fast_clang := '/usr/local/Cellar/llvm/8.0.0/bin/clang' // fast_clang := '/usr/local/Cellar/llvm/8.0.0/bin/clang'
// if os.exists(fast_clang) { // if os.exists(fast_clang) {
// return fast_clang // return fast_clang

View File

@ -97,7 +97,6 @@ pub mut:
// This is on by default, since a vast majority of users do not // This is on by default, since a vast majority of users do not
// work on the builtin module itself. // work on the builtin module itself.
// generating_vh bool // generating_vh bool
fast bool // use tcc/x64 codegen
enable_globals bool // allow __global for low level code enable_globals bool // allow __global for low level code
is_fmt bool is_fmt bool
is_vet bool is_vet bool
@ -328,6 +327,9 @@ pub fn parse_args(args []string) (&Preferences, string) {
if res.out_name.ends_with('.js') { if res.out_name.ends_with('.js') {
res.backend = .js res.backend = .js
} }
if !os.is_abs_path(res.out_name) {
res.out_name = os.join_path(os.getwd(), res.out_name)
}
i++ i++
} }
'-b' { '-b' {