mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Improved OpenBSD support (#2317)
* add openbsd support, compiles and passses all tests * fix backtrace * gh actions should include openbsd artifacts
This commit is contained in:
119
.github/workflows/main.yml
vendored
119
.github/workflows/main.yml
vendored
@@ -10,8 +10,10 @@ env:
|
||||
LLVM_RELEASE_VERSION_WINDOWS: 18
|
||||
LLVM_RELEASE_VERSION_MAC: 17
|
||||
LLVM_RELEASE_VERSION_LINUX: 17
|
||||
LLVM_RELEASE_VERSION_OPENBSD: 19
|
||||
LLVM_RELEASE_VERSION_UBUNTU22: 17
|
||||
LLVM_DEV_VERSION: 21
|
||||
OPENBSD_RELEASE: "7.7"
|
||||
jobs:
|
||||
|
||||
build-msvc:
|
||||
@@ -751,6 +753,119 @@ jobs:
|
||||
nix build -L ".#c3c-checks"
|
||||
fi
|
||||
|
||||
build-openbsd:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
# Don't abort runners if a single one fails
|
||||
fail-fast: false
|
||||
matrix:
|
||||
build_type: [Release, Debug]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: OpenBSD VM
|
||||
uses: vmactions/openbsd-vm@main
|
||||
with:
|
||||
prepare: |
|
||||
pkg_add cmake llvm-19.1.7p3 ninja
|
||||
|
||||
run: |
|
||||
echo "CMake"
|
||||
cmake -B build \
|
||||
-G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
|
||||
-DLLVM_ENABLE_LIBXML2=OFF \
|
||||
-DC3_LLVM_VERSION=${LLVM_RELEASE_VERSION_OPENBSD}
|
||||
cmake --build build
|
||||
echo "Compile and run some examples"
|
||||
cd resources
|
||||
../build/c3c compile examples/base64.c3
|
||||
../build/c3c compile examples/binarydigits.c3
|
||||
../build/c3c compile examples/brainfk.c3
|
||||
../build/c3c compile examples/factorial_macro.c3
|
||||
../build/c3c compile examples/fasta.c3
|
||||
../build/c3c compile examples/gameoflife.c3
|
||||
../build/c3c compile examples/hash.c3
|
||||
../build/c3c compile-only examples/levenshtein.c3
|
||||
../build/c3c compile examples/load_world.c3
|
||||
../build/c3c compile-only examples/map.c3
|
||||
../build/c3c compile examples/mandelbrot.c3
|
||||
../build/c3c compile examples/plus_minus.c3
|
||||
../build/c3c compile examples/nbodies.c3
|
||||
../build/c3c compile examples/spectralnorm.c3
|
||||
../build/c3c compile examples/swap.c3
|
||||
../build/c3c compile examples/contextfree/boolerr.c3
|
||||
../build/c3c compile examples/contextfree/dynscope.c3
|
||||
../build/c3c compile examples/contextfree/guess_number.c3
|
||||
../build/c3c compile examples/contextfree/multi.c3
|
||||
../build/c3c compile examples/contextfree/cleanup.c3
|
||||
../build/c3c compile-run examples/hello_world_many.c3
|
||||
../build/c3c compile-run examples/time.c3
|
||||
../build/c3c compile-run examples/fannkuch-redux.c3
|
||||
../build/c3c compile-run examples/contextfree/boolerr.c3
|
||||
../build/c3c compile-run examples/load_world.c3
|
||||
../build/c3c compile-run examples/process.c3
|
||||
../build/c3c compile-run examples/ls.c3
|
||||
../build/c3c compile-run examples/args.c3 -- foo -bar "baz baz"
|
||||
cd ..
|
||||
echo "Compile and run dynlib-test"
|
||||
cd resources/examples/dynlib-test
|
||||
../../../build/c3c -vv dynamic-lib add.c3
|
||||
mv add.so libadd.so
|
||||
cc test.c -L. -ladd -Wl,-rpath=.
|
||||
./a.out
|
||||
../../../build/c3c compile-run test.c3 -L . -l add -z -Wl,-rpath=.
|
||||
cd ../../../
|
||||
echo "Compile and run staticlib-test"
|
||||
cd resources/examples/staticlib-test
|
||||
../../../build/c3c -vv static-lib add.c3
|
||||
mv add.a libadd.a
|
||||
cc test.c -L. -ladd
|
||||
./a.out
|
||||
../../../build/c3c compile-run test.c3 -L . -l add
|
||||
cd ../../../
|
||||
echo "Compile run unit tests"
|
||||
cd test
|
||||
../build/c3c --max-mem 128 compile-test unit -D SLOW_TESTS
|
||||
cd ..
|
||||
echo "Build testproject"
|
||||
cd resources/testproject
|
||||
../../build/c3c run -vvv --trust=full
|
||||
cd ../../
|
||||
echo "Test WASM"
|
||||
cd resources/testfragments
|
||||
../../build/c3c compile --target wasm32 -g0 --no-entry -Os wasm4.c3
|
||||
cd ../../
|
||||
echo "Build testproject direct linker"
|
||||
cd resources/testproject
|
||||
../../build/c3c run -vvv --linker=builtin --trust=full
|
||||
cd ../../
|
||||
echo "Init a library & a project"
|
||||
./build/c3c init-lib mylib
|
||||
ls mylib.c3l
|
||||
./build/c3c init myproject
|
||||
ls myproject
|
||||
echo "run compiler tests"
|
||||
cd test
|
||||
../build/c3c --max-mem 128 compile-run -O1 src/test_suite_runner.c3 -- ../build/c3c test_suite/
|
||||
cd ..
|
||||
|
||||
- name: bundle_output
|
||||
run: |
|
||||
mkdir c3
|
||||
cp -r lib c3
|
||||
cp msvc_build_libraries.py c3
|
||||
cp build/c3c c3
|
||||
cp README.md c3
|
||||
cp releasenotes.md c3
|
||||
tar czf c3-openbsd-$OPENBSD_RELEASE-${{matrix.build_type}}.tar.gz c3
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: c3-openbsd-$OPENBSD_RELEASE-${{matrix.build_type}}
|
||||
path: c3-openbsd-$OPENBSD_RELEASE-${{matrix.build_type}}.tar.gz
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [build-msvc, build-linux, build-mac, build-linux-ubuntu22]
|
||||
@@ -773,6 +888,8 @@ jobs:
|
||||
- run: zip -r c3-windows-debug.zip c3-windows-Debug
|
||||
- run: mv c3-linux-Release/c3-linux-Release.tar.gz c3-linux-Release/c3-linux.tar.gz
|
||||
- run: mv c3-linux-Debug/c3-linux-Debug.tar.gz c3-linux-Debug/c3-linux-debug.tar.gz
|
||||
- run: mv c3-openbsd-$OPENBSD_RELEASE-Release/c3-openbsd-$OPENBSD_RELEASE-Release.tar.gz c3-openbsd-$OPENBSD_RELEASE-Release/c3-openbsd-$OPENBSD_RELEASE.tar.gz
|
||||
- run: mv c3-openbsd-$OPENBSD_RELEASE-Debug/c3-openbsd-$OPENBSD_RELEASE-Debug.tar.gz c3-openbsd-$OPENBSD_RELEASE-Debug/c3-openbsd-$OPENBSD_RELEASE-debug.tar.gz
|
||||
- run: mv c3-ubuntu-22-Release/c3-ubuntu-22-Release.tar.gz c3-ubuntu-22-Release/c3-ubuntu-22.tar.gz
|
||||
- run: mv c3-ubuntu-22-Debug/c3-ubuntu-22-Debug.tar.gz c3-ubuntu-22-Debug/c3-ubuntu-22-debug.tar.gz
|
||||
- run: mv c3-macos-Release/c3-macos-Release.zip c3-macos-Release/c3-macos.zip
|
||||
@@ -794,6 +911,8 @@ jobs:
|
||||
c3-windows-debug.zip
|
||||
c3-linux-Release/c3-linux.tar.gz
|
||||
c3-linux-Debug/c3-linux-debug.tar.gz
|
||||
c3-openbsd-$OPENBSD_RELEASE-Release/c3-openbsd-$OPENBSD_RELEASE.tar.gz
|
||||
g3-openbsd-$OPENBSD_RELEASE-Debug/c3-openbsd-$OPENBSD_RELEASE-debug.tar.gz
|
||||
c3-ubuntu-22-Release/c3-ubuntu-22.tar.gz
|
||||
c3-ubuntu-22-Debug/c3-ubuntu-22-debug.tar.gz
|
||||
c3-macos-Release/c3-macos.zip
|
||||
|
||||
15
README.md
15
README.md
@@ -12,6 +12,7 @@ Precompiled binaries for the following operating systems are available:
|
||||
- Debian x64 [download](https://github.com/c3lang/c3c/releases/download/latest-prerelease/c3-linux.tar.gz), [install instructions](#installing-on-debian-with-precompiled-binaries).
|
||||
- Ubuntu x86 [download](https://github.com/c3lang/c3c/releases/download/latest-prerelease/c3-ubuntu-20.tar.gz), [install instructions](#installing-on-ubuntu-with-precompiled-binaries).
|
||||
- MacOS Arm64 [download](https://github.com/c3lang/c3c/releases/download/latest-prerelease/c3-macos.zip), [install instructions](#installing-on-macos-with-precompiled-binaries).
|
||||
- OpenBSD 7.7 x64 [download](https://github.com/c3lang/c3c/releases/download/latest-prerelease/c3-openbsd-7.7.tar.gz), [install instructions](#installing-on-openbsd-with-precompiled-binaries).
|
||||
|
||||
The manual for C3 can be found at [www.c3-lang.org](http://www.c3-lang.org).
|
||||
|
||||
@@ -176,12 +177,14 @@ The compiler is currently verified to compile on Linux, Windows and MacOS.
|
||||
| NetBSD x86 | Untested | Untested | No | Yes | Untested | Yes* |
|
||||
| NetBSD x64 | Untested | Untested | No | Yes | Untested | Yes* |
|
||||
| OpenBSD x86 | Untested | Untested | No | Yes | Untested | Yes* |
|
||||
| OpenBSD x64 | Untested | Untested | No | Yes | Untested | Yes* |
|
||||
| OpenBSD x64 | Yes* | Yes | Yes* | Yes | Untested | Yes* |
|
||||
| MCU x86 | No | Untested | No | No | No | Yes* |
|
||||
| Wasm32 | No | Yes | No | No | No | No |
|
||||
| Wasm64 | No | Untested | No | No | No | No |
|
||||
|
||||
*\* Inline asm is still a work in progress*
|
||||
*\* Inline asm is still a work in progress*<br>
|
||||
*\* OpenBSD 7.7 is the only tested version*<br>
|
||||
*\* OpenBSD has limited stacktrace, needs to be tested further*
|
||||
|
||||
More platforms will be supported in the future.
|
||||
|
||||
@@ -227,6 +230,14 @@ This installs the latest prerelease build, as opposed to the latest released ver
|
||||
|
||||
(*Note that there is a known issue with debug symbol generation on MacOS 13, see [issue #1086](https://github.com/c3lang/c3c/issues/1086))
|
||||
|
||||
#### Installing on OpenBSD with precompiled binaries
|
||||
1. Download tar file: [https://github.com/c3lang/c3c/releases/download/latest-prerelease/c3-openbsd-7.7.tar.gz](https://github.com/c3lang/c3c/releases/download/latest-prerelease/c3-openbsd-7.7.tar.gz)
|
||||
(debug version [here](https://github.com/c3lang/c3c/releases/download/latest-prerelease/c3-openbsd-7.7-debug.tar.gz))
|
||||
2. Unpack executable and standard lib.
|
||||
3. Run `./c3c`.
|
||||
|
||||
(*Note that this is specifically for OpenBSD 7.7, running it on any other version is prone to ABI breaks)
|
||||
|
||||
#### Installing on Arch Linux
|
||||
Arch includes c3c in the official 'extra' repo. It can be easily installed the usual way:
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ const bool TRACK_MEMORY = DEBUG_SYMBOLS && (COMPILER_SAFE_MODE || TESTING);
|
||||
const bool X86_64 = ARCH_TYPE == X86_64;
|
||||
const bool X86 = ARCH_TYPE == X86;
|
||||
const bool AARCH64 = ARCH_TYPE == AARCH64;
|
||||
const bool NATIVE_STACKTRACE = LINUX || DARWIN || WIN32;
|
||||
const bool NATIVE_STACKTRACE = LINUX || DARWIN || OPENBSD || WIN32;
|
||||
const bool LINUX = LIBC && OS_TYPE == LINUX;
|
||||
const bool DARWIN = LIBC && os_is_darwin();
|
||||
const bool WIN32 = LIBC && OS_TYPE == WIN32;
|
||||
@@ -160,7 +160,7 @@ const bool MEMORY_SANITIZER = $$MEMORY_SANITIZER;
|
||||
const bool THREAD_SANITIZER = $$THREAD_SANITIZER;
|
||||
const bool ANY_SANITIZER = ADDRESS_SANITIZER || MEMORY_SANITIZER || THREAD_SANITIZER;
|
||||
const int LANGUAGE_DEV_VERSION = $$LANGUAGE_DEV_VERSION;
|
||||
const bool HAS_NATIVE_ERRNO = env::LINUX || env::ANDROID || env::DARWIN || env::WIN32;
|
||||
const bool HAS_NATIVE_ERRNO = env::LINUX || env::ANDROID || env::OPENBSD || env::DARWIN || env::WIN32;
|
||||
|
||||
macro bool os_is_darwin() @const
|
||||
{
|
||||
|
||||
@@ -11,6 +11,11 @@ extern fn int* __errno() @if(env::ANDROID);
|
||||
macro int errno() @if(env::ANDROID) => *__errno();
|
||||
macro void errno_set(int err) @if(env::ANDROID) => *(__errno()) = err;
|
||||
|
||||
// OpenBSD
|
||||
extern fn int* __errno() @if(env::OPENBSD);
|
||||
macro int errno() @if(env::OPENBSD) => *__errno();
|
||||
macro void errno_set(int err) @if(env::OPENBSD) => *(__errno()) = err;
|
||||
|
||||
// Darwin
|
||||
extern fn int* __error() @if(env::DARWIN);
|
||||
macro int errno() @if(env::DARWIN) => *__error();
|
||||
|
||||
60
lib/std/libc/os/openbsd.c3
Normal file
60
lib/std/libc/os/openbsd.c3
Normal file
@@ -0,0 +1,60 @@
|
||||
module libc @if(env::OPENBSD);
|
||||
|
||||
// Checked for x86_64
|
||||
|
||||
alias Blksize_t = int;
|
||||
alias Nlink_t = $typefrom(env::X86_64 ? uint.typeid : CUInt.typeid);
|
||||
alias Dev_t = int;
|
||||
alias Ino_t = ulong;
|
||||
alias Mode_t = uint;
|
||||
alias Blkcnt_t = long;
|
||||
alias Fflags_t = uint;
|
||||
|
||||
struct Stat @if(env::X86_64)
|
||||
{
|
||||
Mode_t st_mode;
|
||||
Dev_t st_dev;
|
||||
Ino_t st_ino;
|
||||
Nlink_t st_nlink;
|
||||
Uid_t st_uid;
|
||||
Gid_t st_gid;
|
||||
Dev_t st_rdev;
|
||||
TimeSpec st_atime;
|
||||
TimeSpec st_mtime;
|
||||
TimeSpec st_ctime;
|
||||
Off_t st_size;
|
||||
Blkcnt_t st_blocks;
|
||||
Blksize_t st_blksize;
|
||||
Fflags_t st_flags;
|
||||
uint st_gen;
|
||||
ulong[10] st_spare;
|
||||
}
|
||||
|
||||
// TODO: Investigate if this needs to be fixed
|
||||
struct Stat @if(!env::X86_64)
|
||||
{
|
||||
Dev_t st_dev;
|
||||
Ino_t st_ino;
|
||||
Mode_t st_mode;
|
||||
Nlink_t st_nlink;
|
||||
Uid_t st_uid;
|
||||
Gid_t st_gid;
|
||||
Dev_t st_rdev;
|
||||
CInt __pad1;
|
||||
Off_t st_size;
|
||||
Blksize_t st_blksize;
|
||||
CInt __pad2;
|
||||
Blkcnt_t st_blocks;
|
||||
Time_t st_atime;
|
||||
long st_atime_nsec;
|
||||
Time_t st_mtime;
|
||||
long st_mtime_nsec;
|
||||
Time_t st_ctime;
|
||||
long st_ctime_nsec;
|
||||
CInt[2] __unused;
|
||||
}
|
||||
|
||||
extern fn CInt stat(ZString path, Stat* stat);
|
||||
|
||||
extern fn CInt get_nprocs();
|
||||
extern fn CInt get_nprocs_conf();
|
||||
@@ -87,11 +87,12 @@ fn void*[] capture_current(void*[] buffer)
|
||||
|
||||
alias BacktraceList = List{Backtrace};
|
||||
|
||||
alias symbolize_backtrace @if(env::LINUX) = linux::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::WIN32) = win32::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::DARWIN) = darwin::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::LINUX) = linux::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::WIN32) = win32::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::DARWIN) = darwin::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::OPENBSD) = openbsd::symbolize_backtrace;
|
||||
|
||||
fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace) @if(!env::NATIVE_STACKTRACE)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,74 @@
|
||||
module std::os::openbsd @if(env::OPENBSD);
|
||||
import libc, std::os, std::collections::list;
|
||||
|
||||
extern fn ZString* backtrace_symbols_fmt(void **addrlist, usz len, ZString fmt);
|
||||
|
||||
fn Backtrace? backtrace_line_parse(Allocator allocator, String obj, String addr2line) @local
|
||||
{
|
||||
@stack_mem(256; Allocator mem)
|
||||
{
|
||||
String[] parts = addr2line.trim().split(mem, " at ");
|
||||
if (parts.len != 2) return NOT_FOUND?;
|
||||
|
||||
uint line = 0;
|
||||
String source = "";
|
||||
if (!parts[1].contains("?") && parts[1].contains(":"))
|
||||
{
|
||||
usz index = parts[1].rindex_of_char(':')!;
|
||||
source = parts[1][:index];
|
||||
line = parts[1][index + 1..].to_uint()!;
|
||||
}
|
||||
return {
|
||||
.function = parts[0].copy(allocator),
|
||||
.object_file = obj.copy(allocator),
|
||||
.file = source.copy(allocator),
|
||||
.line = line,
|
||||
.allocator = allocator,
|
||||
.is_inline = false,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
fn void? backtrace_add_addr2line(Allocator allocator, BacktraceList* list, String obj, String addr2line) @local
|
||||
{
|
||||
list.push(backtrace_line_parse(allocator, obj, addr2line)!);
|
||||
}
|
||||
|
||||
fn void? backtrace_add_from_exec(Allocator allocator, BacktraceList* list, String fun, String obj) @local
|
||||
{
|
||||
char[1024] buf @noinit;
|
||||
String addr2line = process::execute_stdout_to_buffer(&buf, {"llvm-addr2line", "-fpe", obj, fun})!;
|
||||
return backtrace_add_addr2line(allocator, list, obj, addr2line);
|
||||
}
|
||||
|
||||
fn void? backtrace_add_element(Allocator allocator, BacktraceList *list, String fun, String obj) @local
|
||||
{
|
||||
return backtrace_add_from_exec(allocator, list, fun, obj);
|
||||
}
|
||||
|
||||
fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace)
|
||||
{
|
||||
BacktraceList list;
|
||||
list.init(allocator, backtrace.len);
|
||||
defer catch
|
||||
{
|
||||
foreach (trace : list)
|
||||
{
|
||||
trace.free();
|
||||
}
|
||||
list.free();
|
||||
}
|
||||
|
||||
ZString *strings = backtrace_symbols_fmt(backtrace.ptr, backtrace.len, "%n%D %f");
|
||||
|
||||
for (int i = 0; i < backtrace.len; i++) {
|
||||
String full = strings[i].str_view();
|
||||
Splitter iter = full.tokenize(" ");
|
||||
String fun = iter.next()!;
|
||||
String obj = iter.next()!;
|
||||
backtrace_add_element(allocator, &list, fun, obj)!;
|
||||
}
|
||||
|
||||
free(strings);
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,9 @@ const CInt WUNTRACES = 2;
|
||||
JmpBuf backtrace_jmpbuf @local;
|
||||
alias BacktraceFn = fn CInt(void** buffer, CInt size);
|
||||
|
||||
fn CInt backtrace(void** buffer, CInt size)
|
||||
extern fn CInt backtrace(void** buffer, CInt size) @if(env::OPENBSD);
|
||||
|
||||
fn CInt backtrace(void** buffer, CInt size) @if(!env::OPENBSD)
|
||||
{
|
||||
if (size < 1) return 0;
|
||||
void* handle = libc::dlopen("libc.so.6", libc::RTLD_LAZY|libc::RTLD_NODELETE);
|
||||
|
||||
@@ -532,6 +532,11 @@ static void linker_setup_freebsd(const char ***args_ref, Linker linker_type, boo
|
||||
{
|
||||
if (linker_type == LINKER_CC) {
|
||||
linking_add_link(&compiler.linking, "pthread");
|
||||
linking_add_link(&compiler.linking, "execinfo"); // for backtrace
|
||||
if (compiler.build.debug_info == DEBUG_INFO_FULL)
|
||||
{
|
||||
add_plain_arg("-rdynamic");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (is_no_pie(compiler.platform.reloc_model)) add_plain_arg("-no-pie");
|
||||
|
||||
10
src/main.c
10
src/main.c
@@ -4,6 +4,9 @@
|
||||
#include "utils/lib.h"
|
||||
#include <compiler_tests/benchmark.h>
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
bool debug_log = false;
|
||||
|
||||
@@ -27,6 +30,13 @@ int main_real(int argc, const char *argv[])
|
||||
{
|
||||
srand((unsigned int)time(NULL));
|
||||
compiler_exe_name = argv[0];
|
||||
#ifdef __OpenBSD__
|
||||
// override data size constrain set up by the system */
|
||||
struct rlimit l;
|
||||
getrlimit(RLIMIT_DATA, &l);
|
||||
l.rlim_cur = l.rlim_max;
|
||||
setrlimit(RLIMIT_DATA, &l);
|
||||
#endif
|
||||
bench_begin();
|
||||
|
||||
// Setjmp will allow us to add things like fuzzing with
|
||||
|
||||
@@ -411,6 +411,10 @@ fn void test_file(Path file_path)
|
||||
// Construct the compile line
|
||||
List{String} cmdline;
|
||||
cmdline.push(compiler_path.str_view());
|
||||
$if env::OPENBSD:
|
||||
cmdline.push("--max-mem");
|
||||
cmdline.push("128");
|
||||
$endif
|
||||
cmdline.push("compile-only");
|
||||
cmdline.push("--test");
|
||||
if (stdlib)
|
||||
|
||||
0
test/unit/stdlib/libc/os/openbsd.c3
Normal file
0
test/unit/stdlib/libc/os/openbsd.c3
Normal file
Reference in New Issue
Block a user