Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.5.1 Do not link with debug libc on win32 when using cross compile libs. A… #1089

Merged
merged 1 commit into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ jobs:
install: git binutils mingw-w64-x86_64-clang mingw-w64-x86_64-ninja mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain mingw-w64-x86_64-python
- shell: msys2 {0}
run: |
pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-llvm-17.0.4-1-any.pkg.tar.zst
pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-lld-17.0.4-1-any.pkg.tar.zst
pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-llvm-17.0.6-1-any.pkg.tar.zst
pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-lld-17.0.6-1-any.pkg.tar.zst
- name: CMake
run: |
cmake -B build -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
Expand Down
31 changes: 31 additions & 0 deletions lib/std/core/dstring.c3
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,37 @@ fn void DString.append_char(&self, char c)
data.chars[data.len++] = c;
}

/**
* @require start < self.len()
* @require end < self.len()
* @require end >= start "End must be same or equal to the start"
**/
fn void DString.delete_range(&self, usz start, usz end)
{
self.delete(start, end - start + 1);
}

/**
* @require start < self.len()
* @require start + len <= self.len()
**/
fn void DString.delete(&self, usz start, usz len = 1)
{
if (!len) return;
StringData* data = self.data();
usz new_len = data.len - len;
if (new_len == 0)
{
data.len = 0;
return;
}
usz len_after = data.len - start - len;
if (len_after > 0)
{
data.chars[start:len_after] = data.chars[start + len:len_after];
}
data.len = new_len;
}

macro void DString.append(&self, value)
{
Expand Down
40 changes: 40 additions & 0 deletions lib/std/core/string.c3
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,11 @@ fn String String.new_ascii_to_upper(s, Allocator* allocator = mem::heap())
return copy;
}

fn StringIterator String.iterator(s)
{
return { s, 0 };
}

fn String String.temp_ascii_to_upper(s)
{
return s.new_ascii_to_upper(mem::temp());
Expand Down Expand Up @@ -575,3 +580,38 @@ fn char! String.to_uchar(s) => s.to_integer(char);

fn double! String.to_double(s) => s.to_real(double);
fn float! String.to_float(s) => s.to_real(float);

fn Splitter String.splitter(self, String split)
{
return Splitter { self, split, 0 };
}

struct Splitter
{
String string;
String split;
usz current;
}

fn void Splitter.reset(&self)
{
self.current = 0;
}

fn String! Splitter.next(&self)
{
usz len = self.string.len;
usz current = self.current;
if (current >= len) return IteratorResult.NO_MORE_ELEMENT?;
String remaining = self.string[current..];
usz! next = remaining.index_of(self.split);
if (try next)
{
defer self.current = current + next + self.split.len;
return remaining[:next];
}
self.current = len;
return remaining;
}


2 changes: 1 addition & 1 deletion lib/std/core/string_iterator.c3
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ fn Char32! StringIterator.next(&self)
Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!;
self.current += read;
return res;
}
}
44 changes: 44 additions & 0 deletions lib/std/io/file.c3
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,50 @@ fn char! File.read_byte(&self) @dynamic
return (char)c;
}

/**
* Load up to buffer.len characters. Returns IoError.OVERFLOW if the file is longer
* than the buffer.
*
* @param filename "The path to the file to read"
* @param [in] buffer "The buffer to read to"
**/
fn char[]! load_buffer(String filename, char[] buffer)
{
File file = open(filename, "rb")!;
defer (void)file.close();
usz len = file.seek(0, END)!;
if (len > buffer.len) return IoError.OVERFLOW?;
file.seek(0, SET)!;
usz read = 0;
while (read < len)
{
read += file.read(buffer[read:len - read])!;
}
return buffer[:len];

}

fn char[]! load_new(String filename, Allocator* allocator = mem::heap())
{
File file = open(filename, "rb")!;
defer (void)file.close();
usz len = file.seek(0, END)!;
file.seek(0, SET)!;
char* data = allocator.alloc_checked(len)!;
defer catch allocator.free(data);
usz read = 0;
while (read < len)
{
read += file.read(data[read:len - read])!;
}
return data[:len];
}

fn char[]! load_temp(String filename)
{
return load_new(filename, mem::temp());
}

/**
* @require self.file `File must be initialized`
*/
Expand Down
2 changes: 1 addition & 1 deletion lib/std/io/io.c3
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fault IoError
* @param stream
* @require @is_instream(stream)
**/
macro String! readline(stream = io::stdin(), Allocator* allocator = mem::heap())
macro String! readline(stream = io::stdin(), Allocator* allocator = mem::heap())
{
bool $is_stream = @typeid(stream) == InStream*.typeid;
$if $is_stream:
Expand Down
10 changes: 10 additions & 0 deletions lib/std/libc/os/posix.c3
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
module libc @if(env::POSIX);


extern fn void* dlopen(ZString path, int flags);
extern fn CInt dlclose(void*);
extern fn void* dlsym(void* handle, ZString symbol);

const int RTLD_LAZY = 0x1;
const int RTLD_NOW = 0x2;
const int RTLD_LOCAL = 0x4;
const int RTLD_GLOBAL = 0x8;

def Pid_t = int;
def Uid_t = uint;
def Gid_t = uint;
Expand Down
15 changes: 13 additions & 2 deletions lib/std/os/posix/process.c3
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,21 @@ const CInt WNOHANG = 1;
const CInt WUNTRACES = 2;

JmpBuf backtrace_jmpbuf @local;
fn CInt backtrace(void** buffer, CInt size) @extern("backtrace") @weak
def BacktraceFn = fn CInt(void** buffer, CInt size);

fn CInt backtrace(void** buffer, CInt size)
{
if (size < 1) return 0;

void* handle = libc::dlopen("libc.so.6", libc::RTLD_LAZY);
if (handle)
{
BacktraceFn backtrace_fn = libc::dlsym(handle, "backtrace");
libc::dlclose(handle);
if (backtrace_fn)
{
return backtrace_fn(buffer, size);
}
}
// Loop through the return addresses until we hit a signal.
// This avoids using the frame address.
SignalFunction restore_backtrace = fn void(CInt) {
Expand Down
22 changes: 22 additions & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# C3C Release Notes

## 0.5.1 Change list

### Changes / improvements
- Improved error messages for const errors.
- Do not link with debug libraries unless using static libraries.
- Add 'print-linking' build option.
- System linker may be used even if the target arch is different from current.
- Slice -> array/vector works for constant slice lenghts.

### Fixes
- On Aarch64 use the correct frame pointer type.
- On Aarch64 macOS, ensure the minimum version is 11.0 (Big Sur)
- Fixes to the yacc grammar.
- Dsym generation on macOS will correctly emit -arch.
- Stacktrace on signals on Linux when backtrace is available.

### Stdlib changes
- `delete` and `delete_range` added to DString.
- `Splitter` iterator added.
- `splitter` and `iterator` String methods.
- `load_new`, `load_buffer` and `load_temp` std::io::file functions.

## 0.5.0 Change List

### Changes / improvements
Expand Down
2 changes: 2 additions & 0 deletions src/build/build.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ typedef struct BuildOptions_
bool print_project_properties;
bool print_precedence;
bool print_build_settings;
bool print_linking;
bool benchmarking;
bool testing;
} BuildOptions;
Expand Down Expand Up @@ -450,6 +451,7 @@ typedef struct
bool testing;
bool read_stdin;
bool print_output;
bool print_linking;
bool no_entry;
int build_threads;
TrustLevel trust_level;
Expand Down
7 changes: 7 additions & 0 deletions src/build/build_options.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ static void usage(void)
OUTPUT(" -L <library dir> - Append the directory to the linker search paths.");
OUTPUT(" -z <argument> - Send the <argument> as a parameter to the linker.");
OUTPUT(" --system-linker=<yes|no> - Use the system linker (default: no for cross compilation, yes otherwise).");
OUTPUT(" --cc <path> - Set C compiler (for C files in projects and use as system linker).");
OUTPUT("");
OUTPUT(" --use-stdlib=<yes|no> - Include the standard library (default: yes).");
OUTPUT(" --link-libc=<yes|no> - Link libc other default libraries (default: yes).");
Expand All @@ -140,6 +141,7 @@ static void usage(void)
OUTPUT(" --fp-math=<option> - FP math behaviour: strict, relaxed, fast.");
OUTPUT("");
OUTPUT(" --debug-stats - Print debug statistics.");
OUTPUT(" --print-linking - Print linker arguments.");
#ifndef NDEBUG
OUTPUT(" --debug-log - Print debug logging to stdout.");
#endif
Expand Down Expand Up @@ -747,6 +749,11 @@ static void parse_option(BuildOptions *options)
debug_stats = true;
return;
}
if (match_longopt("print-linking"))
{
options->print_linking = true;
return;
}
if (match_longopt("list-keywords"))
{
options->print_keywords = true;
Expand Down
1 change: 1 addition & 0 deletions src/build/builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
{
target->arch_os_target = options->arch_os_target_override;
}
target->print_linking = options->print_linking;
if (options->reloc_model != RELOC_DEFAULT) target->reloc_model = options->reloc_model;

if (options->symtab_size) target->symtab_size = options->symtab_size;
Expand Down
23 changes: 20 additions & 3 deletions src/compiler/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,25 @@ void compiler_compile(void)
{
error_exit("Cannot create exe with the name '%s' - there is already a directory with that name.", output_exe);
}
if (link_libc() && platform_target.os != OS_TYPE_WIN32
&& active_target.arch_os_target == default_target && active_target.system_linker != SYSTEM_LINKER_OFF)
bool system_linker_available = link_libc() && platform_target.os != OS_TYPE_WIN32;
bool use_system_linker = system_linker_available && active_target.arch_os_target == default_target;
switch (active_target.system_linker)
{
case SYSTEM_LINKER_ON:
if (!system_linker_available)
{
eprintf("System linker is not supported, defaulting to built-in linker\n");
break;
}
use_system_linker = true;
break;
case SYSTEM_LINKER_OFF:
use_system_linker = false;
break;
default:
break;
}
if (use_system_linker)
{
platform_linker(output_exe, obj_files, output_file_count);
compiler_link_time = bench_mark();
Expand All @@ -504,7 +521,7 @@ void compiler_compile(void)
if (!obj_format_linking_supported(platform_target.object_format) || !linker(output_exe, obj_files,
output_file_count))
{
printf("No linking is performed due to missing linker support.\n");
eprintf("No linking is performed due to missing linker support.\n");
active_target.run_after_compile = false;
}
else
Expand Down
1 change: 1 addition & 0 deletions src/compiler/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ typedef enum
CAST_SABOOL,
CAST_SAPTR,
CAST_SASA,
CAST_SAARR,
CAST_STRPTR,
CAST_STINLINE,
CAST_VECARR,
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,10 @@ static inline bool expr_cast_is_constant_eval(Expr *expr, ConstantEvalKind eval_
case CAST_IDINT:
case CAST_INTARRBS:
case CAST_BSINTARR:
case CAST_SAARR:
if (eval_kind == CONSTANT_EVAL_CONSTANT_VALUE) return false;
return exprid_is_constant_eval(expr->cast_expr.expr, eval_kind);

}
UNREACHABLE
}
Expand Down
Loading