Git Product home page Git Product logo

unikraft / unikraft Goto Github PK

View Code? Open in Web Editor NEW
2.3K 38.0 1.6K 7.4 MB

A next-generation cloud native kernel designed to unlock best-in-class performance, security primitives and efficiency savings.

Home Page: http://unikraft.org

License: Other

Makefile 0.75% Assembly 2.50% C 76.55% C++ 1.18% Shell 1.01% Perl 3.64% Lex 0.14% Yacc 0.22% Awk 0.23% Python 13.58% Rust 0.20%
unikernel unikraft library application operating-system os osdev kernel unikernels virtualization

unikraft's Introduction

Unikraft logo

The fast, secure and open-source
Unikernel Development Kit

Unikraft powers the next-generation of cloud native, containerless applications by enabling you to radically customize and build custom OS/kernels; unlocking best-in-class performance, security primitives and efficiency savings.

Homepage · Documentation · Report Bug · Feature Request · Join Our Discord · X.com



Features

  • Instantaneous Cold-boots

    • While Linux-based systems might take tens of seconds to boot, Unikraft will be up in milliseconds.
  • Modular Design 🧩

    • Unikraft boasts a modular design approach, allowing developers to include only necessary components, resulting in leaner and more efficient operating system configurations.
  • Optimized for Performance 🚀

    • Built for performance, Unikraft minimizes overheads and leverages platform-specific optimizations, ensuring applications achieve peak performance levels.
  • Flexible Architecture Support 💻

    • With support for multiple hardware architectures including x86, ARM, (and soon RISC-V), Unikraft offers flexibility in deployment across diverse hardware platforms.
  • Broad Language and Application Support 📚

    • Unikraft offers extensive support for multiple programming languages and hardware architectures, providing developers with the flexibility to choose the tools and platforms that best suit your needs.
  • Cloud and Edge Compatibility ☁️

    • Designed for cloud and edge computing environments, Unikraft enables seamless deployment of applications across distributed computing infrastructures.
  • Reduced Attack Surface 🛡️

    • By selectively including only necessary components, Unikraft reduces the attack surface, enhancing security in deployment scenarios. Unikraft also includes many additional modern security features.
  • Developer Friendly 🛠️

    • Unikraft's intuitive toolchain and user-friendly interface simplify the development process, allowing developers to focus on building innovative solutions.
  • Efficient Resource Utilization 🪶

    • Unikraft optimizes resource utilization, leading to smaller footprints (meaning higher server saturation) and improved efficiency in resource-constrained environments.
  • Community-Driven Development 👥

    • Unikraft is an open-source project driven by a vibrant community of over 100 developers, fostering collaboration and innovation from industry and academia.

Quick Start

Install the companion command-line client kraft:

# Install on macOS, Linux, and Windows:
curl -sSfL https://get.kraftkit.sh | sh

See additional installation instructions.

Run your first ultra-lightweight unikernel virtual machine:

kraft run unikraft.org/helloworld:latest

View its status and manage multiple instances:

kraft ps --all

View the community image catalog in your CLI for more apps:

kraft pkg ls --update --apps

Or browse through one of the many starter example projects.

Why Unikraft?

Unikraft is a radical, yet Linux-compatible with effortless tooling, technology for running applications as highly optimized, lightweight and single-purpose virtual machines (known as unikernels).

In today's computing landscape, efficiency is paramount. Unikraft addresses this need with its modular design, enabling developers to create customized, lightweight operating systems tailored to specific application requirements. By trimming excess overhead and minimizing attack surfaces, Unikraft enhances security and performance in cloud and edge computing environments.

Unikraft's focus on optimization ensures that applications run smoothly, leveraging platform-specific optimizations to maximize efficiency. With support for various hardware architectures and programming languages, Unikraft offers flexibility without compromising performance. In a world where resources are precious, Unikraft provides a pragmatic solution for streamlined, high-performance computing.

Getting Started

There are two ways to get started with Unikraft:

  1. (Recommended) Using the companion command-line tool kraft (covered below).

  2. Using the GNU Make-based system. For this, see our advanced usage guide.

Toolchain Installation

You can install the companion command-line client kraft by using the interactive installer:

# Install on macOS, Linux, and Windows:
curl -sSfL https://get.kraftkit.sh | sh

macOS

brew install unikraft/cli/kraftkit

Debian/Fedora/RHEL/Arch/Windows

Use the interactive installer or see additional installation instructions.

Codespaces

Try out one of the examples in GitHub Codespaces:

Open in GitHub Codespaces

Container Build Environment

You can use the pre-built development container environment which has all dependencies necessary for building and trying out Unikraft in emulation mode.

Attach your working directory on your host as a mount path volume mapped to /workspace, e.g.:

docker run --platform linux/x86_64 -it --rm -v $(pwd):/workspace --entrypoint bash kraftkit.sh/base:latest

The above command will drop you into a container shell. Type exit or Ctrl+D to quit.

Testing your Installation

Running unikernels with kraft is designed to be simple and familiar. To test your installation of kraft, you can run the following:

kraft run unikraft.org/helloworld:latest

Build your first unikernel

Building unikernels is also designed to be straightforward. Build your first unikernel by simply placing a Kraftfile into your repo and pointing it to your existing Dockerfile:

spec: v0.6

runtime: base:latest

rootfs: ./Dockerfile

cmd: ["/path/to/my-server-app"]

Learn more about the syntax of a Kraftfile.

Once done, invoke in the context of your working directory:

kraft run .

Example Projects and Pre-built Images

You can find some common project examples below:

Example
Simple "Hello, world!" application written in C
Simple "Hello, world!" application written in C++
Simple "Hello, world!" application written in Rust built via cargo
Simple NodeJS 18 HTTP Web Server with http
Simple Go 1.21 HTTP Web Server with net/http
Simple Flask 3.0 HTTP Web Server
Simple Python 3.10 HTTP Web Server with http.server.HTTPServer

Find more examples and applications in our community catalog!

Cloud Deployment

The creators of Unikraft have built KraftCloud: a next generation cloud platform powered by technology intended to work in millisecond timescales.

Millisecond Scale-to-Zero Millisecond Autoscale Millisecond Cold Boots
Higher Throughput Much Lower Cloud Bill HW-Level Isolation
On-Prem or Cloud-Prem Works with Docker & K8s Terraform Integration

Contributing

Unikraft is open-source and licensed under BSD-3-Clause and the copyright of its authors. If you would like to contribute:

  1. Read the Developer Certificate of Origin Version 1.1.
  2. Sign-off commits as described in the Developer Certificate of Origin Version 1.1.
  3. Grant copyright as detailed in the license header.

This ensures that users, distributors, and other contributors can rely on all the software related to Unikraft being contributed under the terms of the License. No contributions will be accepted without following this process.

Afterwards, navigate to the contributing guide to get started. See also Unikraft's coding conventions.

Additional resources

License

Unikraft Open-Source Project source code and its affiliated projects source code is licensed under a BSD-3-Clause if not otherwise stated. For more information, please refer to COPYING.md.

Affiliation

Unikraft is a member of the Linux Foundation and is a Xen Project Incubator Project. The Unikraft name, logo and its mascot are trademark of Unikraft GmbH.


LinuxFoundation logo     XenProject logo

unikraft's People

Contributors

andreittr avatar cbanu96 avatar clupuishere avatar consra avatar craciunoiuc avatar cristian-vijelie avatar dragosargint avatar eduardvintila avatar felipehuici avatar flpostolache avatar hlef avatar justin-he avatar kha-dinh avatar kubanrob avatar marcrittinghaus avatar michpappas avatar mihaipogonaru avatar mogasergiu avatar mschlumpp avatar nderjung avatar oleksiimoisieiev avatar radunico avatar razvand avatar razvanvirtan avatar roxanan1996 avatar skuenzer avatar stefanjum avatar vladandrew avatar weichen81 avatar yvolchkov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unikraft's Issues

"Processor optimization" in menuconfig does not enable necessary CPU features

"Processor optimization" in menuconfig sets compiler flags, but the entry code might not enable the right features to actually support this. Minimal example: add asm volatile ("VZEROALL\n" :::); (an AVX instruction) to lib/ukboot/boot.c:main(), and a kvm VM will crash:

Welcome to  _ __             _____
 __ _____  (_) /__ _______ _/ _/ /_
/ // / _ \/ /  '_// __/ _ `/ _/ __/
\_,_/_//_/_/_/\_\/_/  \_,_/_/ \__/
           Titan 0.2~b709bf3-custom
weak main() called. Symbol was not replaced!
[    0.406781] ERR:  [libukboot] boot.c @ 274  : weak main() called. Symbol was not replaced!
[    0.424291] CRIT: [libkvmplat] traps.c @ 65   : Unhandled Trap 6 (invalid opcode), error code=0x0
Regs address 0x120030
RIP: 00000000001090c6 CS: 0008
RSP: 000000000013ff80 SS: 0018 EFLAGS: 00010246
RAX: 000000000013fd60 RBX: 0000000000108b20 RCX: 000000000000000f
RDX: 00000000000003d4 RSI: 000000000000000b RDI: 00000000000003d4
RBP: 000000000013ffa0 R08: 0000000000000000 R09: 000000000013fea8
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[    0.521828] CRIT: [libkvmplat] traps.c @ 69   : Crashing
Unikraft halted

For this to work, we need to have additional code in the initialization code, e.g., something like this for AVX:

diff --git a/plat/common/include/x86/cpu_defs.h b/plat/common/include/x86/cpu_defs.h
index 9ecec96..9b16b9e 100644
--- a/plat/common/include/x86/cpu_defs.h
+++ b/plat/common/include/x86/cpu_defs.h
@@ -67,6 +67,7 @@
 #define X86_CR4_PAE             (1 << 5)    /* enable PAE */
 #define X86_CR4_OSFXSR          (1 << 9)    /* OS support for FXSAVE/FXRSTOR */
 #define X86_CR4_OSXMMEXCPT      (1 << 10)   /* OS support for FP exceptions */
+#define X86_CR4_OSXSAVE         (1 << 18)   /* XSAVE and extended states enable */
 
 /*
  * Intel CPU features in EFER
diff --git a/plat/kvm/x86/entry64.S b/plat/kvm/x86/entry64.S
index 35738b6..116dda7 100644
--- a/plat/kvm/x86/entry64.S
+++ b/plat/kvm/x86/entry64.S
@@ -180,8 +180,13 @@ ENTRY(_libkvmplat_start64)
        movq %rax, %cr0
        movq %cr4, %rax
        orq $(X86_CR4_OSXMMEXCPT | X86_CR4_OSFXSR), %rax
+       orq $(X86_CR4_OSXSAVE), %rax
        movq %rax, %cr4
        ldmxcsr (mxcsr_ptr)
+       xorl %ecx, %ecx
+       xgetbv
+       orq $(0x7), %rax
+       xsetbv

Then VZEROALL works. I guess we need some way to set these based on the CONFIG_* choices, because we can't simply add the code to all executions, because that code in itself will lead to crashes if those CPU features are not available. (Though I guess, alternatively, we could also check the VCPU's features and set them accordingly.)

Track changes of compile flags

The build system is currently not taking changes of compile flags or build commands into account for detecting which objects need to be recompiled. We have already fixdep taken from Linux so we should be able to adopt the build rules.

Unikernel QEMU/Stub Domains

The Xen architecture has the concept of "stub domains", where, in principle, dom0 functionality can be dissagregated onto multiple, separate VMs that together mimic the overall functionality of dom0. This improves reliability, performance/scalability and flexibility. This project consists of generating different stub domains based on Unikraft by porting the XenStore and QEMU to Unikraft..

Stack of various sizes (and current thread as global variable)

Currently all stacks have a fixed size, configured at build time.
We want to be able to allocate stacks of different sizes, at runtime (see pthread_attr_setstacksize and friends). This would mean we cannot save the current thread on the stack as we do it now (this being a solution imported from MiniOS). We will use a solution inspired by classical OSes (Linux, FreeBSD, etc) where current thread is saved on per-cpu data memory.

remove __i386__ code

We are never going to support 32-bit on x86, but we have "#ifdef i386" all over the place, which hurts readability. Also many files will shrink dramatically

probably a bug in uk_posix_memalign_ifpages

Hi

I am using uk_posix_memalign_ifpages to allocate memory for a stack and get, let's say, 0x7fb2ae400000.
the corresponding metadata is stored at 0x7fb2ae3ff000 (a previous page, as it stated in alloc.c).
I look inside this structure and see that the allocation starts from 0x7fb2ae000000 and includes 801 pages. I am trying to figure out how the number 801 appears and don't understand. I think it should be 800, because the metadata page is a part of the padding.

I thought the function always returns one additional page, but, when I use it to allocate a smaller memory region, let's say 0x1008 bytes aligned at 8, I receive something like:

return = 0x7fb2ac018010, metadata= 0x7fb2ac018000, metadada.begin = 0x7fb2ac018000 metadata.num_pages = 2. This result is correct, and the metadata page is included into the range.

Django on Unikraft

Unikraft supports Pyhonv3, and the Django packages can be installed via pip. Right now the port crashes because we don't have an implementation of socketpair(), though after fixing this other issues may arise. This project consists of going through these, with the aim of having Django run on Unikraft.

Remove forced timer ticks

Each platform installs a timer for scheduling. Rework on the API to avoid forced ticks.
THere should be a ukplat_ function to setup a time once in order to get back control to the scheduler (e.g., to support preemption).

Reintroduce original vfscore as ukfdtab

The original VFScore implementation was implementing jsut a file descriptor lookup table providing basic callbacks for read/write/... etc. If we do not need any real filesystem, just a few sockets and maybe unnamed pipes, this implementation is good enough for those unikernels and much more specialized. The idea would be to provide ukfdtab as vfscore alternative and maybe introduce macros that map to particular fd creation functionalities depending on which one of the libs is chosen. This way we can keep a single implementation for file descriptor openers provides by other libraries (e.g., socket(), ...).

Move fdtable into its own library (posix-fdtab)

The posix-fdtab internal library will provide the file descriptor abstraction. A file descriptor table will be provided per-thread, if cloned that way.

The fdtable entry is currently held within the vfscore internal microlibrary and sees use with other contexts. This includes libraries which wish to register their own file descriptor type, including vfscore.

The library will provide the interface to register the syscalls that you can have with any file descriptor (read, write, close, etc.).

The file descriptor constructor syscalls (open, socket, eventfd, etc.) will be provided by the according subsystem libraries (e.g, vfscore, posix-socket).

Build system: Recompile an object whenever compiler arguments have changed

Make is not taking compile flags into account for recompilation. We have some weird cases where we have to make clean and make again to solve some problems. Examples:

  • Whenever we switch between newlib and internal nolibc
  • A library is configured by passing MACRO definition as compiler flag (-D) instead of the gnerated KConfig _config.h header
    Since we introduced fixdep from Kbuild, we have almost all pieces for doing this stuff. We just need to port some rules from kbuild.rules (Linux) to make it work. The .d files store already the build command line.

Musl Support

Add support for Musl as standard C library in Unikraft.

Summary of objectives

  • Port Musl
  • Port / test threading support (including clone system call)
  • Test and validate implementation

procfs Support

Applications built for Linux make use of proc filesystem entries.
With procfs support, more applications can be ported.

procfs will use lib/ukstore entries, when available.

KVM/Optimize for Performance casues GPF

Some (many?) languages/applications crash with a page fault or GPF when using KVM and setting Optimization level ---> Optimize for performance in the menu (e.g., this is the case with the Intel WAMR port). Other settings for Optimization level work fine.

nolibc: integer min and max macros (UINT16_MAX etc.) should be defined in stdint.h, not limits.h

This is according to POSIX:
http://pubs.opengroup.org/onlinepubs/007904975/basedefs/stdint.h.html
http://pubs.opengroup.org/onlinepubs/007904975/basedefs/limits.h.html
The change itself is not very complicated (we should just make sure while we're at it that all the correct defines are being provided, considering defines never increase code size anyway), but we need to make sure this change doesn't break any builds that relied on this wrong include.

Two threads waiting on a third with uk_thread_wait() leads to crashes

This is because there's a race condition. My description on the mailing list: "If more than one thread waits on the same other thread, then all of those waiting threads will wait in uk_waitq_event(). The first thread that wakes up after the thread has finished will then proceed to destroy the thread management structure. Every other waiting thread will try to do the same after waking up, ending up with duplicate free's and a crash of that thread."
I first though this could be fixed by only calling uk_thread_destroy in uk_thread_wait is the waitq is empty (i.e., since we just removed ourselves from the waitq, we're the last thread waiting), however, there's also a uk_thread_destroy in the schedcoop implementation, and the race condition still exists afterwards.
Some test code to trigger the problem:

#include <stdio.h>
#include <unistd.h>
#include <uk/sched.h>
#include <uk/config.h>

void print_thread(void *arg __unused)
{
struct uk_thread *cur = uk_thread_current();

uk_pr_crit("This is thread 0x%p\n", cur);
uk_pr_crit("sleeping a bit\n");
sleep(3);
uk_pr_crit("We're done!\n");

}

void wait_for_thread(void *arg)
{
struct uk_thread *cur = uk_thread_current();
struct uk_thread *waitfor = (struct uk_thread *)arg;
int ret;

uk_pr_crit("This is thread 0x%p\n", cur);
uk_pr_crit("Waiting for thread 0x%p\n", waitfor);
ret = uk_thread_wait(waitfor);
uk_pr_crit("uk_thread_wait returned %d\n", ret);
uk_pr_crit("We're done waiting!\n");

}

int main(int argc __unused, char *argv[] __unused)
{
struct uk_thread *t, *t2, *t3;

t = uk_thread_create("sleep", print_thread, NULL);
t2 = uk_thread_create("wait1", wait_for_thread, t);
t3 = uk_thread_create("wait2", wait_for_thread, t);
uk_thread_wait(t3);
uk_thread_wait(t2);

uk_pr_crit("Before sleep\n");
sleep(10);
uk_pr_crit("After sleep\n");
sleep(1);
uk_sched_yield();
uk_pr_crit("Thread test done\n");

return 0;

}

Introduce external library checksums

This issue recommends the the ability to provide a checksum for an external library's source code to be used after the make fetch stage of the unikernel compilation.

For example, checksums would be provided in-line Makefile.uk:

LIBMYLIB_VERSION = 1.0.0
LIBMYLIB_URL = https://github.com/mylib/mylib/archive/v$(LIBMYLIB_VERSION).zip
LIBMYLIB_SHA256 = df5c1978aa5530d8edf411f5091c904386858b8cd93ee5d3bc388f450ce12997

any known bug in vfscore?

Hi

I am trying to benchmark sqlite by the speedtest1 benchmark on top the linuxu build. everything works fine, but sometimes and in very special circumstances I receive an I/O error caused by the unlik syscall. this syscall checks the v_flags field, and returns EBUSY if the field is VROOT. the problem is that sometimes this field has very unexpected values:

 100 - 50000 INSERTs into table with no index...................... vp->v_flags = 45542063   0.120s
 150 - CREATE INDEX five times..................................... vp->v_flags = 0vp->v_flags = 0vp->v_flags = 0   4.728s
 230 - 10000 UPDATES, numeric BETWEEN, indexed..................... vp->v_flags = 69732c72   0.661s

or, in some cases, the flag value is 1, but this is wrong (it is an ordinary file that was created early)

is there any know bug? I am using slightly modified environment to run unikraft, maybe it is a problem.

unikraft: 00bbf2c
newlib: ddc1a4308f9ec8ce742d80e6203a4e76ae5bf802
sqlite: 21ec31d578295982619a164de96b653e93e7cf9c

I don't use pthreads:

LIBS := $(UK_LIBS)/libsqlite:$(UK_LIBS)/newlib

and build sqlite with -DSQLITE_THREADSAFE=0

thank you

Memory Ballooning

Implement memory ballooning driver for Unikraft.

Summary of objectives

  • Implement memory ballooning support in KVM
  • Implement memory ballooning support in Xen

arm32 linuxu is broken

/mnt/filesystems/roaming/workspace/Project/Unikraft/Unikraft_Review/Unikraft/plat/common/sw_ctx.c:64:2: note: in expansion of macro ‘uk_pr_debug’
uk_pr_debug("Allocating %lu bytes for sw ctx at %p\n", sz, ctx);
^~~~~~~~~~~
In file included from /mnt/filesystems/roaming/workspace/Project/Unikraft/Unikraft_Review/Unikraft/plat/common/sw_ctx.c:42:0:
/mnt/filesystems/roaming/workspace/Project/Unikraft/Unikraft_Review/Unikraft/plat/common/include/x86/cpu.h:72:3: error: impossible constraint in ‘asm’
asm volatile("xsave (%0)" :: "r"(ctx->extregs),
^~~
/mnt/filesystems/roaming/workspace/Project/Unikraft/Unikraft_Review/Unikraft/plat/common/include/x86/cpu.h:76:3: error: impossible constraint in ‘asm’
asm volatile("xsaveopt (%0)" :: "r"(ctx->extregs),

remove code under #ifndef CONFIG_PARAVIRT

We inherited bits of PVH code from Minios. The problem is this code did not work even for Minios. There is little point in keeping these bits. However it might be good to keep the -DCONFIG_PARAVIRT, as hints for future

Implement IO multiplex / posix-fdpoll

epoll and select represent two POSIX methods for IO multipex. Currently, select is provided by the external library LwIP and does not reflect use of alternative file descriptors.

These two methods should be provided as a driver mechanism which allows external libraries to register interest in a custom implementation.

FS drivers and vfscore_uiomove

Hi

When VFSCORE deals with RAMFS, it uses ramfs_read and ramfs_write to read and write data. However, these methods, in turn, call vfscore_uiomove for data transfer. Could you please help me to understand the rationale behind that? vfscore_uiomove, in essence, is just memcpy, why not do this inside RAMFS?

thank you.

Fix xen ukplat_monotonic_clock

n Xen, ukplat_monotonic_clock returns the time elapsed (in nanoseconds) since the xen hypervisor booted, not since ukplat_time_init (as the function docs for ukplat_monotonic_clock say).

Clean up library names

There's a few inconsistencies, here are my suggestions:

-POSIX process-related functions
+posix-process: Process-related functions
-syscall_shim: Syscall shim layer
+syscall-shim: Syscall shim layer
-POSIX sysinfo: Information about system parameters
+posix-sysinfo: Information about system parameters
-POSIX user-related functions
+posix-user: User-related functions

Xen Project and Unikraft.

Hello Unikraft team,
The Xen Project is in the frontline of the Unikernel projects, but why the team working on the KVM? I can remember that the Unikraft introduced by Xen Project!
Please improve Xen supporting.

Thanks.

Remove internal fixed size integer datatypes (e.g., __u32)

Fixed size integer definitions are provided by the included libc. In principle it should be possible to user uint32_t for everything. Since a libc (including nolibc) is anyway required, those extra dataypes could be removed in order to reduce confusion (especially APIs in include/ folder). All code should then use the standard types. The internal definition is technically not required.
The original idea was to have API definition on include/ completely indepen dent of any libraries. A clean solution is required if this dependency is added (e.g., by moving them to into a library?, like an libukplat API lib?)

remove os.h

placed at plat/xen/include/xen-{x86,arm}.
The files do not make sense. X86 version barely has anything in it, and patches are already out.
It is better to remove the arm version too, for the sake of consistency. Especially since the only meaningful part in it is irq manipulation functions, which do not belong there anyways.
It makes sense to remove that after arm32 build is fixed (patches are already out)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.