Skip to content

Commit 42f3787

Browse files
committed
v3: fix Linux C compiler canaries
1 parent d3f8f9d commit 42f3787

5 files changed

Lines changed: 66 additions & 17 deletions

File tree

vlib/v3/driver/c_compiler_flags_test.v

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module driver
22

3+
import os
4+
35
fn test_v3_tcc_backtrace_enabled() {
46
assert !v3_tcc_backtrace_enabled('macos', 'arm64', false)
57
assert v3_tcc_backtrace_enabled('macos', 'amd64', false)
@@ -8,12 +10,18 @@ fn test_v3_tcc_backtrace_enabled() {
810
}
911

1012
fn test_v3_explicit_tcc_flag_plan_skips_backtrace_on_macos_arm64() {
13+
vroot := os.join_path(os.temp_dir(), 'v3_tcc_flag_plan')
1114
plan := v3_c_compiler_flag_plan(V3CCompilerFlagOptions{
1215
explicit_tcc: true
1316
target_os: 'macos'
1417
target_arch: 'arm64'
18+
vroot: vroot
1519
})
1620
assert '-bt25' !in plan.before_inputs
21+
tcc_install_dir := os.join_path(vroot, 'thirdparty', 'tcc', 'lib')
22+
assert '-B${tcc_install_dir}' in plan.before_inputs
23+
assert '-I${os.join_path_single(tcc_install_dir, 'include')}' in plan.before_inputs
24+
assert '-L${tcc_install_dir}' in plan.before_inputs
1725
}
1826

1927
fn test_add_v3_tcc_compat_defines() {

vlib/v3/driver/driver.v

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,31 @@ fn add_v3_tcc_compat_defines(mut user_defines []string, target_os string, target
18091809
}
18101810
}
18111811

1812+
struct V3TccResourceFlags {
1813+
install_dir string
1814+
base_arg string
1815+
include_arg string
1816+
library_arg string
1817+
}
1818+
1819+
fn v3_tcc_resource_flags(vroot string) V3TccResourceFlags {
1820+
tcc_root_dir := os.join_path(vroot, 'thirdparty', 'tcc')
1821+
tcc_lib_dir := os.join_path_single(tcc_root_dir, 'lib')
1822+
tcc_nested_dir := os.join_path_single(tcc_lib_dir, 'tcc')
1823+
install_dir := if os.is_dir(tcc_nested_dir) { tcc_nested_dir } else { tcc_lib_dir }
1824+
mut include_dir := os.join_path_single(install_dir, 'include')
1825+
tcc_root_include_dir := os.join_path_single(tcc_root_dir, 'include')
1826+
if !os.is_dir(include_dir) && os.is_dir(tcc_root_include_dir) {
1827+
include_dir = tcc_root_include_dir
1828+
}
1829+
return V3TccResourceFlags{
1830+
install_dir: install_dir
1831+
base_arg: '-B${install_dir}'
1832+
include_arg: '-I${include_dir}'
1833+
library_arg: '-L${install_dir}'
1834+
}
1835+
}
1836+
18121837
fn v3_c_compiler_flag_plan(options V3CCompilerFlagOptions) V3CCompilerFlagPlan {
18131838
mut before_inputs := options.environment_c_flags.clone()
18141839
before_inputs << options.target_args
@@ -1822,9 +1847,9 @@ fn v3_c_compiler_flag_plan(options V3CCompilerFlagOptions) V3CCompilerFlagPlan {
18221847
}
18231848
mut tcc_includes := ''
18241849
if options.explicit_tcc {
1825-
tcc_lib_dir := os.join_path(options.vroot, 'thirdparty', 'tcc', 'lib')
1826-
tcc_includes = '-I${os.join_path_single(tcc_lib_dir, 'include')}'
1827-
before_inputs << [tcc_includes, '-L${tcc_lib_dir}']
1850+
tcc_resources := v3_tcc_resource_flags(options.vroot)
1851+
tcc_includes = tcc_resources.include_arg
1852+
before_inputs << [tcc_resources.base_arg, tcc_resources.include_arg, tcc_resources.library_arg]
18281853
if v3_tcc_backtrace_enabled(options.target_os, options.target_arch, options.is_shared) {
18291854
before_inputs << '-bt25'
18301855
}
@@ -9657,11 +9682,9 @@ pub fn run(args []string) {
96579682
tried_tcc = true
96589683
tcc_dir := os.join_path_single(os.join_path_single(prefs.vroot, 'thirdparty'), 'tcc')
96599684
tcc_path := os.join_path_single(tcc_dir, 'tcc.exe')
9660-
tcc_lib_dir := os.join_path_single(tcc_dir, 'lib')
9661-
tcc_includes := '-I${os.join_path_single(tcc_lib_dir, 'include')}'
9662-
tcc_lib := '-L${tcc_lib_dir}'
9663-
mut tcc_args := [c_standard, tcc_includes, tcc_lib, '-w',
9664-
'-Werror=implicit-function-declaration']
9685+
tcc_resources := v3_tcc_resource_flags(prefs.vroot)
9686+
mut tcc_args := [c_standard, tcc_resources.base_arg, tcc_resources.include_arg,
9687+
tcc_resources.library_arg, '-w', '-Werror=implicit-function-declaration']
96659688
if v3_tcc_backtrace_enabled(prefs.normalized_target_os(),
96669689
prefs.normalized_target_arch(), is_shared)
96679690
{
@@ -9672,7 +9695,7 @@ pub fn run(args []string) {
96729695
}
96739696
tcc_args << tcc_cached_main_flags(resolved_c_flags)
96749697
tcc_args << ['-o', 'out', os.base(tcc_main_file)]
9675-
atomic_s := tcc_atomic_arg(prefs, tcc_path, tcc_includes)
9698+
atomic_s := tcc_atomic_arg(prefs, tcc_path, tcc_resources.include_arg)
96769699
if atomic_s.len > 0 {
96779700
tcc_args << atomic_s
96789701
}
@@ -9689,7 +9712,7 @@ pub fn run(args []string) {
96899712
}}'
96909713
tcc_cached_executable := v3_cached_tcc_executable_path(&cache_state.manager,
96919714
program_source_identity, c_object_cache_stats.link_plan_signature, tcc_path,
9692-
tcc_lib_dir, tcc_args)
9715+
tcc_resources.install_dir, tcc_args)
96939716
if os.is_file(tcc_cached_executable) {
96949717
os.cp(tcc_cached_executable, cc_out) or {}
96959718
tcc_cache_hit = os.is_file(cc_out)
@@ -9732,17 +9755,15 @@ pub fn run(args []string) {
97329755
} else {
97339756
bundled_tcc_path
97349757
}
9735-
tcc_lib_dir := os.join_path_single(tcc_dir, 'lib')
9736-
tcc_includes := '-I${os.join_path_single(tcc_lib_dir, 'include')}'
9737-
tcc_lib := '-L${tcc_lib_dir}'
9758+
tcc_resources := v3_tcc_resource_flags(prefs.vroot)
97389759
mut tcc_args := environment_c_flags.clone()
97399760
if link_c_standard.len > 0 {
97409761
tcc_args << link_c_standard
97419762
}
97429763
if pic_flag.len > 0 {
97439764
tcc_args << pic_flag
97449765
}
9745-
tcc_args << [tcc_includes, tcc_lib]
9766+
tcc_args << [tcc_resources.base_arg, tcc_resources.include_arg, tcc_resources.library_arg]
97469767
if v3_tcc_backtrace_enabled(prefs.normalized_target_os(),
97479768
prefs.normalized_target_arch(), is_shared)
97489769
{
@@ -9760,7 +9781,7 @@ pub fn run(args []string) {
97609781
'src.c'
97619782
}
97629783
tcc_args << ['-o', 'out', tcc_source]
9763-
atomic_s := tcc_atomic_arg(prefs, tcc_path, tcc_includes)
9784+
atomic_s := tcc_atomic_arg(prefs, tcc_path, tcc_resources.include_arg)
97649785
if atomic_s.len > 0 {
97659786
tcc_args << atomic_s
97669787
}

vlib/v3/gen/c/cleanc.v

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16596,6 +16596,7 @@ fn (mut g FlatGen) headerless_libc_preamble() {
1659616596
g.writeln('int strcmp(const char* s1, const char* s2);')
1659716597
g.writeln('int strncmp(const char* s1, const char* s2, size_t n);')
1659816598
g.writeln('char* strncpy(char* dest, const char* src, size_t n);')
16599+
g.writeln('void qsort(void* base, size_t items, size_t item_size, int (*cb)(const void*, const void*));')
1659916600
g.writeln('double floor(double x);')
1660016601
g.writeln('double ceil(double x);')
1660116602
g.writeln('float floorf(float x);')
@@ -16989,6 +16990,7 @@ const c_headerless_libc_declared_fns = [
1698916990
'clock',
1699016991
'fprintf',
1699116992
'fflush',
16993+
'qsort',
1699216994
'qsort_r',
1699316995
]
1699416996

@@ -17340,7 +17342,10 @@ fn (mut g FlatGen) headerless_platform_constants() {
1734017342
g.writeln('#define LOCK_EX 2')
1734117343
g.writeln('#define LOCK_NB 4')
1734217344
g.writeln('#define LOCK_UN 8')
17345+
g.writeln('#define EPERM 1')
1734317346
g.writeln('#define ENOENT 2')
17347+
g.writeln('#define ESRCH 3')
17348+
g.writeln('#define EACCES 13')
1734417349
g.writeln('#define RUSAGE_SELF 0')
1734517350
g.writeln('#ifdef __APPLE__')
1734617351
g.headerless_darwin_constants()
@@ -17522,7 +17527,6 @@ fn (mut g FlatGen) headerless_darwin_constants() {
1752217527
g.writeln('#define F_RDLCK 1')
1752317528
g.writeln('#define F_UNLCK 2')
1752417529
g.writeln('#define F_WRLCK 3')
17525-
g.writeln('#define EACCES 13')
1752617530
g.writeln('#define EFAULT 14')
1752717531
g.writeln('#define EINTR 4')
1752817532
g.writeln('#define EINVAL 22')
@@ -17643,7 +17647,6 @@ fn (mut g FlatGen) headerless_bsd_constants(o_cloexec string, f_setlk string, f_
1764317647
g.writeln('#define F_RDLCK 1')
1764417648
g.writeln('#define F_UNLCK 2')
1764517649
g.writeln('#define F_WRLCK 3')
17646-
g.writeln('#define EACCES 13')
1764717650
g.writeln('#define EFAULT 14')
1764817651
g.writeln('#define EINTR 4')
1764917652
g.writeln('#define EINVAL 22')

vlib/v3/gen/c/fn.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14985,6 +14985,7 @@ const c_preamble_declared_extern_symbols = {
1498514985
'clock': true
1498614986
'fprintf': true
1498714987
'fflush': true
14988+
'qsort': true
1498814989
'qsort_r': true
1498914990
'mktime': true
1499014991
'localtime': true

vlib/v3/gen/c/preamble_test.v

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ fn test_headerless_libc_preamble_declares_printf_for_cached_test_harnesses() {
4343
assert c_code.contains('int printf(const char* format, ...);'), c_code
4444
}
4545

46+
fn test_headerless_libc_preamble_declares_qsort_for_generated_sort_helpers() {
47+
mut g := FlatGen.new()
48+
g.headerless_libc_preamble()
49+
c_code := g.sb.str()
50+
assert c_code.contains('void qsort(void* base, size_t items, size_t item_size, int (*cb)(const void*, const void*));'), c_code
51+
}
52+
53+
fn test_headerless_platform_constants_include_process_errno_values() {
54+
mut g := FlatGen.new()
55+
g.headerless_platform_constants()
56+
c_code := g.sb.str()
57+
for definition in ['#define EPERM 1', '#define ESRCH 3', '#define EACCES 13'] {
58+
assert c_code.contains(definition), definition
59+
}
60+
}
61+
4662
fn test_manual_stdlib_headers_define_l_tmpnam_for_glibc() {
4763
// The v3 backend embeds and reuses the v1 c_headers prelude (see manual_stdlib_c_headers).
4864
// Make sure the glibc L_tmpnam define is inherited, so a module header that pulls <stdio.h>

0 commit comments

Comments
 (0)