From 59d9b60fe31fe92c132663122bccae114578296a Mon Sep 17 00:00:00 2001 From: Ybeichen Date: Thu, 28 Dec 2023 23:35:04 +0800 Subject: [PATCH] Add the Ruxgo book and update README.md --- .gitignore | 3 +- README.md | 195 ++---------------- apps/iperf/README.md | 5 +- apps/redis/README.md | 4 +- apps/sqlite3/README.md | 3 +- doc/README.md | 24 +++ doc/ruxgo_book/.gitignore | 1 + doc/ruxgo_book/assets/elasticlunr.js | 28 +++ doc/ruxgo_book/assets/fzf.umd.js | 6 + doc/ruxgo_book/book.toml | 13 ++ doc/ruxgo_book/src/SUMMARY.md | 30 +++ doc/ruxgo_book/src/commands/build-commands.md | 7 + .../src/commands/general-commands.md | 5 + doc/ruxgo_book/src/commands/index.md | 5 + doc/ruxgo_book/src/commands/ruxgo-build.md | 1 + doc/ruxgo_book/src/commands/ruxgo-clean.md | 1 + doc/ruxgo_book/src/commands/ruxgo-help.md | 31 +++ doc/ruxgo_book/src/commands/ruxgo-run.md | 1 + doc/ruxgo_book/src/commands/ruxgo-version.md | 1 + doc/ruxgo_book/src/guide/builder_module.md | 7 + .../src/guide/companion_tool_to_ruxos.md | 7 + doc/ruxgo_book/src/guide/design_features.md | 17 ++ doc/ruxgo_book/src/guide/design_principle.md | 12 ++ doc/ruxgo_book/src/guide/index.md | 11 + doc/ruxgo_book/src/guide/learn_from_cargo.md | 13 ++ doc/ruxgo_book/src/guide/os_module.md | 61 ++++++ .../src/guide/reflections_on_construct.md | 21 ++ .../src/guide/ruxgo_functionality.md | 17 ++ doc/ruxgo_book/src/guide/target_module.md | 23 +++ doc/ruxgo_book/src/guide/toml_example.md | 73 +++++++ doc/ruxgo_book/src/guide/toml_file.md | 9 + doc/ruxgo_book/src/installation.md | 12 ++ doc/ruxgo_book/src/introduction.md | 5 + doc/ruxgo_book/src/run_apps.md | 17 ++ 34 files changed, 489 insertions(+), 180 deletions(-) create mode 100644 doc/README.md create mode 100644 doc/ruxgo_book/.gitignore create mode 100644 doc/ruxgo_book/assets/elasticlunr.js create mode 100644 doc/ruxgo_book/assets/fzf.umd.js create mode 100644 doc/ruxgo_book/book.toml create mode 100644 doc/ruxgo_book/src/SUMMARY.md create mode 100644 doc/ruxgo_book/src/commands/build-commands.md create mode 100644 doc/ruxgo_book/src/commands/general-commands.md create mode 100644 doc/ruxgo_book/src/commands/index.md create mode 100644 doc/ruxgo_book/src/commands/ruxgo-build.md create mode 100644 doc/ruxgo_book/src/commands/ruxgo-clean.md create mode 100644 doc/ruxgo_book/src/commands/ruxgo-help.md create mode 100644 doc/ruxgo_book/src/commands/ruxgo-run.md create mode 100644 doc/ruxgo_book/src/commands/ruxgo-version.md create mode 100644 doc/ruxgo_book/src/guide/builder_module.md create mode 100644 doc/ruxgo_book/src/guide/companion_tool_to_ruxos.md create mode 100644 doc/ruxgo_book/src/guide/design_features.md create mode 100644 doc/ruxgo_book/src/guide/design_principle.md create mode 100644 doc/ruxgo_book/src/guide/index.md create mode 100644 doc/ruxgo_book/src/guide/learn_from_cargo.md create mode 100644 doc/ruxgo_book/src/guide/os_module.md create mode 100644 doc/ruxgo_book/src/guide/reflections_on_construct.md create mode 100644 doc/ruxgo_book/src/guide/ruxgo_functionality.md create mode 100644 doc/ruxgo_book/src/guide/target_module.md create mode 100644 doc/ruxgo_book/src/guide/toml_example.md create mode 100644 doc/ruxgo_book/src/guide/toml_file.md create mode 100644 doc/ruxgo_book/src/installation.md create mode 100644 doc/ruxgo_book/src/introduction.md create mode 100644 doc/ruxgo_book/src/run_apps.md diff --git a/.gitignore b/.gitignore index 2e4eb93..a5d66e2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ compile_commands.json ruxos_bld sqlite-amalgamation-3410100 file.sqlite -dump.rdb \ No newline at end of file +dump.rdb +iperf \ No newline at end of file diff --git a/README.md b/README.md index a5cd622..3c42a2a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Ruxgo -Ruxgo is a Cargo-like build tool for building C and C++ applications that relies solely on a toml file. It abandons the complex syntax and rule-dependent construction in the original MAKE tool, exposing the most original compilation process. If you hate using Makefile, might as well try Ruxgo to build applications, just take a few minutes! +Ruxgo is a Cargo-like build tool for building C and C++ applications that relies solely on a Toml file. -For a project you want to build, you just need to figure out the source file path, header file path, cflags and ldflags, then fill them into the appropriate places in the toml file. Ruxgo does the rest, so easy! +**To start using Ruxgo**, learn more at The Ruxgo Book. 🚧 Working In Progress. @@ -16,7 +16,7 @@ Once you have installed Rust, the following command can be used to build and ins cargo install --git https://github.com/Ybeichen/ruxgo.git ruxgo ``` -This will automatically download `ruxgo`, build it, and install it in Cargo's global binary directory (`~/.cargo/bin/` by default). +This will automatically download Ruxgo, build it, and install it in Cargo's global binary directory (`~/.cargo/bin/` by default). To uninstall, run the command `cargo uninstall ruxgo`. @@ -32,55 +32,9 @@ To uninstall, run the command `cargo uninstall ruxgo`. * [x] Supported ruxlibc and ruxmusl * [ ] Create new project -## Usage +## Quickstart & Ruxgo-apps -Write a `config_linux.toml` for linux and `config_win32.toml` for windows in the project directory. - -You can then build the project with: -```console -ruxgo -b -``` - -Once built, you can execute the project via: -```console -ruxgo -r -``` - -For help: -```console -ruxgo --help -``` - -The help command will show you the following: -```sh -Usage: ruxgo [OPTIONS] [CHOICES]... [COMMAND] - -Commands: - init Initialize a new project Defaults to C++ if no language is specified - config Configuration settings - help Print this message or the help of the given subcommand(s) - -Arguments: - [CHOICES]... Choose which parts to delete - -Options: - -b, --build Build your project - -c, --clean Clean the obj and bin intermediates - -r, --run Run the executable - --bin-args ... Arguments to pass to the executable when running - --gen-cc Generate compile_commands.json - --gen-vsc Generate .vscode/c_cpp_properties.json - --update-packages Update packages - --restore-packages Restore packages - -h, --help Print help - -V, --version Print version -``` - -You can also configure the log level with the environment variable `"RUXGO_LOG_LEVEL"`, the default log level is "Info". - -## Ruxgo-apps - -The `apps/` directory places all the toml files that have been tested. Currently, there are two ways to build an app: locally and on ruxos +The `apps/` directory places all the Toml files that have been tested, you can switch to either directory and follow the instructions to build the application. Currently, there are two ways to build an app: - If building locally, you'll need to download the apps source code and then use ruxgo to build and run it. @@ -98,128 +52,23 @@ The `apps/` directory places all the toml files that have been tested. Currently * [x] nginx * [ ] python3 -## TOML Module Description - -Toml file consists of one **[build]** module and multiple **[targets]** modules. If you want to run on ruxos, you can add the **[os]** module. Here is a description of each module: - -The **[build]** module describes the compiler type and remote library packages. It contains two parts: `compiler` and `packages`. - -- `compiler`: Specifies the compiler type, for example: "gcc". -- `packages`: Optional, mainly used to get the app source code from Github, and then by parsing the `config_linux.toml` file in it to get the required libraries. When using packages, you need to specify the remote repository and branch. - -The **[targets]** module is the core part of the Toml and is used to describe the source build process and dependencies between libraries, as described below: - -- `name`: Specifies the target name, if it is of the "dll" type, must begin with "lib_". -- `src`:Specifies the path to the target source code. -- `src_excluded`:Optional. if you want to exclude some source files or directories, you can specify here. -- `include_dir`:Specifies the path to the header file in the target source code, which allows string and vector types. -- `type`:Specifies the type of the target, which can be of type "static", "dll", "object", or "exe". It should be noted that there can be only one "exe" target in a toml file, but there can be multiple targets of other types. -- `cflags`:Specifies the compilation options of the target. -- `archive`:Optional. If the targets type is static, you can specify an archive tool to create the static library. -- `linker`: Optional. Specifies the linking tool is used to link object files, static libraries, and dynamic libraries. If the value is missing, it is specified according to the `compiler`. -- `ldflags`:Specifies the link options of the target. -- `deps`:Specifies other targets to depend on. - -The **[os]** module is optional. If you want to run locally, **[config]** and **[targets]** are completely satisfied, if you want to run on ruxos, you can add the **[os]** module. After adding the **[os]** module, the original content of the corresponding **[targets]** modules will be changed. Ruxgo runs smoothly on ruxos by changing compiler, cflags, and ldflags in the backend, such as: - -When the platform of the **[os]** module is "x86_64-qemu-q35", the compiler is no longer "gcc", it becomes "x86_64-linux-musl-gcc". Also, all **[targets]** cflags are added with "-nostdinc -fno-builtin -ffreestanding -Wall" by default, you do not need to add them manually. Accordingly, when the type of **[targets]** is "exe", ldflags adds "-nostdlib -static -no-pie --gc-sections" by default. Of course, there are other default additions depending on architecture and platform. Just like, you just need to splice the **[os]** module onto a module that can run locally! The details are as follows: - -- `name`: Specifies the name of the os. -- `services`: Specifies the services that the os can provide, similar to the features in ruxos. -- `ulib`: The user library you want to use, the options are: "ruxlibc", "ruxmusl". -- `platform`:If needed, configure it in **[os.platform]**. - -If you want to configure the platform further, you can do so in **[os.platform]** , if empty, take the default value. The details are as follows: - -- `name`: Specifies what platform you want the os to run on, including: "x86_64-qemu-q35", "aarch64-qemu-virt", "riscv64-qemu-virt". The default value is "x86_64-qemu-q35". -- `smp`: Specifies the number of CPUs. The default value is "1". -- `mode`: Specifies the build mode, including: "release","debug". The default value is "release". -- `log`: Specifies the log level, including: "warn", "error", "info", "debug", and "trace". The default value is "warn". -- `v`: Specifies the Verbose level, including: "", "1", "2". The default value is "". -- `qemu`: If needed, configure it in **[os.platform.qemu]**. - -If your platform depends on qemu, you'll need to configure it further in **[os.platform.qemu]**, if empty, take the default value. The details are as follows: - -- `blk`: Specifies whether to enable storage devices (virtio-blk). The default value is "n". -- `net`: Specifies whether to enable network devices (virtio-net). The default value is "n". -- `graphic`: Specifies whether to enable display devices and graphic output (virtio-gpu). The default value is "n". -- `disk_img`: Specifies the path to the virtual disk image. The default value is "./disk_img". -- `v9p`: Specifies whether to enable virtio-9p devices. The default value is "n". -- `v9p_path`: Specifies the host path for backend of virtio-9p. The default value is "./". -- `qemu_log`: Specifies whether to enable QEMU logging (log file is "qemu.log"). The default value is "n". -- `net_dump`: Specifies whether to enable network packet dump (log file is "netdump.pcap"). The default value is "n". -- `net_dev`: Specifies QEMU netdev backend types: "user" or "tap". The default value is "user". -- `ip`: Specifies IPv4 address of os. The default value is "10.0.2.15" for QEMU user netdev. -- `gw`: Specifies gateway of IPv4 address. The default value is "10.0.2.2" for QEMU user netdev. -- `args`: Specifies the command-line arguments, separated by comma. It is used to pass specific variables, like `argc`, `argv`. The default value is "". -- `envs`: Specifies the environment variables, separated by comma between key value pairs. The default value is "". - -Sample file with a library and an executable (run locally): - -```toml -[build] -compiler = "gcc" - -[[targets]] -name = "libsqlite3" -src = "./sqlite-amalgamation-3410100" -src_excluded = ["shell.c"] -include_dir = "./sqlite-amalgamation-3410100" -type = "static" -cflags = "-w -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_FLOATING_POINT -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_DEBUG" -archive = "ar" -ldflags = "rcs" - -[[targets]] -name = "local_sqlite3" -src = "./" -src_excluded = ["sqlite-amalgamation-3410100"] -include_dir = "./" -type = "exe" -cflags = "" -ldflags = "" -deps = ["libsqlite3"] +## Usage + +Write a `config_linux.toml` for linux and `config_win32.toml` for windows in the project directory. + +You can then build the project with: +```console +ruxgo -b +``` + +Once built, you can execute the project via: +```console +ruxgo -r ``` -Sample file with a library and an executable (run on ruxos): - -```toml -[build] -compiler = "gcc" - -[os] -name = "ruxos" -services = ["fp_simd","alloc","paging","fs","blkfs"] -ulib = "ruxlibc" - -[os.platform] -name = "x86_64-qemu-q35" -smp = "4" -mode = "release" -log = "error" - -[os.platform.qemu] -blk = "y" -graphic = "n" - -[[targets]] -name = "libsqlite3" -src = "./sqlite-amalgamation-3410100" -src_excluded = ["shell.c"] -include_dir = "./sqlite-amalgamation-3410100" -type = "static" -cflags = "-w -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_FLOATING_POINT -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_DEBUG" -archive = "ar" -ldflags = "rcs" - -[[targets]] -name = "ruxos_sqlite3" -src = "./" -src_excluded = ["sqlite-amalgamation-3410100"] -include_dir = "./" -type = "exe" -cflags = "" -linker = "rust-lld -flavor gnu" -ldflags = "" -deps = ["libsqlite3"] +For help: +```console +ruxgo --help ``` + +You can also configure the log level with the environment variable `"RUXGO_LOG_LEVEL"`, the default log level is "Info". diff --git a/apps/iperf/README.md b/apps/iperf/README.md index a1989fe..4677144 100644 --- a/apps/iperf/README.md +++ b/apps/iperf/README.md @@ -5,13 +5,12 @@ Firstly, clone github repository of iperf and configure it: ```bash -git clone -b 3.1-STABLE https://github.com/esnet/iperf.git -./configure +git clone -b 3.1-STABLE https://github.com/esnet/iperf.git && cd iperf && ./configure ``` Then, you need to copy `config_linux.toml` from `ruxgo/apps/iperf/local` and place it in the `iperf/` directory you just downloaded. -Finally, execute the following commands to build and run it: +Finally, cd into `iperf/` and execute the following commands to build and run it: ```bash # Build and Run diff --git a/apps/redis/README.md b/apps/redis/README.md index 825673c..7f754ae 100644 --- a/apps/redis/README.md +++ b/apps/redis/README.md @@ -2,7 +2,7 @@ ## 1. Build and run locally -Firstly, clone github repository of redis and configure it: +Firstly, get the redis source code and configure it: ```bash wget https://github.com/redis/redis/archive/7.0.12.tar.gz @@ -10,7 +10,7 @@ tar -zxvf 7.0.12.tar.gz && rm -f 7.0.12.tar.gz cd redis-7.0.12/src && ./mkreleasehdr.sh && cd ../.. ``` -Then, you need to copy `config_linux.toml` from `ruxgo/apps/redis/local` and place it in the `redis-7.0.12/` directory you just downloaded. +Then, you need to copy `config_linux.toml` from `ruxgo/apps/redis/local` and place it in the `redis-7.0.12/` directory that you just downloaded. Finally, cd into `redis-7.0.12`/ and execute the following commands to build and run it: diff --git a/apps/sqlite3/README.md b/apps/sqlite3/README.md index 88f38cf..2d668ce 100644 --- a/apps/sqlite3/README.md +++ b/apps/sqlite3/README.md @@ -8,8 +8,9 @@ Firstly, get the sqlite3 source code: wget https://sqlite.org/2023/sqlite-amalgamation-3410100.zip unzip sqlite-amalgamation-3410100.zip && rm -f sqlite-amalgamation-3410100.zip ``` +Then, you need to copy `config_linux.toml` and `main.c` from `ruxgo/apps/redis/local` into the same directory as `sqlite-amalgamation-3410100` that you just downloaded. -Then, execute the following commands to build and run it (the main.c already exists): +Finally, execute the following commands to build and run it: ```bash # Build and Run diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..bbb5f6d --- /dev/null +++ b/doc/README.md @@ -0,0 +1,24 @@ +# Ruxgo documentation + +This directory contains Ruxgo's documentation: The Ruxgo Book which is built with [mdbook](https://github.com/rust-lang/mdBook) . + +## Building the book + +Building the book requires mdBook. To get it: + +``` +$ cargo install mdbook +``` + +To build the book: + +``` +$ mdbook build +``` + +`mdbook` provides a variety of different commands and options to help you work on the book: + +- `mdbook build --open`: Build the book and open it in a web browser. +- `mdbook serve`: Launches a web server on localhost. It also automatically rebuilds the book whenever any file changes and automatically reloads your web browser. + +The book contents are driven by the `SUMMARY.md` file, and every file must be linked there. \ No newline at end of file diff --git a/doc/ruxgo_book/.gitignore b/doc/ruxgo_book/.gitignore new file mode 100644 index 0000000..7585238 --- /dev/null +++ b/doc/ruxgo_book/.gitignore @@ -0,0 +1 @@ +book diff --git a/doc/ruxgo_book/assets/elasticlunr.js b/doc/ruxgo_book/assets/elasticlunr.js new file mode 100644 index 0000000..dab09a3 --- /dev/null +++ b/doc/ruxgo_book/assets/elasticlunr.js @@ -0,0 +1,28 @@ +/** + * @see https://github.com/HillLiu/docker-mdbook + */ +window.elasticlunr.Index.load = (index) => { + const FzF = window.fzf.Fzf; + const storeDocs = index.documentStore.docs; + const indexArr = Object.keys(storeDocs); + const ofzf = new FzF(indexArr, { + selector: (item) => { + const res = storeDocs[item]; + res.text = `${res.title}${res.breadcrumbs}${res.body}`; + return res.text; + }, + }); + return { + search: (searchterm) => { + const entries = ofzf.find(searchterm); + return entries.map((data) => { + const { item, score } = data; + return { + doc: storeDocs[item], + ref: item, + score, + }; + }); + }, + }; + }; \ No newline at end of file diff --git a/doc/ruxgo_book/assets/fzf.umd.js b/doc/ruxgo_book/assets/fzf.umd.js new file mode 100644 index 0000000..f7992ac --- /dev/null +++ b/doc/ruxgo_book/assets/fzf.umd.js @@ -0,0 +1,6 @@ +/** @license + * fzf v0.5.1 + * Copyright (c) 2021-2022 Ajit + * Licensed under BSD 3-Clause + */ +var __defProp=Object.defineProperty,__defProps=Object.defineProperties,__getOwnPropDescs=Object.getOwnPropertyDescriptors,__getOwnPropSymbols=Object.getOwnPropertySymbols,__hasOwnProp=Object.prototype.hasOwnProperty,__propIsEnum=Object.prototype.propertyIsEnumerable,__defNormalProp=(t,e,n)=>e in t?__defProp(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,__spreadValues=(t,e)=>{for(var n in e||(e={}))__hasOwnProp.call(e,n)&&__defNormalProp(t,n,e[n]);if(__getOwnPropSymbols)for(var n of __getOwnPropSymbols(e))__propIsEnum.call(e,n)&&__defNormalProp(t,n,e[n]);return t},__spreadProps=(t,e)=>__defProps(t,__getOwnPropDescs(e));!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).fzf={})}(this,(function(t){"use strict";const e={216:"O",223:"s",248:"o",273:"d",295:"h",305:"i",320:"l",322:"l",359:"t",383:"s",384:"b",385:"B",387:"b",390:"O",392:"c",393:"D",394:"D",396:"d",398:"E",400:"E",402:"f",403:"G",407:"I",409:"k",410:"l",412:"M",413:"N",414:"n",415:"O",421:"p",427:"t",429:"t",430:"T",434:"V",436:"y",438:"z",477:"e",485:"g",544:"N",545:"d",549:"z",564:"l",565:"n",566:"t",567:"j",570:"A",571:"C",572:"c",573:"L",574:"T",575:"s",576:"z",579:"B",580:"U",581:"V",582:"E",583:"e",584:"J",585:"j",586:"Q",587:"q",588:"R",589:"r",590:"Y",591:"y",592:"a",593:"a",595:"b",596:"o",597:"c",598:"d",599:"d",600:"e",603:"e",604:"e",605:"e",606:"e",607:"j",608:"g",609:"g",610:"G",613:"h",614:"h",616:"i",618:"I",619:"l",620:"l",621:"l",623:"m",624:"m",625:"m",626:"n",627:"n",628:"N",629:"o",633:"r",634:"r",635:"r",636:"r",637:"r",638:"r",639:"r",640:"R",641:"R",642:"s",647:"t",648:"t",649:"u",651:"v",652:"v",653:"w",654:"y",655:"Y",656:"z",657:"z",663:"c",665:"B",666:"e",667:"G",668:"H",669:"j",670:"k",671:"L",672:"q",686:"h",867:"a",868:"e",869:"i",870:"o",871:"u",872:"c",873:"d",874:"h",875:"m",876:"r",877:"t",878:"v",879:"x",7424:"A",7427:"B",7428:"C",7429:"D",7431:"E",7432:"e",7433:"i",7434:"J",7435:"K",7436:"L",7437:"M",7438:"N",7439:"O",7440:"O",7441:"o",7442:"o",7443:"o",7446:"o",7447:"o",7448:"P",7449:"R",7450:"R",7451:"T",7452:"U",7453:"u",7454:"u",7455:"m",7456:"V",7457:"W",7458:"Z",7522:"i",7523:"r",7524:"u",7525:"v",7834:"a",7835:"s",8305:"i",8341:"h",8342:"k",8343:"l",8344:"m",8345:"n",8346:"p",8347:"s",8348:"t",8580:"c"};for(let ot="̀".codePointAt(0);ot<="ͯ".codePointAt(0);++ot){const t=String.fromCodePoint(ot);for(const n of"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"){const r=(n+t).normalize().codePointAt(0);r>126&&(e[r]=n)}}const n={a:[7844,7863],e:[7870,7879],o:[7888,7907],u:[7912,7921]};for(const ot of Object.keys(n)){const t=ot.toUpperCase();for(let r=n[ot][0];r<=n[ot][1];++r)e[r]=r%2==0?t:ot}function r(t){if(t<192||t>8580)return t;const n=e[t];return void 0!==n?n.codePointAt(0):t}function s(t,e){return t>e?t:e}const o=t=>t.split("").map((t=>t.codePointAt(0))),i=t=>t.map((t=>String.fromCodePoint(t))).join(""),l=new Set(" \f\n\r\t\v  \u2028\u2029   \ufeff".split("").map((t=>t.codePointAt(0))));for(let ot=" ".codePointAt(0);ot<=" ".codePointAt(0);ot++)l.add(ot);const a=t=>l.has(t),c=t=>{let e=0;for(const n of t){if(!a(n))break;e++}return e},u=t=>{let e=0;for(let n=t.length-1;n>=0&&a(t[n]);n--)e++;return e},f="".codePointAt(0),h="A".codePointAt(0),d="Z".codePointAt(0),p="a".codePointAt(0),g="z".codePointAt(0),m="0".codePointAt(0),b="9".codePointAt(0);function y(t,e,n){return n?t:e-t-1}const P=16;var _,w;function z(t){return t?new Set:null}function S(t,e,n){if(null!==e&&e.i16.length>t+n){return[t+n,e.i16.subarray(t,t+n)]}return[t,new Int16Array(n)]}function L(t,e,n){if(null!==e&&e.i32.length>t+n){return[t+n,e.i32.subarray(t,t+n)]}return[t,new Int32Array(n)]}function A(t){return t>=p&&t<=g?1:t>=h&&t<=d?2:t>=m&&t<=b?4:0}function v(t){const e=String.fromCodePoint(t);return e!==e.toUpperCase()?1:e!==e.toLowerCase()?2:null!==e.match(/\p{Number}/gu)?4:null!==e.match(/\p{Letter}/gu)?3:0}function C(t){return t<=f?A(t):v(t)}function O(t,e){return 0===t&&0!==e?8:1===t&&2===e||4!==t&&4===e?7:0===e?8:0}function x(t,e,n,r){let s=t.slice(r),o=s.indexOf(n);if(0===o)return r;if(!e&&n>=p&&n<=g){o>0&&(s=s.slice(0,o));const t=s.indexOf(n-32);t>=0&&(o=t)}return o<0?-1:r+o}function k(t){for(const e of t)if(e>=128)return!1;return!0}function j(t,e,n){if(!k(t))return 0;if(!k(e))return-1;let r=0,s=0;for(let o=0;o0&&(r=s-1),s++}return r}(w=_||(_={}))[w.NonWord=0]="NonWord",w[w.Lower=1]="Lower",w[w.Upper=2]="Upper",w[w.Letter=3]="Letter",w[w.Number=4]="Number";const E=(t,e,n,o,i,l,a)=>{const c=i.length;if(0===c)return[{start:0,end:0,score:0},z(l)];const u=o.length;if(null!==a&&u*c>a.i16.length)return N(t,e,n,o,i,l);const h=j(o,i,t);if(h<0)return[{start:-1,end:-1,score:0},null];let d=0,p=0,g=null,m=null,b=null,y=null;[d,g]=S(d,a,u),[d,m]=S(d,a,u),[d,b]=S(d,a,u),[p,y]=L(p,a,c);const[,_]=L(p,a,u);for(let r=0;r<_.length;r++)_[r]=o[r];let w=0,C=0,x=0,k=0;const E=i[0];let M=i[0],V=0,F=0,I=!1,R=_.subarray(h),q=g.subarray(h).subarray(0,R.length),W=m.subarray(h).subarray(0,R.length),B=b.subarray(h).subarray(0,R.length);for(let[z,S]of R.entries()){let o=null;S<=f?(o=A(S),t||2!==o||(S+=32)):(o=v(S),t||2!==o||(S=String.fromCodePoint(S).toLowerCase().codePointAt(0)),e&&(S=r(S))),R[z]=S;const l=O(F,o);if(B[z]=l,F=o,S===M&&(xw||!n&&t>=w)&&(w=t,C=h+z,n&&8===l))break;I=!1}else q[z]=s(I?V+-1:V+-3,0),W[z]=0,I=!0;V=q[z]}if(x!==c)return[{start:-1,end:-1,score:0},null];if(1===c){const t={start:C,end:C+1,score:w};if(!l)return[t,null];const e=new Set;return e.add(C),[t,e]}const T=y[0],D=k-T+1;let U=null;[d,U]=S(d,a,D*c);{const t=g.subarray(T,k+1);for(const[e,n]of t.entries())U[e]=n}let[,G]=S(d,a,D*c);{const t=m.subarray(T,k+1);for(const[e,n]of t.entries())G[e]=n}const J=y.subarray(1),Y=i.slice(1).slice(0,J.length);for(const[r,f]of J.entries()){let t=!1;const e=Y[r],o=r+1,i=o*D,l=_.subarray(f,k+1),a=b.subarray(f).subarray(0,l.length),u=G.subarray(i+f-T).subarray(0,l.length),h=G.subarray(i+f-T-1-D).subarray(0,l.length),d=U.subarray(i+f-T).subarray(0,l.length),p=U.subarray(i+f-T-1-D).subarray(0,l.length),g=U.subarray(i+f-T-1).subarray(0,l.length);g[0]=0;for(const[r,m]of l.entries()){const i=r+f;let l=0,y=0,_=0;if(y=t?g[r]+-1:g[r]+-3,e===m){l=p[r]+P;let t=a[r];_=h[r]+1,8===t?_=1:_>1&&(t=s(t,s(4,b[i-_+1]))),l+tw||!n&&z>=w)&&(w=z,C=i),d[r]=z}}const Z=z(l);let H=T;if(l&&null!==Z){let t=c-1;H=C;let e=!0;for(;;){const n=t*D,r=H-T,s=U[n+r];let o=0,i=0;if(t>0&&H>=y[t]&&(o=U[n-D+r-1]),H>y[t]&&(i=U[n+r-1]),s>o&&(s>i||s===i&&e)){if(Z.add(H),0===t)break;t--}e=G[n+r]>1||n+D+r+10,H--}}return[{start:H,end:C+1,score:w},Z]};function M(t,e,n,o,i,l,a){let c=0,u=0,p=!1,g=0,m=0;const b=z(a);let y=0;i>0&&(y=C(n[i-1]));for(let _=i;_=h&&i<=d?i+=32:i>f&&(i=String.fromCodePoint(i).toLowerCase().codePointAt(0))),e&&(i=r(i)),i===o[c]){a&&null!==b&&b.add(_),u+=P;let t=O(y,l);0===g?m=t:(8===t&&(m=t),t=s(s(t,m),4)),u+=0===c?2*t:t,p=!1,g++,c++}else u+=p?-1:-3,p=!0,g=0,m=0;y=l}return[u,b]}const N=(t,e,n,s,o,i,l)=>{if(0===o.length)return[{start:0,end:0,score:0},null];if(j(s,o,t)<0)return[{start:-1,end:-1,score:0},null];let a=0,c=-1,u=-1;const p=s.length,g=o.length;for(let m=0;m=h&&i<=d?i+=32:i>f&&(i=String.fromCodePoint(i).toLowerCase().codePointAt(0))),e&&(i=r(i));if(i===o[y(a,g,n)]&&(c<0&&(c=m),a++,a===g)){u=m+1;break}}if(c>=0&&u>=0){a--;for(let e=u-1;e>=c;e--){let r=s[y(e,p,n)];t||(r>=h&&r<=d?r+=32:r>f&&(r=String.fromCodePoint(r).toLowerCase().codePointAt(0)));if(r===o[y(a,g,n)]&&(a--,a<0)){c=e;break}}if(!n){const t=c;c=p-u,u=p-t}const[r,l]=M(t,e,s,o,c,u,i);return[{start:c,end:u,score:r},l]}return[{start:-1,end:-1,score:0},null]},V=(t,e,n,s,o,i,l)=>{if(0===o.length)return[{start:0,end:0,score:0},null];const a=s.length,c=o.length;if(a=h&&l<=d?l+=32:l>f&&(l=String.fromCodePoint(l).toLowerCase().codePointAt(0))),e&&(l=r(l));const w=y(u,c,n);if(o[w]===l){if(0===w&&(b=s,g=0===(P=i)?8:O(C(b[P-1]),C(b[P]))),u++,u===c){if(g>m&&(p=_,m=g),8===g)break;_-=u-1,u=0,g=0}}else _-=u,u=0,g=0}var b,P;if(p>=0){let r=0,i=0;n?(r=p-c+1,i=p+1):(r=a-(p+1),i=a-(p-c+1));const[l]=M(t,e,s,o,r,i,!1);return[{start:r,end:i,score:l},null]}return[{start:-1,end:-1,score:0},null]};const F=(I=2048,{i16:new Int16Array(102400),i32:new Int32Array(I)});var I,R,q;(q=R||(R={}))[q.Fuzzy=0]="Fuzzy",q[q.Exact=1]="Exact",q[q.Prefix=2]="Prefix",q[q.Suffix=3]="Suffix",q[q.Equal=4]="Equal";const W={0:E,1:V,2:(t,e,n,s,o,i,l)=>{if(0===o.length)return[{start:0,end:0,score:0},null];let u=0;if(a(o[0])||(u=c(s)),s.length-u{let c=s.length;if(0!==o.length&&a(o[o.length-1])||(c-=u(s)),0===o.length)return[{start:c,end:c,score:0},null];const f=c-o.length;if(f<0)return[{start:-1,end:-1,score:0},null];for(const[a,u]of o.entries()){let n=s[a+f];if(t||(n=String.fromCodePoint(n).toLowerCase().codePointAt(0)),e&&(n=r(n)),n!==u)return[{start:-1,end:-1,score:0},null]}const h=c-o.length,d=c,[p]=M(t,e,s,o,h,d,!1);return[{start:h,end:d,score:p},null]},4:(t,e,n,s,o,l,f)=>{const h=o.length;if(0===h)return[{start:-1,end:-1,score:0},null];let d=0;a(o[0])||(d=c(s));let p=0;if(a(o[h-1])||(p=u(s)),s.length-d-p!=h)return[{start:-1,end:-1,score:0},null];let g=!0;if(e){const e=s;for(const[n,s]of o.entries()){let o=e[d+n];if(t||(o=String.fromCodePoint(o).toLowerCase().codePointAt(0)),r(s)!==r(o)){g=!1;break}}}else{let e=i(s).substring(d,s.length-p);t||(e=e.toLowerCase()),g=e===i(o)}return g?[{start:d,end:d+h,score:24*h+8},null]:[{start:-1,end:-1,score:0},null]}};function B(t,e,n,s){let l=!0;{const t=(s=s.trimLeft()).trimRight();s=t.endsWith("\\")&&" "===s[t.length]?t+" ":t}let a=!1,c=[];c=function(t,e,n,s){const l=(s=s.replace(/\\ /g,"\t")).split(/ +/),a=[];let c=[],u=!1,f=!1;for(const h of l){let s=0,l=!1,d=h.replace(/\t/g," ");const p=d.toLowerCase(),g="case-sensitive"===e||"smart-case"===e&&d!==p,m=n&&p===i(o(p).map(r));if(g||(d=p),t||(s=1),c.length>0&&!f&&"|"===d)u=!1,f=!0;else if(f=!1,d.startsWith("!")&&(l=!0,s=1,d=d.substring(1)),"$"!==d&&d.endsWith("$")&&(s=3,d=d.substring(0,d.length-1)),d.startsWith("'")?(s=t&&!l?1:0,d=d.substring(1)):d.startsWith("^")&&(s=3===s?4:2,d=d.substring(1)),d.length>0){u&&(a.push(c),c=[]);let t=o(d);m&&(t=t.map(r)),c.push({typ:s,inv:l,text:t,caseSensitive:g,normalize:m}),u=!0}}c.length>0&&a.push(c);return a}(t,e,n,s);t:for(const r of c)for(const[e,n]of r.entries())if(n.inv||(a=!0),(!l||e>0||n.inv||t&&0!==n.typ||!t&&1!==n.typ)&&(l=!1,a))break t;return{str:s,termSets:c,sortable:a,cacheable:l,fuzzy:t}}const T=(t,e,n)=>{let s=!1;switch(e){case"smart-case":t.toLowerCase()!==t&&(s=!0);break;case"case-sensitive":s=!0;break;case"case-insensitive":t=t.toLowerCase(),s=!1}let i=o(t);return n&&(i=i.map(r)),{queryRunes:i,caseSensitive:s}};function D(t,e,n,r,s,o,i){for(const l of e){const[e,a]=t(n,r,s,l.text,o,!0,i);if(e.start>=0){const t=e.start+l.prefixLength,n=e.end+l.prefixLength;if(null!==a){const r=new Set;return a.forEach((t=>r.add(l.prefixLength+t))),[[t,n],e.score,r]}return[[t,n],e.score,a]}}return[[-1,-1],0,null]}function U(t,e){const n=Object.keys(t).map((t=>parseInt(t,10))).sort(((t,e)=>e-t));let r=[];for(const s of n)if(r=r.concat(t[s]),r.length>=e)break;return r}function G(t,e,n){return r=>{const s=this.runesList[r];if(e.length>s.length)return;let[o,i]=this.algoFn(n,this.opts.normalize,this.opts.forward,s,e,!0,F);if(-1===o.start)return;if(!1===this.opts.fuzzy){i=new Set;for(let t=o.start;t{const r=function(t,e,n,r){const s=[{text:t,prefixLength:0}],o=[];let i=0;const l=new Set;for(const a of e.termSets){let t=[0,0],e=0,c=!1;for(const o of a){let i=W[o.typ];o.typ===R.Fuzzy&&(i=n);const[a,u,f]=D(i,s,o.caseSensitive,o.normalize,r,o.text,F);if(a[0]>=0){if(o.inv)continue;if(t=a,e=u,c=!0,null!==f)f.forEach((t=>l.add(t)));else for(let t=a[0];t0&&(s=Math.min(...r.allPos),o=Math.max(...r.allPos)+1);const i=this.opts.sort?r.totalScore:0;void 0===t[i]&&(t[i]=[]),t[i].push({score:r.totalScore,item:this.items[n],positions:r.allPos,start:s,end:o})}}function Y(t){const{queryRunes:e,caseSensitive:n}=T(t,this.opts.casing,this.opts.normalize),r={},s=G.bind(this)(r,e,n);for(let o=0,i=this.runesList.length;o{let i=0,l=Math.min(1e3,e);const a=()=>{if(t.cancelled)return o("search cancelled");for(;iU(s,this.opts.limit)))}const Q={limit:1/0,selector:t=>t,casing:"smart-case",normalize:!0,fuzzy:"v2",tiebreakers:[],sort:!0,forward:!0};class ${constructor(t,...e){switch(this.opts=__spreadValues(__spreadValues({},Q),e[0]),this.items=t,this.runesList=t.map((t=>o(this.opts.selector(t).normalize()))),this.algoFn=V,this.opts.fuzzy){case"v2":this.algoFn=E;break;case"v1":this.algoFn=N}}}const X=__spreadProps(__spreadValues({},Q),{match:Y});class tt extends ${constructor(t,...e){super(t,...e),this.opts=__spreadValues(__spreadValues({},X),e[0])}find(t){if(0===t.length||0===this.items.length)return this.items.slice(0,this.opts.limit).map(rt);return t=t.normalize(),st(this.opts.match.bind(this)(t),this.opts)}}const et=__spreadProps(__spreadValues({},Q),{match:K});class nt extends ${constructor(t,...e){super(t,...e),this.opts=__spreadValues(__spreadValues({},et),e[0]),this.token={cancelled:!1}}async find(t){if(this.token.cancelled=!0,this.token={cancelled:!1},0===t.length||0===this.items.length)return this.items.slice(0,this.opts.limit).map(rt);return t=t.normalize(),st(await this.opts.match.bind(this)(t,this.token),this.opts)}}const rt=t=>({item:t,start:-1,end:-1,score:0,positions:new Set});function st(t,e){if(e.sort){const{selector:n}=e;t.sort(((t,r)=>{if(t.score===r.score)for(const s of e.tiebreakers){const e=s(t,r,n);if(0!==e)return e}return 0}))}return Number.isFinite(e.limit)&&t.splice(e.limit),t}t.AsyncFzf=class{constructor(t,...e){this.finder=new nt(t,...e),this.find=this.finder.find.bind(this.finder)}},t.Fzf=class{constructor(t,...e){this.finder=new tt(t,...e),this.find=this.finder.find.bind(this.finder)}},t.asyncBasicMatch=K,t.asyncExtendedMatch=function(t,e){const n=B(Boolean(this.opts.fuzzy),this.opts.casing,this.opts.normalize,t),r={};return H(e,this.runesList.length,J.bind(this)(r,n),(()=>U(r,this.opts.limit)))},t.basicMatch=Y,t.byLengthAsc=function(t,e,n){return n(t.item).length-n(e.item).length},t.byStartAsc=function(t,e){return t.start-e.start},t.extendedMatch=function(t){const e=B(Boolean(this.opts.fuzzy),this.opts.casing,this.opts.normalize,t),n={},r=J.bind(this)(n,e);for(let s=0,o=this.runesList.length;s... Arguments to pass to the executable when running + --gen-cc Generate compile_commands.json + --gen-vsc Generate .vscode/c_cpp_properties.json + --update-packages Update packages + --restore-packages Restore packages + -h, --help Print help + -V, --version Print version +``` \ No newline at end of file diff --git a/doc/ruxgo_book/src/commands/ruxgo-run.md b/doc/ruxgo_book/src/commands/ruxgo-run.md new file mode 100644 index 0000000..26006a4 --- /dev/null +++ b/doc/ruxgo_book/src/commands/ruxgo-run.md @@ -0,0 +1 @@ +# ruxgo run diff --git a/doc/ruxgo_book/src/commands/ruxgo-version.md b/doc/ruxgo_book/src/commands/ruxgo-version.md new file mode 100644 index 0000000..77d705a --- /dev/null +++ b/doc/ruxgo_book/src/commands/ruxgo-version.md @@ -0,0 +1 @@ +# ruxgo version diff --git a/doc/ruxgo_book/src/guide/builder_module.md b/doc/ruxgo_book/src/guide/builder_module.md new file mode 100644 index 0000000..b187529 --- /dev/null +++ b/doc/ruxgo_book/src/guide/builder_module.md @@ -0,0 +1,7 @@ +# builder 模块 + +**[build]** 模块描述了编译器的类型和所需远程库包。它包含两个部分: `compiler`和`packages`。 + +- `compiler`: 指定编译器类型,例如: "gcc"。 + +- `packages`: 可选。主要用于从 Github 中获取应用的源代码,然后通过解析其中的 `config_linux.toml`文件来获取所需的库。当使用包时,你需要指定远程仓库和分支。 \ No newline at end of file diff --git a/doc/ruxgo_book/src/guide/companion_tool_to_ruxos.md b/doc/ruxgo_book/src/guide/companion_tool_to_ruxos.md new file mode 100644 index 0000000..2ee334f --- /dev/null +++ b/doc/ruxgo_book/src/guide/companion_tool_to_ruxos.md @@ -0,0 +1,7 @@ +# 作为 RuxOS 的伴生工具 + +- 一方面 Ruxgo 将在本地构建应用程序,以探索其实用性以及可行性,并期望在没有 Makefile 的场景下实现高效构建; + +- 另一方面 Ruxgo 将作为 RuxOS 的伴生工具,通过在 Toml 内部以搭积木的方式进行模块组合与选取,进而高效构建 RuxOS 及其上的 C/C++ 应用程序。 + +最终利用 Ruxgo 促进 RuxOS 生态系统的形成,进一步推动 RuxOS 操作系统的发展。 \ No newline at end of file diff --git a/doc/ruxgo_book/src/guide/design_features.md b/doc/ruxgo_book/src/guide/design_features.md new file mode 100644 index 0000000..8d7e2d8 --- /dev/null +++ b/doc/ruxgo_book/src/guide/design_features.md @@ -0,0 +1,17 @@ +# ​设计特性 + +Ruxgo 设计充分考虑构建过程的效率、可靠性和可维护性,同时充分适应 RuxOS 的构件化特性: + +- **构建过程简化:** 完全使用 Toml 文件来描述构建参数,避免了使用复杂的语法和依赖规则的构建流程,同时依赖关系更加简单直观。 + +- **组件模块化:** 构建过程以 target 为中心,按照不同的 target 模块来配置目标文件、依赖库等。构建应用程序或操作系统可以像搭积木一样进行组合配置。 + +- **源码和构建目录分离:** 在构建过程中,生成的可执行文件、中间文件、OS构件以及远程拉取的相关构件都会被放置在构建目录`ruxos_bld/`中,防止构建过程中的文件冲突和混乱。 + +- **自动生成配置文件:** Ruxgo可以生成一些常用的配置文件,如 .vscode 和 c_cpp_properties.json,减少了手动配置的工作量。 + +- **多线程支持:** Ruxgo支持多线程构建应用程序,提高了构建效率。 + +- **支持远程库:** Ruxgo 可以从 Github 等远程仓库获取应用程序的源代码,并根据配置文件获取所需的库文件。 + +- **跨平台支持:** Ruxgo 支持在 Linux、Windows 等多种平台上构建应用程序。 \ No newline at end of file diff --git a/doc/ruxgo_book/src/guide/design_principle.md b/doc/ruxgo_book/src/guide/design_principle.md new file mode 100644 index 0000000..2e2221a --- /dev/null +++ b/doc/ruxgo_book/src/guide/design_principle.md @@ -0,0 +1,12 @@ +# ​设计理念 + +* [借鉴 Cargo](./learn_from_cargo.md) + +* [C/C++ 构建过程的思考](./reflections_on_construct.md) + +* [Ruxgo 要实现的功能](./ruxgo_functionality.md) + +* [作为 RuxOS 的伴生工具](./companion_tool_to_ruxos.md) + + + diff --git a/doc/ruxgo_book/src/guide/index.md b/doc/ruxgo_book/src/guide/index.md new file mode 100644 index 0000000..1ba0a26 --- /dev/null +++ b/doc/ruxgo_book/src/guide/index.md @@ -0,0 +1,11 @@ +# Ruxgo 指南 + +本指南包括 Ruxgo 的设计理念和设计特性,同时重点对 Toml 文件及其各个模块做出阐述,并辅以样例说明。 + +* [​设计理念](./design_principle.md) + +* [​设计特性](./design_features.md) + +* [TOML 文件说明](./toml_file.md) + +* [TOML 文件示例](./toml_example.md) diff --git a/doc/ruxgo_book/src/guide/learn_from_cargo.md b/doc/ruxgo_book/src/guide/learn_from_cargo.md new file mode 100644 index 0000000..6839f58 --- /dev/null +++ b/doc/ruxgo_book/src/guide/learn_from_cargo.md @@ -0,0 +1,13 @@ +# 借鉴 Cargo + +Rust 1.8 发布以后,Rust 团队便放弃了 Unix 系统传统的 [Make](https://www.gnu.org/software/make/) 工具,转而使用他们自己的 [Cargo 包管理工具](https://github.com/rust-lang/cargo)。当然,为了实现自举,减少对外部工具的依赖,Rust 必须通过自己的语言构建一些工具。其他语言也大多都经过这个过程。Google 的 Go 语言,从1.5版本开始,其编译器和解释器都由 Go 语言实现(有一小部分用了汇编),放弃了基于 C 语言的工具。 + +从 Make 换到 Cargo 的[原因](https://github.com/rust-lang/rust/pull/31123),Rust团队核心成员 *Alex Crichton* 解释道: + +> “在这个星球上只有一小部分人能够熟练使用 Makefile,这意味着对构建系统的贡献几乎是不存在,而且如果需要对构建系统进行更改,它是很难弄清楚应该怎么做。这种障碍使我们无法在 make 中做一些也许更花哨的事情”; +> +> “Make虽然可移植,但不幸的是,它并不是无限可移植的。例如,最近引入的MSVC目标不太可能默认安装(例如, 它目前需要在MSYS2 shell内构建)。相反,make的可移植性是以疯狂和奇怪的操作为代价的,需要围绕各种软件版本进行工作,特别是在配置脚本和 Makefile 方面。” +> +> “改变编译系统使 Rust 标准库和编译器可以轻松从crates.io生态系统中获益。” +> +> …… diff --git a/doc/ruxgo_book/src/guide/os_module.md b/doc/ruxgo_book/src/guide/os_module.md new file mode 100644 index 0000000..13d40b8 --- /dev/null +++ b/doc/ruxgo_book/src/guide/os_module.md @@ -0,0 +1,61 @@ +# os 模块 + +**[os]** 模块是可选的。如果你想在本地运行,[build] 和 [targets] 是完全满足,如果你想在 RuxOS 上运行,则需要添加[os] 模块。 + +添加 [os] 模块后,原有 [targets] 模块的一些内容将会发生改变。例如: + +当 [os] 模块的平台是 "x86_64-qemu-q35" 时,编译器类型不再是 "gcc",它将变成 "x86_64-linux-musl-gcc"。此外,所有 [targets] 的 cflags 都默认添加了 "-nostdinc -fno-builtin -ffreestanding -Wall",当 [targets] 类型是 "exe" 时,ldflags 还默认添加了 "-nostdlib -static -no-pie --gc-sections",你不需要去手动添加它们。当然,根据架构和平台的不同,还有其他默认的添加及改变。 + +Ruxgo 通过修改一些代码逻辑实现,这么做是为了,如果你能在本地跑通一个程序,那么只需要将定制的 [os] 模块拼接到你本地跑通的模块上,即可实现在 RuxOS 上流畅的运行,而不需要额外的操作! + +具体 **[os]** 模块描述如下: + +- `name`: 指定操作系统的名称。 + +- `services`: 指定操作系统可以提供的服务,类似于 RuxOS 中的 `features`。 + +- `ulib`: 指定想要使用的用户库,可选项有: "ruxlibc","ruxmusl"。 + +- `platform`: 如果需要,请在 [os.platform] 中进行配置。 + +如果你想进一步配置平台,可以在 **[os.platform]** 中实现。如果为空,则使用默认值。具体细节如下: + +- `name`: 指定操作系统在哪个平台上运行,可选项有: "x86_64-qemu-q35", "aarch64-qemu-virt", "riscv64-qemu-virt"。默认值为 "x86_64-qemu-q35"。 + +- `smp`: 指定cpu数量。默认值为 "1"。 + +- `mode`: 指定构建模式,可选项有: "release","debug"。默认值为 "release"。 + +- `log`: 指定日志级别,可选项有: "warn","error","info","debug" 和 "trace"。默认值为 "warn"。 + +- `v`: 指定 verbose 级别,可选项有: "","1","2"。默认值为 ""。 + +- `qemu`: 如果需要,请在 [os.platform.qemu] 中进行配置。 + +如果你的平台依赖于 qemu ,你需要在 **[os.platform.qemu]** 中进一步配置它。如果为空,则使用默认值。具体细节如下: + +- `blk`: 指定是否启用存储设备(virtio-blk)。默认值为 "n"。 + +- `net`: 指定是否启用网络设备(virtio-net)。默认值为 "n"。 + +- `graphic`: 指定是否启用显示设备和图形输出(virtio-gpu)。默认值为"n"。 + +- `disk_img`: 指定虚拟磁盘镜像的路径。默认值为 "./disk_img"。 + +- `v9p`: 指定是否启用 virtio-9p 设备。默认值为 "n"。 + +- `v9p_path`: 指定 virtio-9p 后端的主机路径。默认值为 "./"。 + +- `qemu_log`: 指定是否启用 QEMU 日志(日志文件为 "qemu.log" )。默认值为 "n"。 + +- `net_dump`: 指定是否启用网络包转储(日志文件为 "netdump.pcap" )。默认值为 "n"。 + +- `net_dev`: 指定 QEMU 网络设备后端类型: "user" 或 "tap"。默认值为 "user"。 + +- `ip`: 指定 IPv4 地址。QEMU "user" 网络设备的默认值为 "10.0.2.15"。 + +- `gw`: 指定 IPv4 地址的网关。QEMU "user" 网络设备的默认值为 "10.0.2.2"。 + +- `args`: 指定命令行参数,以逗号分隔。它用于传递特定的变量,如`argc`、`argv`。默认值为 ""。 + +- `envs`: 指定环境变量,键值对之间用逗号分隔。默认值为 ""。 \ No newline at end of file diff --git a/doc/ruxgo_book/src/guide/reflections_on_construct.md b/doc/ruxgo_book/src/guide/reflections_on_construct.md new file mode 100644 index 0000000..f513537 --- /dev/null +++ b/doc/ruxgo_book/src/guide/reflections_on_construct.md @@ -0,0 +1,21 @@ +# C/C++ 构建过程的思考 + +C/C++ 项目的构建过程涉及源代码的编译、依赖项的解析、库的链接、以及各种优化等一系列步骤,它直接影响着项目的开发效率和代码质量。当项目规模不断扩大时,构建速度、可维护性、复杂的依赖关系等问题随之产生,与此同时,跨平台的问题也不得不考虑。 + +构建工具是构建过程优化的关键,在现代化软件工程的衍进下,似乎原有的 Make 构建工具产生了许多不可调和的矛盾: + +- 构建一个项目时,首先需要学习 Make 的复杂构建语法,在层层依赖和规则的递进下,轻松达到数千行的境界,或许一些花哨的技巧和想法,别人也很难理解,也不想去维护... + +- 重构一个项目时,Make 仅依赖于文件的时间戳来判断是否需要重新构建。那么假如仅修改了文件的时间戳而未对文件内容进行实质性的修改,make一下是不是又会花费大把的时间?当然也可以有一些花哨的操作,同上。 + +- 管理依赖配置时,似乎无法使用一些插件,也没有类似 crate.io 的生态,手写构建依赖,手写配置扩展... + +- 跨平台构建时,需要针对不同的操作系统编写不同的 Makefile,当数千行时,工作量可想而知。当然可以使用 CMake,但又要新学一个工具的构建语法... + +国内外研究人员一直在努力探索新的针对 C/C++ 项目的构建工具。例如,CMake 和 Ninja 尝试减轻开发人员在不同平台上进行构建的负担;Bazel 和 Gradle 试图解决待办事项和依赖项管理的问题,并提供更好的性能;Unikraft 的伴生工具 kraft,可以简化和自动化单一工作载荷的 Unikernel 的构建和运行。 + +当然,回归到构建过程本身,回归到最原始的阶段,也只有诸如 gcc 或 g++ 等一系列过程,Makefile 定制了它。Kraft 在 Unikraft 上的运用给了我一些灵感,似乎模块化的操作系统也可以采用模块化的构建工具,原先臃肿的 Make 工具只需要做些减法,当然形式不能太灵活。于是,在最原始的编译基础上,加上增量编译、预编译、并行构建、包管理等等,或许能组装出不错的构建工具!如果是组件化操作系统,还可以针对其进行定制化处理。 + +另一个想解决的是学习曲线和语法问题。Cargo 工具在构建项目的过程中,充分利用了 Cargo.toml 和 config.toml 两个文件,即完成了整个项目的所有配置,用户也可以在 Toml 中进行一些花哨的选择以实现定制化!或许语义明显、配置最小化且多平台支持的 [TOML](https://github.com/toml-lang/toml) 语言可以在新的组件化构建工具中大展拳脚。当然,如果只需要一个 TOML 文件就能构建出整个 C/C++ 项目,并且构建出运行于组件化操作系统上的 C/C++ 项目,应该是件令人兴奋的事情。 + +所以 Ruxgo! \ No newline at end of file diff --git a/doc/ruxgo_book/src/guide/ruxgo_functionality.md b/doc/ruxgo_book/src/guide/ruxgo_functionality.md new file mode 100644 index 0000000..262bc28 --- /dev/null +++ b/doc/ruxgo_book/src/guide/ruxgo_functionality.md @@ -0,0 +1,17 @@ +# Ruxgo 要实现的功能 + +既然是组件化的新尝试,功能先暂定如下: + +- **编译器类型多样化:** C/C++ 有多种编译器可供选择,如 GCC、Clang、MSVC 等。不同编译器对语言标准的支持程度、性能优化的策略等可能有所不同,可利用此特点组合出最佳性能。 + +- **中间过程多样化:** 可以根据实际需求选择生成静态库,动态库或者一系列中间文件,如预处理后的代码、汇编代码、目标文件等。这些中间文件可以用于调试和优化,也可以用于构建过程的加速。 + +- **增量构建:** 采用增量构建的方式缩短构建时间,只重新编译修改过的文件或受影响的模块。 + +- **并行构建:** 将构建任务并行化,利用多核处理器来同时编译多个文件。 + +- **依赖管理:** 对于要依赖的外部库和组件,可以充分利用 [crate.io](https://crates.io/) 的生态,或者使用一些包管理工具。 + +- **可移植性:** 在代码中尽量使用平台无关的 API 和规范,避免平台特定的实现方式。 + +- **编译错误诊断:** 使用更友好的编译器错误输出显示,包括清晰的错误提示、指向源代码行数等信息。 \ No newline at end of file diff --git a/doc/ruxgo_book/src/guide/target_module.md b/doc/ruxgo_book/src/guide/target_module.md new file mode 100644 index 0000000..c513254 --- /dev/null +++ b/doc/ruxgo_book/src/guide/target_module.md @@ -0,0 +1,23 @@ +# target 模块 + +**[targets]** 模块是 Toml 的核心部分,主要用于描述源代码的构建过程和库之间的依赖关系,如下所示: + +- `name`: 指定目标的名称,如果是 "dll" 类型,必须以 "lib_" 开头。 + +- `src`: 指定目标源代码的路径,会递归构建该目录下的所有源文件。 + +- `src_excluded`: 可选。如果要排除某些源文件或目录,可以在此处指定。 + +- `include_dir`: 指定目标源代码的头文件路径,允许向量类型以支持多个头文件路径。 + +- `type`: 指定目标的类型,可以是 "static"、"dll"、"object" 或 "exe"。需要注意的是,在一个 Toml 文件中只能有一个 "exe" 目标,但可以有多个其他类型的目标。 + +- `cflags`: 指定目标的编译选项。 + +- `archive`: 可选。如果目标类型是 "static",你可以指定一个归档工具来创建静态库。 + +- `linker`: 可选。指定用于链接动态库或其他目标文件的链接工具。如果该值缺失,则默认根据`compiler`指定。 + +- `ldflags`: 指定目标的链接选项。 + +- `deps`: 指定当前目标依赖的其他目标。 \ No newline at end of file diff --git a/doc/ruxgo_book/src/guide/toml_example.md b/doc/ruxgo_book/src/guide/toml_example.md new file mode 100644 index 0000000..7094e8f --- /dev/null +++ b/doc/ruxgo_book/src/guide/toml_example.md @@ -0,0 +1,73 @@ +# TOML 文件示例 + +下面是 [sqlite3](https://github.com/Ybeichen/ruxgo/tree/master/apps/sqlite3) 的 Toml 文件示例,具体运行可参考 `apps/sqlite3` 下的 README.md 。 + +带有库和可执行文件的示例文件(在本地运行): + +```toml +[build] +compiler = "gcc" + +[[targets]] +name = "libsqlite3" +src = "./sqlite-amalgamation-3410100" +src_excluded = ["shell.c"] +include_dir = "./sqlite-amalgamation-3410100" +type = "static" +cflags = "-w -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_FLOATING_POINT -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_DEBUG" +archive = "ar" +ldflags = "rcs" + +[[targets]] +name = "local_sqlite3" +src = "./" +src_excluded = ["sqlite-amalgamation-3410100"] +include_dir = "./" +type = "exe" +cflags = "" +ldflags = "" +deps = ["libsqlite3"] +``` + +带有库和可执行文件的示例文件(在ruxos上运行): + +```toml +[build] +compiler = "gcc" + +[os] +name = "ruxos" +services = ["fp_simd","alloc","paging","fs","blkfs"] +ulib = "ruxlibc" + +[os.platform] +name = "x86_64-qemu-q35" +smp = "4" +mode = "release" +log = "error" + +[os.platform.qemu] +blk = "y" +graphic = "n" + +[[targets]] +name = "libsqlite3" +src = "./sqlite-amalgamation-3410100" +src_excluded = ["shell.c"] +include_dir = "./sqlite-amalgamation-3410100" +type = "static" +cflags = "-w -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_FLOATING_POINT -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_DEBUG" +archive = "ar" +ldflags = "rcs" + +[[targets]] +name = "ruxos_sqlite3" +src = "./" +src_excluded = ["sqlite-amalgamation-3410100"] +include_dir = "./" +type = "exe" +cflags = "" +linker = "rust-lld -flavor gnu" +ldflags = "" +deps = ["libsqlite3"] +``` \ No newline at end of file diff --git a/doc/ruxgo_book/src/guide/toml_file.md b/doc/ruxgo_book/src/guide/toml_file.md new file mode 100644 index 0000000..02ff0bb --- /dev/null +++ b/doc/ruxgo_book/src/guide/toml_file.md @@ -0,0 +1,9 @@ +# TOML 文件说明 + +Toml 文件由一个 **[build]** 模块和多个 **[targets]** 模块组成。如果你想在 RuxOS 上运行,可以添加 **[os]** 模块。 + +* [builder 模块](./builder_module.md) + +* [target 模块](./target_module.md) + +* [os 模块](./os_module.md) \ No newline at end of file diff --git a/doc/ruxgo_book/src/installation.md b/doc/ruxgo_book/src/installation.md new file mode 100644 index 0000000..1c6b96c --- /dev/null +++ b/doc/ruxgo_book/src/installation.md @@ -0,0 +1,12 @@ +# Ruxgo 安装 +要从源代码构建`ruxgo`可执行文件,你首先需要安装 Rust 和 Cargo。按照[Rust安装页面](https://www.rust-lang.org/tools/install)上的说明操作。Ruxgo 目前至少需要 Rust 1.70 版本。 + +一旦你安装了 Rust,就可以使用以下命令来构建和安装 Ruxgo: + +```sh +cargo install --git https://github.com/Ybeichen/ruxgo.git ruxgo +``` + +这将自动下载、构建 Ruxgo,并将其安装到 Cargo 的全局二进制目录(默认为`~/.cargo/bin/`)。 + +要卸载,请执行命令`cargo uninstall ruxgo`。 diff --git a/doc/ruxgo_book/src/introduction.md b/doc/ruxgo_book/src/introduction.md new file mode 100644 index 0000000..3a2ae3a --- /dev/null +++ b/doc/ruxgo_book/src/introduction.md @@ -0,0 +1,5 @@ +# 简介 + +[Ruxgo](https://github.com/syswonder/ruxgo) 是一个类似 Cargo 的构建工具,用于构建 C 和 C++ 应用程序,它只依赖于一个 Toml 文件。它摒弃了原有 MAKE 构建工具中的复杂语法和依赖规则构造的方式,展现了最原始的编译过程。如果你讨厌使用 Makefile,不妨尝试使用 Ruxgo 来构建应用程序,只需花几分钟! + +如果你想要构建一个项目,你只需要弄清楚源文件路径、头文件路径、cflags 和 ldflags,然后将它们填写到 Toml 文件中的对应位置。剩下的都是 Ruxgo 做,很简单! \ No newline at end of file diff --git a/doc/ruxgo_book/src/run_apps.md b/doc/ruxgo_book/src/run_apps.md new file mode 100644 index 0000000..06ba146 --- /dev/null +++ b/doc/ruxgo_book/src/run_apps.md @@ -0,0 +1,17 @@ +# 运行不同的app +在`ruxgo/apps/`目录下放置了所有经过测试的 Toml 文件。目前,有两种方法构建应用程序: + +- 如果在本地构建,你只需要在`ruxgo/apps//local`目录下下载 app 的源代码,然后使用 ruxgo 构建并运行它。 + +- 如果在 RuxOS 上构建,你需要将`config_linux.toml`从`ruxgo/apps//ruxos`复制到`ruxos/apps/c/`,然后下载 app 的源代码并使用 ruxgo 来构建并运行它。 + +**注:** 有关详细信息,请参阅每个 app 目录下的 README.md。以下应用程序已获支持: + +* [x] [redis](https://github.com/Ybeichen/ruxgo/tree/master/apps/redis) +* [x] [sqlite3](https://github.com/Ybeichen/ruxgo/tree/master/apps/sqlite3) +* [x] [iperf](https://github.com/Ybeichen/ruxgo/tree/master/apps/iperf) +* [x] helloworld +* [x] memtest +* [x] httpclient +* [x] httpserver +* [x] nginx