tools: improve oldv compatibility for using new stricter C compilers like clang-18, to compile older V versions from 2020 and 2019

This commit is contained in:
Delyan Angelov 2024-12-01 18:27:59 +02:00
parent d8021bd459
commit 13fd599619
No known key found for this signature in database
GPG key ID: 66886C0F12D595ED
2 changed files with 43 additions and 22 deletions

View file

@ -83,14 +83,14 @@ pub fn clone_or_pull(remote_git_url string, local_worktree_path string) {
// Note: after clone_or_pull, the current repo branch is === HEAD === master
if os.is_dir(local_worktree_path) && os.is_dir(os.join_path_single(local_worktree_path, '.git')) {
// Already existing ... Just pulling in this case is faster usually.
scripting.run('git -C "${local_worktree_path}" checkout --quiet master')
scripting.run('git -C "${local_worktree_path}" pull --quiet ')
scripting.run('git -C "${local_worktree_path}" checkout --quiet master')
scripting.run('git -C "${local_worktree_path}" pull --quiet ')
} else {
// Clone a fresh local tree.
if remote_git_url.starts_with('http') {
// cloning an https remote with --filter=blob:none is usually much less bandwidth intensive, at the
// expense of doing small network ops later when using checkouts.
scripting.run('git clone --filter=blob:none --quiet "${remote_git_url}" "${local_worktree_path}" ')
scripting.run('git clone --filter=blob:none --quiet "${remote_git_url}" "${local_worktree_path}" ')
return
}
mut is_blobless_clone := false
@ -112,7 +112,7 @@ pub fn clone_or_pull(remote_git_url string, local_worktree_path string) {
// at the expense of a little more space usage, which will make the new tree in local_worktree_path,
// exactly 1:1 the same, as the one in remote_git_url, just independent from it .
copy_cmd := if os.user_os() == 'windows' { 'robocopy /MIR' } else { 'rsync -a' }
scripting.run('${copy_cmd} "${remote_git_url}/" "${local_worktree_path}/"')
scripting.run('${copy_cmd} "${remote_git_url}/" "${local_worktree_path}/"')
return
}
scripting.run('git clone --quiet "${remote_git_url}" "${local_worktree_path}" ')
@ -121,7 +121,8 @@ pub fn clone_or_pull(remote_git_url string, local_worktree_path string) {
pub struct VGitContext {
pub:
cc string = 'cc' // what compiler to use
cc string = 'cc' // what C compiler to use for bootstrapping
cc_options string // what additional C compiler options to use for bootstrapping
workdir string = '/tmp' // the base working folder
commit_v string = 'master' // the commit-ish that needs to be prepared
path_v string // where is the local working copy v repo
@ -195,12 +196,16 @@ pub fn (mut vgit_context VGitContext) compile_oldv_if_needed() {
mut c_flags := '-std=gnu11 -I ./thirdparty/stdatomic/nix -w'
mut c_ldflags := '-lm -lpthread'
mut vc_source_file_location := os.join_path_single(vgit_context.path_vc, 'v.c')
mut vc_v_bootstrap_flags := ''
mut vc_v_cpermissive_flags := '${vgit_context.cc_options} -Wno-error=incompatible-function-pointer-types -Wno-error=implicit-function-declaration -Wno-error=int-conversion'
// after 85b58b0 2021-09-28, -no-parallel is supported, and can be used to force the cgen stage to be single threaded, which increases the chances of successful bootstraps
mut vc_v_bootstrap_flags := ''
if vgit_context.commit_v__ts >= 1632778086 {
vc_v_bootstrap_flags += '-no-parallel'
vc_v_bootstrap_flags += ' -no-parallel'
}
scripting.verbose_trace(@FN, 'vc_v_bootstrap_flags: ${vc_v_bootstrap_flags} | vgit_context.commit_v__ts: ${vgit_context.commit_v__ts}')
vc_v_bootstrap_flags = vc_v_bootstrap_flags.trim_space()
scripting.verbose_trace(@FN, 'vc_v_bootstrap_flags: ${vc_v_bootstrap_flags}')
scripting.verbose_trace(@FN, 'vc_v_cpermissive_flags: ${vc_v_cpermissive_flags}')
scripting.verbose_trace(@FN, 'vgit_context.commit_v__ts: ${vgit_context.commit_v__ts}')
if 'windows' == os.user_os() {
c_flags = '-std=c99 -I ./thirdparty/stdatomic/win -w'
@ -219,11 +224,11 @@ pub fn (mut vgit_context VGitContext) compile_oldv_if_needed() {
if vgit_context.commit_v__ts >= 1699341818 && !vgit_context.cc.contains('msvc') {
c_flags += '-lws2_32'
}
command_for_building_v_from_c_source = '${vgit_context.cc} ${c_flags} -o cv.exe "${vc_source_file_location}" ${c_ldflags}'
command_for_selfbuilding = '.\\cv.exe ${vc_v_bootstrap_flags} -o ${vgit_context.vexename} {SOURCE}'
command_for_building_v_from_c_source = c(vgit_context.cc, '${vc_v_cpermissive_flags} ${c_flags} -o cv.exe "${vc_source_file_location}" ${c_ldflags}')
command_for_selfbuilding = c('.\\cv.exe', '${vc_v_bootstrap_flags} -o ${vgit_context.vexename} {SOURCE}')
} else {
command_for_building_v_from_c_source = '${vgit_context.cc} ${c_flags} -o cv "${vc_source_file_location}" ${c_ldflags}'
command_for_selfbuilding = './cv ${vc_v_bootstrap_flags} -o ${vgit_context.vexename} {SOURCE}'
command_for_building_v_from_c_source = c(vgit_context.cc, '${vc_v_cpermissive_flags} ${c_flags} -o cv "${vc_source_file_location}" ${c_ldflags}')
command_for_selfbuilding = c('./cv', '${vc_v_bootstrap_flags} -o ${vgit_context.vexename} {SOURCE}')
}
scripting.run(command_for_building_v_from_c_source)
@ -233,6 +238,11 @@ pub fn (mut vgit_context VGitContext) compile_oldv_if_needed() {
// which should be a valid working V executable.
}
fn c(cmd string, params string) string {
// compose a command, while reducing the potential whitespaces, due to all the interpolations of optional flags above
return '${cmd} ${params.trim_space()}'
}
pub struct VGitOptions {
pub mut:
workdir string = os.temp_dir() // the working folder (typically /tmp), where the tool will write

View file

@ -34,12 +34,13 @@ mut:
path_v string // the full path to the v folder inside workdir.
path_vc string // the full path to the vc folder inside workdir.
cmd_to_run string // the command that you want to run *in* the oldv repo
cleanup bool // should the tool run a cleanup first
use_cache bool // use local cached copies for --vrepo and --vcrepo in
fresh_tcc bool // do use `make fresh_tcc`
is_bisect bool // bisect mode; usage: `cmd/tools/oldv -b -c './v run bug.v'`
show_vccommit bool // show the V and VC commits, corresponding to the V commit-ish, that can be used to build V
cc string = 'cc' // the C compiler to use for bootstrapping.
cleanup bool // should the tool run a cleanup first
use_cache bool // use local cached copies for --vrepo and --vcrepo in
fresh_tcc bool // do use `make fresh_tcc`
is_bisect bool // bisect mode; usage: `cmd/tools/oldv -b -c './v run bug.v'`
show_vccommit bool // show the V and VC commits, corresponding to the V commit-ish, that can be used to build V
cc_options string // additional options to pass to the C compiler while bootstrapping.
}
fn (mut c Context) compile_oldv_if_needed() {
@ -48,6 +49,7 @@ fn (mut c Context) compile_oldv_if_needed() {
v_repo_url: c.vgo.v_repo_url
vc_repo_url: c.vgo.vc_repo_url
cc: c.cc
cc_options: c.cc_options
commit_v: c.commit_v
path_v: c.path_v
path_vc: c.path_vc
@ -126,19 +128,28 @@ fn main() {
context.vgo.v_repo_url = 'https://github.com/vlang/v'
context.vgo.vc_repo_url = 'https://github.com/vlang/vc'
}
should_sync := fp.bool('cache-sync', `s`, false, 'Update the local cache')
context.is_bisect = fp.bool('bisect', `b`, false, 'Bisect mode. Use the current commit in the repo where oldv is.')
if !should_sync && !context.is_bisect {
fp.limit_free_args(1, 1)!
context.cc = fp.string('cc', 0, 'cc', 'Use this C compiler for bootstrapping v.c (defaults to `cc`).')
context.cc_options = fp.string('ccoptions', 0, '', 'Use these C compiler options for bootstrapping v.c (defaults to ``).')
env_cc_options := os.getenv('OLDV_CCOPTIONS')
if env_cc_options != '' {
context.cc_options = env_cc_options
}
////
context.cleanup = fp.bool('clean', 0, false, 'Clean before running (slower).')
context.fresh_tcc = fp.bool('fresh_tcc', 0, true, 'Do `make fresh_tcc` when preparing a V compiler.')
context.cmd_to_run = fp.string('command', `c`, '', 'Command to run in the old V repo.\n')
context.show_vccommit = fp.bool('show_VC_commit', 0, false, 'Show the VC commit, that can be used to compile the given V commit, and exit.\n')
context.is_bisect = fp.bool('bisect', `b`, false, 'Bisect mode. Use the current commit in the repo where oldv is.')
should_sync := fp.bool('cache-sync', `s`, false, 'Update the local cache')
if !should_sync && !context.is_bisect {
fp.limit_free_args(1, 1)!
}
////
commits := vgit.add_common_tool_options(mut context.vgo, mut fp)
if should_sync {
sync_cache()
println('Cache synced, cache folder: ${cache_oldv_folder} .')
exit(0)
}
if context.use_cache {