147 lines
3.6 KiB
V
147 lines
3.6 KiB
V
// Copyright (c) 2020-2024 Joe Conigliaro. All rights reserved.
|
|
// Use of this source code is governed by an MIT license
|
|
// that can be found in the LICENSE file.
|
|
module builder
|
|
|
|
import os
|
|
import v2.pref
|
|
|
|
fn list_dir_entries(path string) []string {
|
|
mut entries := os.ls(path) or { []string{} }
|
|
entries.sort()
|
|
return entries
|
|
}
|
|
|
|
pub fn get_v_files_from_dir(dir string, user_defines []string, target_os string) []string {
|
|
if dir == '' {
|
|
return []string{}
|
|
}
|
|
mod_files := list_dir_entries(dir)
|
|
mut v_files := []string{}
|
|
mut defaults := []string{}
|
|
for file in mod_files {
|
|
if file == '' {
|
|
continue
|
|
}
|
|
// Include .v files (including .c.v), exclude .js.v and test files
|
|
if !file.ends_with('.v') || file.ends_with('.js.v') || file.contains('_test.') {
|
|
continue
|
|
}
|
|
// skip platform-specific files
|
|
if file.contains('.arm64.') || file.contains('.arm32.') || file.contains('.amd64.') {
|
|
continue
|
|
}
|
|
// Skip files specialized for a different target OS before parsing/type checking.
|
|
if pref.file_has_incompatible_os_suffix(file, target_os) {
|
|
continue
|
|
}
|
|
if file.ends_with('prealloc.c.v') && 'prealloc' !in user_defines {
|
|
continue
|
|
}
|
|
// Conditional compilation files: _d_<feature> included when -d <feature> is set,
|
|
// _notd_<feature> included when -d <feature> is NOT set.
|
|
if file.contains('_notd_') {
|
|
feature := extract_define_feature(file, '_notd_')
|
|
if feature.len > 0 && feature in user_defines {
|
|
continue
|
|
}
|
|
} else if file.contains('_d_') {
|
|
feature := extract_define_feature(file, '_d_')
|
|
if feature.len == 0 || feature !in user_defines {
|
|
continue
|
|
}
|
|
}
|
|
path := os.join_path(dir, file)
|
|
if path == '' {
|
|
continue
|
|
}
|
|
// Collect _default.c.v files separately; they are only included when
|
|
// no platform-specific variant exists (e.g. _darwin.c.v, _linux.c.v).
|
|
if file.contains('default.c.v') {
|
|
defaults << path
|
|
} else {
|
|
v_files << path
|
|
}
|
|
}
|
|
// Add _default.c.v files only when no platform-specific variant was selected.
|
|
for dfile in defaults {
|
|
no_postfix := fname_without_platform_postfix(dfile)
|
|
mut has_specialized := false
|
|
for vf in v_files {
|
|
if fname_without_platform_postfix(vf) == no_postfix {
|
|
has_specialized = true
|
|
break
|
|
}
|
|
}
|
|
if !has_specialized {
|
|
v_files << dfile
|
|
}
|
|
}
|
|
return v_files
|
|
}
|
|
|
|
// fname_without_platform_postfix strips the platform-specific suffix from a file path,
|
|
// so that e.g. "free_memory_impl_darwin.c.v" and "free_memory_impl_default.c.v" both
|
|
// map to the same key, allowing detection of specialized vs default variants.
|
|
fn fname_without_platform_postfix(file string) string {
|
|
return file.replace_each([
|
|
'default.c.v',
|
|
'_',
|
|
'windows.c.v',
|
|
'_',
|
|
'linux.c.v',
|
|
'_',
|
|
'darwin.c.v',
|
|
'_',
|
|
'macos.c.v',
|
|
'_',
|
|
'android.c.v',
|
|
'_',
|
|
'android_outside_termux.c.v',
|
|
'_',
|
|
'termux.c.v',
|
|
'_',
|
|
'ios.c.v',
|
|
'_',
|
|
'freebsd.c.v',
|
|
'_',
|
|
'openbsd.c.v',
|
|
'_',
|
|
'netbsd.c.v',
|
|
'_',
|
|
'dragonfly.c.v',
|
|
'_',
|
|
'bsd.c.v',
|
|
'_',
|
|
'solaris.c.v',
|
|
'_',
|
|
'qnx.c.v',
|
|
'_',
|
|
'serenity.c.v',
|
|
'_',
|
|
'plan9.c.v',
|
|
'_',
|
|
'vinix.c.v',
|
|
'_',
|
|
'nix.c.v',
|
|
'_',
|
|
])
|
|
}
|
|
|
|
// extract_define_feature extracts the feature name from a _d_ or _notd_ filename.
|
|
// e.g. "parse_d_parallel.v" with marker "_d_" returns "parallel"
|
|
// e.g. "array_notd_gcboehm_opt.v" with marker "_notd_" returns "gcboehm_opt"
|
|
fn extract_define_feature(file string, marker string) string {
|
|
idx := file.index(marker) or { return '' }
|
|
rest := file[idx + marker.len..]
|
|
// Strip .v or .c.v suffix
|
|
feature := if rest.ends_with('.c.v') {
|
|
rest[..rest.len - 4]
|
|
} else if rest.ends_with('.v') {
|
|
rest[..rest.len - 2]
|
|
} else {
|
|
rest
|
|
}
|
|
return feature
|
|
}
|