Skip to content

Commit

Permalink
Added the framework for compiling and running musl app (#4)
Browse files Browse the repository at this point in the history
* [app] Add testcases for musl libc

* [feat] Support for loading musl app and entering main function

* [syscall] Add some necessary syscalls for base musl applications

* [ci] Add deploy CI and update test CI

* [syscall] Split syscalls into multiple files according to the syscall categories

* [build] Add configuration for user space

* [loader] Move IO methods to axmem module and simplify codes.

* [CI] Continue on error for clippy and fmt test

* [CI] Update dependencies for qemu build

* [style] Fix code style according to the PR content

* [fix] Set the base address for static-ELF as 0 by default

* [feat] Support complie and test musl app on rv64 and aarch64

* [config] Fix the format for config file

* [style] format the code style

* [style] format crate import style:
```rust
mod sub_mod1;
mod sub_mod2;

use core::foo::Bar;
use alloc::bar::Foo;

use ext_crate::bar;

use crate::baz;
use self::sub_mod1::foo;
use super::sup_mod::qux;

pub use ...
```

* [style] format code style
  • Loading branch information
Azure-stars authored Nov 24, 2024
1 parent 5a2d23e commit 8e3afa9
Show file tree
Hide file tree
Showing 45 changed files with 2,221 additions and 178 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/actions/setup-musl/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ runs:
steps:
- name: Cache musl
id: cache-musl
uses: actions/cache/restore@v3
uses: actions/cache/restore@v4
with:
path: ${{ inputs.arch }}-linux-musl-cross
key: ${{ inputs.arch }}-linux-musl-cross
Expand All @@ -22,7 +22,7 @@ runs:
MUSL_PATH=${{ inputs.arch }}-linux-musl-cross
wget https://musl.cc/${MUSL_PATH}.tgz
tar -xf ${MUSL_PATH}.tgz
- uses: actions/cache/save@v3
- uses: actions/cache/save@v4
if: steps.cache-musl.outputs.cache-hit != 'true'
with:
path: ${{ inputs.arch }}-linux-musl-cross
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/actions/setup-qemu/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ runs:
steps:
- name: Cache QEMU
id: cache-qemu
uses: actions/cache/restore@v3
uses: actions/cache/restore@v4
with:
path: qemu_build
key: qemu-${{ inputs.qemu-version }}-slirp-1
Expand All @@ -22,13 +22,13 @@ runs:
PREFIX: ${{ github.workspace }}/qemu_build
shell: bash
run: |
sudo apt-get update && sudo apt-get install -y ninja-build libslirp-dev
sudo apt-get update && sudo apt-get install -y ninja-build libslirp-dev libglib2.0-dev
wget https://download.qemu.org/$QEMU_PATH.tar.xz && tar -xJf $QEMU_PATH.tar.xz
cd $QEMU_PATH \
&& ./configure --prefix=$PREFIX --target-list=x86_64-softmmu,riscv64-softmmu,aarch64-softmmu --enable-slirp \
&& make -j > /dev/null 2>&1 \
&& make install
- uses: actions/cache/save@v3
- uses: actions/cache/save@v4
if: steps.cache-qemu.outputs.cache-hit != 'true'
with:
path: qemu_build
Expand Down
28 changes: 18 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,54 +9,59 @@ jobs:
fail-fast: false
matrix:
rust-toolchain: [nightly]
targets: [x86_64-unknown-none, riscv64gc-unknown-none-elf, aarch64-unknown-none-softfloat]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust-toolchain }}
components: rust-src, clippy, rustfmt
targets: ${{ matrix.targets }}
- name: Setup ArceOS
run: ./scripts/get_deps.sh
- name: Check rust version
run: rustc --version --verbose
- name: Check code format
run: cargo fmt -- --check
continue-on-error: ${{ matrix.rust-toolchain == 'nightly' }}
run: cargo fmt --all -- --check
- name: Clippy
run: cargo clippy
continue-on-error: ${{ matrix.rust-toolchain == 'nightly' }}
run: cargo clippy --target ${{ matrix.targets }} --all-features -- -D warnings -A clippy::new_without_default

build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
arch: [x86_64]
arch: [x86_64, riscv64, aarch64]
rust-toolchain: [nightly]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust-toolchain }}
components: rust-src, llvm-tools
targets: x86_64-unknown-none
targets: x86_64-unknown-none, riscv64gc-unknown-none-elf, aarch64-unknown-none, aarch64-unknown-none-softfloat
- uses: Swatinem/rust-cache@v2
- run: cargo install cargo-binutils
- run: ./scripts/get_deps.sh
- name: Build for ${{ matrix.arch }}
run: make ARCH=${{ matrix.arch }}

test:
runs-on: ubuntu-latest
test-musl:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
arch: [x86_64, riscv64, aarch64]
rust-toolchain: [nightly]
arch: [x86_64]
env:
qemu-version: 8.2.0
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust-toolchain }}
components: rust-src, llvm-tools
Expand All @@ -69,5 +74,8 @@ jobs:
- uses: ./.github/workflows/actions/setup-qemu
with:
qemu-version: ${{ env.qemu-version }}
- name: Run tests
- name: Build rustup target
if: ${{ matrix.arch != 'riscv64' }}
run: rustup target add ${{ matrix.arch }}-unknown-linux-musl
- name: Run tests for musl applications
run: make test ARCH=${{ matrix.arch }}
34 changes: 34 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Build & Deploy docs

on: [push, pull_request]

env:
rust-toolchain: nightly-2024-05-02

jobs:
doc:
runs-on: ubuntu-latest
strategy:
fail-fast: false
permissions:
contents: write
env:
default-branch: ${{ format('refs/heads/{0}', github.event.repository.default_branch) }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
toolchain: ${{ env.rust-toolchain }}
- uses: Swatinem/rust-cache@v2
- run: cargo install cargo-binutils
- run: ./scripts/get_deps.sh
- name: Build docs
continue-on-error: ${{ github.ref != env.default-branch && github.event_name != 'pull_request' }}
run: make doc_check_missing
- name: Deploy to Github Pages
if: ${{ github.ref == env.default-branch }}
uses: JamesIves/github-pages-deploy-action@v4
with:
single-commit: true
branch: gh-pages
folder: target/doc
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/target
/.vscode
/.arceos
/.cargo
.DS_Store
Cargo.lock
*.elf
*.bin
apps/*/build/
**/target/
**/Cargo.lock
17 changes: 13 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,23 @@ repository = "https://github.com/arceos-org/starry-next"
log = "0.4"
linkme = "0.3"
axerrno = "0.1"
memory_addr = "0.2"
xmas-elf = "0.8"
memory_addr = "0.3"
xmas-elf = "0.9"
bitflags = "2.6"
kernel-elf-parser = "0.1.0"
num_enum = { version = "0.7", default-features = false }
syscalls = { version = "0.6", default-features = false }

axstd = { git = "https://github.com/arceos-org/arceos.git", features = ["paging"] }
arceos_posix_api = { git = "https://github.com/arceos-org/arceos.git" }

axhal = { git = "https://github.com/arceos-org/arceos.git", features = ["uspace"] }
axmm = { git = "https://github.com/arceos-org/arceos.git" }
axtask = { git = "https://github.com/arceos-org/arceos.git" }
axsync = { git = "https://github.com/arceos-org/arceos.git" }
axruntime = { git = "https://github.com/arceos-org/arceos.git", features = ["multitask"] }
arceos_posix_api = { git = "https://github.com/arceos-org/arceos.git" }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86 = "0.52"

[build-dependencies]
toml_edit = "0.22"
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
AX_ROOT ?= $(PWD)/.arceos
AX_TESTCASE ?= nimbos
ARCH ?= x86_64
AX_TESTCASES_LIST=$(shell cat ./apps/$(AX_TESTCASE)/testcase_list | tr '\n' ',')

export AX_TESTCASES_LIST=$(shell cat ./apps/$(AX_TESTCASE)/testcase_list | tr '\n' ',')
RUSTDOCFLAGS := -Z unstable-options --enable-index-page -D rustdoc::broken_intra_doc_links -D missing-docs

ifneq ($(filter $(MAKECMDGOALS),doc_check_missing),) # make doc_check_missing
export RUSTDOCFLAGS
else ifeq ($(filter $(MAKECMDGOALS),clean user_apps ax_root),) # Not make clean, user_apps, ax_root
export AX_TESTCASES_LIST
endif

all: build

Expand All @@ -22,4 +29,7 @@ clean: ax_root
@make -C $(AX_ROOT) A=$(PWD) clean
@cargo clean

doc_check_missing:
@cargo doc --no-deps --all-features --workspace

.PHONY: all ax_root build run justrun debug disasm clean
76 changes: 76 additions & 0 deletions apps/libc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Build testcases for rust and c programs

ARCH ?= x86_64
# Whether cross-compiling
TARGET ?= musl

# Build target for c programs
CC := $(ARCH)-linux-$(TARGET)-gcc

# Build target for rust programs
ifeq ($(TARGET),musl)
CFLAGS := -static -no-pie
ifeq ($(ARCH),x86_64)
RUST_TARGET := x86_64-unknown-linux-musl
RUSTFLAGS :=
else ifeq ($(ARCH),aarch64)
RUST_TARGET := aarch64-unknown-linux-musl
RUSTFLAGS := -C linker=aarch64-linux-musl-ld
else ifeq ($(ARCH),riscv64)
$(warning "Warn: Rust musl target not supported for riscv64")
RUST_TARGET := ""
RUSTFLAGS :=
else
$(error "Unknown ARCH")
endif
else ifeq ($(TARGET),gnu)
CFLAGS :=
ifeq ($(ARCH),x86_64)
RUST_TARGET := x86_64-unknown-linux-gnu
else ifeq ($(ARCH),aarch64)
RUST_TARGET := aarch64-unknown-linux-gnu
else ifeq ($(ARCH),riscv64)
RUST_TARGET := riscv64gc-unknown-linux-gnu
else
$(error "Unknown ARCH")
endif
else
$(error "Unknown TARGET")
endif

$(info RUSTFLAGS: "$(RUSTFLAGS)")
export RUSTFLAGS

all: build

build: build_dir build_c build_rust

build_dir:
@mkdir -p build
@mkdir -p build/$(ARCH)

build_c:
@for app in $(wildcard c/*/*.c); do \
echo "Building $${app%.c}"; \
app_name=$$(basename $$(dirname $${app})); \
$(CC) -o build/$(ARCH)/$${app_name}_c $${app} $(CFLAGS); \
done

build_rust:
if [ -n $(RUST_TARGET) ]; then \
for app in $(shell find rust -name Cargo.toml); do \
echo "Building $$(dirname $${app})"; \
app_name=$$(basename $$(dirname $${app})); \
cargo build --release --target $(RUST_TARGET) --manifest-path $${app} ; \
cp $$(dirname $${app})/target/$(RUST_TARGET)/release/$${app_name} build/$(ARCH)/$${app_name}_rust ; \
done \
fi

clean:
@rm -rf build
@for app in $(shell find rust -name Cargo.toml); do \
app_name=$$(basename $$(dirname $${app})); \
cargo clean --manifest-path $${app} ; \
done

.PHONY: all build_dir build_c build_rust clean
6 changes: 6 additions & 0 deletions apps/libc/c/helloworld/helloworld.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <stdio.h>

int main() {
printf("Hello, World!\n");
return 0;
}
9 changes: 9 additions & 0 deletions apps/libc/c/sleep/sleep.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <stdio.h>

int main()
{
printf("Sleeping for 5 seconds...\n");
sleep(5);
printf("Done!\n");
return 0;
}
7 changes: 7 additions & 0 deletions apps/libc/expect_off.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
smp = 1
build_mode = release
log_level = off

Hello, World!
Sleeping for 5 seconds...
Done!
6 changes: 6 additions & 0 deletions apps/libc/rust/helloworld/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "helloworld"
version = "0.1.0"
edition = "2021"

[dependencies]
3 changes: 3 additions & 0 deletions apps/libc/rust/helloworld/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello world from Rust!");
}
6 changes: 6 additions & 0 deletions apps/libc/rust/task/sleep/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "sleep"
version = "0.1.0"
edition = "2021"

[dependencies]
6 changes: 6 additions & 0 deletions apps/libc/rust/task/sleep/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
println!("Sleep for 5 seconds from Rust!");
let duration = std::time::Duration::from_secs(5);
std::thread::sleep(duration);
println!("Woke up from sleep!");
}
1 change: 1 addition & 0 deletions apps/libc/test_cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test_one "LOG=off FEATURES=fp_simd" "expect_off.out"
2 changes: 2 additions & 0 deletions apps/libc/testcase_list
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
helloworld_c
sleep_c
4 changes: 2 additions & 2 deletions apps/nimbos/c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,6 @@ endforeach()
add_custom_command(
OUTPUT syscall_ids.h
COMMAND sed ARGS -n -e s/__NR_/SYS_/p
< ${CMAKE_SOURCE_DIR}/lib/syscall_ids.h.in
< ${CMAKE_SOURCE_DIR}/${ARCH_DIR}/syscall_ids.h.in
> ${CMAKE_SOURCE_DIR}/lib/syscall_ids.h
)
)
11 changes: 11 additions & 0 deletions apps/nimbos/c/lib/arch/aarch64/syscall_ids.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#define __NR_read 63
#define __NR_write 64
#define __NR_exit 93
#define __NR_yield 124
#define __NR_getpid 172
#define __NR_clone 220
#define __NR_fork 220
#define __NR_exec 221
#define __NR_waitpid 260
#define __NR_clock_gettime 403
#define __NR_clock_nanosleep 407
11 changes: 11 additions & 0 deletions apps/nimbos/c/lib/arch/riscv/syscall_ids.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#define __NR_read 63
#define __NR_write 64
#define __NR_exit 93
#define __NR_yield 124
#define __NR_getpid 172
#define __NR_clone 220
#define __NR_fork 220
#define __NR_exec 221
#define __NR_waitpid 260
#define __NR_clock_gettime 403
#define __NR_clock_nanosleep 407
Loading

0 comments on commit 8e3afa9

Please sign in to comment.